diff --git a/docs/ko/automation/cron-jobs.md b/docs/ko/automation/cron-jobs.md index 443cf3c5b..07edb773a 100644 --- a/docs/ko/automation/cron-jobs.md +++ b/docs/ko/automation/cron-jobs.md @@ -2,25 +2,25 @@ read_when: - 백그라운드 작업 또는 깨우기 예약 - 외부 트리거(Webhook, Gmail)를 OpenClaw에 연결하기 - - 예약된 작업에 Heartbeat와 Cron 중 무엇을 사용할지 결정하기 + - 예약 작업에 Heartbeat와 Cron 중 무엇을 사용할지 결정하기 sidebarTitle: Scheduled tasks -summary: Gateway 스케줄러를 위한 예약된 작업, Webhook 및 Gmail PubSub 트리거 +summary: Gateway 스케줄러를 위한 예약 작업, Webhook 및 Gmail PubSub 트리거 title: 예약된 작업 x-i18n: - generated_at: "2026-05-02T20:41:37Z" + generated_at: "2026-05-06T17:52:32Z" model: gpt-5.5 provider: openai - source_hash: d7c70042c28b08140d664678ef42146942158512dce1f41c988be0f2dd9bedf5 + source_hash: 19c3505408ab7602775dc1168c2c7a626986fa2a15ef02a44dc864d5ec538bfe source_path: automation/cron-jobs.md workflow: 16 --- -Cron은 Gateway에 내장된 스케줄러입니다. 작업을 영구 저장하고, 적절한 시간에 에이전트를 깨우며, 출력을 채팅 채널이나 Webhook 엔드포인트로 다시 전달할 수 있습니다. +Cron은 Gateway에 내장된 스케줄러입니다. 작업을 영구 저장하고, 적절한 시간에 에이전트를 깨우며, 출력을 채팅 채널 또는 Webhook 엔드포인트로 다시 전달할 수 있습니다. ## 빠른 시작 - + ```bash openclaw cron add \ --name "Reminder" \ @@ -46,24 +46,25 @@ Cron은 Gateway에 내장된 스케줄러입니다. 작업을 영구 저장하 ## Cron 작동 방식 -- Cron은 **Gateway** 프로세스 내부에서 실행됩니다(모델 내부가 아님). -- 작업 정의는 `~/.openclaw/cron/jobs.json`에 영구 저장되므로 다시 시작해도 스케줄이 사라지지 않습니다. -- 런타임 실행 상태는 그 옆의 `~/.openclaw/cron/jobs-state.json`에 영구 저장됩니다. git에서 Cron 정의를 추적한다면 `jobs.json`을 추적하고 `jobs-state.json`은 gitignore에 추가하세요. -- 분리 이후에는 이전 OpenClaw 버전이 `jobs.json`을 읽을 수 있지만, 런타임 필드가 이제 `jobs-state.json`에 있으므로 작업을 새 작업으로 취급할 수 있습니다. -- Gateway가 실행 중이거나 중지된 동안 `jobs.json`을 편집하면, OpenClaw는 변경된 스케줄 필드를 보류 중인 런타임 슬롯 메타데이터와 비교하고 오래된 `nextRunAtMs` 값을 지웁니다. 순수한 서식 변경이나 키 순서만 바꾼 재작성은 보류 중인 슬롯을 보존합니다. -- 모든 Cron 실행은 [백그라운드 작업](/ko/automation/tasks) 레코드를 만듭니다. -- Gateway 시작 시, 기한이 지난 격리된 에이전트 턴 작업은 즉시 재생되는 대신 채널 연결 창 밖으로 다시 스케줄링되므로 다시 시작 후에도 Discord/Telegram 시작과 네이티브 명령 설정이 빠르게 응답합니다. +- Cron은 **Gateway 내부** 프로세스에서 실행됩니다(모델 내부가 아님). +- 작업 정의는 `~/.openclaw/cron/jobs.json`에 영구 저장되므로 재시작해도 스케줄이 손실되지 않습니다. +- 런타임 실행 상태는 그 옆의 `~/.openclaw/cron/jobs-state.json`에 영구 저장됩니다. Cron 정의를 git에서 추적한다면 `jobs.json`을 추적하고 `jobs-state.json`은 gitignore에 추가하세요. +- 분리 이후 이전 OpenClaw 버전은 `jobs.json`을 읽을 수 있지만, 런타임 필드가 이제 `jobs-state.json`에 있으므로 작업을 새 작업처럼 처리할 수 있습니다. +- Gateway가 실행 중이거나 중지된 동안 `jobs.json`이 편집되면 OpenClaw는 변경된 스케줄 필드를 대기 중인 런타임 슬롯 메타데이터와 비교하고 오래된 `nextRunAtMs` 값을 지웁니다. 순수한 형식 변경이나 키 순서만 바뀐 재작성은 대기 중인 슬롯을 보존합니다. +- 모든 Cron 실행은 [백그라운드 작업](/ko/automation/tasks) 레코드를 생성합니다. +- Gateway 시작 시 기한이 지난 격리된 에이전트 턴 작업은 즉시 재생되는 대신 채널 연결 창 밖으로 다시 스케줄되므로, 재시작 후에도 Discord/Telegram 시작과 네이티브 명령 설정이 응답성을 유지합니다. - 일회성 작업(`--at`)은 기본적으로 성공 후 자동 삭제됩니다. -- 격리된 Cron 실행은 실행이 완료되면 해당 `cron:` 세션의 추적된 브라우저 탭/프로세스를 최선의 노력으로 닫아, 분리된 브라우저 자동화가 고아 프로세스를 남기지 않도록 합니다. -- 격리된 Cron 실행은 오래된 확인 응답도 방지합니다. 첫 결과가 단순한 중간 상태 업데이트(`on it`, `pulling everything together` 및 유사한 힌트)이고 최종 답변을 담당하는 하위 서브에이전트 실행이 더 이상 없다면, OpenClaw는 전달 전에 실제 결과를 한 번 다시 요청합니다. -- 격리된 Cron 실행은 임베디드 실행의 구조화된 실행 거부 메타데이터를 우선 사용한 다음, `SYSTEM_RUN_DENIED`와 `INVALID_REQUEST` 같은 알려진 최종 요약/출력 마커로 폴백하므로, 차단된 명령이 성공한 실행으로 보고되지 않습니다. -- 격리된 Cron 실행은 응답 페이로드가 생성되지 않아도 실행 수준의 에이전트 실패를 작업 오류로 취급하므로, 모델/제공자 실패는 오류 카운터를 증가시키고 작업을 성공으로 지우는 대신 실패 알림을 트리거합니다. -- 격리된 에이전트 턴 작업이 `timeoutSeconds`에 도달하면 Cron은 기본 에이전트 실행을 중단하고 짧은 정리 시간을 제공합니다. 실행이 비워지지 않으면 Gateway 소유 정리가 Cron이 타임아웃을 기록하기 전에 해당 실행의 세션 소유권을 강제로 지워, 대기 중인 채팅 작업이 오래된 처리 세션 뒤에 남지 않도록 합니다. +- 격리된 Cron 실행은 실행이 완료되면 해당 `cron:` 세션의 추적된 브라우저 탭/프로세스를 최선의 방식으로 닫으므로, 분리된 브라우저 자동화가 고아 프로세스를 남기지 않습니다. +- 좁은 범위의 Cron 자체 정리 권한을 받은 격리된 Cron 실행은 여전히 스케줄러 상태와 현재 작업에 대한 자체 필터링된 목록을 읽을 수 있으므로, 상태/Heartbeat 확인은 더 넓은 Cron 변경 접근 권한을 얻지 않고도 자체 스케줄을 검사할 수 있습니다. +- 격리된 Cron 실행은 오래된 확인 응답도 방지합니다. 첫 번째 결과가 중간 상태 업데이트(`on it`, `pulling everything together` 및 유사한 힌트)일 뿐이고 최종 답변을 아직 담당하는 하위 서브에이전트 실행이 없다면, OpenClaw는 전달 전에 실제 결과를 한 번 다시 요청합니다. +- 격리된 Cron 실행은 임베디드 실행의 구조화된 실행 거부 메타데이터를 우선 사용한 다음, `SYSTEM_RUN_DENIED` 및 `INVALID_REQUEST` 같은 알려진 최종 요약/출력 마커로 폴백하므로, 차단된 명령이 성공한 실행으로 보고되지 않습니다. +- 격리된 Cron 실행은 응답 페이로드가 생성되지 않은 경우에도 실행 수준의 에이전트 실패를 작업 오류로 처리하므로, 모델/프로바이더 실패는 작업을 성공으로 지우는 대신 오류 카운터를 증가시키고 실패 알림을 트리거합니다. +- 격리된 에이전트 턴 작업이 `timeoutSeconds`에 도달하면 Cron은 기본 에이전트 실행을 중단하고 짧은 정리 창을 제공합니다. 실행이 비워지지 않으면 Gateway 소유 정리가 Cron이 타임아웃을 기록하기 전에 해당 실행의 세션 소유권을 강제로 지우므로, 대기 중인 채팅 작업이 오래된 처리 세션 뒤에 남지 않습니다. -Cron의 작업 조정은 먼저 런타임 소유이고, 그다음은 내구성 있는 기록 기반입니다. 활성 Cron 작업은 오래된 하위 세션 행이 아직 존재하더라도 Cron 런타임이 해당 작업을 실행 중으로 추적하는 동안 계속 활성 상태로 유지됩니다. 런타임이 작업 소유를 중지하고 5분 유예 시간이 만료되면, 유지 관리가 일치하는 `cron::` 실행의 영구 실행 로그와 작업 상태를 확인합니다. 해당 내구성 있는 기록에 종료 결과가 있으면 작업 원장이 그 기록에서 확정되고, 그렇지 않으면 Gateway 소유 유지 관리가 작업을 `lost`로 표시할 수 있습니다. 오프라인 CLI 감사는 내구성 있는 기록에서 복구할 수 있지만, 자체적으로 비어 있는 인프로세스 활성 작업 집합을 Gateway 소유 Cron 실행이 사라졌다는 증거로 취급하지 않습니다. +Cron의 작업 조정은 먼저 런타임 소유이고, 그다음으로 내구성 있는 기록 기반입니다. 활성 Cron 작업은 오래된 자식 세션 행이 여전히 존재하더라도 Cron 런타임이 해당 작업을 실행 중으로 계속 추적하는 동안 라이브 상태로 유지됩니다. 런타임이 작업 소유를 중지하고 5분 유예 시간이 만료되면, 유지 관리 검사는 일치하는 `cron::` 실행에 대해 영구 저장된 실행 로그와 작업 상태를 확인합니다. 해당 내구성 있는 기록이 종료 결과를 보여주면 작업 원장이 그 결과로 마무리됩니다. 그렇지 않으면 Gateway 소유 유지 관리가 작업을 `lost`로 표시할 수 있습니다. 오프라인 CLI 감사는 내구성 있는 기록에서 복구할 수 있지만, 자체의 비어 있는 인프로세스 활성 작업 집합을 Gateway 소유 Cron 실행이 사라졌다는 증거로 취급하지 않습니다. ## 스케줄 유형 @@ -74,13 +75,13 @@ Cron의 작업 조정은 먼저 런타임 소유이고, 그다음은 내구성 | `every` | `--every` | 고정 간격 | | `cron` | `--cron` | 선택적 `--tz`가 있는 5필드 또는 6필드 Cron 표현식 | -시간대가 없는 타임스탬프는 UTC로 처리됩니다. 로컬 시계 기준 스케줄링에는 `--tz America/New_York`를 추가하세요. +시간대가 없는 타임스탬프는 UTC로 처리됩니다. 로컬 벽시계 기준 스케줄링에는 `--tz America/New_York`를 추가하세요. 매시 정각에 반복되는 표현식은 부하 급증을 줄이기 위해 자동으로 최대 5분까지 분산됩니다. 정확한 타이밍을 강제하려면 `--exact`를 사용하고, 명시적 창을 지정하려면 `--stagger 30s`를 사용하세요. -### 월의 일자와 요일은 OR 논리를 사용합니다 +### 일(day-of-month)과 요일(day-of-week)은 OR 논리를 사용합니다 -Cron 표현식은 [croner](https://github.com/Hexagon/croner)로 파싱됩니다. 월의 일자 필드와 요일 필드가 모두 와일드카드가 아니면, croner는 두 필드가 모두 일치할 때가 아니라 **둘 중 하나**가 일치할 때 매치합니다. 이는 표준 Vixie cron 동작입니다. +Cron 표현식은 [croner](https://github.com/Hexagon/croner)로 파싱됩니다. 일 필드와 요일 필드가 모두 와일드카드가 아닌 경우, croner는 두 필드가 모두 일치할 때가 아니라 **둘 중 하나**가 일치할 때 매칭합니다. 이는 표준 Vixie cron 동작입니다. ``` # Intended: "9 AM on the 15th, only if it's a Monday" @@ -88,48 +89,48 @@ Cron 표현식은 [croner](https://github.com/Hexagon/croner)로 파싱됩니다 0 9 15 * 1 ``` -이는 월 0~1회가 아니라 약 5~6회 실행됩니다. OpenClaw는 여기서 Croner의 기본 OR 동작을 사용합니다. 두 조건을 모두 요구하려면 Croner의 `+` 요일 수정자(`0 9 15 * +1`)를 사용하거나, 한 필드로 스케줄링하고 다른 조건은 작업의 프롬프트나 명령에서 검사하세요. +이는 한 달에 0~1회가 아니라 약 5~6회 실행됩니다. OpenClaw는 여기서 Croner의 기본 OR 동작을 사용합니다. 두 조건을 모두 요구하려면 Croner의 `+` 요일 수정자(`0 9 15 * +1`)를 사용하거나, 한 필드로 스케줄하고 작업의 프롬프트 또는 명령에서 다른 조건을 검사하세요. ## 실행 스타일 | 스타일 | `--session` 값 | 실행 위치 | 적합한 용도 | | --------------- | ------------------- | ------------------------ | ------------------------------- | -| 기본 세션 | `main` | 다음 Heartbeat 턴 | 알림, 시스템 이벤트 | -| 격리됨 | `isolated` | 전용 `cron:` | 보고서, 백그라운드 작업 | +| 메인 세션 | `main` | 다음 Heartbeat 턴 | 리마인더, 시스템 이벤트 | +| 격리 | `isolated` | 전용 `cron:` | 보고서, 백그라운드 작업 | | 현재 세션 | `current` | 생성 시점에 바인딩됨 | 컨텍스트 인식 반복 작업 | -| 사용자 지정 세션 | `session:custom-id` | 영구 이름 지정 세션 | 기록을 기반으로 쌓아 가는 워크플로 | +| 사용자 지정 세션 | `session:custom-id` | 영구 명명 세션 | 기록을 기반으로 이어지는 워크플로 | - - **기본 세션** 작업은 시스템 이벤트를 큐에 넣고 선택적으로 Heartbeat를 깨웁니다(`--wake now` 또는 `--wake next-heartbeat`). 이러한 시스템 이벤트는 대상 세션의 일일/유휴 재설정 최신성을 연장하지 않습니다. **격리된** 작업은 새 세션으로 전용 에이전트 턴을 실행합니다. **사용자 지정 세션**(`session:xxx`)은 실행 간 컨텍스트를 영구 유지하여 이전 요약을 기반으로 쌓아 가는 일일 스탠드업 같은 워크플로를 가능하게 합니다. + + **메인 세션** 작업은 시스템 이벤트를 큐에 넣고 선택적으로 Heartbeat를 깨웁니다(`--wake now` 또는 `--wake next-heartbeat`). 이러한 시스템 이벤트는 대상 세션의 일일/유휴 재설정 신선도를 연장하지 않습니다. **격리** 작업은 새로운 세션에서 전용 에이전트 턴을 실행합니다. **사용자 지정 세션**(`session:xxx`)은 실행 간 컨텍스트를 유지하여 이전 요약을 기반으로 하는 일일 스탠드업 같은 워크플로를 가능하게 합니다. - - 격리된 작업에서 "새 세션"은 각 실행마다 새로운 트랜스크립트/세션 ID를 의미합니다. OpenClaw는 thinking/fast/verbose 설정, 레이블, 명시적으로 사용자가 선택한 모델/인증 재정의 같은 안전한 기본 설정을 가져올 수 있지만, 이전 Cron 행의 주변 대화 컨텍스트는 상속하지 않습니다. 여기에는 채널/그룹 라우팅, 전송 또는 큐 정책, 승격, 출처, ACP 런타임 바인딩이 포함됩니다. 반복 작업이 의도적으로 동일한 대화 컨텍스트를 기반으로 해야 한다면 `current` 또는 `session:`를 사용하세요. + + 격리 작업에서 "새 세션"은 각 실행마다 새 트랜스크립트/세션 ID를 의미합니다. OpenClaw는 thinking/fast/verbose 설정, 레이블, 명시적으로 사용자가 선택한 모델/인증 오버라이드 같은 안전한 선호 설정을 유지할 수 있지만, 이전 Cron 행의 주변 대화 컨텍스트인 채널/그룹 라우팅, 전송 또는 큐 정책, 권한 상승, 출처 또는 ACP 런타임 바인딩은 상속하지 않습니다. 반복 작업이 의도적으로 동일한 대화 컨텍스트를 기반으로 이어져야 하는 경우 `current` 또는 `session:`를 사용하세요. - 격리된 작업의 경우 런타임 해체에는 이제 해당 Cron 세션에 대한 최선의 브라우저 정리가 포함됩니다. 정리 실패는 무시되므로 실제 Cron 결과가 여전히 우선합니다. + 격리 작업의 경우 런타임 종료에는 이제 해당 Cron 세션에 대한 최선의 브라우저 정리가 포함됩니다. 실제 Cron 결과가 우선되도록 정리 실패는 무시됩니다. - 격리된 Cron 실행은 공유 런타임 정리 경로를 통해 작업을 위해 생성된 번들 MCP 런타임 인스턴스도 모두 폐기합니다. 이는 기본 세션 및 사용자 지정 세션 MCP 클라이언트를 해체하는 방식과 일치하므로, 격리된 Cron 작업은 실행 간에 stdio 하위 프로세스나 오래 지속되는 MCP 연결을 누수하지 않습니다. + 격리된 Cron 실행은 공유 런타임 정리 경로를 통해 작업에 대해 생성된 번들 MCP 런타임 인스턴스도 모두 폐기합니다. 이는 메인 세션 및 사용자 지정 세션 MCP 클라이언트가 종료되는 방식과 일치하므로, 격리된 Cron 작업은 실행 간 stdio 자식 프로세스나 장기 실행 MCP 연결을 누수하지 않습니다. - 격리된 Cron 실행이 서브에이전트를 오케스트레이션할 때, 전달도 오래된 부모 중간 텍스트보다 최종 하위 출력을 선호합니다. 하위 실행이 아직 실행 중이면 OpenClaw는 해당 부분적인 부모 업데이트를 알리는 대신 억제합니다. + 격리된 Cron 실행이 서브에이전트를 오케스트레이션할 때, 전달은 오래된 부모 중간 텍스트보다 최종 하위 출력도 우선합니다. 하위 항목이 아직 실행 중이면 OpenClaw는 해당 부분적인 부모 업데이트를 알리는 대신 억제합니다. - 텍스트 전용 Discord 알림 대상의 경우, OpenClaw는 스트리밍/중간 텍스트 페이로드와 최종 답변을 모두 재생하는 대신 표준 최종 어시스턴트 텍스트를 한 번 보냅니다. 미디어 및 구조화된 Discord 페이로드는 첨부 파일과 구성 요소가 누락되지 않도록 여전히 별도 페이로드로 전달됩니다. + 텍스트 전용 Discord 알림 대상의 경우 OpenClaw는 스트리밍/중간 텍스트 페이로드와 최종 답변을 모두 재생하는 대신 표준 최종 어시스턴트 텍스트를 한 번 전송합니다. 미디어 및 구조화된 Discord 페이로드는 첨부 파일과 컴포넌트가 누락되지 않도록 여전히 별도 페이로드로 전달됩니다. -### 격리된 작업의 페이로드 옵션 +### 격리 작업의 페이로드 옵션 - 프롬프트 텍스트(격리된 작업에 필요). + 프롬프트 텍스트(격리에는 필수). - 모델 재정의입니다. 작업에 선택된 허용 모델을 사용합니다. + 모델 오버라이드입니다. 작업에 선택된 허용 모델을 사용합니다. - Thinking 수준 재정의입니다. + 사고 수준 오버라이드입니다. 워크스페이스 부트스트랩 파일 주입을 건너뜁니다. @@ -138,48 +139,48 @@ Cron 표현식은 [croner](https://github.com/Hexagon/croner)로 파싱됩니다 작업이 사용할 수 있는 도구를 제한합니다. 예: `--tools exec,read`. -`--model`은 선택된 허용 모델을 해당 작업의 기본 모델로 사용합니다. 이는 채팅 세션 `/model` 재정의와 같지 않습니다. 작업 기본 모델이 실패하면 구성된 폴백 체인이 계속 적용됩니다. 요청된 모델이 허용되지 않거나 확인될 수 없으면, Cron은 작업의 에이전트/기본 모델 선택으로 조용히 폴백하는 대신 명시적 검증 오류로 실행을 실패시킵니다. +`--model`은 선택된 허용 모델을 해당 작업의 기본 모델로 사용합니다. 이는 채팅 세션 `/model` 오버라이드와 같지 않습니다. 작업 기본 모델이 실패해도 구성된 폴백 체인은 계속 적용됩니다. 요청한 모델이 허용되지 않았거나 확인할 수 없으면, Cron은 작업의 에이전트/기본 모델 선택으로 조용히 폴백하는 대신 명시적 검증 오류로 실행을 실패 처리합니다. -Cron 작업은 페이로드 수준의 `fallbacks`도 포함할 수 있습니다. 존재할 경우 해당 목록은 작업에 구성된 폴백 체인을 대체합니다. 선택된 모델만 시도하는 엄격한 Cron 실행을 원하면 작업 페이로드/API에서 `fallbacks: []`를 사용하세요. 작업에 `--model`이 있지만 페이로드 폴백도 구성된 폴백도 없다면, OpenClaw는 명시적인 빈 폴백 재정의를 전달하여 에이전트 기본 모델이 숨겨진 추가 재시도 대상으로 추가되지 않도록 합니다. +Cron 작업은 페이로드 수준의 `fallbacks`도 포함할 수 있습니다. 이 목록이 있으면 작업에 대해 구성된 폴백 체인을 대체합니다. 선택한 모델만 시도하는 엄격한 Cron 실행을 원할 때는 작업 페이로드/API에서 `fallbacks: []`를 사용하세요. 작업에 `--model`이 있지만 페이로드나 구성된 폴백이 없으면, OpenClaw는 명시적인 빈 폴백 오버라이드를 전달하여 에이전트 기본 모델이 숨겨진 추가 재시도 대상으로 덧붙지 않게 합니다. -격리된 작업의 모델 선택 우선순위는 다음과 같습니다. +격리 작업의 모델 선택 우선순위는 다음과 같습니다. -1. Gmail hook 모델 재정의(실행이 Gmail에서 왔고 해당 재정의가 허용되는 경우) +1. Gmail 훅 모델 오버라이드(실행이 Gmail에서 왔고 해당 오버라이드가 허용되는 경우) 2. 작업별 페이로드 `model` -3. 사용자가 선택해 저장한 Cron 세션 모델 재정의 +3. 사용자가 선택해 저장한 Cron 세션 모델 오버라이드 4. 에이전트/기본 모델 선택 -빠른 모드도 확인된 라이브 선택을 따릅니다. 선택된 모델 구성에 `params.fastMode`가 있으면 격리된 Cron은 기본적으로 이를 사용합니다. 저장된 세션 `fastMode` 재정의는 어느 방향이든 여전히 구성보다 우선합니다. +빠른 모드도 확인된 라이브 선택을 따릅니다. 선택한 모델 구성에 `params.fastMode`가 있으면 격리된 Cron은 기본적으로 이를 사용합니다. 저장된 세션 `fastMode` 오버라이드는 어느 방향이든 구성보다 우선합니다. -격리된 실행이 라이브 모델 전환 핸드오프에 도달하면, Cron은 전환된 제공자/모델로 다시 시도하고 재시도하기 전에 활성 실행에 해당 라이브 선택을 영구 저장합니다. 전환에 새 인증 프로필도 포함되어 있으면, Cron은 활성 실행에 해당 인증 프로필 재정의도 영구 저장합니다. 재시도에는 한도가 있습니다. 최초 시도 후 전환 재시도 2회를 지나면 Cron은 무한 루프 대신 중단합니다. +격리된 실행에서 라이브 모델 전환 핸드오프가 발생하면, Cron은 전환된 프로바이더/모델로 다시 시도하고 재시도 전에 해당 라이브 선택을 활성 실행에 영구 저장합니다. 전환에 새 인증 프로필도 포함된 경우, Cron은 해당 인증 프로필 오버라이드도 활성 실행에 영구 저장합니다. 재시도에는 제한이 있습니다. 최초 시도와 2회의 전환 재시도 후에는 무한 루프 대신 Cron이 중단됩니다. -격리된 Cron 실행이 에이전트 러너에 진입하기 전에, OpenClaw는 `baseUrl`이 local loopback, 사설 네트워크 또는 `.local`인 구성된 `api: "ollama"` 및 `api: "openai-completions"` 제공자에 대해 도달 가능한 로컬 제공자 엔드포인트를 확인합니다. 해당 엔드포인트가 내려가 있으면 실행은 모델 호출을 시작하는 대신 명확한 제공자/모델 오류와 함께 `skipped`로 기록됩니다. 엔드포인트 결과는 5분 동안 캐시되므로, 동일하게 죽은 로컬 Ollama, vLLM, SGLang 또는 LM Studio 서버를 사용하는 많은 만기 작업이 요청 폭주를 만들지 않고 하나의 작은 프로브를 공유합니다. 건너뛴 제공자 사전 점검 실행은 실행 오류 백오프를 증가시키지 않습니다. 반복적인 건너뜀 알림을 원하면 `failureAlert.includeSkipped`를 활성화하세요. +격리된 Cron 실행이 에이전트 러너에 들어가기 전에 OpenClaw는 `baseUrl`이 local loopback, 사설 네트워크 또는 `.local`인 구성된 `api: "ollama"` 및 `api: "openai-completions"` 프로바이더에 대해 연결 가능한 로컬 프로바이더 엔드포인트를 확인합니다. 해당 엔드포인트가 다운되어 있으면, 실행은 모델 호출을 시작하는 대신 명확한 프로바이더/모델 오류와 함께 `skipped`로 기록됩니다. 엔드포인트 결과는 5분 동안 캐시되므로, 동일하게 죽은 로컬 Ollama, vLLM, SGLang 또는 LM Studio 서버를 사용하는 많은 만료 작업이 요청 폭주를 만들지 않고 하나의 작은 프로브를 공유합니다. 건너뛴 프로바이더 사전 점검 실행은 실행 오류 백오프를 증가시키지 않습니다. 반복적인 건너뜀 알림을 원하면 `failureAlert.includeSkipped`를 활성화하세요. ## 전달 및 출력 -| 모드 | 동작 | +| 모드 | 발생하는 일 | | ---------- | ------------------------------------------------------------------- | -| `announce` | 에이전트가 보내지 않은 경우 최종 텍스트를 대상으로 폴백 전달 | +| `announce` | 에이전트가 전송하지 않은 경우 대상에 최종 텍스트를 폴백 전달 | | `webhook` | 완료된 이벤트 페이로드를 URL로 POST | | `none` | 러너 폴백 전달 없음 | -`--announce --channel telegram --to "-1001234567890"`를 사용해 채널로 전달합니다. Telegram 포럼 주제의 경우 `-1001234567890:topic:123`을 사용합니다. 직접 RPC/config 호출자는 `delivery.threadId`를 문자열이나 숫자로 전달할 수도 있습니다. Slack/Discord/Mattermost 대상은 명시적 접두사(`channel:`, `user:`)를 사용해야 합니다. Matrix 방 ID는 대소문자를 구분합니다. Matrix의 정확한 방 ID 또는 `room:!room:server` 형식을 사용하세요. +`--announce --channel telegram --to "-1001234567890"`를 사용해 채널로 전달합니다. Telegram 포럼 주제의 경우 `-1001234567890:topic:123`을 사용합니다. 직접 RPC/config 호출자는 `delivery.threadId`를 문자열 또는 숫자로 전달할 수도 있습니다. Slack/Discord/Mattermost 대상은 명시적 접두사(`channel:`, `user:`)를 사용해야 합니다. Matrix 방 ID는 대소문자를 구분하므로 Matrix의 정확한 방 ID 또는 `room:!room:server` 형식을 사용하세요. -공지 전달에서 `channel: "last"`를 사용하거나 `channel`을 생략하면, `telegram:123` 같은 provider 접두사가 붙은 대상이 채널을 선택할 수 있으며, 그 이후 cron은 세션 기록이나 단일 구성 채널로 대체됩니다. 로드된 Plugin이 알리는 접두사만 provider 선택자입니다. `delivery.channel`이 명시적이면 대상 접두사는 같은 provider 이름이어야 합니다. 예를 들어 `channel: "whatsapp"`와 `to: "telegram:123"`은 WhatsApp이 Telegram ID를 전화번호로 해석하게 두는 대신 거부됩니다. `channel:`, `user:`, `imessage:`, `sms:` 같은 대상 종류 및 서비스 접두사는 provider 선택자가 아니라 채널 소유 대상 구문으로 유지됩니다. +공지 전달에서 `channel: "last"`를 사용하거나 `channel`을 생략하면, `telegram:123` 같은 공급자 접두사가 붙은 대상이 cron이 세션 기록 또는 구성된 단일 채널로 폴백하기 전에 채널을 선택할 수 있습니다. 로드된 Plugin이 알리는 접두사만 공급자 선택자입니다. `delivery.channel`이 명시적이면 대상 접두사는 같은 공급자를 이름으로 지정해야 합니다. 예를 들어 `channel: "whatsapp"`와 `to: "telegram:123"` 조합은 WhatsApp이 Telegram ID를 전화번호로 해석하게 두지 않고 거부됩니다. `channel:`, `user:`, `imessage:`, `sms:` 같은 대상 종류 및 서비스 접두사는 공급자 선택자가 아니라 채널 소유 대상 구문으로 유지됩니다. -격리된 작업의 경우 채팅 전달은 공유됩니다. 채팅 경로를 사용할 수 있으면 작업이 `--no-deliver`를 사용하더라도 에이전트가 `message` 도구를 사용할 수 있습니다. 에이전트가 구성된/현재 대상에 보내면 OpenClaw는 대체 공지를 건너뜁니다. 그렇지 않으면 `announce`, `webhook`, `none`은 에이전트 턴 이후 최종 응답을 runner가 어떻게 처리할지만 제어합니다. +격리된 작업에서는 채팅 전달이 공유됩니다. 채팅 경로를 사용할 수 있으면 작업이 `--no-deliver`를 사용하더라도 에이전트가 `message` 도구를 사용할 수 있습니다. 에이전트가 구성된/현재 대상으로 보내면 OpenClaw는 폴백 공지를 건너뜁니다. 그렇지 않으면 `announce`, `webhook`, `none`은 에이전트 턴 이후 최종 응답을 러너가 어떻게 처리할지만 제어합니다. -에이전트가 활성 채팅에서 격리된 reminder를 만들면 OpenClaw는 대체 공지 경로를 위해 보존된 실시간 전달 대상을 저장합니다. 내부 세션 키는 소문자일 수 있지만, 현재 채팅 컨텍스트를 사용할 수 있을 때 provider 전달 대상은 해당 키에서 재구성되지 않습니다. +에이전트가 활성 채팅에서 격리된 알림을 만들면 OpenClaw는 폴백 공지 경로를 위해 보존된 실시간 전달 대상을 저장합니다. 내부 세션 키는 소문자일 수 있으며, 현재 채팅 컨텍스트를 사용할 수 있을 때 공급자 전달 대상은 해당 키에서 재구성되지 않습니다. -암시적 공지 전달은 구성된 채널 허용 목록을 사용해 오래된 대상을 검증하고 다시 라우팅합니다. DM pairing-store 승인은 대체 자동화 수신자가 아닙니다. 예약된 작업이 DM으로 선제적으로 보내야 한다면 `delivery.to`를 설정하거나 채널 `allowFrom` 항목을 구성하세요. +암시적 공지 전달은 구성된 채널 허용 목록을 사용해 오래된 대상을 검증하고 다시 라우팅합니다. DM 페어링 저장소 승인은 폴백 자동화 수신자가 아닙니다. 예약된 작업이 DM으로 선제적으로 보내야 한다면 `delivery.to`를 설정하거나 채널 `allowFrom` 항목을 구성하세요. 실패 알림은 별도의 대상 경로를 따릅니다. - `cron.failureDestination`은 실패 알림의 전역 기본값을 설정합니다. - `job.delivery.failureDestination`은 작업별로 이를 재정의합니다. -- 둘 다 설정되지 않았고 작업이 이미 `announce`를 통해 전달되는 경우, 실패 알림은 이제 해당 기본 공지 대상으로 대체됩니다. +- 둘 다 설정되지 않았고 작업이 이미 `announce`를 통해 전달되는 경우, 실패 알림은 이제 해당 기본 공지 대상으로 폴백합니다. - `delivery.failureDestination`은 기본 전달 모드가 `webhook`인 경우를 제외하고 `sessionTarget="isolated"` 작업에서만 지원됩니다. -- `failureAlert.includeSkipped: true`는 작업 또는 전역 cron 알림 정책이 반복된 건너뛴 실행 알림을 받도록 선택합니다. 건너뛴 실행은 별도의 연속 건너뜀 카운터를 유지하므로 실행 오류 backoff에 영향을 주지 않습니다. +- `failureAlert.includeSkipped: true`는 작업 또는 전역 cron 알림 정책이 반복된 건너뛴 실행 알림을 받도록 선택합니다. 건너뛴 실행은 별도의 연속 건너뛰기 카운터를 유지하므로 실행 오류 백오프에 영향을 주지 않습니다. ## CLI 예시 @@ -238,16 +239,16 @@ Gateway는 외부 트리거를 위한 HTTP Webhook 엔드포인트를 노출할 ### 인증 -모든 요청은 헤더를 통해 hook 토큰을 포함해야 합니다. +모든 요청은 헤더를 통해 훅 토큰을 포함해야 합니다. -- `Authorization: Bearer `(권장) +- `Authorization: Bearer ` (권장) - `x-openclaw-token: ` 쿼리 문자열 토큰은 거부됩니다. - 기본 세션에 대한 시스템 이벤트를 대기열에 넣습니다. + 기본 세션에 시스템 이벤트를 큐에 넣습니다. ```bash curl -X POST http://127.0.0.1:18789/hooks/wake \ @@ -278,43 +279,43 @@ Gateway는 외부 트리거를 위한 HTTP Webhook 엔드포인트를 노출할 - 사용자 지정 hook 이름은 config의 `hooks.mappings`를 통해 해석됩니다. Mapping은 임의의 payload를 템플릿이나 코드 변환으로 `wake` 또는 `agent` 동작으로 변환할 수 있습니다. + 사용자 지정 훅 이름은 config의 `hooks.mappings`를 통해 해석됩니다. 매핑은 템플릿 또는 코드 변환으로 임의의 페이로드를 `wake` 또는 `agent` 액션으로 변환할 수 있습니다. -hook 엔드포인트를 loopback, tailnet 또는 신뢰할 수 있는 reverse proxy 뒤에 두세요. +훅 엔드포인트는 loopback, tailnet 또는 신뢰할 수 있는 리버스 프록시 뒤에 두세요. -- 전용 hook 토큰을 사용하고, Gateway auth 토큰을 재사용하지 마세요. -- `hooks.path`를 전용 하위 경로에 유지하세요. `/`는 거부됩니다. +- 전용 훅 토큰을 사용하고, gateway 인증 토큰을 재사용하지 마세요. +- `hooks.path`는 전용 하위 경로에 유지하세요. `/`는 거부됩니다. - 명시적 `agentId` 라우팅을 제한하려면 `hooks.allowedAgentIds`를 설정하세요. -- 호출자가 선택하는 세션이 필요하지 않다면 `hooks.allowRequestSessionKey=false`를 유지하세요. -- `hooks.allowRequestSessionKey`를 활성화하는 경우, 허용되는 세션 키 형태를 제한하려면 `hooks.allowedSessionKeyPrefixes`도 설정하세요. -- hook payload는 기본적으로 안전 경계로 감싸집니다. +- 호출자가 세션을 선택해야 하는 경우가 아니라면 `hooks.allowRequestSessionKey=false`로 유지하세요. +- `hooks.allowRequestSessionKey`를 활성화하는 경우, 허용되는 세션 키 형태를 제한하도록 `hooks.allowedSessionKeyPrefixes`도 설정하세요. +- 훅 페이로드는 기본적으로 안전 경계로 래핑됩니다. ## Gmail PubSub 통합 -Google PubSub를 통해 Gmail 받은편지함 트리거를 OpenClaw에 연결합니다. +Google PubSub을 통해 Gmail 받은편지함 트리거를 OpenClaw에 연결합니다. -**필수 조건:** `gcloud` CLI, `gog`(gogcli), OpenClaw hooks 활성화, 공개 HTTPS 엔드포인트용 Tailscale. +**필수 조건:** `gcloud` CLI, `gog`(gogcli), 활성화된 OpenClaw 훅, 공용 HTTPS 엔드포인트용 Tailscale. -### Wizard 설정(권장) +### 마법사 설정(권장) ```bash openclaw webhooks gmail setup --account openclaw@gmail.com ``` -이는 `hooks.gmail` config를 작성하고, Gmail preset을 활성화하며, push 엔드포인트에 Tailscale Funnel을 사용합니다. +이는 `hooks.gmail` config를 쓰고, Gmail 프리셋을 활성화하며, 푸시 엔드포인트에 Tailscale Funnel을 사용합니다. ### Gateway 자동 시작 -`hooks.enabled=true`이고 `hooks.gmail.account`가 설정되어 있으면 Gateway는 부팅 시 `gog gmail watch serve`를 시작하고 watch를 자동 갱신합니다. 사용하지 않으려면 `OPENCLAW_SKIP_GMAIL_WATCHER=1`을 설정하세요. +`hooks.enabled=true`이고 `hooks.gmail.account`가 설정되어 있으면 Gateway는 부팅 시 `gog gmail watch serve`를 시작하고 watch를 자동 갱신합니다. 선택 해제하려면 `OPENCLAW_SKIP_GMAIL_WATCHER=1`을 설정하세요. -### 수동 일회성 설정 +### 수동 1회 설정 @@ -391,11 +392,11 @@ openclaw cron edit --clear-agent 모델 재정의 참고: - `openclaw cron add|edit --model ...`은 작업의 선택된 모델을 변경합니다. -- 모델이 허용되면, 해당 정확한 provider/model이 격리된 에이전트 실행에 전달됩니다. -- 허용되지 않거나 해석할 수 없으면 cron은 명시적 검증 오류와 함께 실행에 실패합니다. -- 구성된 fallback 체인은 계속 적용됩니다. cron `--model`은 세션 `/model` 재정의가 아니라 작업 primary이기 때문입니다. -- Payload `fallbacks`는 해당 작업의 구성된 fallback을 대체합니다. `fallbacks: []`는 fallback을 비활성화하고 실행을 strict로 만듭니다. -- 명시적 또는 구성된 fallback 목록 없이 단순히 `--model`만 지정해도 조용한 추가 재시도 대상으로 에이전트 primary에 넘어가지 않습니다. +- 모델이 허용되면 정확한 공급자/모델이 격리된 에이전트 실행에 도달합니다. +- 허용되지 않았거나 해석할 수 없으면 cron은 명시적 검증 오류로 실행을 실패 처리합니다. +- 구성된 폴백 체인은 계속 적용됩니다. cron `--model`은 세션 `/model` 재정의가 아니라 작업 기본값이기 때문입니다. +- 페이로드 `fallbacks`는 해당 작업의 구성된 폴백을 대체합니다. `fallbacks: []`는 폴백을 비활성화하고 실행을 엄격하게 만듭니다. +- 명시적 또는 구성된 폴백 목록이 없는 단순 `--model`은 조용한 추가 재시도 대상으로 에이전트 기본값까지 폴스루하지 않습니다. @@ -419,29 +420,29 @@ openclaw cron edit --clear-agent } ``` -`maxConcurrentRuns`는 예약된 cron dispatch와 격리된 에이전트 턴 실행을 모두 제한합니다. 격리된 cron 에이전트 턴은 내부적으로 queue의 전용 `cron-nested` 실행 lane을 사용하므로, 이 값을 높이면 독립적인 cron LLM 실행이 외부 cron wrapper만 시작되는 대신 병렬로 진행될 수 있습니다. 공유 non-cron `nested` lane은 이 설정으로 확장되지 않습니다. +`maxConcurrentRuns`는 예약된 cron 디스패치와 격리된 에이전트 턴 실행을 모두 제한합니다. 격리된 cron 에이전트 턴은 내부적으로 큐의 전용 `cron-nested` 실행 레인을 사용하므로, 이 값을 높이면 독립적인 cron LLM 실행이 외부 cron 래퍼만 시작하는 대신 병렬로 진행될 수 있습니다. 공유되는 비 cron `nested` 레인은 이 설정으로 확장되지 않습니다. -런타임 상태 sidecar는 `cron.store`에서 파생됩니다. `~/clawd/cron/jobs.json` 같은 `.json` store는 `~/clawd/cron/jobs-state.json`을 사용하고, `.json` suffix가 없는 store 경로는 `-state.json`을 추가합니다. +런타임 상태 사이드카는 `cron.store`에서 파생됩니다. `~/clawd/cron/jobs.json` 같은 `.json` 저장소는 `~/clawd/cron/jobs-state.json`을 사용하고, `.json` 접미사가 없는 저장소 경로에는 `-state.json`이 추가됩니다. -`jobs.json`을 직접 편집하는 경우 `jobs-state.json`은 source control에서 제외하세요. OpenClaw는 이 sidecar를 pending slot, active marker, last-run metadata, 그리고 외부에서 편집된 작업에 새 `nextRunAtMs`가 필요할 때 scheduler에 알려 주는 schedule identity에 사용합니다. +`jobs.json`을 직접 편집하는 경우 `jobs-state.json`은 소스 제어에 포함하지 마세요. OpenClaw는 해당 사이드카를 대기 중인 슬롯, 활성 마커, 마지막 실행 메타데이터, 외부에서 편집된 작업에 새 `nextRunAtMs`가 필요한 시점을 스케줄러에 알려 주는 일정 ID에 사용합니다. cron 비활성화: `cron.enabled: false` 또는 `OPENCLAW_SKIP_CRON=1`. - **일회성 retry**: 일시적 오류(rate limit, overload, network, server error)는 exponential backoff로 최대 3회 retry합니다. 영구 오류는 즉시 비활성화됩니다. + **일회성 재시도**: 일시적 오류(속도 제한, 과부하, 네트워크, 서버 오류)는 지수 백오프로 최대 3회 재시도됩니다. 영구 오류는 즉시 비활성화됩니다. - **반복 retry**: retry 사이에 exponential backoff(30초에서 60분)를 적용합니다. Backoff는 다음 성공 실행 이후 reset됩니다. + **반복 재시도**: 재시도 사이에는 지수 백오프(30초~60분)가 적용됩니다. 백오프는 다음 성공 실행 이후 초기화됩니다. - `cron.sessionRetention`(기본값 `24h`)은 격리된 실행 세션 항목을 정리합니다. `cron.runLog.maxBytes` / `cron.runLog.keepLines`는 run-log 파일을 자동 정리합니다. + `cron.sessionRetention`(기본값 `24h`)은 격리된 실행 세션 항목을 정리합니다. `cron.runLog.maxBytes` / `cron.runLog.keepLines`는 실행 로그 파일을 자동으로 정리합니다. ## 문제 해결 -### 명령 ladder +### 명령 단계 ```bash openclaw status @@ -458,23 +459,23 @@ openclaw doctor - `cron.enabled`와 `OPENCLAW_SKIP_CRON` env var를 확인하세요. - Gateway가 계속 실행 중인지 확인하세요. - - `cron` schedule의 경우 timezone(`--tz`)과 host timezone을 비교해 확인하세요. - - run output의 `reason: not-due`는 manual run이 `openclaw cron run --due`로 확인되었고 작업이 아직 due 상태가 아니었음을 의미합니다. + - `cron` 일정의 경우 시간대(`--tz`)와 호스트 시간대를 확인하세요. + - 실행 출력의 `reason: not-due`는 수동 실행이 `openclaw cron run --due`로 확인되었고 작업의 기한이 아직 되지 않았다는 뜻입니다. - - 전달 모드 `none`은 runner 대체 전송이 예상되지 않음을 의미합니다. 채팅 경로를 사용할 수 있으면 에이전트는 여전히 `message` 도구로 직접 보낼 수 있습니다. - - 전달 대상이 없거나 잘못된 경우(`channel`/`to`) 아웃바운드가 건너뛰어졌음을 의미합니다. - - Matrix의 경우, `delivery.to` 방 ID가 소문자로 변환된 복사 작업이나 레거시 작업은 실패할 수 있습니다. Matrix 방 ID는 대소문자를 구분하기 때문입니다. 작업을 Matrix의 정확한 `!room:server` 또는 `room:!room:server` 값으로 수정하세요. - - 채널 인증 오류(`unauthorized`, `Forbidden`)는 자격 증명에 의해 전달이 차단되었음을 의미합니다. - - 격리된 실행이 무음 토큰(`NO_REPLY` / `no_reply`)만 반환하면, OpenClaw는 직접 아웃바운드 전달과 대체 대기열 요약 경로를 모두 억제하므로 채팅에 아무것도 다시 게시되지 않습니다. - - 에이전트가 사용자에게 직접 메시지를 보내야 하는 경우, 작업에 사용 가능한 경로가 있는지 확인하세요(`channel: "last"`와 이전 채팅, 또는 명시적 채널/대상). + - 전달 모드가 `none`이면 러너 폴백 전송이 예상되지 않습니다. 채팅 경로를 사용할 수 있으면 에이전트는 여전히 `message` 도구로 직접 보낼 수 있습니다. + - 전달 대상이 없거나 잘못된 경우(`channel`/`to`) 아웃바운드를 건너뜁니다. + - Matrix의 경우, `delivery.to` 방 ID가 소문자로 변환된 복사된 작업이나 레거시 작업은 Matrix 방 ID가 대소문자를 구분하기 때문에 실패할 수 있습니다. 작업을 Matrix의 정확한 `!room:server` 또는 `room:!room:server` 값으로 수정하세요. + - 채널 인증 오류(`unauthorized`, `Forbidden`)는 자격 증명 때문에 전달이 차단되었음을 의미합니다. + - 격리된 실행이 무음 토큰(`NO_REPLY` / `no_reply`)만 반환하면 OpenClaw는 직접 아웃바운드 전달을 억제하고 폴백 대기열 요약 경로도 억제하므로 채팅에 아무것도 게시되지 않습니다. + - 에이전트가 사용자에게 직접 메시지를 보내야 한다면 작업에 사용 가능한 경로가 있는지 확인하세요(`channel: "last"`와 이전 채팅, 또는 명시적 채널/대상). - - 일일 및 유휴 초기화 최신성은 `updatedAt`을 기준으로 하지 않습니다. [세션 관리](/ko/concepts/session#session-lifecycle)를 참고하세요. - - Cron 깨우기, Heartbeat 실행, exec 알림, Gateway 장부 처리는 라우팅/상태를 위해 세션 행을 업데이트할 수 있지만, `sessionStartedAt` 또는 `lastInteractionAt`을 연장하지 않습니다. - - 해당 필드가 존재하기 전에 생성된 레거시 행의 경우, 파일을 계속 사용할 수 있으면 OpenClaw가 transcript JSONL 세션 헤더에서 `sessionStartedAt`을 복구할 수 있습니다. `lastInteractionAt`이 없는 레거시 유휴 행은 복구된 시작 시간을 유휴 기준선으로 사용합니다. + - 일일 및 유휴 재설정 최신성은 `updatedAt`을 기준으로 하지 않습니다. [세션 관리](/ko/concepts/session#session-lifecycle)를 참조하세요. + - Cron 깨우기, Heartbeat 실행, exec 알림, Gateway 장부 기록은 라우팅/상태를 위해 세션 행을 업데이트할 수 있지만 `sessionStartedAt` 또는 `lastInteractionAt`을 연장하지는 않습니다. + - 해당 필드가 생기기 전에 생성된 레거시 행의 경우, 파일을 계속 사용할 수 있으면 OpenClaw가 트랜스크립트 JSONL 세션 헤더에서 `sessionStartedAt`을 복구할 수 있습니다. `lastInteractionAt`이 없는 레거시 유휴 행은 복구된 시작 시간을 유휴 기준선으로 사용합니다. @@ -489,5 +490,5 @@ openclaw doctor - [자동화 및 작업](/ko/automation) — 모든 자동화 메커니즘 한눈에 보기 - [백그라운드 작업](/ko/automation/tasks) — Cron 실행을 위한 작업 원장 -- [Heartbeat](/ko/gateway/heartbeat) — 주기적인 기본 세션 턴 +- [Heartbeat](/ko/gateway/heartbeat) — 주기적인 메인 세션 턴 - [시간대](/ko/concepts/timezone) — 시간대 구성 diff --git a/docs/ko/channels/discord.md b/docs/ko/channels/discord.md index 08498feef..eedbfb073 100644 --- a/docs/ko/channels/discord.md +++ b/docs/ko/channels/discord.md @@ -1,107 +1,107 @@ --- read_when: - - Discord 채널 기능 작업 + - Discord 채널 기능 작업하기 summary: Discord 봇 지원 상태, 기능 및 구성 title: Discord x-i18n: - generated_at: "2026-05-04T07:02:43Z" + generated_at: "2026-05-06T17:52:19Z" model: gpt-5.5 provider: openai - source_hash: 1e00f9d9b134296ac1ca52bb4058fc62ea7a95c4d46d9478648b2ecdd448652a + source_hash: 11cc911dbc569db7a31ce4a16de167bc8ea771d1dd7842cb151f666f3cb9285b source_path: channels/discord.md workflow: 16 --- -Discord의 공식 Gateway를 통해 DM 및 길드 채널에서 사용할 수 있습니다. +공식 Discord Gateway를 통해 DM과 길드 채널을 사용할 준비가 되었습니다. - - Discord DM은 기본적으로 페어링 모드로 시작합니다. + + Discord DM은 기본적으로 페어링 모드로 설정됩니다. - - 네이티브 명령 동작과 명령 카탈로그입니다. + + 네이티브 명령 동작 및 명령 카탈로그입니다. - + 채널 간 진단 및 복구 흐름입니다. ## 빠른 설정 -봇이 포함된 새 애플리케이션을 만들고, 봇을 서버에 추가한 다음, OpenClaw에 페어링해야 합니다. 봇은 본인의 비공개 서버에 추가하는 것을 권장합니다. 아직 서버가 없다면 [먼저 서버를 만드세요](https://support.discord.com/hc/en-us/articles/204849977-How-do-I-create-a-server) (**Create My Own > For me and my friends** 선택). +봇이 포함된 새 애플리케이션을 만들고, 봇을 서버에 추가한 다음, OpenClaw와 페어링해야 합니다. 봇은 본인의 비공개 서버에 추가하는 것을 권장합니다. 아직 서버가 없다면 [먼저 서버를 만드세요](https://support.discord.com/hc/en-us/articles/204849977-How-do-I-create-a-server)(**Create My Own > For me and my friends** 선택). - - [Discord Developer Portal](https://discord.com/developers/applications)로 이동하여 **New Application**을 클릭합니다. 이름은 "OpenClaw"처럼 지정합니다. + + [Discord Developer Portal](https://discord.com/developers/applications)로 이동해 **New Application**을 클릭합니다. 이름은 "OpenClaw"와 같이 지정합니다. - 사이드바에서 **Bot**을 클릭합니다. **Username**을 OpenClaw 에이전트를 부르는 이름으로 설정합니다. + 사이드바에서 **Bot**을 클릭합니다. **Username**을 OpenClaw 에이전트에 붙일 이름으로 설정합니다. - - 계속 **Bot** 페이지에서 아래로 스크롤하여 **Privileged Gateway Intents**로 이동한 다음 다음을 활성화합니다. + + 계속 **Bot** 페이지에서 아래로 스크롤해 **Privileged Gateway Intents**로 이동한 뒤 다음을 활성화합니다. - - **Message Content Intent** (필수) - - **Server Members Intent** (권장, 역할 허용 목록 및 이름-ID 매칭에 필요) - - **Presence Intent** (선택 사항, 현재 상태 업데이트에만 필요) + - **Message Content Intent**(필수) + - **Server Members Intent**(권장, 역할 허용 목록 및 이름-ID 매칭에 필요) + - **Presence Intent**(선택, 프레즌스 업데이트에만 필요) - - **Bot** 페이지에서 다시 위로 스크롤한 뒤 **Reset Token**을 클릭합니다. + + **Bot** 페이지에서 다시 위로 스크롤해 **Reset Token**을 클릭합니다. - 이름과 달리, 이 작업은 첫 토큰을 생성합니다. 아무것도 "재설정"되지 않습니다. + 이름과 달리, 이 작업은 첫 번째 토큰을 생성합니다. 실제로 "재설정"되는 것은 없습니다. - 토큰을 복사하여 어딘가에 저장합니다. 이것이 **봇 토큰**이며 곧 필요합니다. + 토큰을 복사해 어딘가에 저장합니다. 이것이 **Bot Token**이며 곧 필요합니다. - - 사이드바에서 **OAuth2**를 클릭합니다. 봇을 서버에 추가할 수 있는 적절한 권한이 포함된 초대 URL을 생성합니다. + + 사이드바에서 **OAuth2**를 클릭합니다. 봇을 서버에 추가하는 데 필요한 권한이 포함된 초대 URL을 생성합니다. - **OAuth2 URL Generator**까지 아래로 스크롤하고 다음을 활성화합니다. + 아래로 스크롤해 **OAuth2 URL Generator**로 이동하고 다음을 활성화합니다. - `bot` - `applications.commands` - 아래에 **Bot Permissions** 섹션이 나타납니다. 최소한 다음을 활성화합니다. + 아래에 **Bot Permissions** 섹션이 표시됩니다. 최소한 다음을 활성화합니다. - **일반 권한** + **General Permissions** - 채널 보기 - **텍스트 권한** + **Text Permissions** - 메시지 보내기 - 메시지 기록 읽기 - 링크 임베드 - 파일 첨부 - - 반응 추가 (선택 사항) + - 반응 추가(선택) - 이는 일반 텍스트 채널을 위한 기본 권한 세트입니다. 스레드를 만들거나 이어가는 포럼 또는 미디어 채널 워크플로를 포함하여 Discord 스레드에 게시할 계획이라면 **스레드에서 메시지 보내기**도 활성화합니다. - 하단에 생성된 URL을 복사하여 브라우저에 붙여넣고, 서버를 선택한 다음 **Continue**를 클릭하여 연결합니다. 이제 Discord 서버에서 봇이 보일 것입니다. + 이는 일반 텍스트 채널을 위한 기본 권한 집합입니다. 포럼 또는 미디어 채널 워크플로처럼 스레드를 만들거나 이어 가는 경우를 포함해 Discord 스레드에 게시할 계획이라면 **Send Messages in Threads**도 활성화하세요. + 맨 아래에서 생성된 URL을 복사해 브라우저에 붙여넣고, 서버를 선택한 뒤 **Continue**를 클릭해 연결합니다. 이제 Discord 서버에서 봇이 보여야 합니다. - - Discord 앱으로 돌아가 내부 ID를 복사할 수 있도록 개발자 모드를 활성화해야 합니다. + + Discord 앱으로 돌아가 내부 ID를 복사할 수 있도록 Developer Mode를 활성화해야 합니다. - 1. **User Settings**(아바타 옆 톱니바퀴 아이콘) → **Advanced**를 클릭하고 **Developer Mode**를 켭니다. - 2. 사이드바의 **서버 아이콘**을 오른쪽 클릭 → **Copy Server ID** - 3. **본인 아바타**를 오른쪽 클릭 → **Copy User ID** + 1. **User Settings**(아바타 옆 톱니바퀴 아이콘) → **Advanced** → **Developer Mode** 토글 켜기 + 2. 사이드바의 **서버 아이콘**을 마우스 오른쪽 버튼으로 클릭 → **Copy Server ID** + 3. **내 아바타**를 마우스 오른쪽 버튼으로 클릭 → **Copy User ID** - **Server ID**와 **User ID**를 Bot Token과 함께 저장합니다. 다음 단계에서 세 가지를 모두 OpenClaw에 보냅니다. + **Server ID**와 **User ID**를 Bot Token과 함께 저장합니다. 다음 단계에서 세 가지를 모두 OpenClaw로 보냅니다. - - 페어링이 작동하려면 Discord가 봇이 사용자에게 DM을 보낼 수 있도록 허용해야 합니다. **서버 아이콘**을 오른쪽 클릭 → **Privacy Settings** → **Direct Messages**를 켭니다. + + 페어링이 작동하려면 Discord에서 봇이 사용자에게 DM을 보낼 수 있어야 합니다. **서버 아이콘**을 마우스 오른쪽 버튼으로 클릭 → **Privacy Settings** → **Direct Messages** 토글을 켭니다. - 이렇게 하면 봇을 포함한 서버 멤버가 사용자에게 DM을 보낼 수 있습니다. OpenClaw와 함께 Discord DM을 사용하려면 이 설정을 켜 둡니다. 길드 채널만 사용할 계획이라면 페어링 후 DM을 비활성화할 수 있습니다. + 이렇게 하면 봇을 포함한 서버 멤버가 사용자에게 DM을 보낼 수 있습니다. OpenClaw와 함께 Discord DM을 사용하려면 이 설정을 계속 켜 두세요. 길드 채널만 사용할 계획이라면 페어링 후 DM을 비활성화해도 됩니다. - - Discord 봇 토큰은 비밀번호와 같은 비밀 정보입니다. 에이전트에게 메시지를 보내기 전에 OpenClaw를 실행하는 머신에 설정합니다. + + Discord 봇 토큰은 비밀 정보입니다(비밀번호와 같습니다). 에이전트에게 메시지를 보내기 전에 OpenClaw를 실행하는 머신에 설정하세요. ```bash export DISCORD_BOT_TOKEN="YOUR_BOT_TOKEN" @@ -120,22 +120,22 @@ openclaw config patch --file ./discord.patch.json5 openclaw gateway ``` - OpenClaw가 이미 백그라운드 서비스로 실행 중이라면 OpenClaw Mac 앱을 통해 다시 시작하거나 `openclaw gateway run` 프로세스를 중지한 뒤 다시 시작합니다. - 관리형 서비스 설치의 경우 `DISCORD_BOT_TOKEN`이 있는 셸에서 `openclaw gateway install`을 실행하거나 변수를 `~/.openclaw/.env`에 저장하여, 다시 시작한 뒤 서비스가 env SecretRef를 확인할 수 있게 합니다. - 호스트가 Discord의 시작 애플리케이션 조회에서 차단되었거나 속도 제한을 받는 경우, 시작 시 해당 REST 호출을 건너뛸 수 있도록 Developer Portal의 Discord 애플리케이션/클라이언트 ID를 설정합니다. 기본 계정에는 `channels.discord.applicationId`를 사용하고, 여러 Discord 봇을 실행할 때는 `channels.discord.accounts..applicationId`를 사용합니다. + OpenClaw가 이미 백그라운드 서비스로 실행 중이라면 OpenClaw Mac 앱을 통해 다시 시작하거나 `openclaw gateway run` 프로세스를 중지한 뒤 다시 시작하세요. + 관리형 서비스 설치의 경우 `DISCORD_BOT_TOKEN`이 있는 셸에서 `openclaw gateway install`을 실행하거나 변수를 `~/.openclaw/.env`에 저장해, 재시작 후 서비스가 env SecretRef를 해석할 수 있게 하세요. + 호스트가 Discord의 시작 애플리케이션 조회에 의해 차단되거나 rate limit에 걸리는 경우, 시작 시 해당 REST 호출을 건너뛸 수 있도록 Developer Portal에서 Discord 애플리케이션/클라이언트 ID를 설정하세요. 기본 계정에는 `channels.discord.applicationId`를 사용하고, 여러 Discord 봇을 실행하는 경우에는 `channels.discord.accounts..applicationId`를 사용하세요. - + - - 기존 채널(예: Telegram)에서 OpenClaw 에이전트와 채팅하고 알려줍니다. Discord가 첫 채널이라면 대신 CLI / 구성 탭을 사용합니다. + + 기존 채널(예: Telegram)에서 OpenClaw 에이전트와 채팅해 다음과 같이 말합니다. Discord가 첫 번째 채널이라면 대신 CLI / config 탭을 사용하세요. - > "이미 구성에 Discord 봇 토큰을 설정했습니다. User ID ``와 Server ID ``로 Discord 설정을 완료해 주세요." + > "Discord 봇 토큰은 이미 config에 설정했습니다. User ID `` 및 Server ID ``로 Discord 설정을 완료해 주세요." - - 파일 기반 구성을 선호한다면 다음을 설정합니다. + + 파일 기반 config를 선호한다면 다음을 설정합니다. ```json5 { @@ -152,15 +152,15 @@ openclaw gateway } ``` - 기본 계정의 env 대체값: + 기본 계정의 env fallback: ```bash DISCORD_BOT_TOKEN=... ``` - 스크립트 기반 또는 원격 설정의 경우 같은 JSON5 블록을 `openclaw config patch --file ./discord.patch.json5 --dry-run`으로 작성한 다음 `--dry-run` 없이 다시 실행합니다. 일반 텍스트 `token` 값이 지원됩니다. SecretRef 값도 env/file/exec 공급자 전반에서 `channels.discord.token`에 지원됩니다. [비밀 관리](/ko/gateway/secrets)를 참조하세요. + 스크립트 기반 또는 원격 설정의 경우 동일한 JSON5 블록을 `openclaw config patch --file ./discord.patch.json5 --dry-run`으로 작성한 다음 `--dry-run` 없이 다시 실행합니다. 평문 `token` 값이 지원됩니다. env/file/exec provider 전반에서 `channels.discord.token`에 SecretRef 값도 지원됩니다. [비밀 정보 관리](/ko/gateway/secrets)를 참조하세요. - 여러 Discord 봇의 경우 각 봇 토큰과 애플리케이션 ID를 해당 계정 아래에 유지합니다. 최상위 `channels.discord.applicationId`는 계정에 상속되므로 모든 계정이 같은 애플리케이션 ID를 사용해야 할 때만 그곳에 설정합니다. + 여러 Discord 봇의 경우 각 봇 토큰과 애플리케이션 ID를 해당 계정 아래에 유지하세요. 최상위 `channels.discord.applicationId`는 계정에 상속되므로, 모든 계정이 동일한 애플리케이션 ID를 사용해야 할 때만 그 위치에 설정하세요. ```json5 { @@ -187,11 +187,11 @@ DISCORD_BOT_TOKEN=... - + Gateway가 실행될 때까지 기다린 다음 Discord에서 봇에게 DM을 보냅니다. 봇이 페어링 코드를 응답합니다. - + 기존 채널에서 에이전트에게 페어링 코드를 보냅니다. > "이 Discord 페어링 코드를 승인해 주세요: ``" @@ -214,24 +214,24 @@ openclaw pairing approve discord -토큰 확인은 계정을 인식합니다. 구성 토큰 값이 env 대체값보다 우선합니다. `DISCORD_BOT_TOKEN`은 기본 계정에만 사용됩니다. -활성화된 두 Discord 계정이 같은 봇 토큰으로 확인되면 OpenClaw는 해당 토큰에 대해 Gateway 모니터를 하나만 시작합니다. 구성에서 제공된 토큰은 기본 env 대체값보다 우선합니다. 그렇지 않으면 첫 번째 활성화된 계정이 우선하며 중복 계정은 비활성화된 것으로 보고됩니다. -고급 아웃바운드 호출(메시지 도구/채널 작업)의 경우 명시적인 호출별 `token`이 해당 호출에 사용됩니다. 이는 전송 및 읽기/프로브 스타일 작업(예: 읽기/검색/가져오기/스레드/핀/권한)에 적용됩니다. 계정 정책/재시도 설정은 여전히 활성 런타임 스냅샷에서 선택된 계정에서 가져옵니다. +토큰 해석은 계정을 인식합니다. Config 토큰 값이 env fallback보다 우선합니다. `DISCORD_BOT_TOKEN`은 기본 계정에만 사용됩니다. +활성화된 두 Discord 계정이 동일한 봇 토큰으로 해석되면 OpenClaw는 해당 토큰에 대해 Gateway 모니터를 하나만 시작합니다. config에서 가져온 토큰이 기본 env fallback보다 우선하며, 그렇지 않으면 처음 활성화된 계정이 우선하고 중복 계정은 비활성화된 것으로 보고됩니다. +고급 아웃바운드 호출(메시지 도구/채널 작업)의 경우 명시적인 호출별 `token`이 해당 호출에 사용됩니다. 이는 보내기 및 읽기/프로브 스타일 작업(예: read/search/fetch/thread/pins/permissions)에 적용됩니다. 계정 정책/재시도 설정은 여전히 활성 런타임 스냅샷에서 선택된 계정에서 가져옵니다. ## 권장: 길드 작업 공간 설정 -DM이 작동하면 Discord 서버를 전체 작업 공간으로 설정할 수 있으며, 각 채널은 고유한 컨텍스트를 가진 자체 에이전트 세션을 갖습니다. 사용자와 봇만 있는 비공개 서버에 권장됩니다. +DM이 작동하면 Discord 서버를 전체 작업 공간으로 설정할 수 있습니다. 각 채널은 자체 컨텍스트를 가진 자체 에이전트 세션을 갖게 됩니다. 사용자와 봇만 있는 비공개 서버에 권장됩니다. - - 이렇게 하면 에이전트가 DM뿐 아니라 서버의 모든 채널에서 응답할 수 있습니다. + + 이렇게 하면 에이전트가 DM뿐만 아니라 서버의 모든 채널에서 응답할 수 있습니다. - + > "내 Discord Server ID ``를 길드 허용 목록에 추가해 주세요" - + ```json5 { @@ -254,19 +254,19 @@ DM이 작동하면 Discord 서버를 전체 작업 공간으로 설정할 수 - - 기본적으로 에이전트는 길드 채널에서 @멘션되었을 때만 응답합니다. 비공개 서버라면 아마 모든 메시지에 응답하도록 하고 싶을 것입니다. + + 기본적으로 에이전트는 길드 채널에서 @멘션된 경우에만 응답합니다. 비공개 서버에서는 모든 메시지에 응답하게 하고 싶을 가능성이 높습니다. - 길드 채널에서 일반 어시스턴트 최종 응답은 기본적으로 비공개로 유지됩니다. 표시되는 Discord 출력은 `message` 도구로 명시적으로 보내야 하므로, 에이전트는 기본적으로 대기하다가 채널 응답이 유용하다고 판단할 때만 게시할 수 있습니다. + 길드 채널에서는 일반 어시스턴트 최종 답변이 기본적으로 비공개로 유지됩니다. Discord에 보이는 출력은 `message` 도구로 명시적으로 보내야 하므로, 에이전트는 기본적으로 조용히 대기하다가 채널 응답이 유용하다고 판단할 때만 게시할 수 있습니다. - 즉, 선택한 모델이 도구를 안정적으로 호출해야 합니다. Discord에 입력 중 표시가 나타나고 로그에 토큰 사용량이 보이지만 게시된 메시지가 없다면 세션 로그에서 `didSendViaMessagingTool: false`가 포함된 어시스턴트 텍스트를 확인하세요. 이는 모델이 `message(action=send)`를 호출하는 대신 비공개 최종 답변을 생성했다는 의미입니다. 더 강력한 도구 호출 모델로 전환하거나 아래 구성을 사용하여 레거시 자동 최종 응답을 복원하세요. + 이는 선택된 모델이 도구를 안정적으로 호출해야 함을 의미합니다. Discord에는 입력 중 표시가 보이고 로그에는 토큰 사용량이 표시되지만 게시된 메시지가 없다면, 세션 로그에서 `didSendViaMessagingTool: false`가 있는 어시스턴트 텍스트를 확인하세요. 이는 모델이 `message(action=send)`를 호출하는 대신 비공개 최종 답변을 생성했다는 뜻입니다. 도구 호출에 더 강한 모델로 전환하거나, 아래 config를 사용해 레거시 자동 최종 답변을 복원하세요. - - > "내 에이전트가 이 서버에서 @멘션되지 않아도 응답할 수 있게 해 주세요" + + > "내 에이전트가 이 서버에서 @멘션 없이 응답할 수 있게 해 주세요" - - 길드 구성에서 `requireMention: false`를 설정합니다. + + 길드 config에서 `requireMention: false`를 설정합니다. ```json5 { @@ -282,95 +282,95 @@ DM이 작동하면 Discord 서버를 전체 작업 공간으로 설정할 수 } ``` - 그룹/채널 방에 대해 레거시 자동 최종 응답을 복원하려면 `messages.groupChat.visibleReplies: "automatic"`을 설정합니다. + 그룹/채널 방의 레거시 자동 최종 답변을 복원하려면 `messages.groupChat.visibleReplies: "automatic"`을 설정합니다. - + 기본적으로 장기 메모리(MEMORY.md)는 DM 세션에서만 로드됩니다. 길드 채널은 MEMORY.md를 자동으로 로드하지 않습니다. - - > "Discord 채널에서 내가 질문할 때 MEMORY.md의 장기 컨텍스트가 필요하면 memory_search 또는 memory_get을 사용해 주세요." + + > "Discord 채널에서 질문할 때 MEMORY.md의 장기 컨텍스트가 필요하면 memory_search 또는 memory_get을 사용해 주세요." - - 모든 채널에 공유 컨텍스트가 필요하다면 안정적인 지침을 `AGENTS.md` 또는 `USER.md`에 넣으세요(모든 세션에 주입됩니다). 장기 메모는 `MEMORY.md`에 유지하고 필요할 때 메모리 도구로 접근합니다. + + 모든 채널에서 공유 컨텍스트가 필요하다면 안정적인 지침을 `AGENTS.md` 또는 `USER.md`에 넣으세요(모든 세션에 주입됩니다). 장기 노트는 `MEMORY.md`에 보관하고 필요할 때 메모리 도구로 접근하세요. -이제 Discord 서버에 채널을 몇 개 만들고 채팅을 시작하세요. 에이전트는 채널 이름을 볼 수 있으며, 각 채널은 고유한 격리 세션을 갖습니다. 따라서 워크플로에 맞게 `#coding`, `#home`, `#research` 또는 원하는 채널을 설정할 수 있습니다. +이제 Discord 서버에 몇 개의 채널을 만들고 채팅을 시작하세요. 에이전트는 채널 이름을 볼 수 있으며, 각 채널은 자체 격리 세션을 갖습니다. 따라서 워크플로에 맞게 `#coding`, `#home`, `#research` 등을 설정할 수 있습니다. ## 런타임 모델 - Gateway가 Discord 연결을 소유합니다. - 답장 라우팅은 결정적입니다. Discord 인바운드 답장은 Discord로 돌아갑니다. -- Discord 길드/채널 메타데이터는 사용자에게 표시되는 답장 접두사가 아니라 신뢰할 수 없는 +- Discord 길드/채널 메타데이터는 사용자가 볼 수 있는 답장 접두사가 아니라 신뢰할 수 없는 컨텍스트로 모델 프롬프트에 추가됩니다. 모델이 해당 봉투를 다시 복사하면 - OpenClaw는 아웃바운드 답장과 이후 리플레이 컨텍스트에서 복사된 메타데이터를 제거합니다. -- 기본적으로 (`session.dmScope=main`) 직접 채팅은 에이전트 메인 세션(`agent:main:main`)을 공유합니다. + OpenClaw는 아웃바운드 답장과 향후 재생 컨텍스트에서 복사된 메타데이터를 제거합니다. +- 기본적으로(`session.dmScope=main`) 직접 채팅은 에이전트 기본 세션(`agent:main:main`)을 공유합니다. - 길드 채널은 격리된 세션 키입니다(`agent::discord:channel:`). - 그룹 DM은 기본적으로 무시됩니다(`channels.discord.dm.groupEnabled=false`). -- 네이티브 슬래시 명령은 격리된 명령 세션(`agent::discord:slash:`)에서 실행되며, 라우팅된 대화 세션으로 `CommandTargetSessionKey`를 계속 전달합니다. -- Discord로 전달되는 텍스트 전용 Cron/Heartbeat 알림은 최종 +- 네이티브 슬래시 명령은 격리된 명령 세션(`agent::discord:slash:`)에서 실행되며, 라우팅된 대화 세션으로 `CommandTargetSessionKey`도 함께 전달합니다. +- Discord로 텍스트 전용 Cron/Heartbeat 공지 전달은 최종 어시스턴트 표시 답변을 한 번 사용합니다. 미디어 및 구조화된 컴포넌트 페이로드는 - 에이전트가 여러 전달 가능 페이로드를 내보낼 때 다중 메시지로 유지됩니다. + 에이전트가 전달 가능한 페이로드를 여러 개 내보낼 때 다중 메시지로 유지됩니다. ## 포럼 채널 -Discord 포럼 및 미디어 채널은 스레드 게시물만 허용합니다. OpenClaw는 이를 생성하는 두 가지 방법을 지원합니다. +Discord 포럼 및 미디어 채널은 스레드 게시물만 허용합니다. OpenClaw는 이를 만드는 두 가지 방법을 지원합니다. -- 포럼 상위 항목(`channel:`)으로 메시지를 보내 스레드를 자동 생성합니다. 스레드 제목은 메시지의 첫 번째 비어 있지 않은 줄을 사용합니다. -- `openclaw message thread create`를 사용해 스레드를 직접 생성합니다. 포럼 채널에는 `--message-id`를 전달하지 마세요. +- 포럼 부모(`channel:`)로 메시지를 보내 스레드를 자동 생성합니다. 스레드 제목은 메시지의 첫 번째 비어 있지 않은 줄을 사용합니다. +- `openclaw message thread create`를 사용해 스레드를 직접 만듭니다. 포럼 채널에는 `--message-id`를 전달하지 마세요. -예: 포럼 상위 항목으로 보내 스레드 생성 +예: 포럼 부모로 보내 스레드 만들기 ```bash openclaw message send --channel discord --target channel: \ --message "Topic title\nBody of the post" ``` -예: 포럼 스레드를 명시적으로 생성 +예: 포럼 스레드를 명시적으로 만들기 ```bash openclaw message thread create --channel discord --target channel: \ --thread-name "Topic title" --message "Body of the post" ``` -포럼 상위 항목은 Discord 컴포넌트를 허용하지 않습니다. 컴포넌트가 필요하면 스레드 자체(`channel:`)로 보내세요. +포럼 부모는 Discord 컴포넌트를 허용하지 않습니다. 컴포넌트가 필요하면 스레드 자체(`channel:`)로 보내세요. ## 대화형 컴포넌트 -OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 지원합니다. `components` 페이로드와 함께 메시지 도구를 사용하세요. 상호작용 결과는 일반 인바운드 메시지처럼 에이전트로 다시 라우팅되며 기존 Discord `replyToMode` 설정을 따릅니다. +OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 지원합니다. `components` 페이로드와 함께 메시지 도구를 사용하세요. 상호작용 결과는 일반 인바운드 메시지로 에이전트에 다시 라우팅되며 기존 Discord `replyToMode` 설정을 따릅니다. 지원되는 블록: - `text`, `section`, `separator`, `actions`, `media-gallery`, `file` -- 작업 행은 최대 5개의 버튼 또는 단일 선택 메뉴를 허용합니다 +- 작업 행은 최대 5개의 버튼 또는 단일 선택 메뉴를 허용합니다. - 선택 유형: `string`, `user`, `role`, `mentionable`, `channel` -기본적으로 컴포넌트는 일회용입니다. 버튼, 선택 항목, 양식을 만료될 때까지 여러 번 사용할 수 있게 하려면 `components.reusable=true`를 설정하세요. +기본적으로 컴포넌트는 한 번만 사용할 수 있습니다. 버튼, 선택 항목, 폼을 만료될 때까지 여러 번 사용할 수 있게 하려면 `components.reusable=true`를 설정하세요. -버튼을 클릭할 수 있는 사용자를 제한하려면 해당 버튼에 `allowedUsers`를 설정하세요(Discord 사용자 ID, 태그 또는 `*`). 구성된 경우 일치하지 않는 사용자는 임시 거부 메시지를 받습니다. +버튼을 클릭할 수 있는 사용자를 제한하려면 해당 버튼에 `allowedUsers`를 설정하세요(Discord 사용자 ID, 태그 또는 `*`). 설정된 경우 일치하지 않는 사용자는 일시적 거부 메시지를 받습니다. -`/model` 및 `/models` 슬래시 명령은 제공자, 모델, 호환 런타임 드롭다운과 제출 단계가 있는 대화형 모델 선택기를 엽니다. `/models add`는 더 이상 사용되지 않으며 이제 채팅에서 모델을 등록하는 대신 지원 중단 메시지를 반환합니다. 선택기 답장은 임시 메시지이며 호출한 사용자만 사용할 수 있습니다. +`/model` 및 `/models` 슬래시 명령은 공급자, 모델, 호환되는 런타임 드롭다운과 제출 단계가 포함된 대화형 모델 선택기를 엽니다. `/models add`는 더 이상 권장되지 않으며 이제 채팅에서 모델을 등록하는 대신 지원 중단 메시지를 반환합니다. 선택기 답장은 일시적이며 호출한 사용자만 사용할 수 있습니다. 파일 첨부: -- `file` 블록은 첨부 참조(`attachment://`)를 가리켜야 합니다 -- `media`/`path`/`filePath`(단일 파일)를 통해 첨부를 제공하세요. 여러 파일에는 `media-gallery`를 사용하세요 -- 업로드 이름이 첨부 참조와 일치해야 하는 경우 `filename`을 사용해 재정의하세요 +- `file` 블록은 첨부 참조(`attachment://`)를 가리켜야 합니다. +- `media`/`path`/`filePath`를 통해 첨부 파일을 제공하세요(단일 파일). 여러 파일에는 `media-gallery`를 사용하세요. +- 업로드 이름이 첨부 참조와 일치해야 하는 경우 `filename`을 사용해 재정의하세요. -모달 양식: +모달 폼: -- 최대 5개 필드와 함께 `components.modal`을 추가하세요 +- 최대 5개 필드와 함께 `components.modal`을 추가하세요. - 필드 유형: `text`, `checkbox`, `radio`, `select`, `role-select`, `user-select` -- OpenClaw는 트리거 버튼을 자동으로 추가합니다 +- OpenClaw는 트리거 버튼을 자동으로 추가합니다. 예: @@ -426,41 +426,41 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 } ``` -## 액세스 제어 및 라우팅 +## 접근 제어 및 라우팅 - `channels.discord.dmPolicy`는 DM 액세스를 제어합니다. `channels.discord.allowFrom`은 표준 DM 허용 목록입니다. + `channels.discord.dmPolicy`는 DM 접근을 제어합니다. `channels.discord.allowFrom`은 표준 DM 허용 목록입니다. - `pairing`(기본값) - `allowlist` - `open`(`channels.discord.allowFrom`에 `"*"`가 포함되어야 함) - `disabled` - DM 정책이 열림이 아닌 경우, 알 수 없는 사용자는 차단됩니다(또는 `pairing` 모드에서는 페어링하라는 메시지가 표시됩니다). + DM 정책이 열려 있지 않으면 알 수 없는 사용자는 차단됩니다(`pairing` 모드에서는 페어링을 요청받음). 다중 계정 우선순위: - `channels.discord.accounts.default.allowFrom`은 `default` 계정에만 적용됩니다. - - 하나의 계정에서는 `allowFrom`이 레거시 `dm.allowFrom`보다 우선합니다. - - 이름이 지정된 계정은 자체 `allowFrom` 및 레거시 `dm.allowFrom`이 설정되지 않은 경우 `channels.discord.allowFrom`을 상속합니다. - - 이름이 지정된 계정은 `channels.discord.accounts.default.allowFrom`을 상속하지 않습니다. + - 계정이 하나인 경우 `allowFrom`이 레거시 `dm.allowFrom`보다 우선합니다. + - 이름이 있는 계정은 자체 `allowFrom` 및 레거시 `dm.allowFrom`이 설정되지 않은 경우 `channels.discord.allowFrom`을 상속합니다. + - 이름이 있는 계정은 `channels.discord.accounts.default.allowFrom`을 상속하지 않습니다. - 레거시 `channels.discord.dm.policy` 및 `channels.discord.dm.allowFrom`은 호환성을 위해 계속 읽습니다. `openclaw doctor --fix`는 액세스를 변경하지 않고 가능할 때 이를 `dmPolicy` 및 `allowFrom`으로 마이그레이션합니다. + 레거시 `channels.discord.dm.policy` 및 `channels.discord.dm.allowFrom`은 호환성을 위해 계속 읽습니다. `openclaw doctor --fix`는 접근 권한을 변경하지 않고 수행할 수 있을 때 이를 `dmPolicy` 및 `allowFrom`으로 마이그레이션합니다. 전달용 DM 대상 형식: - `user:` - `<@id>` 멘션 - 단순 숫자 ID는 일반적으로 채널 기본값이 활성 상태일 때 채널 ID로 해석되지만, 계정의 유효 DM `allowFrom`에 나열된 ID는 호환성을 위해 사용자 DM 대상으로 취급됩니다. + 채널 기본값이 활성화된 경우 순수 숫자 ID는 일반적으로 채널 ID로 해석되지만, 계정의 유효 DM `allowFrom`에 나열된 ID는 호환성을 위해 사용자 DM 대상으로 처리됩니다. - + Discord DM은 `channels.discord.allowFrom`에서 동적 `accessGroup:` 항목을 사용할 수 있습니다. - 액세스 그룹 이름은 메시지 채널 간에 공유됩니다. 멤버가 각 채널의 일반 `allowFrom` 구문으로 표현되는 정적 그룹에는 `type: "message.senders"`를 사용하고, Discord 채널의 현재 `ViewChannel` 대상자가 멤버십을 동적으로 정의해야 할 때는 `type: "discord.channelAudience"`를 사용하세요. 공유 액세스 그룹 동작은 여기 문서에 설명되어 있습니다. [액세스 그룹](/ko/channels/access-groups) + 접근 그룹 이름은 메시지 채널 전체에서 공유됩니다. 구성원이 각 채널의 일반 `allowFrom` 구문으로 표현되는 정적 그룹에는 `type: "message.senders"`를 사용하고, Discord 채널의 현재 `ViewChannel` 대상자가 멤버십을 동적으로 정의해야 하는 경우에는 `type: "discord.channelAudience"`를 사용하세요. 공유 접근 그룹 동작은 여기 문서에 있습니다: [접근 그룹](/ko/channels/access-groups). ```json5 { @@ -483,9 +483,9 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 } ``` - Discord 텍스트 채널에는 별도의 멤버 목록이 없습니다. `type: "discord.channelAudience"`는 멤버십을 다음과 같이 모델링합니다. DM 발신자는 구성된 길드의 멤버이고, 역할 및 채널 덮어쓰기가 적용된 후 구성된 채널에 대해 현재 유효한 `ViewChannel` 권한을 가지고 있습니다. + Discord 텍스트 채널에는 별도의 구성원 목록이 없습니다. `type: "discord.channelAudience"`는 멤버십을 다음과 같이 모델링합니다. DM 발신자가 구성된 길드의 구성원이고, 역할 및 채널 덮어쓰기가 적용된 뒤 현재 구성된 채널에 대한 유효 `ViewChannel` 권한을 가지고 있습니다. - 예: 다른 모든 사용자에게는 DM을 닫아 두면서, `#maintainers`를 볼 수 있는 모든 사람이 봇에 DM을 보낼 수 있도록 허용합니다. + 예: DM은 다른 모든 사용자에게 닫아 둔 채, `#maintainers`를 볼 수 있는 누구나 봇에게 DM할 수 있게 허용합니다. ```json5 { @@ -526,9 +526,9 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 } ``` - 조회는 실패 시 닫힘으로 처리됩니다. Discord가 `Missing Access`를 반환하거나, 멤버 조회가 실패하거나, 채널이 다른 길드에 속한 경우 DM 발신자는 권한이 없는 것으로 처리됩니다. + 조회는 닫힌 상태로 실패합니다. Discord가 `Missing Access`를 반환하거나, 구성원 조회가 실패하거나, 채널이 다른 길드에 속한 경우 DM 발신자는 권한이 없는 것으로 처리됩니다. - 채널 대상자 액세스 그룹을 사용할 때 봇에 대해 Discord Developer Portal **Server Members Intent**를 활성화하세요. DM에는 길드 멤버 상태가 포함되지 않으므로, OpenClaw는 권한 부여 시점에 Discord REST를 통해 멤버를 확인합니다. + 채널 대상자 접근 그룹을 사용할 때는 Discord Developer Portal에서 봇의 **Server Members Intent**를 활성화하세요. DM에는 길드 구성원 상태가 포함되지 않으므로 OpenClaw는 권한 부여 시점에 Discord REST를 통해 구성원을 해석합니다. @@ -539,16 +539,16 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 - `allowlist` - `disabled` - `channels.discord`가 있을 때 보안 기준선은 `allowlist`입니다. + `channels.discord`가 있을 때 보안 기본선은 `allowlist`입니다. `allowlist` 동작: - - 길드는 `channels.discord.guilds`와 일치해야 합니다(`id` 권장, 슬러그 허용) - - 선택적 발신자 허용 목록: `users`(안정적인 ID 권장) 및 `roles`(역할 ID만). 둘 중 하나가 구성된 경우 발신자는 `users` 또는 `roles`와 일치할 때 허용됩니다 - - 직접 이름/태그 매칭은 기본적으로 비활성화되어 있습니다. 비상 호환 모드로만 `channels.discord.dangerouslyAllowNameMatching: true`를 활성화하세요 - - `users`에는 이름/태그가 지원되지만 ID가 더 안전합니다. 이름/태그 항목이 사용되면 `openclaw security audit`가 경고합니다 - - 길드에 `channels`가 구성된 경우 목록에 없는 채널은 거부됩니다 - - 길드에 `channels` 블록이 없으면 해당 허용 목록 길드의 모든 채널이 허용됩니다 + - 길드는 `channels.discord.guilds`와 일치해야 합니다(`id` 권장, slug 허용). + - 선택적 발신자 허용 목록: `users`(안정적인 ID 권장) 및 `roles`(역할 ID만). 둘 중 하나가 구성된 경우 발신자가 `users` 또는 `roles`와 일치하면 허용됩니다. + - 직접 이름/태그 매칭은 기본적으로 비활성화되어 있습니다. 긴급 호환 모드로만 `channels.discord.dangerouslyAllowNameMatching: true`를 활성화하세요. + - `users`에는 이름/태그가 지원되지만 ID가 더 안전합니다. 이름/태그 항목이 사용되면 `openclaw security audit`가 경고합니다. + - 길드에 `channels`가 구성되어 있으면 목록에 없는 채널은 거부됩니다. + - 길드에 `channels` 블록이 없으면 해당 허용 목록 길드의 모든 채널이 허용됩니다. 예: @@ -574,23 +574,23 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 } ``` - `DISCORD_BOT_TOKEN`만 설정하고 `channels.discord` 블록을 생성하지 않으면, 런타임 대체값은 `channels.defaults.groupPolicy`가 `open`이더라도 `groupPolicy="allowlist"`입니다(로그에 경고가 표시됨). + `DISCORD_BOT_TOKEN`만 설정하고 `channels.discord` 블록을 만들지 않으면, 런타임 대체값은 `channels.defaults.groupPolicy`가 `open`이더라도 `groupPolicy="allowlist"`입니다(로그에 경고 표시). 길드 메시지는 기본적으로 멘션으로 제한됩니다. - 멘션 감지에는 다음이 포함됩니다. + 멘션 감지는 다음을 포함합니다. - 명시적 봇 멘션 - 구성된 멘션 패턴(`agents.list[].groupChat.mentionPatterns`, 대체값 `messages.groupChat.mentionPatterns`) - 지원되는 경우의 암시적 봇 답장 동작 - 아웃바운드 Discord 메시지를 작성할 때 표준 멘션 구문을 사용하세요. 사용자는 `<@USER_ID>`, 채널은 `<#CHANNEL_ID>`, 역할은 `<@&ROLE_ID>`입니다. 레거시 `<@!USER_ID>` 닉네임 멘션 형식을 사용하지 마세요. + 아웃바운드 Discord 메시지를 작성할 때는 표준 멘션 구문을 사용하세요. 사용자는 `<@USER_ID>`, 채널은 `<#CHANNEL_ID>`, 역할은 `<@&ROLE_ID>`입니다. 레거시 `<@!USER_ID>` 별명 멘션 형식은 사용하지 마세요. `requireMention`은 길드/채널별로 구성됩니다(`channels.discord.guilds...`). - `ignoreOtherMentions`는 봇이 아닌 다른 사용자/역할을 멘션하는 메시지를 선택적으로 삭제합니다(@everyone/@here 제외). + `ignoreOtherMentions`는 선택적으로 봇이 아닌 다른 사용자/역할을 멘션하는 메시지를 삭제합니다(@everyone/@here 제외). 그룹 DM: @@ -602,7 +602,7 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 ### 역할 기반 에이전트 라우팅 -`bindings[].match.roles`를 사용해 Discord 길드 멤버를 역할 ID별로 다른 에이전트에 라우팅하세요. 역할 기반 바인딩은 역할 ID만 허용하며 피어 또는 부모 피어 바인딩 이후, 길드 전용 바인딩 이전에 평가됩니다. 바인딩이 다른 매치 필드도 설정한 경우(예: `peer` + `guildId` + `roles`), 구성된 모든 필드가 일치해야 합니다. +`bindings[].match.roles`를 사용해 Discord 길드 구성원을 역할 ID별로 다른 에이전트로 라우팅하세요. 역할 기반 바인딩은 역할 ID만 허용하며 피어 또는 부모-피어 바인딩 이후, 길드 전용 바인딩 이전에 평가됩니다. 바인딩이 다른 매치 필드도 설정하는 경우(예: `peer` + `guildId` + `roles`) 구성된 모든 필드가 일치해야 합니다. ```json5 { @@ -628,13 +628,13 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 ## 네이티브 명령 및 명령 인증 -- `commands.native`는 기본값이 `"auto"`이며 Discord에서 활성화됩니다. +- `commands.native`의 기본값은 `"auto"`이며 Discord에서 활성화됩니다. - 채널별 재정의: `channels.discord.commands.native`. - `commands.native=false`는 시작 중 Discord 슬래시 명령 등록 및 정리를 건너뜁니다. 이전에 등록된 명령은 Discord 앱에서 제거할 때까지 Discord에 계속 표시될 수 있습니다. - 네이티브 명령 인증은 일반 메시지 처리와 동일한 Discord 허용 목록/정책을 사용합니다. -- 권한이 없는 사용자에게도 Discord UI에서 명령이 계속 표시될 수 있습니다. 실행 시에는 여전히 OpenClaw 인증을 적용하며 "not authorized"를 반환합니다. +- 권한이 없는 사용자에게도 명령이 Discord UI에 계속 표시될 수 있습니다. 실행 시에는 여전히 OpenClaw 인증이 적용되며 "not authorized"를 반환합니다. -명령 카탈로그와 동작은 [슬래시 명령](/ko/tools/slash-commands)을 참조하세요. +명령 카탈로그와 동작은 [슬래시 명령](/ko/tools/slash-commands)을 참고하세요. 기본 슬래시 명령 설정: @@ -643,31 +643,31 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 ## 기능 세부 정보 - + Discord는 에이전트 출력에서 답장 태그를 지원합니다. - `[[reply_to_current]]` - `[[reply_to:]]` - `channels.discord.replyToMode`로 제어됩니다. + `channels.discord.replyToMode`로 제어합니다. - - `off` (기본값) + - `off`(기본값) - `first` - `all` - `batched` 참고: `off`는 암시적 답장 스레딩을 비활성화합니다. 명시적 `[[reply_to_*]]` 태그는 계속 적용됩니다. `first`는 항상 해당 턴의 첫 번째 발신 Discord 메시지에 암시적 네이티브 답장 참조를 첨부합니다. - `batched`는 수신 턴이 여러 메시지의 디바운스된 배치였을 때만 Discord의 암시적 네이티브 답장 참조를 첨부합니다. 이는 모든 단일 메시지 턴이 아니라, 주로 모호하고 짧은 시간에 몰리는 채팅에 네이티브 답장을 사용하려는 경우 유용합니다. + `batched`는 수신 턴이 여러 메시지의 디바운스된 배치였을 때만 Discord의 암시적 네이티브 답장 참조를 첨부합니다. 이는 모든 단일 메시지 턴이 아니라, 모호하게 폭주하는 채팅에 주로 네이티브 답장을 사용하고 싶을 때 유용합니다. - 메시지 ID는 컨텍스트/기록에 노출되어 에이전트가 특정 메시지를 대상으로 지정할 수 있습니다. + 메시지 ID는 컨텍스트/히스토리에 노출되므로 에이전트가 특정 메시지를 대상으로 지정할 수 있습니다. - OpenClaw는 임시 메시지를 보내고 텍스트가 도착하는 동안 이를 편집하여 초안 답장을 스트리밍할 수 있습니다. `channels.discord.streaming`은 `off` (기본값) | `partial` | `block` | `progress`를 받습니다. `progress`는 편집 가능한 상태 초안 하나를 유지하고 최종 전달 전까지 도구 진행 상황으로 업데이트합니다. `streamMode`는 기존 별칭이며 자동 마이그레이션됩니다. + OpenClaw는 임시 메시지를 보내고 텍스트가 도착할 때 이를 편집하여 초안 답장을 스트리밍할 수 있습니다. `channels.discord.streaming`은 `off`(기본값) | `partial` | `block` | `progress`를 받습니다. `progress`는 편집 가능한 상태 초안 하나를 유지하고 최종 전달 전까지 도구 진행 상황으로 업데이트합니다. `streamMode`는 레거시 런타임 별칭입니다. 저장된 구성을 표준 키로 다시 쓰려면 `openclaw doctor --fix`를 실행하세요. - 여러 봇이나 gateways가 계정을 공유할 때 Discord 미리보기 편집이 빠르게 속도 제한에 걸리므로 기본값은 `off`로 유지됩니다. + 여러 봇이나 Gateway가 계정을 공유할 때 Discord 미리보기 편집은 빠르게 속도 제한에 걸리므로 기본값은 `off`로 유지됩니다. ```json5 { @@ -684,13 +684,13 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 } ``` - - `partial`은 토큰이 도착하는 동안 단일 미리보기 메시지를 편집합니다. - - `block`은 초안 크기의 청크를 내보냅니다(`draftChunk`를 사용해 크기와 중단 지점을 조정하며, `textChunkLimit`로 제한됨). + - `partial`은 토큰이 도착할 때 단일 미리보기 메시지를 편집합니다. + - `block`은 초안 크기의 청크를 내보냅니다(크기와 중단점을 조정하려면 `draftChunk`를 사용하며, `textChunkLimit`로 제한됩니다). - 미디어, 오류, 명시적 답장 최종 메시지는 대기 중인 미리보기 편집을 취소합니다. - `streaming.preview.toolProgress`(기본값 `true`)는 도구/진행 상황 업데이트가 미리보기 메시지를 재사용할지 제어합니다. - - `streaming.preview.commandText` / `streaming.progress.commandText`는 압축된 진행 상황 줄의 명령/실행 세부 정보를 제어합니다: `raw`(기본값) 또는 `status`(도구 레이블만). + - `streaming.preview.commandText` / `streaming.progress.commandText`는 간결한 진행 상황 줄의 명령/실행 세부 정보를 제어합니다: `raw`(기본값) 또는 `status`(도구 레이블만). - 압축된 진행 상황 줄은 유지하면서 원시 명령/실행 텍스트를 숨깁니다. + 간결한 진행 상황 줄은 유지하면서 원시 명령/실행 텍스트를 숨기려면: ```json { @@ -708,44 +708,44 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 } ``` - 미리보기 스트리밍은 텍스트 전용입니다. 미디어 답장은 일반 전달로 폴백됩니다. `block` 스트리밍이 명시적으로 활성화된 경우 OpenClaw는 이중 스트리밍을 피하기 위해 미리보기 스트림을 건너뜁니다. + 미리보기 스트리밍은 텍스트 전용입니다. 미디어 답장은 일반 전달 방식으로 대체됩니다. `block` 스트리밍이 명시적으로 활성화된 경우 OpenClaw는 중복 스트리밍을 피하기 위해 미리보기 스트림을 건너뜁니다. - - 길드 기록 컨텍스트: + + 길드 히스토리 컨텍스트: - `channels.discord.historyLimit` 기본값 `20` - - 폴백: `messages.groupChat.historyLimit` + - 대체값: `messages.groupChat.historyLimit` - `0`은 비활성화 - DM 기록 제어: + DM 히스토리 제어: - `channels.discord.dmHistoryLimit` - `channels.discord.dms[""].historyLimit` 스레드 동작: - - Discord 스레드는 채널 세션으로 라우팅되며, 재정의하지 않는 한 부모 채널 구성을 상속합니다. - - 스레드 세션은 모델 전용 폴백으로 부모 채널의 세션 수준 `/model` 선택을 상속합니다. 스레드 로컬 `/model` 선택이 여전히 우선하며, 대화 기록 상속이 활성화되지 않는 한 부모 transcript 기록은 복사되지 않습니다. - - `channels.discord.thread.inheritParent`(기본값 `false`)는 새 자동 스레드가 부모 transcript에서 시드를 받도록 선택합니다. 계정별 재정의는 `channels.discord.accounts..thread.inheritParent` 아래에 있습니다. + - Discord 스레드는 채널 세션으로 라우팅되며, 재정의하지 않는 한 상위 채널 구성을 상속합니다. + - 스레드 세션은 상위 채널의 세션 수준 `/model` 선택을 모델 전용 대체값으로 상속합니다. 스레드 로컬 `/model` 선택은 여전히 우선하며, 트랜스크립트 상속이 활성화되지 않는 한 상위 트랜스크립트 히스토리는 복사되지 않습니다. + - `channels.discord.thread.inheritParent`(기본값 `false`)는 새 자동 스레드가 상위 트랜스크립트에서 시드되도록 선택합니다. 계정별 재정의는 `channels.discord.accounts..thread.inheritParent` 아래에 있습니다. - 메시지 도구 반응은 `user:` DM 대상을 확인할 수 있습니다. - - `guilds..channels..requireMention: false`는 답장 단계 활성화 폴백 중에도 유지됩니다. + - `guilds..channels..requireMention: false`는 답장 단계 활성화 대체 중에도 보존됩니다. - 채널 주제는 **신뢰할 수 없는** 컨텍스트로 주입됩니다. 허용 목록은 누가 에이전트를 트리거할 수 있는지를 제한하며, 완전한 보조 컨텍스트 비식별화 경계가 아닙니다. + 채널 주제는 **신뢰할 수 없는** 컨텍스트로 주입됩니다. 허용 목록은 누가 에이전트를 트리거할 수 있는지 제한하지만, 완전한 보조 컨텍스트 삭제 경계는 아닙니다. - Discord는 스레드를 세션 대상에 바인딩하여 해당 스레드의 후속 메시지가 동일한 세션(하위 에이전트 세션 포함)으로 계속 라우팅되도록 할 수 있습니다. + Discord는 스레드를 세션 대상에 바인딩하여 해당 스레드의 후속 메시지가 같은 세션(하위 에이전트 세션 포함)으로 계속 라우팅되도록 할 수 있습니다. 명령: - `/focus ` 현재/새 스레드를 하위 에이전트/세션 대상에 바인딩 - `/unfocus` 현재 스레드 바인딩 제거 - - `/agents` 활성 실행 및 바인딩 상태 표시 + - `/agents` 활성 실행과 바인딩 상태 표시 - `/session idle ` 포커스된 바인딩의 비활성 자동 포커스 해제를 조회/업데이트 - - `/session max-age ` 포커스된 바인딩의 강제 최대 수명을 조회/업데이트 + - `/session max-age ` 포커스된 바인딩의 하드 최대 수명을 조회/업데이트 구성: @@ -776,23 +776,23 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 - `session.threadBindings.*`는 전역 기본값을 설정합니다. - `channels.discord.threadBindings.*`는 Discord 동작을 재정의합니다. - - `spawnSessions`는 `sessions_spawn({ thread: true })` 및 ACP 스레드 생성에 대한 자동 생성/바인딩 스레드를 제어합니다. 기본값: `true`. + - `spawnSessions`는 `sessions_spawn({ thread: true })` 및 ACP 스레드 생성에 대한 스레드 자동 생성/바인딩을 제어합니다. 기본값: `true`. - `defaultSpawnContext`는 스레드 바인딩 생성의 네이티브 하위 에이전트 컨텍스트를 제어합니다. 기본값: `"fork"`. - 더 이상 사용되지 않는 `spawnSubagentSessions`/`spawnAcpSessions` 키는 `openclaw doctor --fix`로 마이그레이션됩니다. - - 계정에 대해 스레드 바인딩이 비활성화된 경우 `/focus` 및 관련 스레드 바인딩 작업을 사용할 수 없습니다. + - 계정에서 스레드 바인딩이 비활성화된 경우 `/focus` 및 관련 스레드 바인딩 작업을 사용할 수 없습니다. - [하위 에이전트](/ko/tools/subagents), [ACP 에이전트](/ko/tools/acp-agents), [구성 참조](/ko/gateway/configuration-reference)를 참조하세요. + [하위 에이전트](/ko/tools/subagents), [ACP 에이전트](/ko/tools/acp-agents), [구성 참조](/ko/gateway/configuration-reference)를 참고하세요. - 안정적인 "상시 실행" ACP 작업 공간의 경우 Discord 대화를 대상으로 하는 최상위 typed ACP 바인딩을 구성하세요. + 안정적인 "항상 켜짐" ACP 작업 공간의 경우 Discord 대화를 대상으로 하는 최상위 typed ACP 바인딩을 구성하세요. 구성 경로: - - `type: "acp"` 및 `match.channel: "discord"`가 있는 `bindings[]` + - `type: "acp"` 및 `match.channel: "discord"`를 포함하는 `bindings[]` - 예시: + 예: ```json5 { @@ -842,11 +842,11 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 참고: - - `/acp spawn codex --bind here`는 현재 채널 또는 스레드를 제자리에서 바인딩하고 이후 메시지를 동일한 ACP 세션에 유지합니다. 스레드 메시지는 부모 채널 바인딩을 상속합니다. - - 바인딩된 채널 또는 스레드에서 `/new` 및 `/reset`은 동일한 ACP 세션을 제자리에서 재설정합니다. 임시 스레드 바인딩은 활성 상태인 동안 대상 확인을 재정의할 수 있습니다. - - `spawnSessions`는 `--thread auto|here`를 통한 자식 스레드 생성/바인딩을 제한합니다. + - `/acp spawn codex --bind here`는 현재 채널 또는 스레드를 제자리에 바인딩하고 이후 메시지를 같은 ACP 세션에 유지합니다. 스레드 메시지는 상위 채널 바인딩을 상속합니다. + - 바인딩된 채널 또는 스레드에서 `/new`와 `/reset`은 같은 ACP 세션을 제자리에서 재설정합니다. 임시 스레드 바인딩은 활성 상태일 때 대상 확인을 재정의할 수 있습니다. + - `spawnSessions`는 `--thread auto|here`를 통한 하위 스레드 생성/바인딩을 제한합니다. - 바인딩 동작 세부 정보는 [ACP 에이전트](/ko/tools/acp-agents)를 참조하세요. + 바인딩 동작 세부 정보는 [ACP 에이전트](/ko/tools/acp-agents)를 참고하세요. @@ -854,7 +854,7 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 길드별 반응 알림 모드: - `off` - - `own` (기본값) + - `own`(기본값) - `all` - `allowlist`(`guilds..users` 사용) @@ -870,19 +870,19 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 - `channels.discord.accounts..ackReaction` - `channels.discord.ackReaction` - `messages.ackReaction` - - 에이전트 ID 이모지 폴백(`agents.list[].identity.emoji`, 없으면 "👀") + - 에이전트 ID 이모지 대체값(`agents.list[].identity.emoji`, 없으면 "👀") 참고: - - Discord는 유니코드 이모지 또는 사용자 지정 이모지 이름을 허용합니다. + - Discord는 유니코드 이모지 또는 커스텀 이모지 이름을 허용합니다. - 채널 또는 계정의 반응을 비활성화하려면 `""`를 사용하세요. - 채널에서 시작되는 구성 쓰기는 기본적으로 활성화됩니다. + 채널에서 시작된 구성 쓰기는 기본적으로 활성화되어 있습니다. - 이는 `/config set|unset` 흐름(명령 기능이 활성화된 경우)에 영향을 줍니다. + 이는 `/config set|unset` 흐름에 영향을 줍니다(명령 기능이 활성화된 경우). 비활성화: @@ -899,7 +899,7 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 - `channels.discord.proxy`를 사용해 Discord gateway WebSocket 트래픽과 시작 시 REST 조회(애플리케이션 ID + 허용 목록 확인)를 HTTP(S) 프록시를 통해 라우팅합니다. + `channels.discord.proxy`를 사용하여 Discord Gateway WebSocket 트래픽과 시작 시 REST 조회(애플리케이션 ID + 허용 목록 확인)를 HTTP(S) 프록시를 통해 라우팅합니다. ```json5 { @@ -948,14 +948,14 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 참고: - 허용 목록은 `pk:`를 사용할 수 있습니다. - - 멤버 표시 이름은 `channels.discord.dangerouslyAllowNameMatching: true`일 때만 이름/슬러그로 일치됩니다. + - 멤버 표시 이름은 `channels.discord.dangerouslyAllowNameMatching: true`일 때만 이름/슬러그로 매칭됩니다. - 조회는 원본 메시지 ID를 사용하며 시간 창으로 제한됩니다. - - 조회가 실패하면 프록시된 메시지는 봇 메시지로 처리되어 `allowBots=true`가 아닌 한 삭제됩니다. + - 조회에 실패하면 프록시된 메시지는 봇 메시지로 처리되어 `allowBots=true`가 아닌 한 삭제됩니다. - 에이전트가 알려진 Discord 사용자에 대해 결정적인 발신 멘션이 필요할 때 `mentionAliases`를 사용하세요. 키는 앞의 `@`가 없는 핸들이며, 값은 Discord 사용자 ID입니다. 알 수 없는 핸들, `@everyone`, `@here`, Markdown 코드 스팬 안의 멘션은 변경되지 않습니다. + 에이전트가 알려진 Discord 사용자에게 결정적인 발신 멘션을 사용해야 할 때 `mentionAliases`를 사용하세요. 키는 앞의 `@`가 없는 핸들이고, 값은 Discord 사용자 ID입니다. 알 수 없는 핸들, `@everyone`, `@here`, Markdown 코드 스팬 안의 멘션은 변경되지 않습니다. ```json5 { @@ -979,9 +979,9 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 - 상태 또는 활동 필드를 설정하거나 자동 presence를 활성화하면 presence 업데이트가 적용됩니다. + 상태 또는 활동 필드를 설정하거나 자동 Presence를 활성화하면 Presence 업데이트가 적용됩니다. - 상태만 사용하는 예시: + 상태만 설정하는 예: ```json5 { @@ -993,7 +993,7 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 } ``` - 활동 예시(사용자 지정 상태가 기본 활동 유형): + 활동 예(커스텀 상태가 기본 활동 유형): ```json5 { @@ -1006,7 +1006,7 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 } ``` - 스트리밍 예시: + 스트리밍 예: ```json5 { @@ -1023,13 +1023,13 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 활동 유형 맵: - 0: 플레이 중 - - 1: 스트리밍 중(`activityUrl` 필요) + - 1: 스트리밍(`activityUrl` 필요) - 2: 듣는 중 - 3: 시청 중 - - 4: 사용자 지정(활동 텍스트를 상태 값으로 사용, 이모지는 선택 사항) + - 4: 커스텀(활동 텍스트를 상태 값으로 사용하며, 이모지는 선택 사항) - 5: 경쟁 중 - 자동 presence 예시(런타임 상태 신호): + 자동 Presence 예(런타임 상태 신호): ```json5 { @@ -1046,76 +1046,77 @@ OpenClaw는 에이전트 메시지용 Discord 컴포넌트 v2 컨테이너를 } ``` - 자동 presence는 런타임 가용성을 Discord 상태에 매핑합니다. healthy => online, degraded 또는 unknown => idle, exhausted 또는 unavailable => dnd. 선택적 텍스트 재정의: + 자동 상태 표시는 런타임 가용성을 Discord 상태로 매핑합니다: healthy => online, degraded 또는 unknown => idle, exhausted 또는 unavailable => dnd. 선택적 텍스트 재정의: - `autoPresence.healthyText` - `autoPresence.degradedText` - - `autoPresence.exhaustedText` (`{reason}` placeholder 지원) + - `autoPresence.exhaustedText` (`{reason}` 플레이스홀더 지원) Discord는 DM에서 버튼 기반 승인 처리를 지원하며, 선택적으로 원래 채널에 승인 프롬프트를 게시할 수 있습니다. - Config 경로: + 구성 경로: - `channels.discord.execApprovals.enabled` - - `channels.discord.execApprovals.approvers` (선택 사항; 가능한 경우 `commands.ownerAllowFrom`으로 fallback) + - `channels.discord.execApprovals.approvers` (선택 사항; 가능한 경우 `commands.ownerAllowFrom`으로 폴백) - `channels.discord.execApprovals.target` (`dm` | `channel` | `both`, 기본값: `dm`) - `agentFilter`, `sessionFilter`, `cleanupAfterResolve` - Discord는 `enabled`가 설정되지 않았거나 `"auto"`이고 `execApprovals.approvers` 또는 `commands.ownerAllowFrom`에서 하나 이상의 승인자를 확인할 수 있으면 native exec approvals를 자동으로 활성화합니다. Discord는 channel `allowFrom`, legacy `dm.allowFrom` 또는 direct-message `defaultTo`에서 exec 승인자를 추론하지 않습니다. Discord를 native approval 클라이언트로 명시적으로 비활성화하려면 `enabled: false`를 설정하세요. + Discord는 `enabled`가 설정되지 않았거나 `"auto"`이고 승인자를 하나 이상 해석할 수 있을 때 네이티브 exec 승인을 자동으로 활성화합니다. 승인자는 `execApprovals.approvers` 또는 `commands.ownerAllowFrom`에서 해석할 수 있습니다. Discord는 채널 `allowFrom`, 레거시 `dm.allowFrom`, 또는 직접 메시지 `defaultTo`에서 exec 승인자를 추론하지 않습니다. Discord를 네이티브 승인 클라이언트로 명시적으로 비활성화하려면 `enabled: false`를 설정하세요. - `/diagnostics` 및 `/export-trajectory` 같은 민감한 owner-only group 명령의 경우 OpenClaw는 승인 프롬프트와 최종 결과를 비공개로 보냅니다. 호출한 owner에게 Discord owner route가 있으면 먼저 Discord DM을 시도합니다. 사용할 수 없으면 Telegram 같은 `commands.ownerAllowFrom`의 첫 번째 사용 가능한 owner route로 fallback합니다. + `/diagnostics` 및 `/export-trajectory` 같은 민감한 소유자 전용 그룹 명령의 경우, OpenClaw는 승인 프롬프트와 최종 결과를 비공개로 보냅니다. 호출한 소유자에게 Discord 소유자 경로가 있으면 먼저 Discord DM을 시도하고, 사용할 수 없으면 Telegram 같은 `commands.ownerAllowFrom`의 첫 번째 사용 가능한 소유자 경로로 폴백합니다. - `target`이 `channel` 또는 `both`이면 승인 프롬프트가 채널에 표시됩니다. 확인된 승인자만 버튼을 사용할 수 있으며, 다른 사용자는 ephemeral 거부를 받습니다. 승인 프롬프트에는 명령 텍스트가 포함되므로 신뢰할 수 있는 채널에서만 채널 전달을 활성화하세요. 세션 키에서 채널 ID를 파생할 수 없으면 OpenClaw는 DM 전달로 fallback합니다. + `target`이 `channel` 또는 `both`이면 승인 프롬프트가 채널에 표시됩니다. 해석된 승인자만 버튼을 사용할 수 있으며, 다른 사용자는 임시 거부 응답을 받습니다. 승인 프롬프트에는 명령 텍스트가 포함되므로 신뢰할 수 있는 채널에서만 채널 전달을 활성화하세요. 세션 키에서 채널 ID를 파생할 수 없으면 OpenClaw는 DM 전달로 폴백합니다. - Discord는 다른 chat channel에서 사용하는 공유 승인 버튼도 렌더링합니다. native Discord adapter는 주로 승인자 DM routing과 channel fanout을 추가합니다. - 이러한 버튼이 있으면 기본 승인 UX가 됩니다. OpenClaw는 - tool 결과에서 chat approvals를 사용할 수 없거나 수동 승인이 유일한 경로라고 할 때만 수동 `/approve` 명령을 포함해야 합니다. - Discord native approval runtime이 활성 상태가 아니면 OpenClaw는 - local deterministic `/approve ` 프롬프트를 계속 표시합니다. runtime은 활성 상태지만 native card를 어떤 target에도 전달할 수 없으면 - OpenClaw는 pending approval의 정확한 `/approve` - 명령이 포함된 same-chat fallback notice를 보냅니다. + Discord는 다른 채팅 채널에서 사용하는 공유 승인 버튼도 렌더링합니다. 네이티브 Discord 어댑터는 주로 승인자 DM 라우팅과 채널 팬아웃을 추가합니다. + 해당 버튼이 있으면 그것이 기본 승인 UX입니다. OpenClaw는 도구 결과가 + 채팅 승인을 사용할 수 없다고 하거나 수동 승인이 유일한 경로라고 할 때만 + 수동 `/approve` 명령을 포함해야 합니다. + Discord 네이티브 승인 런타임이 활성 상태가 아니면 OpenClaw는 + 로컬 결정적 `/approve ` 프롬프트를 계속 표시합니다. 런타임이 + 활성 상태이지만 어떤 대상에도 네이티브 카드를 전달할 수 없으면 + OpenClaw는 보류 중인 승인에서 정확한 `/approve` 명령이 포함된 동일 채팅 폴백 알림을 보냅니다. - Gateway auth와 승인 확인은 공유 Gateway client contract를 따릅니다(`plugin:` ID는 `plugin.approval.resolve`를 통해 확인되고, 다른 ID는 `exec.approval.resolve`를 통해 확인됨). 승인은 기본적으로 30분 후 만료됩니다. + Gateway 인증 및 승인 해석은 공유 Gateway 클라이언트 계약을 따릅니다(`plugin:` ID는 `plugin.approval.resolve`를 통해 해석되고, 다른 ID는 `exec.approval.resolve`를 통해 해석됩니다). 승인은 기본적으로 30분 후 만료됩니다. - [Exec approvals](/ko/tools/exec-approvals)를 참조하세요. + [exec 승인](/ko/tools/exec-approvals)을 참고하세요. ## 도구 및 작업 게이트 -Discord 메시지 작업에는 messaging, channel admin, moderation, presence, metadata 작업이 포함됩니다. +Discord 메시지 작업에는 메시징, 채널 관리, 모더레이션, 상태 표시, 메타데이터 작업이 포함됩니다. 핵심 예시: -- messaging: `sendMessage`, `readMessages`, `editMessage`, `deleteMessage`, `threadReply` -- reactions: `react`, `reactions`, `emojiList` -- moderation: `timeout`, `kick`, `ban` -- presence: `setPresence` +- 메시징: `sendMessage`, `readMessages`, `editMessage`, `deleteMessage`, `threadReply` +- 반응: `react`, `reactions`, `emojiList` +- 모더레이션: `timeout`, `kick`, `ban` +- 상태 표시: `setPresence` -`event-create` 작업은 scheduled event cover image를 설정하기 위해 선택적 `image` 매개변수(URL 또는 local file path)를 허용합니다. +`event-create` 작업은 예약된 이벤트 커버 이미지를 설정하기 위한 선택적 `image` 매개변수(URL 또는 로컬 파일 경로)를 허용합니다. -Action gates는 `channels.discord.actions.*` 아래에 있습니다. +작업 게이트는 `channels.discord.actions.*` 아래에 있습니다. 기본 게이트 동작: -| 작업 그룹 | 기본값 | -| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- | -| reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions | 활성화됨 | +| 작업 그룹 | 기본값 | +| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------- | +| reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions | 활성화됨 | | roles | 비활성화됨 | | moderation | 비활성화됨 | | presence | 비활성화됨 | -## Components v2 UI +## 컴포넌트 v2 UI -OpenClaw는 exec approvals와 cross-context markers에 Discord components v2를 사용합니다. Discord 메시지 작업은 custom UI를 위해 `components`도 허용할 수 있습니다(고급; discord tool을 통해 component payload를 구성해야 함). legacy `embeds`는 계속 사용할 수 있지만 권장되지 않습니다. +OpenClaw는 exec 승인과 교차 컨텍스트 마커에 Discord 컴포넌트 v2를 사용합니다. Discord 메시지 작업은 사용자 지정 UI를 위해 `components`도 허용할 수 있지만(고급; discord 도구를 통해 컴포넌트 페이로드를 구성해야 함), 레거시 `embeds`는 계속 사용할 수 있으나 권장되지 않습니다. -- `channels.discord.ui.components.accentColor`는 Discord component container에서 사용하는 accent color를 설정합니다(hex). -- `channels.discord.accounts..ui.components.accentColor`로 account별로 설정합니다. -- components v2가 있으면 `embeds`는 무시됩니다. +- `channels.discord.ui.components.accentColor`는 Discord 컴포넌트 컨테이너에서 사용하는 강조 색상(hex)을 설정합니다. +- 계정별로 `channels.discord.accounts..ui.components.accentColor`로 설정합니다. +- 컴포넌트 v2가 있으면 `embeds`는 무시됩니다. 예시: @@ -1135,20 +1136,20 @@ OpenClaw는 exec approvals와 cross-context markers에 Discord components v2를 ## 음성 -Discord에는 두 가지 별도의 음성 표면이 있습니다. realtime **voice channels**(연속 대화)와 **voice message attachments**(waveform preview 형식)입니다. Gateway는 둘 다 지원합니다. +Discord에는 두 가지 별개의 음성 표면이 있습니다: 실시간 **음성 채널**(연속 대화)과 **음성 메시지 첨부 파일**(파형 미리보기 형식). Gateway는 둘 다 지원합니다. ### 음성 채널 설정 체크리스트: 1. Discord Developer Portal에서 Message Content Intent를 활성화합니다. -2. role/user allowlists를 사용할 때 Server Members Intent를 활성화합니다. -3. `bot` 및 `applications.commands` scope로 bot을 초대합니다. -4. 대상 voice channel에서 Connect, Speak, Send Messages, Read Message History를 부여합니다. -5. native commands(`commands.native` 또는 `channels.discord.commands.native`)를 활성화합니다. +2. 역할/사용자 허용 목록을 사용할 때 Server Members Intent를 활성화합니다. +3. `bot` 및 `applications.commands` 범위로 봇을 초대합니다. +4. 대상 음성 채널에서 Connect, Speak, Send Messages, Read Message History를 부여합니다. +5. 네이티브 명령(`commands.native` 또는 `channels.discord.commands.native`)을 활성화합니다. 6. `channels.discord.voice`를 구성합니다. -세션을 제어하려면 `/vc join|leave|status`를 사용하세요. 이 명령은 account default agent를 사용하며 다른 Discord 명령과 동일한 allowlist 및 group policy 규칙을 따릅니다. +세션을 제어하려면 `/vc join|leave|status`를 사용하세요. 이 명령은 계정 기본 에이전트를 사용하며 다른 Discord 명령과 동일한 허용 목록 및 그룹 정책 규칙을 따릅니다. ```bash /vc join channel: @@ -1156,7 +1157,7 @@ Discord에는 두 가지 별도의 음성 표면이 있습니다. realtime **voi /vc leave ``` -Auto-join 예시: +자동 참여 예시: ```json5 { @@ -1187,37 +1188,37 @@ Auto-join 예시: 참고: -- `voice.tts`는 음성 재생에 대해서만 `messages.tts`를 재정의합니다. -- `voice.model`은 Discord voice channel 응답에 사용되는 LLM만 재정의합니다. routed agent model을 상속하려면 설정하지 않은 상태로 두세요. -- STT는 `tools.media.audio`를 사용합니다. `voice.model`은 transcription에 영향을 주지 않습니다. -- channel별 Discord `systemPrompt` 재정의는 해당 voice channel의 voice transcript turns에 적용됩니다. -- Voice transcript turns는 Discord `allowFrom`(또는 `dm.allowFrom`)에서 owner status를 파생합니다. non-owner speaker는 owner-only tools(예: `gateway` 및 `cron`)에 접근할 수 없습니다. -- Discord voice는 text-only config에서는 opt-in입니다. `/vc` 명령, voice runtime 및 `GuildVoiceStates` gateway intent를 활성화하려면 `channels.discord.voice.enabled=true`를 설정하세요(또는 기존 `channels.discord.voice` block을 유지하세요). -- `channels.discord.intents.voiceStates`는 voice-state intent subscription을 명시적으로 재정의할 수 있습니다. effective voice enablement를 따르게 하려면 설정하지 않은 상태로 두세요. -- `voice.daveEncryption` 및 `voice.decryptionFailureTolerance`는 `@discordjs/voice` join options로 전달됩니다. -- `@discordjs/voice` 기본값은 설정하지 않은 경우 `daveEncryption=true` 및 `decryptionFailureTolerance=24`입니다. -- `voice.connectTimeoutMs`는 `/vc join` 및 auto-join 시도의 초기 `@discordjs/voice` Ready 대기를 제어합니다. 기본값: `30000`. -- `voice.reconnectGraceMs`는 연결이 끊긴 voice session이 재연결을 시작하기 전까지 OpenClaw가 기다리는 시간을 제어하며, 이 시간이 지나면 세션을 종료합니다. 기본값: `15000`. -- OpenClaw는 receive decrypt failures도 감시하며, 짧은 시간 내 반복 실패가 발생하면 voice channel을 나갔다가 다시 참여하여 자동 복구합니다. -- 업데이트 후 receive logs에 `DecryptionFailed(UnencryptedWhenPassthroughDisabled)`가 반복적으로 표시되면 dependency report와 logs를 수집하세요. 번들된 `@discordjs/voice` line에는 discord.js issue #11419를 닫은 discord.js PR #11449의 upstream padding fix가 포함되어 있습니다. +- `voice.tts`는 음성 재생에만 `messages.tts`를 재정의합니다. +- `voice.model`은 Discord 음성 채널 응답에 사용하는 LLM만 재정의합니다. 라우팅된 에이전트 모델을 상속하려면 설정하지 않은 상태로 두세요. +- STT는 `tools.media.audio`를 사용합니다. `voice.model`은 전사에 영향을 주지 않습니다. +- 채널별 Discord `systemPrompt` 재정의는 해당 음성 채널의 음성 전사 턴에 적용됩니다. +- 음성 전사 턴은 Discord `allowFrom`(또는 `dm.allowFrom`)에서 소유자 상태를 파생합니다. 소유자가 아닌 발화자는 소유자 전용 도구(예: `gateway` 및 `cron`)에 접근할 수 없습니다. +- Discord 음성은 텍스트 전용 구성에서 옵트인입니다. `/vc` 명령, 음성 런타임, `GuildVoiceStates` gateway intent를 활성화하려면 `channels.discord.voice.enabled=true`를 설정하세요(또는 기존 `channels.discord.voice` 블록 유지). +- `channels.discord.intents.voiceStates`는 음성 상태 intent 구독을 명시적으로 재정의할 수 있습니다. intent가 유효한 음성 활성화 상태를 따르도록 하려면 설정하지 않은 상태로 두세요. +- `voice.daveEncryption` 및 `voice.decryptionFailureTolerance`는 `@discordjs/voice` 참여 옵션으로 전달됩니다. +- 설정하지 않으면 `@discordjs/voice` 기본값은 `daveEncryption=true` 및 `decryptionFailureTolerance=24`입니다. +- `voice.connectTimeoutMs`는 `/vc join` 및 자동 참여 시도의 초기 `@discordjs/voice` Ready 대기를 제어합니다. 기본값: `30000`. +- `voice.reconnectGraceMs`는 연결이 끊긴 음성 세션이 다시 연결을 시작하기 전 OpenClaw가 세션을 종료하기까지 기다리는 시간을 제어합니다. 기본값: `15000`. +- OpenClaw는 수신 복호화 실패도 감시하며, 짧은 시간 안에 반복적으로 실패하면 음성 채널에서 나갔다가 다시 참여하여 자동 복구합니다. +- 업데이트 후 수신 로그에 `DecryptionFailed(UnencryptedWhenPassthroughDisabled)`가 반복적으로 표시되면 의존성 보고서와 로그를 수집하세요. 번들된 `@discordjs/voice` 라인에는 discord.js 이슈 #11419를 종료한 discord.js PR #11449의 업스트림 패딩 수정이 포함되어 있습니다. -Voice channel pipeline: +음성 채널 파이프라인: -- Discord PCM capture가 WAV temp file로 변환됩니다. +- Discord PCM 캡처가 WAV 임시 파일로 변환됩니다. - `tools.media.audio`가 STT를 처리합니다. 예: `openai/gpt-4o-mini-transcribe`. -- transcript는 Discord ingress 및 routing을 통해 전송되고, 응답 LLM은 agent `tts` tool을 숨기고 반환 텍스트를 요청하는 voice-output policy로 실행됩니다. 최종 TTS playback은 Discord voice가 소유하기 때문입니다. -- `voice.model`이 설정되면 이 voice-channel turn의 response LLM만 재정의합니다. -- `voice.tts`는 `messages.tts` 위에 병합되며, 결과 audio가 joined channel에서 재생됩니다. +- 전사는 Discord 인그레스와 라우팅을 통해 전송되며, 응답 LLM은 Discord 음성이 최종 TTS 재생을 소유하므로 에이전트 `tts` 도구를 숨기고 반환 텍스트를 요청하는 음성 출력 정책으로 실행됩니다. +- `voice.model`이 설정되면 이 음성 채널 턴의 응답 LLM만 재정의합니다. +- `voice.tts`는 `messages.tts` 위에 병합되며, 결과 오디오는 참여 중인 채널에서 재생됩니다. -Credentials는 component별로 확인됩니다. `voice.model`의 LLM route auth, `tools.media.audio`의 STT auth, `messages.tts`/`voice.tts`의 TTS auth입니다. +자격 증명은 컴포넌트별로 해석됩니다: `voice.model`의 LLM 경로 인증, `tools.media.audio`의 STT 인증, `messages.tts`/`voice.tts`의 TTS 인증. ### 음성 메시지 -Discord voice messages는 waveform preview를 표시하며 OGG/Opus audio가 필요합니다. OpenClaw는 waveform을 자동으로 생성하지만, inspect 및 convert를 위해 gateway host에 `ffmpeg`와 `ffprobe`가 필요합니다. +Discord 음성 메시지는 파형 미리보기를 표시하며 OGG/Opus 오디오가 필요합니다. OpenClaw는 파형을 자동으로 생성하지만, 검사와 변환을 위해 Gateway 호스트에 `ffmpeg` 및 `ffprobe`가 필요합니다. -- **local file path**를 제공하세요(URL은 거부됨). -- text content를 생략하세요(Discord는 같은 payload에서 text + voice message를 거부함). -- 모든 audio format이 허용됩니다. OpenClaw는 필요에 따라 OGG/Opus로 변환합니다. +- **로컬 파일 경로**를 제공하세요(URL은 거부됨). +- 텍스트 콘텐츠를 생략하세요(Discord는 동일 페이로드의 텍스트 + 음성 메시지를 거부함). +- 모든 오디오 형식이 허용됩니다. OpenClaw는 필요에 따라 OGG/Opus로 변환합니다. ```bash message(action="send", channel="discord", target="channel:123", path="/path/to/audio.mp3", asVoice=true) @@ -1226,20 +1227,20 @@ message(action="send", channel="discord", target="channel:123", path="/path/to/a ## 문제 해결 - + - - Message Content Intent를 활성화합니다 - - user/member resolution에 의존하는 경우 Server Members Intent를 활성화합니다 - - intents를 변경한 후 gateway를 재시작합니다 + - Message Content Intent 활성화 + - 사용자/멤버 해석에 의존할 때 Server Members Intent 활성화 + - intent를 변경한 후 gateway 다시 시작 - + - - `groupPolicy`를 확인합니다 - - `channels.discord.guilds` 아래의 guild allowlist를 확인합니다 - - guild `channels` map이 있으면 나열된 channels만 허용됩니다 - - `requireMention` 동작과 mention patterns를 확인합니다 + - `groupPolicy` 확인 + - `channels.discord.guilds` 아래의 guild 허용 목록 확인 + - guild `channels` 맵이 있으면 나열된 채널만 허용됨 + - `requireMention` 동작과 멘션 패턴 확인 유용한 확인: @@ -1251,29 +1252,29 @@ openclaw logs --follow - + 일반적인 원인: - - 일치하는 guild/channel allowlist 없이 `groupPolicy="allowlist"`가 설정됨 - - `requireMention`이 잘못된 위치에 구성됨(`channels.discord.guilds` 또는 channel entry 아래에 있어야 함) - - sender가 guild/channel `users` allowlist에 의해 차단됨 + - 일치하는 guild/channel 허용 목록 없이 `groupPolicy="allowlist"` 사용 + - `requireMention`이 잘못된 위치에 구성됨(`channels.discord.guilds` 또는 채널 항목 아래에 있어야 함) + - 발신자가 guild/channel `users` 허용 목록에 의해 차단됨 - + - 일반적인 logs: + 일반적인 로그: - `Slow listener detected ...` - `stuck session: sessionKey=agent:...:discord:... state=processing ...` - Discord gateway queue knobs: + Discord gateway 큐 조정값: - - single-account: `channels.discord.eventQueue.listenerTimeout` - - multi-account: `channels.discord.accounts..eventQueue.listenerTimeout` - - 이는 Discord gateway listener work만 제어하며 agent turn lifetime은 제어하지 않습니다 + - 단일 계정: `channels.discord.eventQueue.listenerTimeout` + - 다중 계정: `channels.discord.accounts..eventQueue.listenerTimeout` + - 이는 에이전트 턴 수명이 아니라 Discord gateway 리스너 작업만 제어합니다. - Discord는 queued agent turns에 channel-owned timeout을 적용하지 않습니다. Message listeners는 즉시 hand off하며, queued Discord runs는 session/tool/runtime lifecycle이 완료되거나 작업을 abort할 때까지 per-session ordering을 보존합니다. + Discord는 큐에 들어간 에이전트 턴에 채널 소유 timeout을 적용하지 않습니다. 메시지 리스너는 즉시 넘겨주며, 큐에 들어간 Discord 실행은 세션/도구/런타임 수명 주기가 완료되거나 작업이 중단될 때까지 세션별 순서를 유지합니다. ```json5 { @@ -1294,44 +1295,44 @@ openclaw logs --follow - OpenClaw는 연결하기 전에 Discord `/gateway/bot` 메타데이터를 가져옵니다. 일시적인 실패는 Discord의 기본 Gateway URL로 대체되며 로그에서 속도 제한됩니다. + OpenClaw는 연결하기 전에 Discord `/gateway/bot` 메타데이터를 가져옵니다. 일시적인 실패 시 Discord의 기본 Gateway URL로 대체되며 로그에서 속도 제한됩니다. - 메타데이터 시간 초과 조정값: + 메타데이터 시간 초과 조정 항목: - 단일 계정: `channels.discord.gatewayInfoTimeoutMs` - 다중 계정: `channels.discord.accounts..gatewayInfoTimeoutMs` - - 설정이 지정되지 않은 경우 env 대체값: `OPENCLAW_DISCORD_GATEWAY_INFO_TIMEOUT_MS` + - 구성이 설정되지 않았을 때 환경 변수 fallback: `OPENCLAW_DISCORD_GATEWAY_INFO_TIMEOUT_MS` - 기본값: `30000`(30초), 최대: `120000` - OpenClaw는 시작 중과 런타임 재연결 후 Discord의 Gateway `READY` 이벤트를 기다립니다. 시작 시차가 있는 다중 계정 설정은 기본값보다 더 긴 시작 READY 창이 필요할 수 있습니다. + OpenClaw는 시작 중과 런타임 재연결 후 Discord의 Gateway `READY` 이벤트를 기다립니다. 시작 시차를 둔 다중 계정 설정에서는 기본값보다 더 긴 시작 READY 기간이 필요할 수 있습니다. - READY 시간 초과 조정값: + READY 시간 초과 조정 항목: - 시작 단일 계정: `channels.discord.gatewayReadyTimeoutMs` - 시작 다중 계정: `channels.discord.accounts..gatewayReadyTimeoutMs` - - 설정이 지정되지 않은 경우 시작 env 대체값: `OPENCLAW_DISCORD_READY_TIMEOUT_MS` + - 구성이 설정되지 않았을 때 시작 환경 변수 fallback: `OPENCLAW_DISCORD_READY_TIMEOUT_MS` - 시작 기본값: `15000`(15초), 최대: `120000` - 런타임 단일 계정: `channels.discord.gatewayRuntimeReadyTimeoutMs` - 런타임 다중 계정: `channels.discord.accounts..gatewayRuntimeReadyTimeoutMs` - - 설정이 지정되지 않은 경우 런타임 env 대체값: `OPENCLAW_DISCORD_RUNTIME_READY_TIMEOUT_MS` + - 구성이 설정되지 않았을 때 런타임 환경 변수 fallback: `OPENCLAW_DISCORD_RUNTIME_READY_TIMEOUT_MS` - 런타임 기본값: `30000`(30초), 최대: `120000` - `channels status --probe` 권한 검사는 숫자 채널 ID에 대해서만 작동합니다. + `channels status --probe` 권한 검사는 숫자 채널 ID에서만 작동합니다. - 슬러그 키를 사용하는 경우에도 런타임 매칭은 계속 작동할 수 있지만, 프로브가 권한을 완전히 검증할 수는 없습니다. + slug 키를 사용하는 경우 런타임 매칭은 계속 작동할 수 있지만, probe가 권한을 완전히 검증할 수는 없습니다. - - DM 비활성화: `channels.discord.dm.enabled=false` - - DM 정책 비활성화: `channels.discord.dmPolicy="disabled"`(레거시: `channels.discord.dm.policy`) + - DM 비활성화됨: `channels.discord.dm.enabled=false` + - DM 정책 비활성화됨: `channels.discord.dmPolicy="disabled"`(레거시: `channels.discord.dm.policy`) - `pairing` 모드에서 페어링 승인 대기 중 @@ -1339,7 +1340,7 @@ openclaw logs --follow 기본적으로 봇이 작성한 메시지는 무시됩니다. - `channels.discord.allowBots=true`를 설정한 경우 루프 동작을 피하려면 엄격한 멘션 및 허용 목록 규칙을 사용하세요. + `channels.discord.allowBots=true`를 설정하는 경우 루프 동작을 피하기 위해 엄격한 멘션 및 허용 목록 규칙을 사용하세요. 봇을 멘션하는 봇 메시지만 허용하려면 `channels.discord.allowBots="mentions"`를 선호하세요. ```json5 @@ -1367,7 +1368,7 @@ openclaw logs --follow - + - Discord 음성 수신 복구 로직이 포함되도록 OpenClaw를 최신 상태로 유지하세요(`openclaw update`) - `channels.discord.voice.daveEncryption=true`(기본값)인지 확인하세요 @@ -1375,23 +1376,23 @@ openclaw logs --follow - 다음 로그를 확인하세요: - `discord voice: DAVE decrypt failures detected` - `discord voice: repeated decrypt failures; attempting rejoin` - - 자동 재참여 후에도 실패가 계속되면 로그를 수집하고 [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419) 및 [discord.js #11449](https://github.com/discordjs/discord.js/pull/11449)의 업스트림 DAVE 수신 이력과 비교하세요 + - 자동 재참여 후에도 실패가 계속되면 로그를 수집하고 [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419) 및 [discord.js #11449](https://github.com/discordjs/discord.js/pull/11449)의 업스트림 DAVE 수신 기록과 비교하세요 -## 설정 참조 +## 구성 참조 -기본 참조: [설정 참조 - Discord](/ko/gateway/config-channels#discord). +기본 참조: [구성 참조 - Discord](/ko/gateway/config-channels#discord). - + - 시작/인증: `enabled`, `token`, `accounts.*`, `allowBots` - 정책: `groupPolicy`, `dm.*`, `guilds.*`, `guilds.*.channels.*` - 명령: `commands.native`, `commands.useAccessGroups`, `configWrites`, `slashCommand.*` -- 이벤트 큐: `eventQueue.listenerTimeout`(리스너 예산), `eventQueue.maxQueueSize`, `eventQueue.maxConcurrency` +- 이벤트 큐: `eventQueue.listenerTimeout`(listener 예산), `eventQueue.maxQueueSize`, `eventQueue.maxConcurrency` - Gateway: `gatewayInfoTimeoutMs`, `gatewayReadyTimeoutMs`, `gatewayRuntimeReadyTimeoutMs` -- 응답/기록: `replyToMode`, `historyLimit`, `dmHistoryLimit`, `dms.*.historyLimit` +- 답장/기록: `replyToMode`, `historyLimit`, `dmHistoryLimit`, `dms.*.historyLimit` - 전달: `textChunkLimit`, `chunkMode`, `maxLinesPerMessage` - 스트리밍: `streaming`(레거시 별칭: `streamMode`), `streaming.preview.toolProgress`, `draftChunk`, `blockStreaming`, `blockStreamingCoalesce` - 미디어/재시도: `mediaMaxMb`(발신 Discord 업로드 제한, 기본값 `100MB`), `retry` @@ -1404,7 +1405,7 @@ openclaw logs --follow ## 안전 및 운영 -- 봇 토큰은 비밀로 취급하세요(감독 환경에서는 `DISCORD_BOT_TOKEN` 권장). +- 봇 토큰은 비밀로 취급하세요(관리형 환경에서는 `DISCORD_BOT_TOKEN` 권장). - 최소 권한 Discord 권한을 부여하세요. - 명령 배포/상태가 오래된 경우 Gateway를 재시작하고 `openclaw channels status --probe`로 다시 확인하세요. @@ -1415,18 +1416,18 @@ openclaw logs --follow Discord 사용자를 Gateway에 페어링합니다. - 그룹 채팅 및 허용 목록 동작입니다. + 그룹 채팅 및 허용 목록 동작. - 인바운드 메시지를 에이전트로 라우팅합니다. + 들어오는 메시지를 에이전트로 라우팅합니다. - 위협 모델 및 강화입니다. + 위협 모델 및 강화. 길드와 채널을 에이전트에 매핑합니다. - - 네이티브 명령 동작입니다. + + 네이티브 명령 동작. diff --git a/docs/ko/channels/msteams.md b/docs/ko/channels/msteams.md index bc6299c1b..7ab1a9a81 100644 --- a/docs/ko/channels/msteams.md +++ b/docs/ko/channels/msteams.md @@ -4,27 +4,27 @@ read_when: summary: Microsoft Teams 봇 지원 상태, 기능 및 구성 title: Microsoft Teams x-i18n: - generated_at: "2026-05-06T06:17:45Z" + generated_at: "2026-05-06T17:52:17Z" model: gpt-5.5 provider: openai - source_hash: 48e6cba4c5204726015758503e596fc02938d9de788c363190c3e6988e75ce8a + source_hash: be669545bd692754fbee8b670b1b482c39399a3d26e06a7ae01230fdaee645fe source_path: channels/msteams.md workflow: 16 --- -상태: 텍스트 + DM 첨부 파일이 지원됩니다. 채널/그룹 파일 전송에는 `sharePointSiteId` + Graph 권한이 필요합니다([그룹 채팅에서 파일 보내기](#sending-files-in-group-chats) 참조). 설문은 Adaptive Cards를 통해 전송됩니다. 메시지 작업은 파일 우선 전송을 위한 명시적 `upload-file`을 제공합니다. +상태: 텍스트 + DM 첨부 파일이 지원됩니다. 채널/그룹 파일 전송에는 `sharePointSiteId` + Graph 권한이 필요합니다([그룹 채팅에서 파일 보내기](#sending-files-in-group-chats) 참조). 투표는 Adaptive Cards를 통해 전송됩니다. 메시지 액션은 파일 우선 전송을 위한 명시적 `upload-file`을 노출합니다. ## 번들 Plugin -Microsoft Teams는 현재 OpenClaw 릴리스에 번들 Plugin으로 포함되어 있으므로, 일반 패키지 빌드에서는 별도 설치가 필요하지 않습니다. +Microsoft Teams는 현재 OpenClaw 릴리스에서 번들 Plugin으로 제공되므로 일반 패키지 빌드에서는 별도 설치가 필요하지 않습니다. -이전 빌드이거나 번들 Teams가 제외된 사용자 지정 설치를 사용하는 경우, npm 패키지를 직접 설치하세요. +이전 빌드나 번들 Teams를 제외한 사용자 지정 설치를 사용 중이라면 npm 패키지를 직접 설치하세요. ```bash openclaw plugins install @openclaw/msteams ``` -현재 공식 릴리스 태그를 따라가려면 기본 패키지를 사용하세요. 재현 가능한 설치가 필요할 때만 정확한 버전을 고정하세요. +현재 공식 릴리스 태그를 따르려면 순수 패키지를 사용하세요. 재현 가능한 설치가 필요할 때만 정확한 버전을 고정하세요. 로컬 체크아웃(git 저장소에서 실행하는 경우): @@ -32,13 +32,13 @@ openclaw plugins install @openclaw/msteams openclaw plugins install ./path/to/local/msteams-plugin ``` -자세한 내용: [Plugins](/ko/tools/plugin) +자세히: [Plugins](/ko/tools/plugin) ## 빠른 설정 [`@microsoft/teams.cli`](https://www.npmjs.com/package/@microsoft/teams.cli)는 단일 명령으로 봇 등록, 매니페스트 생성, 자격 증명 생성을 처리합니다. -**1. 설치하고 로그인** +**1. 설치하고 로그인하기** ```bash npm install -g @microsoft/teams.cli@preview @@ -47,10 +47,10 @@ teams status # verify you're logged in and see your tenant info ``` -Teams CLI는 현재 프리뷰 상태입니다. 명령과 플래그는 릴리스마다 변경될 수 있습니다. +Teams CLI는 현재 프리뷰 상태입니다. 명령과 플래그는 릴리스 간에 변경될 수 있습니다. -**2. 터널 시작**(Teams는 localhost에 접근할 수 없음) +**2. 터널 시작하기**(Teams는 localhost에 접근할 수 없음) 아직 설치하지 않았다면 devtunnel CLI를 설치하고 인증하세요([시작 가이드](https://learn.microsoft.com/en-us/azure/developer/dev-tunnels/get-started)). @@ -65,12 +65,12 @@ devtunnel host my-openclaw-bot ``` -Teams는 devtunnels로 인증할 수 없으므로 `--allow-anonymous`가 필요합니다. 각 수신 봇 요청은 여전히 Teams SDK에 의해 자동으로 검증됩니다. +Teams는 devtunnels로 인증할 수 없으므로 `--allow-anonymous`가 필요합니다. 들어오는 각 봇 요청은 여전히 Teams SDK가 자동으로 검증합니다. -대안: `ngrok http 3978` 또는 `tailscale funnel 3978`(단, 세션마다 URL이 바뀔 수 있음). +대안: `ngrok http 3978` 또는 `tailscale funnel 3978`(하지만 세션마다 URL이 바뀔 수 있음). -**3. 앱 생성** +**3. 앱 생성하기** ```bash teams app create \ @@ -81,13 +81,13 @@ teams app create \ 이 단일 명령은 다음을 수행합니다. - Entra ID(Azure AD) 애플리케이션 생성 -- 클라이언트 암호 생성 -- Teams 앱 매니페스트 빌드 및 업로드(아이콘 포함) -- 봇 등록(기본적으로 Teams 관리 - Azure 구독 필요 없음) +- 클라이언트 시크릿 생성 +- Teams 앱 매니페스트(아이콘 포함) 빌드 및 업로드 +- 봇 등록(기본적으로 Teams 관리 - Azure 구독 불필요) -출력에는 `CLIENT_ID`, `CLIENT_SECRET`, `TENANT_ID`, 그리고 **Teams App ID**가 표시됩니다. 다음 단계에서 사용할 수 있도록 기록해 두세요. Teams에 앱을 직접 설치할 수도 있습니다. +출력에는 `CLIENT_ID`, `CLIENT_SECRET`, `TENANT_ID`, **Teams App ID**가 표시됩니다. 다음 단계에서 필요하므로 기록해 두세요. 또한 앱을 Teams에 직접 설치하는 옵션도 제공합니다. -**4. 출력의 자격 증명으로 OpenClaw 구성:** +**4. OpenClaw 구성하기** 출력의 자격 증명을 사용합니다. ```json5 { @@ -105,23 +105,23 @@ teams app create \ 또는 환경 변수를 직접 사용하세요: `MSTEAMS_APP_ID`, `MSTEAMS_APP_PASSWORD`, `MSTEAMS_TENANT_ID`. -**5. Teams에 앱 설치** +**5. Teams에 앱 설치하기** -`teams app create`는 앱을 설치할지 묻습니다. "Install in Teams"를 선택하세요. 건너뛰었다면 나중에 링크를 가져올 수 있습니다. +`teams app create`는 앱 설치를 묻는 메시지를 표시합니다. "Install in Teams"를 선택하세요. 건너뛰었다면 나중에 링크를 가져올 수 있습니다. ```bash teams app get --install-link ``` -**6. 모든 것이 작동하는지 확인** +**6. 모든 것이 작동하는지 확인하기** ```bash teams app doctor ``` -이 명령은 봇 등록, AAD 앱 구성, 매니페스트 유효성, SSO 설정 전반에 대해 진단을 실행합니다. +이 명령은 봇 등록, AAD 앱 구성, 매니페스트 유효성, SSO 설정 전반의 진단을 실행합니다. -프로덕션 배포에서는 클라이언트 암호 대신 [페더레이션 인증](/ko/channels/msteams#federated-authentication-certificate-plus-managed-identity)(인증서 또는 관리 ID)을 사용하는 것을 고려하세요. +프로덕션 배포에서는 클라이언트 시크릿 대신 [페더레이션 인증](/ko/channels/msteams#federated-authentication-certificate-plus-managed-identity)(인증서 또는 관리 ID)을 사용하는 것을 고려하세요. 그룹 채팅은 기본적으로 차단됩니다(`channels.msteams.groupPolicy: "allowlist"`). 그룹 답장을 허용하려면 `channels.msteams.groupAllowFrom`을 설정하거나, 모든 구성원(멘션 게이트 적용)을 허용하려면 `groupPolicy: "open"`을 사용하세요. @@ -130,14 +130,14 @@ teams app doctor ## 목표 - Teams DM, 그룹 채팅 또는 채널을 통해 OpenClaw와 대화합니다. -- 라우팅을 결정적으로 유지합니다. 답장은 항상 들어온 채널로 돌아갑니다. -- 안전한 채널 동작을 기본값으로 사용합니다(달리 구성하지 않는 한 멘션 필요). +- 라우팅을 결정적으로 유지합니다. 답장은 항상 도착한 채널로 돌아갑니다. +- 안전한 채널 동작을 기본값으로 사용합니다(별도로 구성하지 않는 한 멘션 필요). ## 구성 쓰기 -기본적으로 Microsoft Teams는 `/config set|unset`에 의해 트리거되는 구성 업데이트를 쓸 수 있습니다(`commands.config: true` 필요). +기본적으로 Microsoft Teams는 `/config set|unset`으로 트리거된 구성 업데이트를 쓸 수 있습니다(`commands.config: true` 필요). -비활성화: +비활성화하려면: ```json5 { @@ -150,14 +150,14 @@ teams app doctor **DM 접근** - 기본값: `channels.msteams.dmPolicy = "pairing"`. 알 수 없는 발신자는 승인될 때까지 무시됩니다. -- `channels.msteams.allowFrom`에는 안정적인 AAD 객체 ID를 사용해야 합니다. -- 허용 목록에는 UPN/표시 이름 매칭에 의존하지 마세요. 변경될 수 있습니다. OpenClaw는 기본적으로 직접 이름 매칭을 비활성화합니다. 명시적으로 사용하려면 `channels.msteams.dangerouslyAllowNameMatching: true`를 설정하세요. -- 마법사는 자격 증명이 허용하는 경우 Microsoft Graph를 통해 이름을 ID로 확인할 수 있습니다. +- `channels.msteams.allowFrom`에는 안정적인 AAD 개체 ID를 사용해야 합니다. +- allowlist에 UPN/표시 이름 매칭을 의존하지 마세요. 변경될 수 있습니다. OpenClaw는 기본적으로 직접 이름 매칭을 비활성화합니다. 명시적으로 사용하려면 `channels.msteams.dangerouslyAllowNameMatching: true`를 설정하세요. +- 자격 증명이 허용하는 경우 마법사가 Microsoft Graph를 통해 이름을 ID로 해석할 수 있습니다. **그룹 접근** - 기본값: `channels.msteams.groupPolicy = "allowlist"`(`groupAllowFrom`을 추가하지 않으면 차단됨). 설정되지 않았을 때 기본값을 재정의하려면 `channels.defaults.groupPolicy`를 사용하세요. -- `channels.msteams.groupAllowFrom`은 그룹 채팅/채널에서 어떤 발신자가 트리거할 수 있는지 제어합니다(`channels.msteams.allowFrom`으로 폴백). +- `channels.msteams.groupAllowFrom`은 그룹 채팅/채널에서 어떤 발신자가 트리거할 수 있는지 제어합니다(`channels.msteams.allowFrom`으로 대체됨). - 모든 구성원(기본적으로 여전히 멘션 게이트 적용)을 허용하려면 `groupPolicy: "open"`을 설정하세요. - **채널을 전혀 허용하지 않으려면** `channels.msteams.groupPolicy: "disabled"`를 설정하세요. @@ -174,14 +174,14 @@ teams app doctor } ``` -**Teams + 채널 허용 목록** +**Teams + 채널 allowlist** -- `channels.msteams.teams` 아래에 팀과 채널을 나열하여 그룹/채널 답장 범위를 지정합니다. -- 키는 변경 가능한 표시 이름이 아니라 Teams 링크의 안정적인 Teams 대화 ID를 사용해야 합니다. -- `groupPolicy="allowlist"`이고 teams 허용 목록이 있으면, 나열된 팀/채널만 허용됩니다(멘션 게이트 적용). -- 구성 마법사는 `Team/Channel` 항목을 받아 저장해 줍니다. -- 시작 시 OpenClaw는 Graph 권한이 허용하는 경우 팀/채널 및 사용자 허용 목록 이름을 ID로 확인하고 - 매핑을 로그에 기록합니다. 확인되지 않은 팀/채널 이름은 입력한 그대로 유지되지만, 기본적으로 라우팅에서는 무시됩니다. 단, `channels.msteams.dangerouslyAllowNameMatching: true`가 활성화된 경우는 예외입니다. +- `channels.msteams.teams` 아래에 팀과 채널을 나열해 그룹/채널 답장의 범위를 지정하세요. +- 키에는 변경 가능한 표시 이름이 아니라 Teams 링크의 안정적인 Teams 대화 ID를 사용해야 합니다. +- `groupPolicy="allowlist"`이고 teams allowlist가 있으면 나열된 팀/채널만 허용됩니다(멘션 게이트 적용). +- 구성 마법사는 `Team/Channel` 항목을 받아 저장합니다. +- 시작 시 OpenClaw는 팀/채널 및 사용자 allowlist 이름을 ID로 해석하고(Graph 권한이 허용하는 경우) + 매핑을 로그에 기록합니다. 해석되지 않은 팀/채널 이름은 입력한 그대로 유지되지만, `channels.msteams.dangerouslyAllowNameMatching: true`가 활성화되어 있지 않으면 기본적으로 라우팅에서 무시됩니다. 예: @@ -205,66 +205,66 @@ teams app doctor
수동 설정(Teams CLI 없이) -Teams CLI를 사용할 수 없는 경우 Azure Portal을 통해 봇을 수동으로 설정할 수 있습니다. +Teams CLI를 사용할 수 없다면 Azure Portal을 통해 봇을 수동으로 설정할 수 있습니다. ### 작동 방식 -1. Microsoft Teams Plugin이 사용 가능한지 확인합니다(현재 릴리스에 번들 포함). -2. **Azure Bot**을 생성합니다(App ID + 암호 + 테넌트 ID). +1. Microsoft Teams Plugin을 사용할 수 있는지 확인합니다(현재 릴리스에 번들됨). +2. **Azure Bot**(App ID + secret + tenant ID)을 생성합니다. 3. 봇을 참조하고 아래 RSC 권한을 포함하는 **Teams 앱 패키지**를 빌드합니다. -4. Teams 앱을 팀에 업로드/설치합니다(DM의 경우 개인 범위). +4. Teams 앱을 팀(또는 DM용 개인 범위)에 업로드/설치합니다. 5. `~/.openclaw/openclaw.json`(또는 env vars)에서 `msteams`를 구성하고 Gateway를 시작합니다. 6. Gateway는 기본적으로 `/api/messages`에서 Bot Framework Webhook 트래픽을 수신합니다. ### 1단계: Azure Bot 생성 -1. [Azure Bot 만들기](https://portal.azure.com/#create/Microsoft.AzureBot)로 이동합니다. -2. **Basics** 탭을 채웁니다. +1. [Create Azure Bot](https://portal.azure.com/#create/Microsoft.AzureBot)으로 이동합니다. +2. **Basics** 탭을 입력합니다. - | 필드 | 값 | + | 필드 | 값 | | ------------------ | -------------------------------------------------------- | - | **Bot handle** | 봇 이름, 예: `openclaw-msteams`(고유해야 함) | - | **Subscription** | Azure 구독 선택 | - | **Resource group** | 새로 만들거나 기존 항목 사용 | - | **Pricing tier** | 개발/테스트용 **Free** | - | **Type of App** | **Single Tenant**(권장 - 아래 참고 참조) | - | **Creation type** | **Create new Microsoft App ID** | + | **Bot handle** | 봇 이름, 예: `openclaw-msteams`(고유해야 함) | + | **Subscription** | Azure 구독 선택 | + | **Resource group** | 새로 만들거나 기존 항목 사용 | + | **Pricing tier** | 개발/테스트에는 **Free** | + | **Type of App** | **Single Tenant**(권장 - 아래 참고 참조) | + | **Creation type** | **Create new Microsoft App ID** | 새 멀티 테넌트 봇 생성은 2025-07-31 이후 사용 중단되었습니다. 새 봇에는 **Single Tenant**를 사용하세요. -3. **Review + create** → **Create**를 클릭합니다(~1-2분 대기). +3. **Review + create** → **Create**를 클릭합니다(약 1~2분 대기). ### 2단계: 자격 증명 가져오기 1. Azure Bot 리소스 → **Configuration**으로 이동합니다. -2. **Microsoft App ID** 복사 → 이것이 `appId`입니다. -3. **Manage Password** 클릭 → App Registration으로 이동합니다. -4. **Certificates & secrets** → **New client secret** 아래에서 **Value** 복사 → 이것이 `appPassword`입니다. -5. **Overview**로 이동 → **Directory (tenant) ID** 복사 → 이것이 `tenantId`입니다. +2. **Microsoft App ID**를 복사합니다. 이것이 `appId`입니다. +3. **Manage Password**를 클릭하고 App Registration으로 이동합니다. +4. **Certificates & secrets** → **New client secret**에서 **Value**를 복사합니다. 이것이 `appPassword`입니다. +5. **Overview**로 이동해 **Directory (tenant) ID**를 복사합니다. 이것이 `tenantId`입니다. -### 3단계: Messaging Endpoint 구성 +### 3단계: 메시징 엔드포인트 구성 1. Azure Bot → **Configuration**에서 2. **Messaging endpoint**를 Webhook URL로 설정합니다. - 프로덕션: `https://your-domain.com/api/messages` - 로컬 개발: 터널 사용(아래 [로컬 개발](#local-development-tunneling) 참조) -### 4단계: Teams Channel 활성화 +### 4단계: Teams 채널 활성화 -1. Azure Bot → **Channels**에서 +1. Azure Bot → **Channels**로 이동합니다. 2. **Microsoft Teams** → Configure → Save를 클릭합니다. 3. 서비스 약관에 동의합니다. ### 5단계: Teams 앱 매니페스트 빌드 -- `botId = `인 `bot` 항목을 포함합니다. +- `botId = `가 포함된 `bot` 항목을 포함합니다. - 범위: `personal`, `team`, `groupChat`. -- `supportsFiles: true`(개인 범위 파일 처리에 필요). +- `supportsFiles: true`(개인 범위 파일 처리를 위해 필요). - RSC 권한을 추가합니다([RSC 권한](#current-teams-rsc-permissions-manifest) 참조). - 아이콘 생성: `outline.png`(32x32) 및 `color.png`(192x192). -- 세 파일 `manifest.json`, `outline.png`, `color.png`를 함께 zip으로 압축합니다. +- 세 파일을 함께 압축합니다: `manifest.json`, `outline.png`, `color.png`. ### 6단계: OpenClaw 구성 @@ -286,7 +286,7 @@ Teams CLI를 사용할 수 없는 경우 Azure Portal을 통해 봇을 수동으 ### 7단계: Gateway 실행 -Teams 채널은 Plugin이 사용 가능하고 자격 증명이 포함된 `msteams` 구성이 있으면 자동으로 시작됩니다. +Plugin을 사용할 수 있고 자격 증명이 포함된 `msteams` 구성이 있으면 Teams 채널이 자동으로 시작됩니다.
@@ -294,7 +294,7 @@ Teams 채널은 Plugin이 사용 가능하고 자격 증명이 포함된 `msteam > 2026.4.11에 추가됨 -프로덕션 배포의 경우 OpenClaw는 클라이언트 암호보다 더 안전한 대안으로 **페더레이션 인증**을 지원합니다. 두 가지 방법을 사용할 수 있습니다. +프로덕션 배포를 위해 OpenClaw는 클라이언트 시크릿보다 더 안전한 대안으로 **페더레이션 인증**을 지원합니다. 두 가지 방법을 사용할 수 있습니다. ### 옵션 A: 인증서 기반 인증 @@ -302,7 +302,7 @@ Entra ID 앱 등록에 등록된 PEM 인증서를 사용합니다. **설정:** -1. 인증서를 생성하거나 가져옵니다(개인 키가 포함된 PEM 형식). +1. 인증서를 생성하거나 확보합니다(개인 키가 포함된 PEM 형식). 2. Entra ID → App Registration → **Certificates & secrets** → **Certificates** → 공개 인증서를 업로드합니다. **구성:** @@ -329,18 +329,18 @@ Entra ID 앱 등록에 등록된 PEM 인증서를 사용합니다. ### 옵션 B: Azure Managed Identity -비밀번호 없는 인증에는 Azure Managed Identity를 사용합니다. 이는 관리 ID를 사용할 수 있는 Azure 인프라(AKS, App Service, Azure VMs)의 배포에 적합합니다. +비밀번호 없는 인증에는 Azure Managed Identity를 사용합니다. 이는 관리 ID를 사용할 수 있는 Azure 인프라(AKS, App Service, Azure VMs) 배포에 이상적입니다. **작동 방식:** -1. 봇 pod/VM에 관리 ID가 있습니다(시스템 할당 또는 사용자 할당). +1. 봇 pod/VM에 관리 ID(시스템 할당 또는 사용자 할당)가 있습니다. 2. **페더레이션 ID 자격 증명**이 관리 ID를 Entra ID 앱 등록에 연결합니다. -3. 런타임에 OpenClaw는 `@azure/identity`를 사용하여 Azure IMDS 엔드포인트(`169.254.169.254`)에서 토큰을 획득합니다. +3. 런타임에 OpenClaw는 `@azure/identity`를 사용해 Azure IMDS 엔드포인트(`169.254.169.254`)에서 토큰을 획득합니다. 4. 토큰은 봇 인증을 위해 Teams SDK에 전달됩니다. -**필수 조건:** +**사전 요구 사항:** -- 관리 ID가 활성화된 Azure 인프라(AKS workload identity, App Service, VM) +- 관리 ID가 활성화된 Azure 인프라(AKS 워크로드 ID, App Service, VM) - Entra ID 앱 등록에 생성된 페더레이션 ID 자격 증명 - pod/VM에서 IMDS(`169.254.169.254:80`)로의 네트워크 접근 @@ -383,13 +383,13 @@ Entra ID 앱 등록에 등록된 PEM 인증서를 사용합니다. - `MSTEAMS_AUTH_TYPE=federated` - `MSTEAMS_USE_MANAGED_IDENTITY=true` -- `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID=`(사용자 할당에만 해당) +- `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID=` (사용자 할당인 경우에만) -### AKS 워크로드 ID 설정 +### AKS Workload Identity 설정 -워크로드 ID를 사용하는 AKS 배포의 경우: +Workload Identity를 사용하는 AKS 배포의 경우: -1. AKS 클러스터에서 **워크로드 ID를 활성화**합니다. +1. AKS 클러스터에서 **Workload Identity를 활성화**합니다. 2. Entra ID 앱 등록에 **페더레이션 ID 자격 증명**을 만듭니다. ```bash @@ -412,7 +412,7 @@ Entra ID 앱 등록에 등록된 PEM 인증서를 사용합니다. azure.workload.identity/client-id: "" ``` -4. 워크로드 ID 주입을 위해 **pod에 레이블을 지정**합니다. +4. Workload Identity 삽입을 위해 **Pod에 레이블을 지정**합니다. ```yaml metadata: @@ -420,21 +420,21 @@ Entra ID 앱 등록에 등록된 PEM 인증서를 사용합니다. azure.workload.identity/use: "true" ``` -5. IMDS(`169.254.169.254`)에 대한 **네트워크 액세스를 보장**합니다. NetworkPolicy를 사용하는 경우 포트 80에서 `169.254.169.254/32`로 향하는 트래픽을 허용하는 이그레스 규칙을 추가합니다. +5. IMDS(`169.254.169.254`)에 대한 **네트워크 액세스를 보장**합니다. NetworkPolicy를 사용하는 경우 포트 80에서 `169.254.169.254/32`로 향하는 트래픽을 허용하는 egress 규칙을 추가하세요. ### 인증 유형 비교 -| 방법 | 구성 | 장점 | 단점 | -| -------------------- | ---------------------------------------------- | ----------------------------- | --------------------------------- | -| **클라이언트 시크릿** | `appPassword` | 설정이 간단함 | 시크릿 순환 필요, 보안성이 낮음 | -| **인증서** | `authType: "federated"` + `certificatePath` | 네트워크를 통한 공유 시크릿 없음 | 인증서 관리 부담 | -| **관리 ID** | `authType: "federated"` + `useManagedIdentity` | 비밀번호 없음, 관리할 시크릿 없음 | Azure 인프라 필요 | +| 방법 | 구성 | 장점 | 단점 | +| -------------------- | ---------------------------------------------- | --------------------------------- | ----------------------------------------- | +| **클라이언트 비밀** | `appPassword` | 설정이 간단함 | 비밀 순환이 필요하며 보안성이 낮음 | +| **인증서** | `authType: "federated"` + `certificatePath` | 네트워크를 통한 공유 비밀이 없음 | 인증서 관리 부담 | +| **관리 ID** | `authType: "federated"` + `useManagedIdentity` | 비밀번호가 없고 관리할 비밀 없음 | Azure 인프라가 필요함 | -**기본 동작:** `authType`이 설정되지 않으면 OpenClaw는 기본적으로 클라이언트 시크릿 인증을 사용합니다. 기존 구성은 변경 없이 계속 작동합니다. +**기본 동작:** `authType`이 설정되지 않은 경우 OpenClaw는 기본적으로 클라이언트 비밀 인증을 사용합니다. 기존 구성은 변경 없이 계속 작동합니다. ## 로컬 개발(터널링) -Teams는 `localhost`에 도달할 수 없습니다. 세션 간에도 URL이 동일하게 유지되도록 영구 개발 터널을 사용하세요. +Teams는 `localhost`에 접근할 수 없습니다. 세션이 바뀌어도 URL이 동일하게 유지되도록 영구 개발 터널을 사용하세요. ```bash # One-time setup: @@ -445,9 +445,9 @@ devtunnel port create my-openclaw-bot -p 3978 --protocol auto devtunnel host my-openclaw-bot ``` -대안: `ngrok http 3978` 또는 `tailscale funnel 3978`(URL은 세션마다 바뀔 수 있음). +대안: `ngrok http 3978` 또는 `tailscale funnel 3978`(URL은 세션마다 변경될 수 있음). -터널 URL이 변경되면 엔드포인트를 업데이트합니다. +터널 URL이 변경되면 엔드포인트를 업데이트하세요. ```bash teams app update --endpoint "https:///api/messages" @@ -461,64 +461,64 @@ teams app update --endpoint "https:///api/messages" teams app doctor ``` -한 번에 bot 등록, AAD 앱, 매니페스트, SSO 구성을 검사합니다. +Bot 등록, AAD 앱, 매니페스트, SSO 구성을 한 번에 확인합니다. **테스트 메시지 보내기:** 1. Teams 앱을 설치합니다(`teams app get --install-link`의 설치 링크 사용). -2. Teams에서 bot을 찾아 DM을 보냅니다. +2. Teams에서 Bot을 찾아 DM을 보냅니다. 3. 들어오는 활동이 있는지 Gateway 로그를 확인합니다. ## 환경 변수 -대신 모든 구성 키를 환경 변수로 설정할 수 있습니다. +모든 구성 키는 대신 환경 변수로 설정할 수 있습니다. - `MSTEAMS_APP_ID` - `MSTEAMS_APP_PASSWORD` - `MSTEAMS_TENANT_ID` - `MSTEAMS_AUTH_TYPE`(선택 사항: `"secret"` 또는 `"federated"`) -- `MSTEAMS_CERTIFICATE_PATH`(페더레이션 + 인증서) -- `MSTEAMS_CERTIFICATE_THUMBPRINT`(선택 사항, 인증에는 필요하지 않음) -- `MSTEAMS_USE_MANAGED_IDENTITY`(페더레이션 + 관리 ID) -- `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID`(사용자 할당 MI에만 해당) +- `MSTEAMS_CERTIFICATE_PATH`(federated + 인증서) +- `MSTEAMS_CERTIFICATE_THUMBPRINT`(선택 사항, 인증에 필요하지 않음) +- `MSTEAMS_USE_MANAGED_IDENTITY`(federated + 관리 ID) +- `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID`(사용자 할당 MI 전용) ## 멤버 정보 작업 -OpenClaw는 Microsoft Teams용 Graph 기반 `member-info` 작업을 노출하므로 에이전트와 자동화가 Microsoft Graph에서 직접 채널 멤버 세부 정보(표시 이름, 이메일, 역할)를 확인할 수 있습니다. +OpenClaw는 Microsoft Teams용 Graph 기반 `member-info` 작업을 노출하여 에이전트와 자동화가 Microsoft Graph에서 직접 채널 멤버 세부 정보(표시 이름, 이메일, 역할)를 확인할 수 있게 합니다. 요구 사항: - `Member.Read.Group` RSC 권한(권장 매니페스트에 이미 포함됨) -- 팀 간 조회: 관리자 동의가 있는 `User.Read.All` Graph 애플리케이션 권한 +- 팀 간 조회의 경우: 관리자 동의가 있는 `User.Read.All` Graph 애플리케이션 권한 이 작업은 `channels.msteams.actions.memberInfo`로 제어됩니다(기본값: Graph 자격 증명을 사용할 수 있을 때 활성화). ## 기록 컨텍스트 -- `channels.msteams.historyLimit`는 최근 채널/그룹 메시지 몇 개를 프롬프트에 포함할지 제어합니다. -- `messages.groupChat.historyLimit`로 대체됩니다. 비활성화하려면 `0`으로 설정합니다(기본값 50). -- 가져온 스레드 기록은 발신자 허용 목록(`allowFrom` / `groupAllowFrom`)으로 필터링되므로, 스레드 컨텍스트 시딩에는 허용된 발신자의 메시지만 포함됩니다. -- 인용된 첨부 파일 컨텍스트(Teams 답장 HTML에서 파생된 `ReplyTo*`)는 현재 수신된 그대로 전달됩니다. -- 즉, 허용 목록은 누가 에이전트를 트리거할 수 있는지를 제어하며, 현재는 특정 보조 컨텍스트 경로만 필터링됩니다. +- `channels.msteams.historyLimit`은 최근 채널/그룹 메시지를 몇 개까지 프롬프트에 포함할지 제어합니다. +- `messages.groupChat.historyLimit`으로 대체됩니다. 비활성화하려면 `0`으로 설정합니다(기본값 50). +- 가져온 스레드 기록은 보낸 사람 허용 목록(`allowFrom` / `groupAllowFrom`)으로 필터링되므로, 스레드 컨텍스트 시딩에는 허용된 보낸 사람의 메시지만 포함됩니다. +- 인용된 첨부 파일 컨텍스트(Teams 답글 HTML에서 파생된 `ReplyTo*`)는 현재 수신된 그대로 전달됩니다. +- 즉, 허용 목록은 에이전트를 트리거할 수 있는 사람을 제한하며, 현재는 특정 보조 컨텍스트 경로만 필터링됩니다. - DM 기록은 `channels.msteams.dmHistoryLimit`(사용자 턴)로 제한할 수 있습니다. 사용자별 재정의: `channels.msteams.dms[""].historyLimit`. ## 현재 Teams RSC 권한(매니페스트) -다음은 Teams 앱 매니페스트의 **기존 resourceSpecific 권한**입니다. 앱이 설치된 팀/채팅 내부에만 적용됩니다. +다음은 Teams 앱 매니페스트의 **기존 resourceSpecific 권한**입니다. 앱이 설치된 팀/채팅 내부에서만 적용됩니다. **채널(팀 범위):** -- `ChannelMessage.Read.Group`(애플리케이션) - @멘션 없이 모든 채널 메시지 수신 -- `ChannelMessage.Send.Group`(애플리케이션) -- `Member.Read.Group`(애플리케이션) -- `Owner.Read.Group`(애플리케이션) -- `ChannelSettings.Read.Group`(애플리케이션) -- `TeamMember.Read.Group`(애플리케이션) -- `TeamSettings.Read.Group`(애플리케이션) +- `ChannelMessage.Read.Group`(Application) - @mention 없이 모든 채널 메시지 수신 +- `ChannelMessage.Send.Group`(Application) +- `Member.Read.Group`(Application) +- `Owner.Read.Group`(Application) +- `ChannelSettings.Read.Group`(Application) +- `TeamMember.Read.Group`(Application) +- `TeamSettings.Read.Group`(Application) **그룹 채팅:** -- `ChatMessage.Read.Chat`(애플리케이션) - @멘션 없이 모든 그룹 채팅 메시지 수신 +- `ChatMessage.Read.Chat`(Application) - @mention 없이 모든 그룹 채팅 메시지 수신 Teams CLI를 통해 RSC 권한을 추가하려면: @@ -528,7 +528,7 @@ teams app rsc add ChannelMessage.Read.Group --type Application ## Teams 매니페스트 예시(수정됨) -필수 필드가 포함된 최소한의 유효한 예시입니다. ID와 URL을 교체하세요. +필수 필드가 포함된 최소한의 유효한 예시입니다. ID와 URL을 바꾸세요. ```json5 { @@ -596,7 +596,7 @@ teams app manifest upload manifest.json # Version is auto-bumped if content changed ``` -업데이트 후 새 권한이 적용되도록 각 팀에서 앱을 다시 설치하고, 캐시된 앱 메타데이터를 지우기 위해 Teams를 **완전히 종료한 뒤 다시 실행**합니다(창만 닫는 것이 아님). +업데이트 후 새 권한을 적용하려면 각 팀에 앱을 다시 설치하고, 캐시된 앱 메타데이터를 지우기 위해 Teams를 **완전히 종료한 뒤 다시 실행**하세요(창만 닫는 것이 아님).
수동 매니페스트 업데이트(CLI 없이) @@ -605,14 +605,14 @@ teams app manifest upload manifest.json 2. **`version` 필드를 증가**시킵니다(예: `1.0.0` → `1.1.0`). 3. 아이콘과 함께 매니페스트를 **다시 zip으로 압축**합니다(`manifest.json`, `outline.png`, `color.png`). 4. 새 zip을 업로드합니다. - - **Teams Admin Center:** Teams 앱 → 앱 관리 → 앱 찾기 → 새 버전 업로드 + - **Teams 관리 센터:** Teams 앱 → 앱 관리 → 앱 찾기 → 새 버전 업로드 - **사이드로드:** Teams에서 → 앱 → 앱 관리 → 사용자 지정 앱 업로드
-## 기능: RSC만 사용 vs Graph +## 기능: RSC 전용 vs Graph -### **Teams RSC만** 사용하는 경우(앱 설치됨, Graph API 권한 없음) +### **Teams RSC 전용** 사용 시(앱 설치됨, Graph API 권한 없음) 작동함: @@ -624,28 +624,28 @@ teams app manifest upload manifest.json - 채널/그룹 **이미지 또는 파일 콘텐츠**(페이로드에는 HTML 스텁만 포함됨). - SharePoint/OneDrive에 저장된 첨부 파일 다운로드. -- 메시지 기록 읽기(실시간 Webhook 이벤트를 넘어서는 기록). +- 메시지 기록 읽기(실시간 Webhook 이벤트 이후의 기록). -### **Teams RSC + Microsoft Graph 애플리케이션 권한**을 사용하는 경우 +### **Teams RSC + Microsoft Graph 애플리케이션 권한** 사용 시 추가됨: - 호스팅된 콘텐츠 다운로드(메시지에 붙여 넣은 이미지). - SharePoint/OneDrive에 저장된 파일 첨부 파일 다운로드. -- Graph를 통한 채널/채팅 메시지 기록 읽기. +- Graph를 통해 채널/채팅 메시지 기록 읽기. ### RSC vs Graph API -| 기능 | RSC 권한 | Graph API | -| ----------------------- | -------------------- | --------------------------------- | -| **실시간 메시지** | 예(Webhook을 통해) | 아니요(폴링만 가능) | -| **이전 메시지** | 아니요 | 예(기록 쿼리 가능) | -| **설정 복잡도** | 앱 매니페스트만 | 관리자 동의 + 토큰 흐름 필요 | -| **오프라인에서 작동** | 아니요(실행 중이어야 함) | 예(언제든지 쿼리 가능) | +| 기능 | RSC 권한 | Graph API | +| ----------------------- | -------------------- | ----------------------------------- | +| **실시간 메시지** | 예(Webhook을 통해) | 아니요(폴링만 가능) | +| **과거 메시지** | 아니요 | 예(기록 조회 가능) | +| **설정 복잡도** | 앱 매니페스트만 | 관리자 동의 + 토큰 흐름 필요 | +| **오프라인 작동** | 아니요(실행 중이어야 함) | 예(언제든지 조회 가능) | -**핵심:** RSC는 실시간 수신용이고, Graph API는 기록 액세스용입니다. 오프라인 동안 놓친 메시지를 따라잡으려면 `ChannelMessage.Read.All`이 포함된 Graph API가 필요합니다(관리자 동의 필요). +**핵심:** RSC는 실시간 수신용이고, Graph API는 과거 액세스용입니다. 오프라인 중 놓친 메시지를 따라잡으려면 `ChannelMessage.Read.All`이 있는 Graph API가 필요합니다(관리자 동의 필요). -## Graph 사용 미디어 + 기록(채널에 필요) +## Graph 지원 미디어 + 기록(채널에 필요) **채널**에서 이미지/파일이 필요하거나 **메시지 기록**을 가져오려면 Microsoft Graph 권한을 활성화하고 관리자 동의를 부여해야 합니다. @@ -653,48 +653,48 @@ teams app manifest upload manifest.json - `ChannelMessage.Read.All`(채널 첨부 파일 + 기록) - `Chat.Read.All` 또는 `ChatMessage.Read.All`(그룹 채팅) 2. 테넌트에 대해 **관리자 동의**를 부여합니다. -3. Teams 앱 **매니페스트 버전**을 올리고, 다시 업로드한 뒤, **Teams에서 앱을 다시 설치**합니다. -4. 캐시된 앱 메타데이터를 지우려면 Teams를 **완전히 종료한 뒤 다시 실행**합니다. +3. Teams 앱 **매니페스트 버전**을 올리고, 다시 업로드한 다음, **Teams에 앱을 다시 설치**합니다. +4. 캐시된 앱 메타데이터를 지우려면 **Teams를 완전히 종료한 뒤 다시 실행**합니다. -**사용자 멘션을 위한 추가 권한:** 대화에 있는 사용자에 대한 사용자 @멘션은 기본적으로 작동합니다. 그러나 **현재 대화에 없는** 사용자를 동적으로 검색하고 멘션하려면 `User.Read.All`(애플리케이션) 권한을 추가하고 관리자 동의를 부여합니다. +**사용자 멘션을 위한 추가 권한:** 사용자 @mentions는 대화에 있는 사용자에게 기본적으로 작동합니다. 그러나 **현재 대화에 없는** 사용자를 동적으로 검색하고 멘션하려면 `User.Read.All`(Application) 권한을 추가하고 관리자 동의를 부여하세요. ## 알려진 제한 사항 ### Webhook 시간 초과 -Teams는 HTTP Webhook을 통해 메시지를 전달합니다. 처리 시간이 너무 오래 걸리면(예: 느린 LLM 응답) 다음이 발생할 수 있습니다. +Teams는 HTTP Webhook을 통해 메시지를 전달합니다. 처리가 너무 오래 걸리는 경우(예: 느린 LLM 응답) 다음이 발생할 수 있습니다. - Gateway 시간 초과 - Teams가 메시지를 다시 시도함(중복 발생) -- 답장 누락 +- 답글 누락 -OpenClaw는 빠르게 반환하고 능동적으로 답장을 보내 이를 처리하지만, 매우 느린 응답은 여전히 문제를 일으킬 수 있습니다. +OpenClaw는 빠르게 반환하고 선제적으로 답글을 보내 이 문제를 처리하지만, 매우 느린 응답은 여전히 문제를 일으킬 수 있습니다. ### 서식 -Teams Markdown은 Slack이나 Discord보다 더 제한적입니다: +Teams markdown은 Slack이나 Discord보다 더 제한적입니다: - 기본 서식이 작동합니다: **굵게**, _기울임_, `code`, 링크 -- 복잡한 Markdown(표, 중첩 목록)은 올바르게 렌더링되지 않을 수 있습니다 -- Adaptive Cards는 투표와 의미 기반 프레젠테이션 전송에 지원됩니다(아래 참조) +- 복잡한 마크다운(표, 중첩 목록)은 올바르게 렌더링되지 않을 수 있습니다 +- Adaptive Cards는 설문과 의미론적 프레젠테이션 전송에 지원됩니다(아래 참조) ## 구성 -주요 설정(`/gateway/configuration`에서 공유 채널 패턴 참조): +주요 설정(공유 채널 패턴은 `/gateway/configuration` 참조): - `channels.msteams.enabled`: 채널을 활성화/비활성화합니다. - `channels.msteams.appId`, `channels.msteams.appPassword`, `channels.msteams.tenantId`: 봇 자격 증명입니다. - `channels.msteams.webhook.port`(기본값 `3978`) - `channels.msteams.webhook.path`(기본값 `/api/messages`) - `channels.msteams.dmPolicy`: `pairing | allowlist | open | disabled`(기본값: pairing) -- `channels.msteams.allowFrom`: DM 허용 목록(AAD 개체 ID 권장). Graph 액세스가 가능하면 마법사가 설정 중 이름을 ID로 확인합니다. +- `channels.msteams.allowFrom`: DM 허용 목록(AAD 개체 ID 권장). Graph 액세스를 사용할 수 있으면 설정 중 마법사가 이름을 ID로 확인합니다. - `channels.msteams.dangerouslyAllowNameMatching`: 변경 가능한 UPN/표시 이름 매칭 및 직접 팀/채널 이름 라우팅을 다시 활성화하는 비상 토글입니다. - `channels.msteams.textChunkLimit`: 발신 텍스트 청크 크기입니다. -- `channels.msteams.chunkMode`: 길이 기준 청킹 전에 빈 줄(문단 경계)에서 분할하려면 `length`(기본값) 또는 `newline`입니다. +- `channels.msteams.chunkMode`: 길이 청크 분할 전에 빈 줄(문단 경계)에서 분할하려면 `length`(기본값) 또는 `newline`입니다. - `channels.msteams.mediaAllowHosts`: 수신 첨부 파일 호스트 허용 목록(기본값은 Microsoft/Teams 도메인). - `channels.msteams.mediaAuthAllowHosts`: 미디어 재시도 시 Authorization 헤더를 첨부할 호스트 허용 목록(기본값은 Graph + Bot Framework 호스트). - `channels.msteams.requireMention`: 채널/그룹에서 @멘션을 요구합니다(기본값 true). -- `channels.msteams.replyStyle`: `thread | top-level`([답장 스타일](#reply-style-threads-vs-posts) 참조). +- `channels.msteams.replyStyle`: `thread | top-level`([응답 스타일](#reply-style-threads-vs-posts) 참조). - `channels.msteams.teams..replyStyle`: 팀별 재정의입니다. - `channels.msteams.teams..requireMention`: 팀별 재정의입니다. - `channels.msteams.teams..tools`: 채널 재정의가 없을 때 사용되는 기본 팀별 도구 정책 재정의(`allow`/`deny`/`alsoAllow`)입니다. @@ -704,38 +704,38 @@ Teams Markdown은 Slack이나 Discord보다 더 제한적입니다: - `channels.msteams.teams..channels..tools`: 채널별 도구 정책 재정의(`allow`/`deny`/`alsoAllow`)입니다. - `channels.msteams.teams..channels..toolsBySender`: 채널별 발신자별 도구 정책 재정의(`"*"` 와일드카드 지원)입니다. - `toolsBySender` 키는 명시적 접두사를 사용해야 합니다: - `id:`, `e164:`, `username:`, `name:`(레거시 접두사 없는 키는 여전히 `id:`로만 매핑됨). -- `channels.msteams.actions.memberInfo`: Graph 기반 멤버 정보 액션을 활성화하거나 비활성화합니다(기본값: Graph 자격 증명이 있을 때 활성화). + `id:`, `e164:`, `username:`, `name:`(레거시 접두사 없는 키는 여전히 `id:`에만 매핑됨). +- `channels.msteams.actions.memberInfo`: Graph 기반 멤버 정보 작업을 활성화하거나 비활성화합니다(기본값: Graph 자격 증명을 사용할 수 있을 때 활성화). - `channels.msteams.authType`: 인증 유형 - `"secret"`(기본값) 또는 `"federated"`. -- `channels.msteams.certificatePath`: PEM 인증서 파일 경로(federated + 인증서 인증). -- `channels.msteams.certificateThumbprint`: 인증서 지문(선택 사항, 인증에 필수 아님). -- `channels.msteams.useManagedIdentity`: 관리 ID 인증을 활성화합니다(federated 모드). -- `channels.msteams.managedIdentityClientId`: 사용자 할당 관리 ID의 클라이언트 ID입니다. -- `channels.msteams.sharePointSiteId`: 그룹 채팅/채널에서 파일 업로드에 사용할 SharePoint 사이트 ID([그룹 채팅에서 파일 보내기](#sending-files-in-group-chats) 참조). +- `channels.msteams.certificatePath`: PEM 인증서 파일 경로(페더레이션 + 인증서 인증). +- `channels.msteams.certificateThumbprint`: 인증서 지문(선택 사항, 인증에 필요하지 않음). +- `channels.msteams.useManagedIdentity`: 관리 ID 인증을 활성화합니다(페더레이션 모드). +- `channels.msteams.managedIdentityClientId`: 사용자가 할당한 관리 ID의 클라이언트 ID입니다. +- `channels.msteams.sharePointSiteId`: 그룹 채팅/채널에서 파일 업로드를 위한 SharePoint 사이트 ID([그룹 채팅에서 파일 보내기](#sending-files-in-group-chats) 참조). ## 라우팅 및 세션 - 세션 키는 표준 에이전트 형식을 따릅니다([/concepts/session](/ko/concepts/session) 참조): - - 직접 메시지는 기본 세션을 공유합니다(`agent::`). + - 다이렉트 메시지는 기본 세션을 공유합니다(`agent::`). - 채널/그룹 메시지는 대화 ID를 사용합니다: - `agent::msteams:channel:` - `agent::msteams:group:` -## 답장 스타일: 스레드와 게시물 비교 +## 응답 스타일: 스레드와 게시물 -Teams는 최근 동일한 기본 데이터 모델 위에 두 가지 채널 UI 스타일을 도입했습니다: +Teams는 최근 동일한 기반 데이터 모델 위에 두 가지 채널 UI 스타일을 도입했습니다: | 스타일 | 설명 | 권장 `replyStyle` | | ------------------------ | --------------------------------------------------------- | ------------------------ | -| **게시물**(클래식) | 메시지가 아래에 스레드형 답장이 있는 카드로 표시됩니다 | `thread`(기본값) | +| **게시물**(클래식) | 메시지가 아래에 스레드 응답이 있는 카드로 표시됩니다 | `thread`(기본값) | | **스레드**(Slack 유사) | 메시지가 Slack처럼 선형으로 흐릅니다 | `top-level` | **문제:** Teams API는 채널이 어떤 UI 스타일을 사용하는지 노출하지 않습니다. 잘못된 `replyStyle`을 사용하면: -- Threads 스타일 채널에서 `thread` → 답장이 어색하게 중첩되어 표시됩니다 -- Posts 스타일 채널에서 `top-level` → 답장이 스레드 내부가 아니라 별도의 최상위 게시물로 표시됩니다 +- 스레드 스타일 채널의 `thread` → 응답이 어색하게 중첩되어 표시됩니다 +- 게시물 스타일 채널의 `top-level` → 응답이 스레드 안이 아니라 별도의 최상위 게시물로 표시됩니다 -**해결책:** 채널 설정 방식에 따라 채널별로 `replyStyle`을 구성하세요: +**해결책:** 채널 설정 방식에 따라 채널별로 `replyStyle`을 구성합니다: ```json5 { @@ -760,21 +760,21 @@ Teams는 최근 동일한 기본 데이터 모델 위에 두 가지 채널 UI **현재 제한 사항:** -- **DM:** 이미지는 Teams 봇 파일 API를 통해 작동합니다. +- **DM:** 이미지와 파일 첨부는 Teams 봇 파일 API를 통해 작동합니다. - **채널/그룹:** 첨부 파일은 M365 저장소(SharePoint/OneDrive)에 있습니다. Webhook 페이로드에는 실제 파일 바이트가 아니라 HTML 스텁만 포함됩니다. 채널 첨부 파일을 다운로드하려면 **Graph API 권한이 필요합니다**. -- 명시적인 파일 우선 전송에는 `media` / `filePath` / `path`와 함께 `action=upload-file`을 사용하세요. 선택 사항인 `message`는 함께 제공되는 텍스트/댓글이 되며, `filename`은 업로드된 이름을 재정의합니다. +- 명시적인 파일 우선 전송에는 `media` / `filePath` / `path`와 함께 `action=upload-file`을 사용합니다. 선택적 `message`는 함께 전송되는 텍스트/댓글이 되며, `filename`은 업로드된 이름을 재정의합니다. -Graph 권한이 없으면 이미지가 있는 채널 메시지는 텍스트만으로 수신됩니다(이미지 콘텐츠는 봇이 액세스할 수 없음). -기본적으로 OpenClaw는 Microsoft/Teams 호스트 이름에서만 미디어를 다운로드합니다. `channels.msteams.mediaAllowHosts`로 재정의하세요(모든 호스트를 허용하려면 `["*"]` 사용). -Authorization 헤더는 `channels.msteams.mediaAuthAllowHosts`에 있는 호스트에만 첨부됩니다(기본값은 Graph + Bot Framework 호스트). 이 목록은 엄격하게 유지하세요(멀티 테넌트 접미사 피하기). +Graph 권한이 없으면 이미지가 포함된 채널 메시지는 텍스트 전용으로 수신됩니다(봇이 이미지 콘텐츠에 액세스할 수 없음). +기본적으로 OpenClaw는 Microsoft/Teams 호스트 이름에서만 미디어를 다운로드합니다. `channels.msteams.mediaAllowHosts`로 재정의합니다(모든 호스트를 허용하려면 `["*"]` 사용). +Authorization 헤더는 `channels.msteams.mediaAuthAllowHosts`의 호스트에만 첨부됩니다(기본값은 Graph + Bot Framework 호스트). 이 목록은 엄격하게 유지하세요(다중 테넌트 접미사 피하기). ## 그룹 채팅에서 파일 보내기 -봇은 FileConsentCard 흐름(기본 제공)을 사용하여 DM에서 파일을 보낼 수 있습니다. 그러나 **그룹 채팅/채널에서 파일 보내기**에는 추가 설정이 필요합니다: +봇은 FileConsentCard 흐름(기본 제공)을 사용하여 DM에서 파일을 보낼 수 있습니다. 그러나 **그룹 채팅/채널에서 파일을 보내려면** 추가 설정이 필요합니다: | 컨텍스트 | 파일 전송 방식 | 필요한 설정 | | ------------------------ | -------------------------------------------- | ----------------------------------------------- | -| **DM** | FileConsentCard → 사용자가 수락 → 봇 업로드 | 별도 설정 없이 작동 | +| **DM** | FileConsentCard → 사용자가 수락 → 봇이 업로드 | 별도 설정 없이 작동 | | **그룹 채팅/채널** | SharePoint에 업로드 → 링크 공유 | `sharePointSiteId` + Graph 권한 필요 | | **이미지(모든 컨텍스트)** | Base64 인코딩 인라인 | 별도 설정 없이 작동 | @@ -784,27 +784,27 @@ Authorization 헤더는 `channels.msteams.mediaAuthAllowHosts`에 있는 호스 ### 설정 -1. Entra ID(Azure AD) → 앱 등록에서 **Graph API 권한 추가**: - - `Sites.ReadWrite.All`(Application) - SharePoint에 파일 업로드 - - `Chat.Read.All`(Application) - 선택 사항, 사용자별 공유 링크 활성화 +1. Entra ID(Azure AD) → 앱 등록에서 **Graph API 권한을 추가**합니다: + - `Sites.ReadWrite.All`(애플리케이션) - SharePoint에 파일 업로드 + - `Chat.Read.All`(애플리케이션) - 선택 사항, 사용자별 공유 링크 활성화 -2. 테넌트에 대해 **관리자 동의 부여**. +2. 테넌트에 대해 **관리자 동의 부여**를 수행합니다. -3. **SharePoint 사이트 ID 가져오기:** +3. **SharePoint 사이트 ID를 가져옵니다:** ```bash - # Via Graph Explorer or curl with a valid token: + # Graph Explorer 또는 유효한 토큰이 있는 curl을 통해: curl -H "Authorization: Bearer $TOKEN" \ "https://graph.microsoft.com/v1.0/sites/{hostname}:/{site-path}" - # Example: for a site at "contoso.sharepoint.com/sites/BotFiles" + # 예: "contoso.sharepoint.com/sites/BotFiles"에 있는 사이트의 경우 curl -H "Authorization: Bearer $TOKEN" \ "https://graph.microsoft.com/v1.0/sites/contoso.sharepoint.com:/sites/BotFiles" - # Response includes: "id": "contoso.sharepoint.com,guid1,guid2" + # 응답에 포함됨: "id": "contoso.sharepoint.com,guid1,guid2" ``` -4. **OpenClaw 구성:** +4. **OpenClaw를 구성합니다:** ```json5 { @@ -824,7 +824,7 @@ Authorization 헤더는 `channels.msteams.mediaAuthAllowHosts`에 있는 호스 | `Sites.ReadWrite.All`만 | 조직 전체 공유 링크(조직 내 누구나 액세스 가능) | | `Sites.ReadWrite.All` + `Chat.Read.All` | 사용자별 공유 링크(채팅 멤버만 액세스 가능) | -사용자별 공유는 채팅 참여자만 파일에 액세스할 수 있으므로 더 안전합니다. `Chat.Read.All` 권한이 없으면 봇은 조직 전체 공유로 대체합니다. +사용자별 공유는 채팅 참가자만 파일에 액세스할 수 있으므로 더 안전합니다. `Chat.Read.All` 권한이 없으면 봇은 조직 전체 공유로 대체합니다. ### 대체 동작 @@ -837,22 +837,22 @@ Authorization 헤더는 `channels.msteams.mediaAuthAllowHosts`에 있는 호스 ### 파일 저장 위치 -업로드된 파일은 구성된 SharePoint 사이트의 기본 문서 라이브러리 안 `/OpenClawShared/` 폴더에 저장됩니다. +업로드된 파일은 구성된 SharePoint 사이트의 기본 문서 라이브러리에 있는 `/OpenClawShared/` 폴더에 저장됩니다. -## 투표(Adaptive Cards) +## 설문(Adaptive Cards) -OpenClaw는 Teams 투표를 Adaptive Cards로 보냅니다(네이티브 Teams 투표 API는 없음). +OpenClaw는 Teams 설문을 Adaptive Cards로 보냅니다(기본 Teams 설문 API는 없음). - CLI: `openclaw message poll --channel msteams --target conversation: ...` - 투표는 Gateway가 `~/.openclaw/msteams-polls.json`에 기록합니다. -- 투표를 기록하려면 Gateway가 온라인 상태를 유지해야 합니다. -- 투표는 아직 결과 요약을 자동 게시하지 않습니다(필요하면 저장소 파일을 확인하세요). +- 투표를 기록하려면 Gateway가 온라인 상태로 유지되어야 합니다. +- 설문은 아직 결과 요약을 자동 게시하지 않습니다(필요하면 저장소 파일을 확인). ## 프레젠테이션 카드 -`message` 도구 또는 CLI를 사용하여 의미 기반 프레젠테이션 페이로드를 Teams 사용자 또는 대화로 보내세요. OpenClaw는 일반 프레젠테이션 계약에서 이를 Teams Adaptive Cards로 렌더링합니다. +`message` 도구 또는 CLI를 사용하여 Teams 사용자 또는 대화에 의미론적 프레젠테이션 페이로드를 보냅니다. OpenClaw는 일반 프레젠테이션 계약에서 이를 Teams Adaptive Cards로 렌더링합니다. -`presentation` 매개변수는 의미 기반 블록을 받습니다. `presentation`이 제공되면 메시지 텍스트는 선택 사항입니다. +`presentation` 매개변수는 의미론적 블록을 허용합니다. `presentation`이 제공되면 메시지 텍스트는 선택 사항입니다. **에이전트 도구:** @@ -876,20 +876,20 @@ openclaw message send --channel msteams \ --presentation '{"title":"Hello","blocks":[{"type":"text","text":"Hello!"}]}' ``` -대상 형식 세부 정보는 아래 [대상 형식](#target-formats)을 참조하세요. +대상 형식 세부 정보는 아래의 [대상 형식](#target-formats)을 참조하세요. ## 대상 형식 -MSTeams 대상은 사용자와 대화를 구분하기 위해 접두사를 사용합니다: +MSTeams 대상은 접두사를 사용하여 사용자와 대화를 구분합니다: -| 대상 유형 | 형식 | 예시 | +| 대상 유형 | 형식 | 예 | | ------------------- | -------------------------------- | --------------------------------------------------- | | 사용자(ID 기준) | `user:` | `user:40a1a0ed-4ff2-4164-a219-55518990c197` | | 사용자(이름 기준) | `user:` | `user:John Smith`(Graph API 필요) | | 그룹/채널 | `conversation:` | `conversation:19:abc123...@thread.tacv2` | | 그룹/채널(원시) | `` | `19:abc123...@thread.tacv2`(`@thread`를 포함하는 경우) | -**CLI 예시:** +**CLI 예:** ```bash # Send to a user by ID @@ -930,17 +930,17 @@ openclaw message send --channel msteams --target "conversation:19:abc...@thread. ``` -`user:` 접두사가 없으면 이름은 기본적으로 그룹 또는 팀 해석에 사용됩니다. 표시 이름으로 사람을 대상으로 지정할 때는 항상 `user:`를 사용하세요. +`user:` 접두사가 없으면 이름은 기본적으로 그룹 또는 팀 확인 대상으로 처리됩니다. 표시 이름으로 사람을 대상으로 지정할 때는 항상 `user:`를 사용하세요. ## 사전 메시징 -- 사전 메시지는 사용자가 상호작용한 **후에만** 가능합니다. 해당 시점에 대화 참조를 저장하기 때문입니다. +- 사전 메시지는 사용자가 상호작용한 **후에만** 가능합니다. 그 시점에 대화 참조를 저장하기 때문입니다. - `dmPolicy` 및 허용 목록 게이팅은 `/gateway/configuration`을 참조하세요. -## 팀 및 채널 ID (흔한 함정) +## 팀 및 채널 ID(흔한 실수) -Teams URL의 `groupId` 쿼리 매개변수는 구성에 사용되는 팀 ID가 **아닙니다**. 대신 URL 경로에서 ID를 추출하세요. +Teams URL의 `groupId` 쿼리 매개변수는 구성에 사용하는 팀 ID가 **아닙니다**. 대신 URL 경로에서 ID를 추출하세요. **팀 URL:** @@ -958,68 +958,68 @@ https://teams.microsoft.com/l/channel/19%3A15bc...%40thread.tacv2/ChannelName?gr Channel ID (URL-decode this) ``` -**구성의 경우:** +**구성용:** -- 팀 키 = `/team/` 뒤의 경로 세그먼트(URL 디코딩됨, 예: `19:Bk4j...@thread.tacv2`; 오래된 테넌트에서는 `@thread.skype`가 표시될 수 있으며 이것도 유효함) +- 팀 키 = `/team/` 뒤의 경로 세그먼트(URL 디코딩됨, 예: `19:Bk4j...@thread.tacv2`; 오래된 테넌트는 `@thread.skype`를 표시할 수 있으며, 이 역시 유효함) - 채널 키 = `/channel/` 뒤의 경로 세그먼트(URL 디코딩됨) -- OpenClaw 라우팅에서는 `groupId` 쿼리 매개변수를 **무시**하세요. 이는 Microsoft Entra 그룹 ID이며, 수신 Teams 활동에서 사용되는 Bot Framework 대화 ID가 아닙니다. +- OpenClaw 라우팅에는 `groupId` 쿼리 매개변수를 **무시하세요**. 이것은 들어오는 Teams 활동에서 사용하는 Bot Framework 대화 ID가 아니라 Microsoft Entra 그룹 ID입니다. ## 비공개 채널 -Bot은 비공개 채널에서 제한적으로 지원됩니다. +봇은 비공개 채널에서 제한적으로 지원됩니다. | 기능 | 표준 채널 | 비공개 채널 | | ---------------------------- | --------- | ------------------------ | -| Bot 설치 | 예 | 제한적 | +| 봇 설치 | 예 | 제한적 | | 실시간 메시지(Webhook) | 예 | 작동하지 않을 수 있음 | | RSC 권한 | 예 | 다르게 동작할 수 있음 | -| @멘션 | 예 | Bot에 접근할 수 있는 경우 | -| Graph API 기록 | 예 | 예(권한 필요) | +| @멘션 | 예 | 봇에 접근할 수 있는 경우 | +| Graph API 기록 | 예 | 예(권한 필요) | **비공개 채널이 작동하지 않을 때의 우회 방법:** -1. Bot 상호작용에는 표준 채널을 사용합니다 -2. DM을 사용합니다. 사용자는 언제든지 Bot에 직접 메시지를 보낼 수 있습니다 -3. 기록 접근에는 Graph API를 사용합니다(`ChannelMessage.Read.All` 필요) +1. 봇 상호작용에는 표준 채널을 사용하세요 +2. DM을 사용하세요. 사용자는 언제든지 봇에 직접 메시지를 보낼 수 있습니다 +3. 기록 접근에는 Graph API를 사용하세요(`ChannelMessage.Read.All` 필요) ## 문제 해결 ### 일반적인 문제 -- **채널에 이미지가 표시되지 않음:** Graph 권한 또는 관리자 동의가 없습니다. Teams 앱을 다시 설치하고 Teams를 완전히 종료한 뒤 다시 여세요. +- **채널에 이미지가 표시되지 않음:** Graph 권한 또는 관리자 동의가 누락되었습니다. Teams 앱을 다시 설치하고 Teams를 완전히 종료한 뒤 다시 여세요. - **채널에서 응답이 없음:** 기본적으로 멘션이 필요합니다. `channels.msteams.requireMention=false`를 설정하거나 팀/채널별로 구성하세요. -- **버전 불일치(Teams에 여전히 이전 매니페스트가 표시됨):** 앱을 제거한 뒤 다시 추가하고, 새로고침하려면 Teams를 완전히 종료하세요. -- **Webhook에서 401 Unauthorized:** Azure JWT 없이 수동으로 테스트할 때 예상되는 동작입니다. 엔드포인트에 도달할 수 있지만 인증이 실패했다는 의미입니다. 올바르게 테스트하려면 Azure Web Chat을 사용하세요. +- **버전 불일치(Teams에 여전히 이전 매니페스트가 표시됨):** 앱을 제거한 뒤 다시 추가하고 Teams를 완전히 종료해 새로 고치세요. +- **Webhook에서 401 Unauthorized:** Azure JWT 없이 수동 테스트할 때 예상되는 결과입니다. 엔드포인트에는 도달할 수 있지만 인증에 실패했다는 의미입니다. 올바르게 테스트하려면 Azure Web Chat을 사용하세요. ### 매니페스트 업로드 오류 -- **"Icon file cannot be empty":** 매니페스트가 참조하는 아이콘 파일이 0바이트입니다. 유효한 PNG 아이콘을 만드세요(`outline.png`는 32x32, `color.png`는 192x192). -- **"webApplicationInfo.Id already in use":** 앱이 아직 다른 팀/채팅에 설치되어 있습니다. 먼저 찾아서 제거하거나, 전파될 때까지 5~10분 기다리세요. -- **업로드 시 "Something went wrong":** 대신 [https://admin.teams.microsoft.com](https://admin.teams.microsoft.com)을 통해 업로드하고, 브라우저 DevTools(F12) → Network 탭을 열어 실제 오류가 담긴 응답 본문을 확인하세요. -- **사이드로드 실패:** "Upload a custom app" 대신 "Upload an app to your org's app catalog"를 사용해 보세요. 이렇게 하면 사이드로드 제한을 우회하는 경우가 많습니다. +- **"Icon file cannot be empty":** 매니페스트가 0바이트인 아이콘 파일을 참조합니다. 유효한 PNG 아이콘을 만드세요(`outline.png`는 32x32, `color.png`는 192x192). +- **"webApplicationInfo.Id already in use":** 앱이 다른 팀/채팅에 아직 설치되어 있습니다. 먼저 찾아서 제거하거나 전파를 위해 5~10분 기다리세요. +- **업로드 시 "Something went wrong":** 대신 [https://admin.teams.microsoft.com](https://admin.teams.microsoft.com)을 통해 업로드하고, 브라우저 DevTools(F12) → Network 탭을 연 다음 응답 본문에서 실제 오류를 확인하세요. +- **사이드로드 실패:** "Upload a custom app" 대신 "Upload an app to your org's app catalog"를 시도하세요. 이 방법은 종종 사이드로드 제한을 우회합니다. ### RSC 권한이 작동하지 않음 -1. `webApplicationInfo.id`가 Bot의 App ID와 정확히 일치하는지 확인합니다 -2. 앱을 다시 업로드하고 팀/채팅에 다시 설치합니다 -3. 조직 관리자가 RSC 권한을 차단했는지 확인합니다 -4. 올바른 범위를 사용 중인지 확인합니다. 팀에는 `ChannelMessage.Read.Group`, 그룹 채팅에는 `ChatMessage.Read.Chat` +1. `webApplicationInfo.id`가 봇의 App ID와 정확히 일치하는지 확인하세요 +2. 앱을 다시 업로드하고 팀/채팅에 다시 설치하세요 +3. 조직 관리자가 RSC 권한을 차단했는지 확인하세요 +4. 올바른 범위를 사용 중인지 확인하세요. 팀은 `ChannelMessage.Read.Group`, 그룹 채팅은 `ChatMessage.Read.Chat`입니다 -## 참고 자료 +## 참조 - [Azure Bot 만들기](https://learn.microsoft.com/en-us/azure/bot-service/bot-service-quickstart-registration) - Azure Bot 설정 가이드 - [Teams 개발자 포털](https://dev.teams.microsoft.com/apps) - Teams 앱 생성/관리 - [Teams 앱 매니페스트 스키마](https://learn.microsoft.com/en-us/microsoftteams/platform/resources/schema/manifest-schema) - [RSC로 채널 메시지 받기](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/channel-messages-with-rsc) -- [RSC 권한 참고 자료](https://learn.microsoft.com/en-us/microsoftteams/platform/graph-api/rsc/resource-specific-consent) -- [Teams Bot 파일 처리](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/bots-filesv4) (채널/그룹에는 Graph 필요) +- [RSC 권한 참조](https://learn.microsoft.com/en-us/microsoftteams/platform/graph-api/rsc/resource-specific-consent) +- [Teams 봇 파일 처리](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/bots-filesv4) (채널/그룹에는 Graph 필요) - [사전 메시징](https://learn.microsoft.com/en-us/microsoftteams/platform/bots/how-to/conversations/send-proactive-messages) -- [@microsoft/teams.cli](https://www.npmjs.com/package/@microsoft/teams.cli) - Bot 관리를 위한 Teams CLI +- [@microsoft/teams.cli](https://www.npmjs.com/package/@microsoft/teams.cli) - 봇 관리를 위한 Teams CLI -## 관련 문서 +## 관련 항목 - [채널 개요](/ko/channels) - 지원되는 모든 채널 - [페어링](/ko/channels/pairing) - DM 인증 및 페어링 흐름 - [그룹](/ko/channels/groups) - 그룹 채팅 동작 및 멘션 게이팅 -- [채널 라우팅](/ko/channels/channel-routing) - 메시지에 대한 세션 라우팅 +- [채널 라우팅](/ko/channels/channel-routing) - 메시지 세션 라우팅 - [보안](/ko/gateway/security) - 접근 모델 및 강화 diff --git a/docs/ko/channels/pairing.md b/docs/ko/channels/pairing.md index d399d0487..07fb5c87d 100644 --- a/docs/ko/channels/pairing.md +++ b/docs/ko/channels/pairing.md @@ -1,42 +1,42 @@ --- read_when: - DM 접근 제어 설정 - - 새 iOS/Android Node 페어링하기 + - 새 iOS/Android Node 페어링 - OpenClaw 보안 태세 검토 -summary: '페어링 개요: 나에게 DM을 보낼 수 있는 사람 + 참여할 수 있는 노드 승인' +summary: '페어링 개요: 나에게 다이렉트 메시지를 보낼 수 있는 사람 + 참여할 수 있는 Node 승인' title: 페어링 x-i18n: - generated_at: "2026-05-06T06:18:07Z" + generated_at: "2026-05-06T17:52:34Z" model: gpt-5.5 provider: openai - source_hash: 5543c10868418234714b175cd4bd373818be8dd40327121ac6c44819ed7519b2 + source_hash: dcee04ae47bf28caa76c5f6e7218e8b1b24f9ee70bc1b7b65d3f8859797a4645 source_path: channels/pairing.md workflow: 16 --- -“페어링”은 OpenClaw의 명시적인 접근 승인 단계입니다. -두 곳에서 사용됩니다: +"페어링"은 OpenClaw의 명시적 접근 승인 단계입니다. +두 곳에서 사용됩니다. -1. **DM 페어링**(누가 봇과 대화할 수 있는지) -2. **Node 페어링**(어떤 기기/노드가 Gateway 네트워크에 참여할 수 있는지) +1. **DM 페어링**(봇과 대화할 수 있는 사람) +2. **Node 페어링**(Gateway 네트워크에 참여할 수 있는 기기/Node) 보안 컨텍스트: [보안](/ko/gateway/security) -## 1) DM 페어링(인바운드 채팅 접근) +## 1) DM 페어링(수신 채팅 접근) -채널이 DM 정책 `pairing`으로 구성되어 있으면, 알 수 없는 발신자는 짧은 코드를 받으며 승인할 때까지 해당 메시지는 **처리되지 않습니다**. +채널이 DM 정책 `pairing`으로 구성된 경우, 알 수 없는 발신자는 짧은 코드를 받으며, 사용자가 승인할 때까지 해당 메시지는 **처리되지 않습니다**. 기본 DM 정책은 다음 문서에 설명되어 있습니다: [보안](/ko/gateway/security) -`dmPolicy: "open"`은 유효한 DM 허용 목록에 `"*"`가 포함된 경우에만 공개 상태입니다. -설정 및 검증에서는 public-open 구성에 이 와일드카드가 필요합니다. 기존 -상태에 구체적인 `allowFrom` 항목과 함께 `open`이 포함되어 있으면, 런타임은 여전히 -해당 발신자만 허용하며 페어링 저장소 승인은 `open` 접근 범위를 넓히지 않습니다. +`dmPolicy: "open"`은 유효한 DM 허용 목록에 `"*"`가 포함된 경우에만 공개입니다. +공개-open 구성에는 설정 및 검증 시 이 와일드카드가 필요합니다. 기존 +상태에 구체적인 `allowFrom` 항목과 함께 `open`이 포함되어 있으면 런타임은 여전히 +해당 발신자만 허용하며, 페어링 저장소 승인은 `open` 접근을 넓히지 않습니다. 페어링 코드: -- 8자, 대문자, 혼동될 수 있는 문자 없음(`0O1I`). -- **1시간 후 만료됩니다**. 봇은 새 요청이 생성될 때만 페어링 메시지를 보냅니다(대략 발신자당 1시간에 한 번). +- 8자, 대문자, 모호한 문자 없음(`0O1I`). +- **1시간 후 만료**됩니다. 봇은 새 요청이 생성될 때만 페어링 메시지를 보냅니다(발신자당 대략 1시간에 한 번). - 대기 중인 DM 페어링 요청은 기본적으로 **채널당 3개**로 제한됩니다. 추가 요청은 하나가 만료되거나 승인될 때까지 무시됩니다. ### 발신자 승인 @@ -46,21 +46,21 @@ openclaw pairing list telegram openclaw pairing approve telegram ``` -아직 명령 소유자가 구성되어 있지 않으면, DM 페어링 코드를 승인할 때 승인된 발신자로 -`commands.ownerAllowFrom`도 부트스트랩됩니다. 예: `telegram:123456789`. -이를 통해 최초 설정에서 권한 있는 명령과 exec 승인 프롬프트에 사용할 명시적인 -소유자를 갖게 됩니다. 소유자가 생긴 뒤에는 이후 페어링 승인은 DM 접근만 부여하며 +아직 명령 소유자가 구성되어 있지 않으면, DM 페어링 코드를 승인할 때 +`commands.ownerAllowFrom`도 승인된 발신자(예: `telegram:123456789`)로 부트스트랩됩니다. +이렇게 하면 최초 설정에서 권한 있는 명령과 exec 승인 프롬프트를 위한 명시적 소유자가 생깁니다. +소유자가 생긴 뒤에는 이후 페어링 승인은 DM 접근만 허용하며, 소유자를 더 추가하지 않습니다. 지원 채널: `bluebubbles`, `discord`, `feishu`, `googlechat`, `imessage`, `irc`, `line`, `matrix`, `mattermost`, `msteams`, `nextcloud-talk`, `nostr`, `openclaw-weixin`, `signal`, `slack`, `synology-chat`, `telegram`, `twitch`, `whatsapp`, `zalo`, `zalouser`. ### 재사용 가능한 발신자 그룹 -동일한 신뢰할 수 있는 발신자 집합을 여러 메시지 채널 또는 DM과 그룹 허용 목록 -모두에 적용해야 하는 경우 최상위 `accessGroups`를 사용합니다. +동일한 신뢰할 수 있는 발신자 집합을 여러 메시지 채널 또는 DM과 그룹 허용 목록 모두에 +적용해야 할 때는 최상위 `accessGroups`를 사용합니다. -정적 그룹은 `type: "message.senders"`를 사용하며 채널 허용 목록에서 -`accessGroup:`으로 참조됩니다: +정적 그룹은 `type: "message.senders"`를 사용하며, 채널 허용 목록에서 +`accessGroup:`으로 참조됩니다. ```json5 { @@ -81,71 +81,71 @@ openclaw pairing approve telegram } ``` -액세스 그룹은 여기에서 자세히 설명합니다: [액세스 그룹](/ko/channels/access-groups) +접근 그룹은 여기에서 자세히 설명합니다: [접근 그룹](/ko/channels/access-groups) ### 상태가 저장되는 위치 -`~/.openclaw/credentials/` 아래에 저장됩니다: +`~/.openclaw/credentials/` 아래에 저장됩니다. - 대기 중인 요청: `-pairing.json` - 승인된 허용 목록 저장소: - 기본 계정: `-allowFrom.json` - 기본이 아닌 계정: `--allowFrom.json` -계정 범위 지정 동작: +계정 범위 동작: -- 기본이 아닌 계정은 범위가 지정된 허용 목록 파일만 읽고 씁니다. -- 기본 계정은 채널 범위의 범위 미지정 허용 목록 파일을 사용합니다. +- 기본이 아닌 계정은 해당 범위의 허용 목록 파일만 읽고 씁니다. +- 기본 계정은 채널 범위의 범위 지정 없는 허용 목록 파일을 사용합니다. -이를 민감한 정보로 취급하세요(어시스턴트 접근을 제어합니다). +이 항목들은 민감한 정보로 취급하세요(어시스턴트 접근을 제어합니다). 페어링 허용 목록 저장소는 DM 접근용입니다. 그룹 권한 부여는 별도입니다. -DM 페어링 코드를 승인해도 해당 발신자가 자동으로 그룹 -명령을 실행하거나 그룹에서 봇을 제어할 수 있게 되지는 않습니다. 첫 소유자 부트스트랩은 +DM 페어링 코드를 승인해도 해당 발신자가 그룹 +명령을 실행하거나 그룹에서 봇을 제어할 수 있도록 자동 허용되지는 않습니다. 첫 소유자 부트스트랩은 `commands.ownerAllowFrom`의 별도 구성 상태이며, 그룹 채팅 전달은 여전히 -채널의 그룹 허용 목록을 따릅니다(예: 채널에 따라 `groupAllowFrom`, `groups`, 또는 그룹별 -혹은 토픽별 재정의). +채널의 그룹 허용 목록(예: 채널에 따라 `groupAllowFrom`, `groups`, 그룹별 +또는 주제별 재정의)을 따릅니다. -## 2) Node 기기 페어링(iOS/Android/macOS/headless 노드) +## 2) Node 기기 페어링(iOS/Android/macOS/headless Node) -노드는 `role: node`를 가진 **기기**로 Gateway에 연결됩니다. Gateway는 +Node는 `role: node`가 있는 **기기**로 Gateway에 연결됩니다. Gateway는 승인해야 하는 기기 페어링 요청을 생성합니다. -### Telegram을 통한 페어링(iOS에 권장) +### Telegram으로 페어링(iOS에 권장) -`device-pair` Plugin을 사용하면 최초 기기 페어링을 Telegram에서 전부 수행할 수 있습니다: +`device-pair` Plugin을 사용하는 경우, 최초 기기 페어링을 Telegram에서 전부 수행할 수 있습니다. 1. Telegram에서 봇에게 메시지를 보냅니다: `/pair` -2. 봇은 두 개의 메시지로 응답합니다. 안내 메시지와 별도의 **설정 코드** 메시지입니다(Telegram에서 복사/붙여넣기 쉬움). -3. 휴대폰에서 OpenClaw iOS 앱을 엽니다 → 설정 → Gateway. +2. 봇은 안내 메시지와 별도의 **설정 코드** 메시지, 이렇게 두 개의 메시지로 응답합니다(Telegram에서 복사/붙여넣기 쉬움). +3. 휴대폰에서 OpenClaw iOS 앱을 열고 → 설정 → Gateway로 이동합니다. 4. QR 코드를 스캔하거나 설정 코드를 붙여넣고 연결합니다. -5. Telegram으로 돌아와 `/pair pending`(요청 ID, 역할, 범위 검토)을 실행한 다음 승인합니다. +5. 다시 Telegram에서: `/pair pending`(요청 ID, 역할, 범위 검토) 후 승인합니다. -설정 코드는 다음을 포함하는 base64 인코딩 JSON 페이로드입니다: +설정 코드는 다음을 포함하는 base64로 인코딩된 JSON 페이로드입니다. - `url`: Gateway WebSocket URL(`ws://...` 또는 `wss://...`) - `bootstrapToken`: 초기 페어링 핸드셰이크에 사용되는 수명이 짧은 단일 기기 부트스트랩 토큰 -해당 부트스트랩 토큰에는 기본 제공 페어링 부트스트랩 프로필이 포함됩니다: +해당 부트스트랩 토큰에는 기본 제공 페어링 부트스트랩 프로필이 포함됩니다. -- 전달된 기본 `node` 토큰은 `scopes: []`로 유지됩니다 -- 전달된 모든 `operator` 토큰은 부트스트랩 허용 목록으로 계속 제한됩니다: +- 기본으로 넘겨받는 `node` 토큰은 `scopes: []`를 유지합니다. +- 넘겨받는 모든 `operator` 토큰은 부트스트랩 허용 목록으로 제한됩니다: `operator.approvals`, `operator.read`, `operator.talk.secrets`, `operator.write` - 부트스트랩 범위 검사는 하나의 평면 범위 풀이 아니라 역할 접두사가 붙습니다: operator 범위 항목은 operator 요청만 충족하며, operator가 아닌 역할은 - 여전히 자체 역할 접두사 아래에서 범위를 요청해야 합니다 -- 이후 토큰 회전/해지는 기기의 승인된 - 역할 계약과 호출자 세션의 operator 범위 양쪽 모두로 계속 제한됩니다 + 여전히 자체 역할 접두사 아래의 범위를 요청해야 합니다. +- 이후 토큰 회전/폐기는 기기의 승인된 + 역할 계약과 호출자 세션의 operator 범위 모두에 의해 계속 제한됩니다. 설정 코드는 유효한 동안 비밀번호처럼 취급하세요. Tailscale, 공개 또는 기타 원격 모바일 페어링의 경우 Tailscale Serve/Funnel -또는 다른 `wss://` Gateway URL을 사용하세요. 평문 `ws://` 설정 코드는 loopback, -사설 LAN 주소, `.local` Bonjour 호스트, Android 에뮬레이터 호스트에만 -허용됩니다. Tailnet CGNAT 주소, `.ts.net` 이름, 공개 호스트는 여전히 -QR/설정 코드 발급 전에 닫힌 상태로 실패합니다. +또는 다른 `wss://` Gateway URL을 사용합니다. 평문 `ws://` 설정 코드는 +루프백, 사설 LAN 주소, `.local` Bonjour 호스트, Android +에뮬레이터 호스트에 대해서만 허용됩니다. Tailnet CGNAT 주소, `.ts.net` 이름, 공개 호스트는 +QR/설정 코드 발급 전에 여전히 안전하게 실패합니다. ### Node 기기 승인 @@ -155,24 +155,24 @@ openclaw devices approve openclaw devices reject ``` -승인하는 페어링된 기기 세션이 페어링 전용 범위로 열려 있어 명시적 승인이 -거부되면, CLI는 동일한 요청을 `operator.admin`으로 다시 시도합니다. -이를 통해 기존의 관리자 권한이 가능한 페어링된 기기가 `devices/paired.json`을 -직접 편집하지 않고도 새 Control UI/브라우저 페어링을 복구할 수 있습니다. -Gateway는 여전히 다시 시도된 연결을 검증합니다. `operator.admin`으로 인증할 수 없는 -토큰은 계속 차단됩니다. +승인하는 페어링된 기기 세션이 페어링 전용 범위로 열렸기 때문에 명시적 승인이 거부되면, +CLI는 동일한 요청을 `operator.admin`으로 재시도합니다. 이를 통해 기존의 관리자 권한이 있는 페어링된 기기는 +`devices/paired.json`을 직접 편집하지 않고도 새 Control UI/브라우저 페어링을 복구할 수 있습니다. +Gateway는 여전히 재시도된 연결을 검증합니다. `operator.admin`으로 인증할 수 없는 토큰은 +계속 차단됩니다. -동일한 기기가 다른 인증 세부 정보(예: 다른 역할/범위/공개 키)로 다시 시도하면, -이전 대기 요청은 대체되고 새 `requestId`가 생성됩니다. +동일한 기기가 다른 인증 세부 정보(예: 다른 +역할/범위/공개 키)로 재시도하면 이전 대기 요청은 대체되고 새 +`requestId`가 생성됩니다. -이미 페어링된 기기가 조용히 더 넓은 접근 권한을 얻지는 않습니다. 더 많은 범위나 더 넓은 역할을 요청하며 다시 연결하면, OpenClaw는 기존 승인을 그대로 유지하고 새로운 대기 중 업그레이드 요청을 생성합니다. 승인하기 전에 `openclaw devices list`를 사용하여 현재 승인된 접근 권한과 새로 요청된 접근 권한을 비교하세요. +이미 페어링된 기기가 조용히 더 넓은 접근 권한을 얻지는 않습니다. 더 많은 범위나 더 넓은 역할을 요청하며 다시 연결하면, OpenClaw는 기존 승인을 그대로 유지하고 새 대기 중 업그레이드 요청을 생성합니다. 승인하기 전에 `openclaw devices list`를 사용하여 현재 승인된 접근 권한과 새로 요청된 접근 권한을 비교하세요. ### 선택 사항: 신뢰할 수 있는 CIDR Node 자동 승인 -기기 페어링은 기본적으로 수동으로 유지됩니다. 엄격하게 제어되는 Node 네트워크의 경우, -명시적인 CIDR 또는 정확한 IP로 최초 Node 자동 승인을 선택할 수 있습니다: +기기 페어링은 기본적으로 수동입니다. 엄격히 제어되는 Node 네트워크의 경우, +명시적 CIDR 또는 정확한 IP로 최초 Node 자동 승인을 사용하도록 선택할 수 있습니다. ```json5 { @@ -193,23 +193,23 @@ Operator, 브라우저, Control UI, WebChat 클라이언트는 여전히 수동 ### Node 페어링 상태 저장소 -`~/.openclaw/devices/` 아래에 저장됩니다: +`~/.openclaw/devices/` 아래에 저장됩니다. -- `pending.json`(수명이 짧음; 대기 요청은 만료됨) +- `pending.json`(수명이 짧음, 대기 중인 요청은 만료됨) - `paired.json`(페어링된 기기 + 토큰) ### 참고 - 레거시 `node.pair.*` API(CLI: `openclaw nodes pending|approve|reject|remove|rename`)는 - 별도의 gateway 소유 페어링 저장소입니다. WS 노드는 여전히 기기 페어링이 필요합니다. -- 페어링 레코드는 승인된 역할에 대한 영구적인 단일 정보 원천입니다. 활성 - 기기 토큰은 승인된 역할 집합으로 계속 제한됩니다. 승인된 역할 밖의 잘못된 토큰 항목이 - 새 접근 권한을 만들지는 않습니다. + 별도의 Gateway 소유 페어링 저장소입니다. WS Node에는 여전히 기기 페어링이 필요합니다. +- 페어링 레코드는 승인된 역할의 지속적인 단일 진실 공급원입니다. 활성 + 기기 토큰은 해당 승인된 역할 집합으로 계속 제한됩니다. 승인된 역할 밖의 이탈 토큰 항목은 + 새 접근 권한을 만들지 않습니다. ## 관련 문서 - 보안 모델 + 프롬프트 인젝션: [보안](/ko/gateway/security) -- 안전한 업데이트(doctor 실행): [업데이트](/ko/install/updating) +- 안전하게 업데이트(doctor 실행): [업데이트](/ko/install/updating) - 채널 구성: - Telegram: [Telegram](/ko/channels/telegram) - WhatsApp: [WhatsApp](/ko/channels/whatsapp) diff --git a/docs/ko/channels/slack.md b/docs/ko/channels/slack.md index dc032f0f9..5dd6f73ac 100644 --- a/docs/ko/channels/slack.md +++ b/docs/ko/channels/slack.md @@ -1,51 +1,51 @@ --- read_when: - Slack 설정 또는 Slack 소켓/HTTP 모드 디버깅 -summary: Slack 설정 및 런타임 동작(소켓 모드 + HTTP 요청 URL) +summary: Slack 설정 및 런타임 동작 (소켓 모드 + HTTP 요청 URL) title: Slack x-i18n: - generated_at: "2026-05-05T01:44:10Z" + generated_at: "2026-05-06T17:52:21Z" model: gpt-5.5 provider: openai - source_hash: 9a8e1cbfd3d99bfc24d79b56ee762d1ab399402391b241ff40698249b0828008 + source_hash: c3afcedca5004c18949206eee2b2620d07a02c76ef663bea80f29ec2591f737b source_path: channels/slack.md workflow: 16 --- -DM과 채널에서 Slack 앱 통합을 통해 프로덕션에 바로 사용할 수 있습니다. 기본 모드는 Socket Mode이며, HTTP 요청 URL도 지원됩니다. +DM 및 채널에서 Slack 앱 통합을 통해 프로덕션 준비 상태로 사용할 수 있습니다. 기본 모드는 Socket Mode이며 HTTP Request URLs도 지원됩니다. Slack DM은 기본적으로 페어링 모드를 사용합니다. - 네이티브 명령 동작과 명령 카탈로그입니다. + 네이티브 명령 동작 및 명령 카탈로그입니다. 채널 간 진단 및 복구 플레이북입니다. -## Socket Mode 또는 HTTP 요청 URL 선택 +## Socket Mode 또는 HTTP Request URLs 선택 -두 전송 방식 모두 프로덕션에 바로 사용할 수 있으며 메시징, 슬래시 명령, App Home, 상호작용 기능에서 기능 동등성을 갖습니다. 기능이 아니라 배포 형태에 따라 선택하세요. +두 전송 방식 모두 프로덕션 준비 상태이며 메시징, 슬래시 명령, App Home, 상호작용 기능에서 기능 동등성을 갖습니다. 기능이 아니라 배포 형태에 따라 선택하세요. -| 고려 사항 | Socket Mode(기본값) | HTTP 요청 URL | +| 고려 사항 | Socket Mode (기본값) | HTTP Request URLs | | ---------------------------- | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- | -| 공개 Gateway URL | 필요 없음 | 필요함(DNS, TLS, 리버스 프록시 또는 터널) | -| 아웃바운드 네트워크 | `wss-primary.slack.com`으로의 아웃바운드 WSS에 연결할 수 있어야 함 | 아웃바운드 WS 없음, 인바운드 HTTPS만 사용 | -| 필요한 토큰 | 봇 토큰(`xoxb-...`) + `connections:write`가 있는 앱 수준 토큰(`xapp-...`) | 봇 토큰(`xoxb-...`) + 서명 비밀 | -| 개발 노트북 / 방화벽 뒤 | 그대로 작동 | 공개 터널(ngrok, Cloudflare Tunnel, Tailscale Funnel) 또는 스테이징 Gateway 필요 | -| 수평 확장 | 호스트의 앱당 Socket Mode 세션 1개, 여러 Gateway에는 별도 Slack 앱 필요 | 상태 없는 POST 핸들러, 여러 Gateway 복제본이 로드 밸런서 뒤에서 하나의 앱 공유 가능 | -| 하나의 Gateway에서 다중 계정 | 지원됨, 각 계정이 자체 WS를 염 | 지원됨, 등록이 충돌하지 않도록 각 계정에 고유한 `webhookPath`(기본값 `/slack/events`) 필요 | -| 슬래시 명령 전송 | WS 연결을 통해 전달됨, `slash_commands[].url`은 무시됨 | Slack이 `slash_commands[].url`로 POST함, 명령을 디스패치하려면 필드가 필요함 | -| 요청 서명 | 사용하지 않음(인증은 앱 수준 토큰) | Slack이 모든 요청에 서명함, OpenClaw가 `signingSecret`으로 검증함 | -| 연결 끊김 시 복구 | Slack SDK가 자동 재연결함, Gateway의 pong-timeout 전송 튜닝 적용 | 끊길 지속 연결 없음, 재시도는 Slack의 요청별로 수행됨 | +| 공개 Gateway URL | 필요 없음 | 필요함(DNS, TLS, 리버스 프록시 또는 터널) | +| 아웃바운드 네트워크 | `wss-primary.slack.com`으로의 아웃바운드 WSS에 연결할 수 있어야 함 | 아웃바운드 WS 없음, 인바운드 HTTPS만 사용 | +| 필요한 토큰 | Bot 토큰(`xoxb-...`) + `connections:write`가 있는 App-Level Token(`xapp-...`) | Bot 토큰(`xoxb-...`) + Signing Secret | +| 개발 노트북 / 방화벽 뒤 | 그대로 작동 | 공개 터널(ngrok, Cloudflare Tunnel, Tailscale Funnel) 또는 스테이징 Gateway 필요 | +| 수평 확장 | 호스트별 앱당 Socket Mode 세션 하나, 여러 Gateway에는 별도 Slack 앱 필요 | 상태 없는 POST 핸들러, 여러 Gateway 복제본이 로드 밸런서 뒤에서 앱 하나를 공유할 수 있음 | +| Gateway 하나의 다중 계정 | 지원됨, 각 계정이 자체 WS를 엶 | 지원됨, 등록이 충돌하지 않도록 각 계정에 고유한 `webhookPath`(기본값 `/slack/events`) 필요 | +| 슬래시 명령 전송 | WS 연결을 통해 전달됨, `slash_commands[].url`은 무시됨 | Slack이 `slash_commands[].url`로 POST, 명령을 디스패치하려면 필드가 필요함 | +| 요청 서명 | 사용하지 않음(인증은 App-Level Token) | Slack이 모든 요청에 서명, OpenClaw가 `signingSecret`으로 검증 | +| 연결 끊김 복구 | Slack SDK가 자동 재연결, Gateway의 pong-timeout 전송 튜닝이 적용됨 | 끊길 지속 연결 없음, 재시도는 Slack의 요청별로 수행됨 | - 단일 Gateway 호스트, 개발 노트북, 그리고 `*.slack.com`으로의 아웃바운드는 가능하지만 인바운드 HTTPS를 받을 수 없는 온프레미스 네트워크에는 **Socket Mode를 선택**하세요. + **Socket Mode를 선택**하세요. 단일 Gateway 호스트, 개발 노트북, `*.slack.com`으로 아웃바운드 연결은 가능하지만 인바운드 HTTPS는 받을 수 없는 온프레미스 네트워크에 적합합니다. -로드 밸런서 뒤에서 여러 Gateway 복제본을 실행하거나, 아웃바운드 WSS가 차단되어 있지만 인바운드 HTTPS는 허용되거나, 이미 리버스 프록시에서 Slack Webhook을 종료하고 있다면 **HTTP 요청 URL을 선택**하세요. +**HTTP Request URLs를 선택**하세요. 로드 밸런서 뒤에서 여러 Gateway 복제본을 실행하거나, 아웃바운드 WSS는 차단되어 있지만 인바운드 HTTPS는 허용되거나, 이미 리버스 프록시에서 Slack Webhook을 종료하는 경우에 적합합니다. ## 빠른 설정 @@ -54,7 +54,7 @@ DM과 채널에서 Slack 앱 통합을 통해 프로덕션에 바로 사용할 - [api.slack.com/apps](https://api.slack.com/apps/new)를 열고 → **Create New App** → **From a manifest** → 워크스페이스 선택 → 아래 매니페스트 중 하나 붙여넣기 → **Next** → **Create**를 선택합니다. + [api.slack.com/apps](https://api.slack.com/apps/new)를 엽니다 → **Create New App** → **From a manifest** → 워크스페이스 선택 → 아래 매니페스트 중 하나 붙여넣기 → **Next** → **Create**. @@ -188,13 +188,13 @@ DM과 채널에서 Slack 앱 통합을 통해 프로덕션에 바로 사용할 - **Recommended**는 번들 Slack Plugin의 전체 기능 집합과 일치합니다: App Home, 슬래시 명령, 파일, 반응, 고정, 그룹 DM, 이모지/사용자 그룹 읽기. 워크스페이스 정책이 범위를 제한하는 경우 **Minimal**을 선택하세요. DM, 채널/그룹 기록, 멘션, 슬래시 명령은 포함하지만 파일, 반응, 고정, 그룹 DM(`mpim:*`), `emoji:read`, `usergroups:read`는 제외합니다. 범위별 근거와 추가 슬래시 명령 같은 추가 옵션은 [매니페스트 및 범위 체크리스트](#manifest-and-scope-checklist)를 참조하세요. + **권장**은 번들 Slack Plugin의 전체 기능 세트와 일치합니다: App Home, 슬래시 명령, 파일, 반응, 핀, 그룹 DM, 이모지/사용자 그룹 읽기. 워크스페이스 정책이 범위를 제한하는 경우 **최소**를 선택하세요. DM, 채널/그룹 기록, 멘션, 슬래시 명령은 포함하지만 파일, 반응, 핀, 그룹 DM(`mpim:*`), `emoji:read`, `usergroups:read`는 제외합니다. 범위별 근거와 추가 슬래시 명령 같은 추가 옵션은 [매니페스트 및 범위 체크리스트](#manifest-and-scope-checklist)를 참조하세요. - Slack이 앱을 생성한 후: + Slack이 앱을 만든 후: - - **Basic Information → App-Level Tokens → Generate Token and Scopes**: `connections:write`를 추가하고 저장한 뒤 `xapp-...` 값을 복사합니다. - - **Install App → Install to Workspace**: `xoxb-...` 봇 사용자 OAuth 토큰을 복사합니다. + - **Basic Information → App-Level Tokens → Generate Token and Scopes**: `connections:write`를 추가하고, 저장한 뒤 `xapp-...` 값을 복사합니다. + - **Install App → Install to Workspace**: `xoxb-...` Bot User OAuth Token을 복사합니다. @@ -244,7 +244,7 @@ openclaw gateway - [api.slack.com/apps](https://api.slack.com/apps/new)를 열고 → **Create New App** → **From a manifest** → 워크스페이스 선택 → 아래 매니페스트 중 하나 붙여넣기 → `https://gateway-host.example.com/slack/events`를 공개 Gateway URL로 바꾸기 → **Next** → **Create**를 선택합니다. + [api.slack.com/apps](https://api.slack.com/apps/new)를 엽니다 → **Create New App** → **From a manifest** → 워크스페이스 선택 → 아래 매니페스트 중 하나 붙여넣기 → `https://gateway-host.example.com/slack/events`를 공개 Gateway URL로 바꾸기 → **Next** → **Create**. @@ -327,7 +327,7 @@ openclaw gateway } ``` -```json Minimal +```json 최소 { "display_information": { "name": "OpenClaw", @@ -390,21 +390,21 @@ openclaw gateway - **권장**은 번들 Slack Plugin의 전체 기능 세트와 일치합니다. **최소**는 제한적인 워크스페이스를 위해 파일, 반응, 핀, 그룹 DM(`mpim:*`), `emoji:read`, `usergroups:read`를 제외합니다. 범위별 근거는 [매니페스트 및 범위 체크리스트](#manifest-and-scope-checklist)를 참조하세요. + **권장**은 번들 Slack Plugin의 전체 기능 세트와 일치합니다. **최소**는 제한적인 워크스페이스를 위해 파일, 반응, 핀, 그룹 DM(`mpim:*`), `emoji:read`, `usergroups:read`를 제외합니다. 범위별 근거는 [매니페스트 및 범위 체크리스트](#manifest-and-scope-checklist)를 참고하세요. - 세 URL 필드(`slash_commands[].url`, `event_subscriptions.request_url`, `interactivity.request_url` / `message_menu_options_url`)는 모두 동일한 OpenClaw 엔드포인트를 가리킵니다. Slack의 매니페스트 스키마는 이 필드들을 별도 이름으로 요구하지만, OpenClaw는 페이로드 유형별로 라우팅하므로 단일 `webhookPath`(기본값 `/slack/events`)로 충분합니다. `slash_commands[].url`이 없는 슬래시 명령은 HTTP 모드에서 조용히 아무 작업도 하지 않습니다. + 세 URL 필드(`slash_commands[].url`, `event_subscriptions.request_url`, `interactivity.request_url` / `message_menu_options_url`)는 모두 동일한 OpenClaw 엔드포인트를 가리킵니다. Slack의 매니페스트 스키마는 이를 별도 이름으로 요구하지만, OpenClaw는 페이로드 유형별로 라우팅하므로 단일 `webhookPath`(기본값 `/slack/events`)면 충분합니다. `slash_commands[].url`이 없는 슬래시 명령은 HTTP 모드에서 조용히 아무 작업도 하지 않습니다. Slack이 앱을 만든 후: - - **Basic Information → App Credentials**: 요청 검증에 사용할 **Signing Secret**을 복사합니다. - - **Install App → Install to Workspace**: `xoxb-...` Bot User OAuth Token을 복사합니다. + - **기본 정보 → 앱 자격 증명**: 요청 검증에 사용할 **Signing Secret**을 복사합니다. + - **앱 설치 → 워크스페이스에 설치**: `xoxb-...` Bot User OAuth Token을 복사합니다. - + 권장 SecretRef 설정: @@ -429,14 +429,14 @@ openclaw config patch --file ./slack.http.patch.json5 ``` - 다중 계정 HTTP에는 고유한 Webhook 경로 사용 + 다중 계정 HTTP에는 고유한 Webhook 경로를 사용하세요 - 등록이 충돌하지 않도록 각 계정에 서로 다른 `webhookPath`(기본값 `/slack/events`)를 지정하세요. + 각 계정에 서로 다른 `webhookPath`(기본값 `/slack/events`)를 지정하여 등록이 충돌하지 않도록 합니다. - + ```bash openclaw gateway @@ -448,9 +448,9 @@ openclaw gateway
-## Socket Mode 전송 조정 +## Socket Mode 전송 튜닝 -OpenClaw는 기본적으로 Socket Mode에서 Slack SDK 클라이언트 pong 제한 시간을 15초로 설정합니다. 워크스페이스 또는 호스트별 조정이 필요한 경우에만 전송 설정을 재정의하세요. +OpenClaw는 기본적으로 Socket Mode에서 Slack SDK 클라이언트 pong 제한 시간을 15초로 설정합니다. 워크스페이스 또는 호스트별 튜닝이 필요할 때만 전송 설정을 재정의하세요. ```json5 { @@ -467,7 +467,7 @@ OpenClaw는 기본적으로 Socket Mode에서 Slack SDK 클라이언트 pong 제 } ``` -Slack 웹소켓 pong/서버 ping 제한 시간을 기록하는 Socket Mode 워크스페이스이거나 이벤트 루프 고갈이 알려진 호스트에서 실행하는 경우에만 이 설정을 사용하세요. `clientPingTimeout`은 SDK가 클라이언트 ping을 보낸 뒤 pong을 기다리는 시간이고, `serverPingTimeout`은 Slack 서버 ping을 기다리는 시간입니다. 앱 메시지와 이벤트는 전송 활성 신호가 아니라 애플리케이션 상태로 유지됩니다. +Slack 웹소켓 pong/server-ping 제한 시간이 로그에 남거나 이벤트 루프 고갈이 알려진 호스트에서 실행되는 Socket Mode 워크스페이스에만 이것을 사용하세요. `clientPingTimeout`은 SDK가 클라이언트 ping을 보낸 뒤 pong을 기다리는 시간이고, `serverPingTimeout`은 Slack 서버 ping을 기다리는 시간입니다. 앱 메시지와 이벤트는 전송 생존 신호가 아니라 애플리케이션 상태로 유지됩니다. ## 매니페스트 및 범위 체크리스트 @@ -548,7 +548,7 @@ Slack 웹소켓 pong/서버 ping 제한 시간을 기록하는 Socket Mode 워 } ``` -**HTTP Request URLs 모드**의 경우 `settings`를 HTTP 변형으로 교체하고 각 슬래시 명령에 `url`을 추가하세요. 공개 URL이 필요합니다. +**HTTP Request URLs 모드**에서는 `settings`를 HTTP 변형으로 바꾸고 각 슬래시 명령에 `url`을 추가합니다. 공개 URL이 필요합니다. ```json { @@ -592,22 +592,22 @@ Slack 웹소켓 pong/서버 ping 제한 시간을 기록하는 Socket Mode 워 ### 추가 매니페스트 설정 -위 기본값을 확장하는 다양한 기능을 노출합니다. +위 기본값을 확장하는 다른 기능을 표시합니다. -기본 매니페스트는 Slack App Home **Home** 탭을 활성화하고 `app_home_opened`를 구독합니다. 워크스페이스 멤버가 Home 탭을 열면 OpenClaw는 `views.publish`를 사용해 안전한 기본 Home 보기를 게시합니다. 대화 페이로드나 비공개 구성은 포함되지 않습니다. **Messages** 탭은 Slack DM용으로 계속 활성화됩니다. +기본 매니페스트는 Slack App Home **Home** 탭을 활성화하고 `app_home_opened`를 구독합니다. 워크스페이스 구성원이 Home 탭을 열면 OpenClaw는 `views.publish`로 안전한 기본 Home 보기를 게시합니다. 대화 페이로드나 비공개 구성은 포함되지 않습니다. **Messages** 탭은 Slack DM에 대해 계속 활성화됩니다. - + - 여러 [네이티브 슬래시 명령](#commands-and-slash-behavior)을 미묘한 차이가 있는 단일 구성 명령 대신 사용할 수 있습니다. + 단일 구성 명령 대신 여러 [네이티브 슬래시 명령](#commands-and-slash-behavior)을 세부적으로 사용할 수 있습니다. - `/status` 명령은 예약되어 있으므로 `/status` 대신 `/agentstatus`를 사용하세요. - - 한 번에 25개를 초과하는 슬래시 명령을 사용할 수 없습니다. + - 한 번에 25개를 초과하는 슬래시 명령을 사용할 수는 없습니다. - 기존 `features.slash_commands` 섹션을 [사용 가능한 명령](/ko/tools/slash-commands#command-list)의 하위 집합으로 교체하세요. + 기존 `features.slash_commands` 섹션을 [사용 가능한 명령](/ko/tools/slash-commands#command-list)의 하위 집합으로 바꾸세요. - + ```json { @@ -731,7 +731,7 @@ Slack 웹소켓 pong/서버 ping 제한 시간을 기록하는 Socket Mode 워 - 위 Socket Mode와 동일한 `slash_commands` 목록을 사용하고 모든 항목에 `"url": "https://gateway-host.example.com/slack/events"`를 추가하세요. 예: + 위 Socket Mode와 동일한 `slash_commands` 목록을 사용하고, 모든 항목에 `"url": "https://gateway-host.example.com/slack/events"`를 추가하세요. 예: ```json { @@ -758,7 +758,7 @@ Slack 웹소켓 pong/서버 ping 제한 시간을 기록하는 Socket Mode 워 - 발신 메시지가 기본 Slack 앱 ID 대신 활성 에이전트 ID(사용자 지정 사용자 이름 및 아이콘)를 사용하도록 하려면 `chat:write.customize` 봇 범위를 추가하세요. + 발신 메시지에 기본 Slack 앱 ID 대신 활성 에이전트 ID(사용자 지정 사용자 이름 및 아이콘)를 사용하려면 `chat:write.customize` 봇 범위를 추가하세요. 이모지 아이콘을 사용하는 경우 Slack은 `:emoji_name:` 구문을 요구합니다. @@ -781,42 +781,37 @@ Slack 웹소켓 pong/서버 ping 제한 시간을 기록하는 Socket Mode 워 - Socket Mode에는 `botToken` + `appToken`이 필요합니다. - HTTP 모드에는 `botToken` + `signingSecret`이 필요합니다. -- `botToken`, `appToken`, `signingSecret`, `userToken`은 일반 텍스트 - 문자열 또는 SecretRef 객체를 허용합니다. -- 구성 토큰은 env fallback보다 우선합니다. -- `SLACK_BOT_TOKEN` / `SLACK_APP_TOKEN` env fallback은 기본 계정에만 적용됩니다. -- `userToken`(`xoxp-...`)은 구성 전용(env fallback 없음)이며 기본적으로 읽기 전용 동작(`userTokenReadOnly: true`)을 사용합니다. +- `botToken`, `appToken`, `signingSecret`, `userToken`은 일반 텍스트 문자열 또는 SecretRef 객체를 허용합니다. +- 구성 토큰은 env 폴백을 재정의합니다. +- `SLACK_BOT_TOKEN` / `SLACK_APP_TOKEN` env 폴백은 기본 계정에만 적용됩니다. +- `userToken`(`xoxp-...`)은 구성 전용(env 폴백 없음)이며 기본값은 읽기 전용 동작(`userTokenReadOnly: true`)입니다. 상태 스냅샷 동작: -- Slack 계정 검사는 자격 증명별 `*Source` 및 `*Status` - 필드(`botToken`, `appToken`, `signingSecret`, `userToken`)를 추적합니다. -- 상태는 `available`, `configured_unavailable`, 또는 `missing`입니다. -- `configured_unavailable`은 계정이 SecretRef - 또는 다른 비인라인 비밀 소스를 통해 구성되었지만, 현재 명령/런타임 경로에서 - 실제 값을 확인할 수 없었음을 의미합니다. -- HTTP 모드에서는 `signingSecretStatus`가 포함됩니다. Socket Mode에서는 - 필요한 쌍이 `botTokenStatus` + `appTokenStatus`입니다. +- Slack 계정 검사는 자격 증명별 `*Source` 및 `*Status` 필드(`botToken`, `appToken`, `signingSecret`, `userToken`)를 추적합니다. +- 상태는 `available`, `configured_unavailable` 또는 `missing`입니다. +- `configured_unavailable`은 계정이 SecretRef 또는 다른 비인라인 비밀 소스를 통해 구성되었지만 현재 명령/런타임 경로가 실제 값을 해석할 수 없었음을 의미합니다. +- HTTP 모드에서는 `signingSecretStatus`가 포함됩니다. Socket Mode에서는 필요한 쌍이 `botTokenStatus` + `appTokenStatus`입니다. -작업/디렉터리 읽기의 경우 사용자 토큰이 구성되어 있으면 우선될 수 있습니다. 쓰기의 경우 봇 토큰이 계속 우선됩니다. 사용자 토큰 쓰기는 `userTokenReadOnly: false`이고 봇 토큰을 사용할 수 없을 때만 허용됩니다. +작업/디렉터리 읽기의 경우 사용자 토큰이 구성되어 있으면 선호될 수 있습니다. 쓰기의 경우 봇 토큰이 계속 선호됩니다. 사용자 토큰 쓰기는 `userTokenReadOnly: false`이고 봇 토큰을 사용할 수 없을 때만 허용됩니다. ## 작업 및 게이트 Slack 작업은 `channels.slack.actions.*`로 제어됩니다. -현재 Slack 도구에서 사용할 수 있는 작업 그룹은 다음과 같습니다. +현재 Slack 도구에서 사용할 수 있는 작업 그룹: | 그룹 | 기본값 | | ---------- | ------- | -| messages | 활성화됨 | -| reactions | 활성화됨 | -| pins | 활성화됨 | -| memberInfo | 활성화됨 | -| emojiList | 활성화됨 | +| messages | enabled | +| reactions | enabled | +| pins | enabled | +| memberInfo | enabled | +| emojiList | enabled | -현재 Slack 메시지 작업에는 `send`, `upload-file`, `download-file`, `read`, `edit`, `delete`, `pin`, `unpin`, `list-pins`, `member-info`, `emoji-list`가 포함됩니다. `download-file`은 인바운드 파일 플레이스홀더에 표시된 Slack 파일 ID를 허용하며, 이미지의 경우 이미지 미리 보기를, 다른 파일 유형의 경우 로컬 파일 메타데이터를 반환합니다. +현재 Slack 메시지 작업에는 `send`, `upload-file`, `download-file`, `read`, `edit`, `delete`, `pin`, `unpin`, `list-pins`, `member-info`, `emoji-list`가 포함됩니다. `download-file`은 인바운드 파일 플레이스홀더에 표시된 Slack 파일 ID를 허용하며, 이미지의 경우 이미지 미리보기를, 다른 파일 유형의 경우 로컬 파일 메타데이터를 반환합니다. ## 액세스 제어 및 라우팅 @@ -840,12 +835,12 @@ Slack 작업은 `channels.slack.actions.*`로 제어됩니다. 다중 계정 우선순위: - `channels.slack.accounts.default.allowFrom`은 `default` 계정에만 적용됩니다. - - 명명된 계정은 자체 `allowFrom`이 설정되지 않은 경우 `channels.slack.allowFrom`을 상속합니다. - - 명명된 계정은 `channels.slack.accounts.default.allowFrom`을 상속하지 않습니다. + - 이름이 지정된 계정은 자체 `allowFrom`이 설정되지 않은 경우 `channels.slack.allowFrom`을 상속합니다. + - 이름이 지정된 계정은 `channels.slack.accounts.default.allowFrom`을 상속하지 않습니다. - 레거시 `channels.slack.dm.policy` 및 `channels.slack.dm.allowFrom`은 호환성을 위해 계속 읽습니다. `openclaw doctor --fix`는 액세스를 변경하지 않고 가능할 때 이를 `dmPolicy` 및 `allowFrom`으로 마이그레이션합니다. + 레거시 `channels.slack.dm.policy` 및 `channels.slack.dm.allowFrom`은 호환성을 위해 계속 읽힙니다. `openclaw doctor --fix`는 액세스를 변경하지 않고 가능할 때 이를 `dmPolicy` 및 `allowFrom`으로 마이그레이션합니다. - DM에서의 페어링은 `openclaw pairing approve slack `를 사용합니다. + DM에서 페어링은 `openclaw pairing approve slack `를 사용합니다. @@ -858,16 +853,16 @@ Slack 작업은 `channels.slack.actions.*`로 제어됩니다. 채널 허용 목록은 `channels.slack.channels` 아래에 있으며 구성 키로 **안정적인 Slack 채널 ID**(예: `C12345678`)를 사용해야 합니다. - 런타임 참고: `channels.slack`이 완전히 누락된 경우(env 전용 설정), 런타임은 `groupPolicy="allowlist"`로 fallback하고 경고를 기록합니다(`channels.defaults.groupPolicy`가 설정된 경우에도 해당). + 런타임 참고: `channels.slack`이 완전히 없는 경우(env 전용 설정), 런타임은 `groupPolicy="allowlist"`로 폴백하고 경고를 기록합니다(`channels.defaults.groupPolicy`가 설정되어 있더라도). - 이름/ID 확인: + 이름/ID 해석: - - 토큰 액세스가 허용하는 경우 채널 허용 목록 항목과 DM 허용 목록 항목은 시작 시 확인됩니다 - - 확인되지 않은 채널 이름 항목은 구성된 상태로 유지되지만 기본적으로 라우팅에서는 무시됩니다 - - 인바운드 권한 부여와 채널 라우팅은 기본적으로 ID 우선입니다. 직접 사용자 이름/슬러그 매칭에는 `channels.slack.dangerouslyAllowNameMatching: true`가 필요합니다 + - 채널 허용 목록 항목 및 DM 허용 목록 항목은 토큰 액세스가 허용하는 경우 시작 시 해석됩니다. + - 해석되지 않은 채널 이름 항목은 구성된 상태로 유지되지만 기본적으로 라우팅에서는 무시됩니다. + - 인바운드 권한 부여 및 채널 라우팅은 기본적으로 ID 우선입니다. 직접 사용자 이름/슬러그 매칭에는 `channels.slack.dangerouslyAllowNameMatching: true`가 필요합니다. - 이름 기반 키(`#channel-name` 또는 `channel-name`)는 `groupPolicy: "allowlist"`에서 일치하지 않습니다. 채널 조회는 기본적으로 ID 우선이므로 이름 기반 키는 절대 성공적으로 라우팅되지 않으며 해당 채널의 모든 메시지는 조용히 차단됩니다. 이는 채널 키가 라우팅에 필요하지 않아 이름 기반 키가 작동하는 것처럼 보이는 `groupPolicy: "open"`과 다릅니다. + 이름 기반 키(`#channel-name` 또는 `channel-name`)는 `groupPolicy: "allowlist"`에서 일치하지 않습니다. 채널 조회는 기본적으로 ID 우선이므로 이름 기반 키는 절대 성공적으로 라우팅되지 않으며 해당 채널의 모든 메시지가 조용히 차단됩니다. 이는 `groupPolicy: "open"`과 다릅니다. 이 경우 채널 키가 라우팅에 필요하지 않아 이름 기반 키가 동작하는 것처럼 보입니다. 항상 Slack 채널 ID를 키로 사용하세요. 찾는 방법: Slack에서 채널을 마우스 오른쪽 버튼으로 클릭 → **링크 복사** — ID(`C...`)가 URL 끝에 표시됩니다. @@ -886,7 +881,7 @@ Slack 작업은 `channels.slack.actions.*`로 제어됩니다. } ``` - 올바르지 않음(`groupPolicy: "allowlist"`에서 조용히 차단됨): + 잘못된 예(`groupPolicy: "allowlist"`에서 조용히 차단됨): ```json5 { @@ -905,16 +900,16 @@ Slack 작업은 `channels.slack.actions.*`로 제어됩니다. - 채널 메시지는 기본적으로 멘션으로 제어됩니다. + 채널 메시지는 기본적으로 멘션 게이트가 적용됩니다. 멘션 소스: - 명시적 앱 멘션(`<@botId>`) - - 봇 사용자가 해당 사용자 그룹의 구성원일 때의 Slack 사용자 그룹 멘션(``); `usergroups:read` 필요 - - 멘션 정규식 패턴(`agents.list[].groupChat.mentionPatterns`, 대체값 `messages.groupChat.mentionPatterns`) - - 암시적 봇 답글 스레드 동작(`thread.requireExplicitMention`이 `true`일 때 비활성화됨) + - Slack 사용자 그룹 멘션(``): 봇 사용자가 해당 사용자 그룹의 멤버인 경우, `usergroups:read` 필요 + - 멘션 정규식 패턴(`agents.list[].groupChat.mentionPatterns`, 폴백 `messages.groupChat.mentionPatterns`) + - 암시적 봇에게 답장한 스레드 동작(`thread.requireExplicitMention`이 `true`일 때 비활성화됨) - 채널별 제어(`channels.slack.channels.`; 이름은 시작 시 확인 또는 `dangerouslyAllowNameMatching`을 통해서만): + 채널별 제어(`channels.slack.channels.`; 이름은 시작 시 해석 또는 `dangerouslyAllowNameMatching`을 통해서만 가능): - `requireMention` - `users`(허용 목록) @@ -922,68 +917,68 @@ Slack 작업은 `channels.slack.actions.*`로 제어됩니다. - `skills` - `systemPrompt` - `tools`, `toolsBySender` - - `toolsBySender` 키 형식: `id:`, `e164:`, `username:`, `name:`, 또는 `"*"` 와일드카드 + - `toolsBySender` 키 형식: `id:`, `e164:`, `username:`, `name:` 또는 `"*"` 와일드카드 (레거시 접두사 없는 키는 여전히 `id:`에만 매핑됨) - `allowBots`는 채널 및 비공개 채널에 대해 보수적으로 동작합니다. 봇이 작성한 방 메시지는 보내는 봇이 해당 방의 `users` 허용 목록에 명시적으로 나열되어 있거나, `channels.slack.allowFrom`의 명시적 Slack 소유자 ID가 하나 이상 현재 방 구성원일 때만 허용됩니다. 와일드카드와 표시 이름 소유자 항목은 소유자 존재 조건을 충족하지 않습니다. 소유자 존재 여부는 Slack `conversations.members`를 사용합니다. 앱에 방 유형에 맞는 읽기 범위(공개 채널은 `channels:read`, 비공개 채널은 `groups:read`)가 있는지 확인하세요. 구성원 조회에 실패하면 OpenClaw는 봇이 작성한 방 메시지를 삭제합니다. + `allowBots`는 채널 및 비공개 채널에 대해 보수적으로 동작합니다. 봇이 작성한 방 메시지는 보내는 봇이 해당 방의 `users` 허용 목록에 명시적으로 나열되어 있거나, `channels.slack.allowFrom`의 명시적 Slack 소유자 ID 중 하나 이상이 현재 방 멤버일 때만 허용됩니다. 와일드카드 및 표시 이름 소유자 항목은 소유자 존재 조건을 충족하지 않습니다. 소유자 존재 여부는 Slack `conversations.members`를 사용합니다. 앱에 방 유형에 맞는 읽기 범위(공개 채널의 경우 `channels:read`, 비공개 채널의 경우 `groups:read`)가 있는지 확인하세요. 멤버 조회가 실패하면 OpenClaw는 봇이 작성한 방 메시지를 삭제합니다. -## 스레딩, 세션 및 답글 태그 +## 스레딩, 세션 및 답장 태그 - DM은 `direct`로, 채널은 `channel`로, MPIM은 `group`으로 라우팅됩니다. - Slack 라우트 바인딩은 원시 피어 ID와 `channel:C12345678`, `user:U12345678`, `<@U12345678>` 같은 Slack 대상 형식을 허용합니다. - 기본 `session.dmScope=main`에서는 Slack DM이 에이전트 기본 세션으로 합쳐집니다. - 채널 세션: `agent::slack:channel:`. -- 스레드 답글은 해당되는 경우 스레드 세션 접미사(`:thread:`)를 만들 수 있습니다. -- `channels.slack.thread.historyScope` 기본값은 `thread`입니다. `thread.inheritParent` 기본값은 `false`입니다. -- `channels.slack.thread.initialHistoryLimit`은 새 스레드 세션이 시작될 때 가져올 기존 스레드 메시지 수를 제어합니다(기본값 `20`; 비활성화하려면 `0` 설정). -- `channels.slack.thread.requireExplicitMention`(기본값 `false`): `true`이면 암시적 스레드 멘션을 억제하여, 봇이 이미 해당 스레드에 참여했더라도 스레드 안에서 명시적 `@bot` 멘션에만 응답하게 합니다. 이 설정이 없으면 봇이 참여한 스레드의 답글은 `requireMention` 게이트를 우회합니다. +- 스레드 답장은 적용 가능한 경우 스레드 세션 접미사(`:thread:`)를 만들 수 있습니다. +- `channels.slack.thread.historyScope` 기본값은 `thread`이고, `thread.inheritParent` 기본값은 `false`입니다. +- `channels.slack.thread.initialHistoryLimit`은 새 스레드 세션이 시작될 때 가져올 기존 스레드 메시지 수를 제어합니다(기본값 `20`; 비활성화하려면 `0`으로 설정). +- `channels.slack.thread.requireExplicitMention`(기본값 `false`): `true`이면 암시적 스레드 멘션을 억제하여, 봇이 이미 스레드에 참여했더라도 스레드 안의 명시적 `@bot` 멘션에만 응답합니다. 이 설정이 없으면 봇이 참여한 스레드의 답장은 `requireMention` 게이트를 우회합니다. -답글 스레딩 제어: +답장 스레딩 제어: - `channels.slack.replyToMode`: `off|first|all|batched`(기본값 `off`) - `channels.slack.replyToModeByChatType`: `direct|group|channel`별 설정 -- 직접 채팅용 레거시 대체값: `channels.slack.dm.replyToMode` +- 직접 채팅용 레거시 폴백: `channels.slack.dm.replyToMode` -수동 답글 태그가 지원됩니다. +수동 답장 태그가 지원됩니다. - `[[reply_to_current]]` - `[[reply_to:]]` -`replyToMode="off"`는 명시적 `[[reply_to_*]]` 태그를 포함하여 Slack의 **모든** 답글 스레딩을 비활성화합니다. 이는 `"off"` 모드에서도 명시적 태그가 계속 적용되는 Telegram과 다릅니다. Slack 스레드는 채널에서 메시지를 숨기지만, Telegram 답글은 인라인으로 계속 표시됩니다. +`replyToMode="off"`는 명시적 `[[reply_to_*]]` 태그를 포함하여 Slack의 **모든** 답장 스레딩을 비활성화합니다. 이는 `"off"` 모드에서도 명시적 태그를 계속 준수하는 Telegram과 다릅니다. Slack 스레드는 메시지를 채널에서 숨기지만, Telegram 답장은 인라인으로 계속 표시됩니다. ## 확인 반응 `ackReaction`은 OpenClaw가 인바운드 메시지를 처리하는 동안 확인 이모지를 보냅니다. -해결 순서: +해석 순서: - `channels.slack.accounts..ackReaction` - `channels.slack.ackReaction` - `messages.ackReaction` -- 에이전트 ID 이모지 대체값(`agents.list[].identity.emoji`, 없으면 "👀") +- 에이전트 ID 이모지 폴백(`agents.list[].identity.emoji`, 없으면 "👀") 참고: -- Slack은 쇼트코드(예: `"eyes"`)를 기대합니다. -- Slack 계정 또는 전역으로 반응을 비활성화하려면 `""`를 사용하세요. +- Slack은 쇼트코드(예: `"eyes"`)를 요구합니다. +- Slack 계정 또는 전역에서 반응을 비활성화하려면 `""`를 사용하세요. ## 텍스트 스트리밍 `channels.slack.streaming`은 실시간 미리보기 동작을 제어합니다. - `off`: 실시간 미리보기 스트리밍을 비활성화합니다. -- `partial`(기본값): 미리보기 텍스트를 최신 부분 출력으로 교체합니다. -- `block`: 청크 단위 미리보기 업데이트를 추가합니다. -- `progress`: 생성 중에는 진행 상태 텍스트를 표시한 뒤 최종 텍스트를 보냅니다. -- `streaming.preview.toolProgress`: 초안 미리보기가 활성 상태일 때 도구/진행 업데이트를 동일하게 편집되는 미리보기 메시지로 라우팅합니다(기본값: `true`). 별도의 도구/진행 메시지를 유지하려면 `false`로 설정하세요. -- `streaming.preview.commandText` / `streaming.progress.commandText`: 원시 명령/실행 텍스트를 숨기면서 간결한 도구 진행 줄을 유지하려면 `status`로 설정합니다(기본값: `raw`). +- `partial`(기본값): 미리보기 텍스트를 최신 부분 출력으로 바꿉니다. +- `block`: 청크 단위 미리보기 업데이트를 덧붙입니다. +- `progress`: 생성 중 진행 상태 텍스트를 표시한 다음 최종 텍스트를 보냅니다. +- `streaming.preview.toolProgress`: 초안 미리보기가 활성 상태일 때 도구/진행 업데이트를 같은 편집된 미리보기 메시지로 라우팅합니다(기본값: `true`). 별도의 도구/진행 메시지를 유지하려면 `false`로 설정하세요. +- `streaming.preview.commandText` / `streaming.progress.commandText`: 원시 명령/exec 텍스트를 숨기면서 간결한 도구 진행 줄은 유지하려면 `status`로 설정합니다(기본값: `raw`). -간결한 진행 줄은 유지하면서 원시 명령/실행 텍스트 숨기기: +간결한 진행 줄은 유지하면서 원시 명령/exec 텍스트 숨기기: ```json { @@ -1003,12 +998,12 @@ Slack 작업은 `channels.slack.actions.*`로 제어됩니다. `channels.slack.streaming.nativeTransport`는 `channels.slack.streaming.mode`가 `partial`일 때 Slack 네이티브 텍스트 스트리밍을 제어합니다(기본값: `true`). -- 네이티브 텍스트 스트리밍 및 Slack 어시스턴트 스레드 상태가 표시되려면 답글 스레드를 사용할 수 있어야 합니다. 스레드 선택은 여전히 `replyToMode`를 따릅니다. -- 네이티브 스트리밍을 사용할 수 없거나 답글 스레드가 없는 경우에도 채널, 그룹 채팅 및 최상위 DM 루트는 일반 초안 미리보기를 계속 사용할 수 있습니다. -- 최상위 Slack DM은 기본적으로 스레드 밖에 유지되므로 Slack의 스레드 스타일 네이티브 스트림/상태 미리보기를 표시하지 않습니다. 대신 OpenClaw가 DM에 초안 미리보기를 게시하고 편집합니다. -- 미디어 및 텍스트가 아닌 페이로드는 일반 전달로 대체됩니다. -- 미디어/오류 최종 결과는 보류 중인 미리보기 편집을 취소합니다. 적격 텍스트/블록 최종 결과는 미리보기를 제자리에서 편집할 수 있을 때만 플러시됩니다. -- 스트리밍이 답글 도중 실패하면 OpenClaw는 남은 페이로드에 대해 일반 전달로 대체합니다. +- 네이티브 텍스트 스트리밍과 Slack 어시스턴트 스레드 상태가 표시되려면 답장 스레드가 있어야 합니다. 스레드 선택은 계속 `replyToMode`를 따릅니다. +- 채널, 그룹 채팅 및 최상위 DM 루트는 네이티브 스트리밍을 사용할 수 없거나 답장 스레드가 없을 때도 일반 초안 미리보기를 사용할 수 있습니다. +- 최상위 Slack DM은 기본적으로 스레드 밖에 유지되므로 Slack의 스레드 스타일 네이티브 스트림/상태 미리보기를 표시하지 않습니다. 대신 OpenClaw는 DM에 초안 미리보기를 게시하고 편집합니다. +- 미디어 및 텍스트가 아닌 페이로드는 일반 전달로 폴백합니다. +- 미디어/오류 최종 응답은 대기 중인 미리보기 편집을 취소합니다. 적격 텍스트/블록 최종 응답은 미리보기를 제자리에서 편집할 수 있을 때만 플러시됩니다. +- 스트리밍이 답장 중간에 실패하면 OpenClaw는 남은 페이로드를 일반 전달로 폴백합니다. Slack 네이티브 텍스트 스트리밍 대신 초안 미리보기 사용: @@ -1027,13 +1022,14 @@ Slack 네이티브 텍스트 스트리밍 대신 초안 미리보기 사용: 레거시 키: -- `channels.slack.streamMode`(`replace | status_final | append`)는 `channels.slack.streaming.mode`로 자동 마이그레이션됩니다. -- 불리언 `channels.slack.streaming`은 `channels.slack.streaming.mode` 및 `channels.slack.streaming.nativeTransport`로 자동 마이그레이션됩니다. -- 레거시 `channels.slack.nativeStreaming`은 `channels.slack.streaming.nativeTransport`로 자동 마이그레이션됩니다. +- `channels.slack.streamMode`(`replace | status_final | append`)는 `channels.slack.streaming.mode`의 레거시 런타임 별칭입니다. +- boolean `channels.slack.streaming`은 `channels.slack.streaming.mode` 및 `channels.slack.streaming.nativeTransport`의 레거시 런타임 별칭입니다. +- 레거시 `channels.slack.nativeStreaming`은 `channels.slack.streaming.nativeTransport`의 런타임 별칭입니다. +- 지속 저장된 Slack 스트리밍 구성을 표준 키로 다시 쓰려면 `openclaw doctor --fix`를 실행하세요. -## 입력 중 반응 대체값 +## 입력 중 반응 대체 동작 -`typingReaction`은 OpenClaw가 답변을 처리하는 동안 인바운드 Slack 메시지에 임시 리액션을 추가한 다음, 실행이 끝나면 이를 제거합니다. 이는 기본 "입력 중..." 상태 표시기를 사용하는 스레드 답글 외부에서 가장 유용합니다. +`typingReaction`은 OpenClaw가 답장을 처리하는 동안 인바운드 Slack 메시지에 임시 반응을 추가한 뒤, 실행이 끝나면 제거합니다. 이는 기본 "입력 중..." 상태 표시기를 사용하는 스레드 답장 외부에서 가장 유용합니다. 해결 순서: @@ -1042,43 +1038,43 @@ Slack 네이티브 텍스트 스트리밍 대신 초안 미리보기 사용: 참고: -- Slack은 쇼트코드를 기대합니다(예: `"hourglass_flowing_sand"`). -- 리액션은 최선 노력 방식이며, 답변 또는 실패 경로가 완료된 후 정리가 자동으로 시도됩니다. +- Slack은 숏코드를 기대합니다(예: `"hourglass_flowing_sand"`). +- 반응은 최선형 방식이며, 답장 또는 실패 경로가 완료된 뒤 정리가 자동으로 시도됩니다. -## 미디어, 청킹 및 전달 +## 미디어, 청킹, 전달 - - Slack 파일 첨부는 Slack이 호스팅하는 비공개 URL(토큰 인증 요청 흐름)에서 다운로드되며, 가져오기에 성공하고 크기 제한이 허용하면 미디어 저장소에 기록됩니다. 파일 자리표시자는 Slack `fileId`를 포함하므로 에이전트가 `download-file`로 원본 파일을 가져올 수 있습니다. + + Slack 파일 첨부는 Slack이 호스팅하는 비공개 URL(토큰 인증 요청 흐름)에서 다운로드되며, 가져오기에 성공하고 크기 제한이 허용되면 미디어 저장소에 기록됩니다. 파일 자리 표시자에는 Slack `fileId`가 포함되어 에이전트가 `download-file`로 원본 파일을 가져올 수 있습니다. - 다운로드에는 제한된 유휴 및 전체 타임아웃이 사용됩니다. Slack 파일 가져오기가 멈추거나 실패하면 OpenClaw는 메시지 처리를 계속하고 파일 자리표시자로 대체합니다. + 다운로드에는 제한된 유휴 시간 제한과 전체 시간 제한이 사용됩니다. Slack 파일 검색이 멈추거나 실패하면 OpenClaw는 메시지 처리를 계속하고 파일 자리 표시자로 대체합니다. 런타임 인바운드 크기 상한은 `channels.slack.mediaMaxMb`로 재정의하지 않는 한 기본값이 `20MB`입니다. - - - 텍스트 청크는 `channels.slack.textChunkLimit`를 사용합니다(기본값 4000) - - `channels.slack.chunkMode="newline"`은 단락 우선 분할을 활성화합니다 - - 파일 전송은 Slack 업로드 API를 사용하며 스레드 답글(`thread_ts`)을 포함할 수 있습니다 - - 아웃바운드 미디어 상한은 구성된 경우 `channels.slack.mediaMaxMb`를 따르고, 그렇지 않으면 채널 전송은 미디어 파이프라인의 MIME 종류 기본값을 사용합니다 + + - 텍스트 청크는 `channels.slack.textChunkLimit`(기본값 4000)을 사용합니다 + - `channels.slack.chunkMode="newline"`은 문단 우선 분할을 활성화합니다 + - 파일 전송은 Slack 업로드 API를 사용하며 스레드 답장(`thread_ts`)을 포함할 수 있습니다 + - 아웃바운드 미디어 상한은 구성된 경우 `channels.slack.mediaMaxMb`를 따르며, 그렇지 않으면 채널 전송은 미디어 파이프라인의 MIME 종류 기본값을 사용합니다 - + 선호되는 명시적 대상: - DM에는 `user:` - 채널에는 `channel:` - 텍스트/블록 전용 Slack DM은 사용자 ID에 직접 게시할 수 있습니다. 파일 업로드와 스레드 전송은 해당 경로에 구체적인 대화 ID가 필요하므로 먼저 Slack 대화 API를 통해 DM을 엽니다. + 텍스트/블록 전용 Slack DM은 사용자 ID로 직접 게시할 수 있습니다. 파일 업로드와 스레드 전송은 구체적인 대화 ID가 필요하므로 먼저 Slack 대화 API를 통해 DM을 엽니다. -## 명령 및 슬래시 동작 +## 명령과 슬래시 동작 -슬래시 명령은 Slack에서 단일 구성 명령 또는 여러 네이티브 명령으로 표시됩니다. 명령 기본값을 변경하려면 `channels.slack.slashCommand`를 구성하세요. +슬래시 명령은 Slack에서 구성된 단일 명령 또는 여러 네이티브 명령으로 표시됩니다. 명령 기본값을 변경하려면 `channels.slack.slashCommand`를 구성하세요. - `enabled: false` - `name: "openclaw"` @@ -1089,7 +1085,7 @@ Slack 네이티브 텍스트 스트리밍 대신 초안 미리보기 사용: /openclaw /help ``` -네이티브 명령은 Slack 앱에서 [추가 매니페스트 설정](#additional-manifest-settings)이 필요하며, 대신 전역 구성에서 `channels.slack.commands.native: true` 또는 `commands.native: true`로 활성화됩니다. +네이티브 명령은 Slack 앱에 [추가 매니페스트 설정](#additional-manifest-settings)이 필요하며, 대신 전역 구성에서 `channels.slack.commands.native: true` 또는 `commands.native: true`로 활성화됩니다. - Slack에서는 네이티브 명령 자동 모드가 **꺼져** 있으므로 `commands.native: "auto"`는 Slack 네이티브 명령을 활성화하지 않습니다. @@ -1099,9 +1095,9 @@ Slack 네이티브 텍스트 스트리밍 대신 초안 미리보기 사용: 네이티브 인수 메뉴는 선택한 옵션 값을 디스패치하기 전에 확인 모달을 표시하는 적응형 렌더링 전략을 사용합니다. -- 최대 5개 옵션: 버튼 블록 -- 6-100개 옵션: 정적 선택 메뉴 -- 100개 초과 옵션: 상호작용 옵션 핸들러를 사용할 수 있을 때 비동기 옵션 필터링이 포함된 외부 선택 +- 옵션 최대 5개: 버튼 블록 +- 옵션 6-100개: 정적 선택 메뉴 +- 옵션 100개 초과: 상호작용 옵션 핸들러를 사용할 수 있을 때 비동기 옵션 필터링이 포함된 외부 선택 - Slack 제한 초과: 인코딩된 옵션 값은 버튼으로 대체됩니다 ```txt @@ -1110,9 +1106,9 @@ Slack 네이티브 텍스트 스트리밍 대신 초안 미리보기 사용: 슬래시 세션은 `agent::slack:slash:` 같은 격리된 키를 사용하며, 여전히 `CommandTargetSessionKey`를 사용해 명령 실행을 대상 대화 세션으로 라우팅합니다. -## 대화형 답글 +## 대화형 답장 -Slack은 에이전트가 작성한 대화형 답글 컨트롤을 렌더링할 수 있지만, 이 기능은 기본적으로 비활성화되어 있습니다. +Slack은 에이전트가 작성한 대화형 답장 컨트롤을 렌더링할 수 있지만, 이 기능은 기본적으로 비활성화되어 있습니다. 전역으로 활성화: @@ -1128,7 +1124,7 @@ Slack은 에이전트가 작성한 대화형 답글 컨트롤을 렌더링할 } ``` -또는 Slack 계정 하나에만 활성화: +또는 하나의 Slack 계정에만 활성화: ```json5 { @@ -1146,43 +1142,44 @@ Slack은 에이전트가 작성한 대화형 답글 컨트롤을 렌더링할 } ``` -활성화되면 에이전트가 Slack 전용 답글 지시문을 내보낼 수 있습니다. +활성화되면 에이전트는 Slack 전용 답장 지시문을 내보낼 수 있습니다. - `[[slack_buttons: Approve:approve, Reject:reject]]` - `[[slack_select: Choose a target | Canary:canary, Production:production]]` -이 지시문은 Slack Block Kit으로 컴파일되며, 클릭 또는 선택을 기존 Slack 상호작용 이벤트 경로를 통해 다시 라우팅합니다. +이 지시문은 Slack Block Kit으로 컴파일되고, 클릭 또는 선택을 기존 Slack 상호작용 이벤트 경로를 통해 다시 라우팅합니다. 참고: - 이는 Slack 전용 UI입니다. 다른 채널은 Slack Block Kit 지시문을 자체 버튼 시스템으로 변환하지 않습니다. -- 대화형 콜백 값은 에이전트가 작성한 원시 값이 아니라 OpenClaw가 생성한 불투명 토큰입니다. -- 생성된 대화형 블록이 Slack Block Kit 제한을 초과할 경우 OpenClaw는 유효하지 않은 블록 페이로드를 보내는 대신 원래 텍스트 답글로 대체합니다. +- 대화형 콜백 값은 원시 에이전트 작성 값이 아니라 OpenClaw가 생성한 불투명 토큰입니다. +- 생성된 대화형 블록이 Slack Block Kit 제한을 초과할 경우 OpenClaw는 유효하지 않은 블록 페이로드를 보내는 대신 원본 텍스트 답장으로 대체합니다. -## Slack에서 Exec 승인 +## Slack의 Exec 승인 -Slack은 Web UI 또는 터미널로 대체하는 대신, 대화형 버튼과 상호작용이 있는 네이티브 승인 클라이언트로 동작할 수 있습니다. +Slack은 Web UI 또는 터미널로 대체하는 대신, 대화형 버튼과 상호작용을 갖춘 네이티브 승인 클라이언트로 동작할 수 있습니다. - Exec 승인은 네이티브 DM/채널 라우팅에 `channels.slack.execApprovals.*`를 사용합니다. -- Plugin 승인은 요청이 이미 Slack에 도착했고 승인 ID 종류가 `plugin:`인 경우 동일한 Slack 네이티브 버튼 표면을 통해 계속 해결될 수 있습니다. +- Plugin 승인은 요청이 이미 Slack에 도착했고 승인 id 종류가 `plugin:`인 경우 동일한 Slack 네이티브 버튼 화면을 통해 계속 해결될 수 있습니다. - 승인자 권한 부여는 계속 적용됩니다. 승인자로 식별된 사용자만 Slack을 통해 요청을 승인하거나 거부할 수 있습니다. -이는 다른 채널과 동일한 공유 승인 버튼 표면을 사용합니다. Slack 앱 설정에서 `interactivity`가 활성화되면 승인 프롬프트가 대화 안에 Block Kit 버튼으로 직접 렌더링됩니다. -해당 버튼이 있으면 그것이 기본 승인 UX입니다. OpenClaw는 -도구 결과가 채팅 승인을 사용할 수 없다고 말하거나 수동 승인이 유일한 경로라고 말할 때만 +이는 다른 채널과 동일한 공유 승인 버튼 화면을 사용합니다. Slack 앱 설정에서 `interactivity`가 활성화되면 승인 프롬프트가 대화 안에 직접 Block Kit 버튼으로 렌더링됩니다. +이 버튼이 있을 때는 기본 승인 UX입니다. OpenClaw는 도구 결과가 채팅 +승인을 사용할 수 없다고 하거나 수동 승인이 유일한 경로라고 할 때만 수동 `/approve` 명령을 포함해야 합니다. 구성 경로: - `channels.slack.execApprovals.enabled` -- `channels.slack.execApprovals.approvers`(선택 사항; 가능하면 `commands.ownerAllowFrom`으로 대체) +- `channels.slack.execApprovals.approvers`(선택 사항; 가능한 경우 `commands.ownerAllowFrom`으로 대체) - `channels.slack.execApprovals.target`(`dm` | `channel` | `both`, 기본값: `dm`) - `agentFilter`, `sessionFilter` -Slack은 `enabled`가 설정되지 않았거나 `"auto"`이고 하나 이상의 승인자가 확인되면 네이티브 Exec 승인을 자동으로 활성화합니다. Slack을 네이티브 승인 클라이언트로 명시적으로 비활성화하려면 `enabled: false`를 설정하세요. +Slack은 `enabled`가 설정되지 않았거나 `"auto"`이고 최소 하나의 +승인자가 확인되면 네이티브 exec 승인을 자동 활성화합니다. Slack을 네이티브 승인 클라이언트로 명시적으로 비활성화하려면 `enabled: false`를 설정하세요. 승인자가 확인될 때 네이티브 승인을 강제로 켜려면 `enabled: true`를 설정하세요. -명시적 Slack Exec 승인 구성이 없을 때의 기본 동작: +명시적 Slack exec 승인 구성이 없을 때의 기본 동작: ```json5 { @@ -1193,7 +1190,7 @@ Slack은 `enabled`가 설정되지 않았거나 `"auto"`이고 하나 이상의 ``` 명시적 Slack 네이티브 구성은 승인자를 재정의하거나, 필터를 추가하거나, -원본 채팅 전달을 선택하려는 경우에만 필요합니다. +원본 채팅 전달을 사용하려는 경우에만 필요합니다. ```json5 { @@ -1209,34 +1206,35 @@ Slack은 `enabled`가 설정되지 않았거나 `"auto"`이고 하나 이상의 } ``` -공유 `approvals.exec` 전달은 별개입니다. Exec 승인 프롬프트가 다른 채팅 또는 명시적 대역 외 대상으로도 라우팅되어야 할 때만 사용하세요. 공유 `approvals.plugin` 전달도 -별개입니다. 이러한 요청이 이미 Slack에 도착한 경우 Slack 네이티브 버튼은 여전히 Plugin 승인을 해결할 수 있습니다. +공유 `approvals.exec` 전달은 별도입니다. exec 승인 프롬프트를 다른 채팅 또는 명시적인 대역 외 대상으로도 +라우팅해야 할 때만 사용하세요. 공유 `approvals.plugin` 전달도 +별도입니다. 해당 요청이 이미 Slack에 도착한 경우 Slack 네이티브 버튼은 여전히 plugin 승인을 해결할 수 있습니다. -동일 채팅 `/approve`도 이미 명령을 지원하는 Slack 채널 및 DM에서 동작합니다. 전체 승인 전달 모델은 [Exec 승인](/ko/tools/exec-approvals)을 참조하세요. +동일 채팅 `/approve`도 이미 명령을 지원하는 Slack 채널과 DM에서 작동합니다. 전체 승인 전달 모델은 [Exec 승인](/ko/tools/exec-approvals)을 참고하세요. -## 이벤트 및 운영 동작 +## 이벤트와 운영 동작 -- 메시지 수정/삭제는 시스템 이벤트로 매핑됩니다. -- 스레드 브로드캐스트("채널에도 보내기" 스레드 답글)는 일반 사용자 메시지로 처리됩니다. -- 리액션 추가/제거 이벤트는 시스템 이벤트로 매핑됩니다. +- 메시지 편집/삭제는 시스템 이벤트로 매핑됩니다. +- 스레드 브로드캐스트("채널에도 보내기" 스레드 답장)는 일반 사용자 메시지로 처리됩니다. +- 반응 추가/제거 이벤트는 시스템 이벤트로 매핑됩니다. - 멤버 참여/나가기, 채널 생성/이름 변경, 핀 추가/제거 이벤트는 시스템 이벤트로 매핑됩니다. -- `configWrites`가 활성화된 경우 `channel_id_changed`가 채널 구성 키를 마이그레이션할 수 있습니다. -- 채널 주제/목적 메타데이터는 신뢰할 수 없는 컨텍스트로 취급되며 라우팅 컨텍스트에 주입될 수 있습니다. -- 스레드 시작자 및 초기 스레드 기록 컨텍스트 시딩은 해당하는 경우 구성된 발신자 허용 목록으로 필터링됩니다. -- 블록 액션 및 모달 상호작용은 풍부한 페이로드 필드가 있는 구조화된 `Slack interaction: ...` 시스템 이벤트를 내보냅니다. - - 블록 액션: 선택된 값, 라벨, 선택기 값 및 `workflow_*` 메타데이터 - - 라우팅된 채널 메타데이터 및 양식 입력이 있는 모달 `view_submission` 및 `view_closed` 이벤트 +- `configWrites`가 활성화된 경우 `channel_id_changed`는 채널 구성 키를 마이그레이션할 수 있습니다. +- 채널 주제/목적 메타데이터는 신뢰할 수 없는 컨텍스트로 처리되며 라우팅 컨텍스트에 주입될 수 있습니다. +- 스레드 시작자와 초기 스레드 기록 컨텍스트 시딩은 적용 가능한 경우 구성된 발신자 허용 목록으로 필터링됩니다. +- 블록 작업과 모달 상호작용은 풍부한 페이로드 필드가 포함된 구조화된 `Slack interaction: ...` 시스템 이벤트를 내보냅니다. + - 블록 작업: 선택된 값, 레이블, 선택기 값, `workflow_*` 메타데이터 + - 라우팅된 채널 메타데이터와 양식 입력이 포함된 모달 `view_submission` 및 `view_closed` 이벤트 ## 구성 참조 기본 참조: [구성 참조 - Slack](/ko/gateway/config-channels#slack). - + - 모드/인증: `mode`, `botToken`, `appToken`, `signingSecret`, `webhookPath`, `accounts.*` -- DM 액세스: `dm.enabled`, `dmPolicy`, `allowFrom`(레거시: `dm.policy`, `dm.allowFrom`), `dm.groupEnabled`, `dm.groupChannels` -- 호환성 토글: `dangerouslyAllowNameMatching`(긴급 예외용; 필요하지 않으면 끄기 유지) -- 채널 액세스: `groupPolicy`, `channels.*`, `channels.*.users`, `channels.*.requireMention` +- DM 접근: `dm.enabled`, `dmPolicy`, `allowFrom`(레거시: `dm.policy`, `dm.allowFrom`), `dm.groupEnabled`, `dm.groupChannels` +- 호환성 토글: `dangerouslyAllowNameMatching`(비상용; 필요하지 않으면 꺼 둠) +- 채널 접근: `groupPolicy`, `channels.*`, `channels.*.users`, `channels.*.requireMention` - 스레딩/기록: `replyToMode`, `replyToModeByChatType`, `thread.*`, `historyLimit`, `dmHistoryLimit`, `dms.*.historyLimit` - 전달: `textChunkLimit`, `chunkMode`, `mediaMaxMb`, `streaming`, `streaming.nativeTransport`, `streaming.preview.toolProgress` - 운영/기능: `configWrites`, `commands.native`, `slashCommand.*`, `actions.*`, `userToken`, `userTokenReadOnly` @@ -1246,11 +1244,11 @@ Slack은 `enabled`가 설정되지 않았거나 `"auto"`이고 하나 이상의 ## 문제 해결 - + 순서대로 확인하세요. - `groupPolicy` - - 채널 허용 목록(`channels.slack.channels`) — **키는 채널 이름(`#channel-name`)이 아니라 채널 ID**(`C12345678`)여야 합니다. 채널 라우팅은 기본적으로 ID 우선이므로 `groupPolicy: "allowlist"`에서 이름 기반 키는 조용히 실패합니다. ID를 찾으려면 Slack에서 채널을 오른쪽 클릭 → **링크 복사** — URL 끝의 `C...` 값이 채널 ID입니다. + - 채널 허용 목록(`channels.slack.channels`) — **키는 채널 이름**(`#channel-name`)이 아니라 **채널 ID**(`C12345678`)여야 합니다. 채널 라우팅은 기본적으로 ID 우선이므로 이름 기반 키는 `groupPolicy: "allowlist"`에서 조용히 실패합니다. ID를 찾으려면 Slack에서 채널을 오른쪽 클릭 → **링크 복사** — URL 끝의 `C...` 값이 채널 ID입니다. - `requireMention` - 채널별 `users` 허용 목록 @@ -1264,15 +1262,15 @@ openclaw doctor - + 확인하세요. - `channels.slack.dm.enabled` - `channels.slack.dmPolicy`(또는 레거시 `channels.slack.dm.policy`) - 페어링 승인 / 허용 목록 항목 - Slack Assistant DM 이벤트: `drop message_changed`를 언급하는 상세 로그는 - 일반적으로 Slack이 메시지 메타데이터에서 복구 가능한 인간 발신자 없이 - 수정된 Assistant 스레드 이벤트를 보냈다는 뜻입니다 + 보통 Slack이 메시지 메타데이터에서 복구 가능한 사람 발신자 없이 + 편집된 Assistant 스레드 이벤트를 보냈다는 뜻입니다 ```bash openclaw pairing list slack @@ -1280,17 +1278,17 @@ openclaw pairing list slack - - Slack 앱 설정에서 봇 + 앱 토큰 및 Socket Mode 활성화를 검증하세요. + + Slack 앱 설정에서 봇 + 앱 토큰과 Socket Mode 활성화를 검증하세요. `openclaw channels status --probe --json`에 `botTokenStatus` 또는 `appTokenStatus: "configured_unavailable"`가 표시되면 Slack 계정은 - 구성되었지만 현재 런타임이 SecretRef 기반 값을 확인하지 못한 것입니다. + 구성되어 있지만 현재 런타임이 SecretRef 기반 값을 확인할 수 없었다는 뜻입니다. - - 검증하세요. + + 검증 항목: - 서명 시크릿 - Webhook 경로 @@ -1298,106 +1296,106 @@ openclaw pairing list slack - HTTP 계정별 고유한 `webhookPath` 계정 스냅샷에 `signingSecretStatus: "configured_unavailable"`가 표시되면 - HTTP 계정은 구성되었지만 현재 런타임이 SecretRef 기반 서명 시크릿을 - 확인하지 못한 것입니다. + HTTP 계정은 구성되어 있지만 현재 런타임이 SecretRef 기반 서명 시크릿을 + 확인할 수 없었다는 뜻입니다. - - 의도한 것이 무엇인지 확인하세요. + + 의도한 방식이 무엇인지 확인하세요. - - Slack에 등록된 일치하는 슬래시 명령이 있는 네이티브 명령 모드(`channels.slack.commands.native: true`) - - 또는 단일 슬래시 명령 모드(`channels.slack.slashCommand.enabled: true`) + - Slack에 등록된 일치하는 슬래시 명령과 함께 네이티브 명령 모드(`channels.slack.commands.native: true`)를 사용 + - 또는 단일 슬래시 명령 모드(`channels.slack.slashCommand.enabled: true`)를 사용 `commands.useAccessGroups`와 채널/사용자 허용 목록도 확인하세요. -## 첨부 파일 비전 참조 +## 첨부 비전 참조 -Slack 파일 다운로드에 성공하고 크기 제한이 허용하면 Slack은 다운로드된 미디어를 에이전트 턴에 첨부할 수 있습니다. 이미지 파일은 미디어 이해 경로를 통해 전달되거나 비전 가능 답글 모델로 직접 전달될 수 있습니다. 다른 파일은 이미지 입력으로 처리되지 않고 다운로드 가능한 파일 컨텍스트로 유지됩니다. +Slack은 Slack 파일 다운로드가 성공하고 크기 제한이 허용하는 경우 다운로드된 미디어를 에이전트 턴에 첨부할 수 있습니다. 이미지 파일은 미디어 이해 경로를 통해 전달되거나 비전 지원 응답 모델에 직접 전달될 수 있습니다. 다른 파일은 이미지 입력으로 처리되지 않고 다운로드 가능한 파일 컨텍스트로 유지됩니다. ### 지원되는 미디어 유형 -| 미디어 유형 | 소스 | 현재 동작 | 참고 사항 | +| 미디어 유형 | 소스 | 현재 동작 | 참고 | | ------------------------------ | -------------------- | --------------------------------------------------------------------------------- | ------------------------------------------------------------------------- | -| JPEG / PNG / GIF / WebP 이미지 | Slack 파일 URL | 다운로드되어 비전 지원 처리를 위해 해당 턴에 첨부됨 | 파일당 한도: `channels.slack.mediaMaxMb`(기본값 20 MB) | -| PDF 파일 | Slack 파일 URL | 다운로드되어 `download-file` 또는 `pdf` 같은 도구의 파일 컨텍스트로 노출됨 | Slack 수신은 PDF를 이미지 비전 입력으로 자동 변환하지 않음 | -| 기타 파일 | Slack 파일 URL | 가능한 경우 다운로드되어 파일 컨텍스트로 노출됨 | 바이너리 파일은 이미지 입력으로 취급되지 않음 | -| 스레드 답글 | 스레드 시작 메시지 파일 | 답글에 직접 미디어가 없을 때 루트 메시지 파일을 컨텍스트로 하이드레이션할 수 있음 | 파일만 있는 시작 메시지는 첨부 파일 플레이스홀더를 사용함 | -| 다중 이미지 메시지 | 여러 Slack 파일 | 각 파일이 독립적으로 평가됨 | Slack 처리는 메시지당 파일 8개로 제한됨 | +| JPEG / PNG / GIF / WebP 이미지 | Slack 파일 URL | 다운로드되어 비전 지원 처리를 위해 턴에 첨부됨 | 파일당 한도: `channels.slack.mediaMaxMb`(기본값 20 MB) | +| PDF 파일 | Slack 파일 URL | 다운로드되어 `download-file` 또는 `pdf` 같은 도구용 파일 컨텍스트로 노출됨 | Slack 인바운드는 PDF를 이미지 비전 입력으로 자동 변환하지 않음 | +| 기타 파일 | Slack 파일 URL | 가능한 경우 다운로드되어 파일 컨텍스트로 노출됨 | 바이너리 파일은 이미지 입력으로 처리되지 않음 | +| 스레드 답글 | 스레드 시작 파일 | 답글에 직접 미디어가 없을 때 루트 메시지 파일을 컨텍스트로 채울 수 있음 | 파일만 있는 시작 메시지는 첨부 파일 플레이스홀더를 사용함 | +| 다중 이미지 메시지 | 여러 Slack 파일 | 각 파일이 독립적으로 평가됨 | Slack 처리는 메시지당 최대 8개 파일로 제한됨 | -### 수신 파이프라인 +### 인바운드 파이프라인 파일 첨부가 있는 Slack 메시지가 도착하면: -1. OpenClaw가 봇 토큰(`xoxb-...`)을 사용해 Slack의 비공개 URL에서 파일을 다운로드합니다. +1. OpenClaw는 봇 토큰(`xoxb-...`)을 사용해 Slack의 비공개 URL에서 파일을 다운로드합니다. 2. 성공하면 파일이 미디어 저장소에 기록됩니다. -3. 다운로드된 미디어 경로와 콘텐츠 유형이 수신 컨텍스트에 추가됩니다. -4. 이미지 지원 모델/도구 경로는 해당 컨텍스트의 이미지 첨부를 사용할 수 있습니다. -5. 이미지가 아닌 파일은 이를 처리할 수 있는 도구를 위한 파일 메타데이터 또는 미디어 참조로 계속 사용할 수 있습니다. +3. 다운로드된 미디어 경로와 콘텐츠 유형이 인바운드 컨텍스트에 추가됩니다. +4. 이미지 지원 모델/도구 경로는 해당 컨텍스트의 이미지 첨부 파일을 사용할 수 있습니다. +5. 이미지가 아닌 파일은 이를 처리할 수 있는 도구를 위해 파일 메타데이터 또는 미디어 참조로 계속 사용할 수 있습니다. -### 스레드 루트 첨부 상속 +### 스레드 루트 첨부 파일 상속 -메시지가 스레드에 도착하면(`thread_ts` 부모가 있음): +메시지가 스레드에 도착하는 경우(`thread_ts` 부모가 있음): -- 답글 자체에 직접 미디어가 없고 포함된 루트 메시지에 파일이 있으면, Slack은 루트 파일을 스레드 시작 컨텍스트로 하이드레이션할 수 있습니다. -- 직접 답글 첨부가 루트 메시지 첨부보다 우선합니다. -- 파일만 있고 텍스트가 없는 루트 메시지는 폴백이 해당 파일을 계속 포함할 수 있도록 첨부 파일 플레이스홀더로 표현됩니다. +- 답글 자체에 직접 미디어가 없고 포함된 루트 메시지에 파일이 있으면, Slack은 루트 파일을 스레드 시작 컨텍스트로 채울 수 있습니다. +- 직접 답글 첨부 파일은 루트 메시지 첨부 파일보다 우선합니다. +- 파일만 있고 텍스트가 없는 루트 메시지는 첨부 파일 플레이스홀더로 표현되어 폴백이 여전히 해당 파일을 포함할 수 있습니다. -### 다중 첨부 처리 +### 다중 첨부 파일 처리 단일 Slack 메시지에 여러 파일 첨부가 포함된 경우: -- 각 첨부는 미디어 파이프라인을 통해 독립적으로 처리됩니다. +- 각 첨부 파일은 미디어 파이프라인을 통해 독립적으로 처리됩니다. - 다운로드된 미디어 참조는 메시지 컨텍스트에 집계됩니다. - 처리 순서는 이벤트 페이로드의 Slack 파일 순서를 따릅니다. -- 한 첨부의 다운로드 실패가 다른 첨부를 차단하지 않습니다. +- 한 첨부 파일 다운로드 실패는 다른 첨부 파일을 차단하지 않습니다. ### 크기, 다운로드 및 모델 제한 -- **크기 한도**: 파일당 기본값 20 MB. `channels.slack.mediaMaxMb`로 구성할 수 있습니다. -- **다운로드 실패**: Slack이 제공할 수 없는 파일, 만료된 URL, 접근할 수 없는 파일, 크기 초과 파일, Slack 인증/로그인 HTML 응답은 지원되지 않는 형식으로 보고되는 대신 건너뜁니다. -- **비전 모델**: 이미지 분석은 활성 답글 모델이 비전을 지원할 때 해당 모델을 사용하거나, `agents.defaults.imageModel`에 구성된 이미지 모델을 사용합니다. +- **크기 한도**: 기본값은 파일당 20 MB입니다. `channels.slack.mediaMaxMb`로 구성할 수 있습니다. +- **다운로드 실패**: Slack이 제공할 수 없는 파일, 만료된 URL, 접근할 수 없는 파일, 크기 초과 파일, Slack 인증/로그인 HTML 응답은 지원되지 않는 형식으로 보고되지 않고 건너뜁니다. +- **비전 모델**: 이미지 분석은 비전을 지원하는 경우 활성 응답 모델을 사용하거나 `agents.defaults.imageModel`에 구성된 이미지 모델을 사용합니다. -### 알려진 제한 +### 알려진 제한 사항 -| 시나리오 | 현재 동작 | 해결 방법 | -| -------------------------------------- | ---------------------------------------------------------------------------- | -------------------------------------------------------------------------- | -| 만료된 Slack 파일 URL | 파일을 건너뜀; 오류가 표시되지 않음 | Slack에 파일을 다시 업로드 | -| 비전 모델이 구성되지 않음 | 이미지 첨부가 미디어 참조로 저장되지만 이미지로 분석되지는 않음 | `agents.defaults.imageModel`을 구성하거나 비전 지원 답글 모델 사용 | -| 매우 큰 이미지(기본값 기준 20 MB 초과) | 크기 한도에 따라 건너뜀 | Slack이 허용하면 `channels.slack.mediaMaxMb` 증가 | -| 전달/공유된 첨부 | 텍스트 및 Slack 호스팅 이미지/파일 미디어는 최선을 다해 처리됨 | OpenClaw 스레드에서 직접 다시 공유 | -| PDF 첨부 | 파일/미디어 컨텍스트로 저장되며 이미지 비전을 통해 자동 라우팅되지 않음 | 파일 메타데이터에는 `download-file`을 사용하거나 PDF 분석에는 `pdf` 도구 사용 | +| 시나리오 | 현재 동작 | 우회 방법 | +| -------------------------------------- | -------------------------------------------------------------------------------- | --------------------------------------------------------------------------- | +| 만료된 Slack 파일 URL | 파일을 건너뜀; 오류가 표시되지 않음 | Slack에 파일을 다시 업로드 | +| 비전 모델이 구성되지 않음 | 이미지 첨부 파일은 미디어 참조로 저장되지만 이미지로 분석되지 않음 | `agents.defaults.imageModel`을 구성하거나 비전 지원 응답 모델 사용 | +| 매우 큰 이미지(기본값 기준 > 20 MB) | 크기 한도에 따라 건너뜀 | Slack이 허용하는 경우 `channels.slack.mediaMaxMb` 증가 | +| 전달/공유된 첨부 파일 | 텍스트와 Slack 호스팅 이미지/파일 미디어는 최선의 방식으로 처리됨 | OpenClaw 스레드에서 직접 다시 공유 | +| PDF 첨부 파일 | 파일/미디어 컨텍스트로 저장되며 이미지 비전으로 자동 라우팅되지 않음 | 파일 메타데이터에는 `download-file`을 사용하거나 PDF 분석에는 `pdf` 도구 사용 | ### 관련 문서 - [미디어 이해 파이프라인](/ko/nodes/media-understanding) - [PDF 도구](/ko/tools/pdf) -- 에픽: [#51349](https://github.com/openclaw/openclaw/issues/51349) — Slack 첨부 비전 활성화 +- Epic: [#51349](https://github.com/openclaw/openclaw/issues/51349) — Slack 첨부 파일 비전 활성화 - 회귀 테스트: [#51353](https://github.com/openclaw/openclaw/issues/51353) - 라이브 검증: [#51354](https://github.com/openclaw/openclaw/issues/51354) ## 관련 항목 - + Slack 사용자를 Gateway에 페어링합니다. - - 채널 및 그룹 DM 동작. + + 채널 및 그룹 DM 동작입니다. - - 수신 메시지를 에이전트로 라우팅합니다. + + 인바운드 메시지를 에이전트로 라우팅합니다. - - 위협 모델 및 강화. + + 위협 모델과 강화입니다. - - 구성 레이아웃 및 우선순위. + + 구성 레이아웃과 우선순위입니다. - - 명령 카탈로그 및 동작. + + 명령 카탈로그와 동작입니다. diff --git a/docs/ko/channels/zalouser.md b/docs/ko/channels/zalouser.md index 73215f927..f08177dc3 100644 --- a/docs/ko/channels/zalouser.md +++ b/docs/ko/channels/zalouser.md @@ -2,18 +2,18 @@ read_when: - OpenClaw용 Zalo Personal 설정 - Zalo Personal 로그인 또는 메시지 흐름 디버깅 -summary: 네이티브 zca-js(QR 로그인)를 통한 Zalo 개인 계정 지원, 기능 및 구성 +summary: 네이티브 zca-js(QR 로그인)를 통한 Zalo 개인 계정 지원, 기능 및 설정 title: Zalo 개인용 x-i18n: - generated_at: "2026-05-04T18:23:46Z" + generated_at: "2026-05-06T17:52:27Z" model: gpt-5.5 provider: openai - source_hash: 0f6d27f0ca502e6426abe21d609efd0a168a0b6b0fafe8d52d59f1a717da1ed5 + source_hash: d56cbf0a6300709e9fe23421cd134acc68852d0025f305c73413308f412349e8 source_path: channels/zalouser.md workflow: 16 --- -상태: 실험적. 이 통합은 OpenClaw 내부의 네이티브 `zca-js`를 통해 **개인 Zalo 계정**을 자동화합니다. +상태: 실험적입니다. 이 통합은 OpenClaw 내부의 네이티브 `zca-js`를 통해 **개인 Zalo 계정**을 자동화합니다. 이는 비공식 통합이며 계정 정지 또는 차단으로 이어질 수 있습니다. 본인 책임하에 사용하세요. @@ -21,25 +21,25 @@ x-i18n: ## 번들 Plugin -Zalo Personal은 현재 OpenClaw 릴리스에 번들 Plugin으로 제공되므로, 일반적인 +Zalo Personal은 현재 OpenClaw 릴리스에 번들 Plugin으로 제공되므로, 일반 패키지 빌드에서는 별도 설치가 필요하지 않습니다. -이전 빌드를 사용 중이거나 Zalo Personal을 제외한 사용자 지정 설치를 사용하는 경우, +Zalo Personal이 제외된 이전 빌드나 사용자 지정 설치를 사용 중이라면, npm 패키지를 직접 설치하세요. - CLI로 설치: `openclaw plugins install @openclaw/zalouser` - 고정 버전: `openclaw plugins install @openclaw/zalouser@2026.5.2` - 또는 소스 체크아웃에서 설치: `openclaw plugins install ./path/to/local/zalouser-plugin` -- 자세한 내용: [Plugins](/ko/tools/plugin) +- 자세한 내용: [Plugin](/ko/tools/plugin) 외부 `zca`/`openzca` CLI 바이너리는 필요하지 않습니다. -## 빠른 설정(초보자) +## 빠른 설정(초보자용) 1. Zalo Personal Plugin을 사용할 수 있는지 확인합니다. - - 현재 패키지된 OpenClaw 릴리스에는 이미 번들로 포함되어 있습니다. - - 이전/사용자 지정 설치는 위 명령으로 수동 추가할 수 있습니다. -2. 로그인(QR, Gateway 머신에서): + - 현재 패키지 OpenClaw 릴리스에는 이미 번들로 포함되어 있습니다. + - 이전/사용자 지정 설치에서는 위 명령으로 수동 추가할 수 있습니다. +2. 로그인합니다(QR, Gateway 머신에서): - `openclaw channels login --channel zalouser` - Zalo 모바일 앱으로 QR 코드를 스캔합니다. 3. 채널을 활성화합니다. @@ -56,22 +56,22 @@ npm 패키지를 직접 설치하세요. ``` 4. Gateway를 다시 시작합니다(또는 설정을 완료합니다). -5. DM 접근은 기본적으로 페어링을 사용합니다. 첫 연락 시 페어링 코드를 승인하세요. +5. DM 액세스는 기본적으로 페어링을 사용합니다. 첫 연락 시 페어링 코드를 승인하세요. -## 정의 +## 개요 -- `zca-js`를 통해 전적으로 프로세스 내부에서 실행됩니다. +- `zca-js`를 통해 완전히 프로세스 내부에서 실행됩니다. - 네이티브 이벤트 리스너를 사용해 인바운드 메시지를 수신합니다. -- JS API(텍스트/미디어/링크)를 통해 직접 답장을 보냅니다. -- Zalo Bot API를 사용할 수 없는 “개인 계정” 사용 사례를 위해 설계되었습니다. +- JS API를 통해 직접 답장을 보냅니다(텍스트/미디어/링크). +- Zalo Bot API를 사용할 수 없는 "개인 계정" 사용 사례를 위해 설계되었습니다. ## 이름 지정 -채널 ID는 `zalouser`입니다. 이는 **개인 Zalo 사용자 계정**을 자동화한다는 점을 명확히 하기 위한 것입니다(비공식). `zalo`는 향후 공식 Zalo API 통합 가능성을 위해 예약해 둡니다. +채널 ID는 `zalouser`입니다. 이는 **개인 Zalo 사용자 계정**(비공식)을 자동화한다는 점을 명확히 하기 위한 것입니다. `zalo`는 향후 공식 Zalo API 통합 가능성을 위해 예약해 둡니다. ## ID 찾기(디렉터리) -디렉터리 CLI를 사용해 피어/그룹과 해당 ID를 찾습니다. +디렉터리 CLI를 사용해 피어/그룹과 해당 ID를 찾으세요. ```bash openclaw directory self --channel zalouser @@ -79,40 +79,40 @@ openclaw directory peers list --channel zalouser --query "name" openclaw directory groups list --channel zalouser --query "work" ``` -## 제한 사항 +## 제한 -- 아웃바운드 텍스트는 약 2000자로 분할됩니다(Zalo 클라이언트 제한). +- 아웃바운드 텍스트는 약 2000자 단위로 분할됩니다(Zalo 클라이언트 제한). - 스트리밍은 기본적으로 차단됩니다. -## 접근 제어(DM) +## 액세스 제어(DM) `channels.zalouser.dmPolicy`는 `pairing | allowlist | open | disabled`를 지원합니다(기본값: `pairing`). -`channels.zalouser.allowFrom`에는 안정적인 Zalo 사용자 ID를 사용해야 합니다. 대화형 설정 중 입력한 이름은 Plugin의 프로세스 내부 연락처 조회를 사용해 ID로 해석할 수 있습니다. +`channels.zalouser.allowFrom`에는 안정적인 Zalo 사용자 ID를 사용해야 합니다. 대화형 설정 중 입력한 이름은 Plugin의 프로세스 내부 연락처 조회를 사용해 ID로 확인할 수 있습니다. -원시 이름이 설정에 남아 있는 경우, 시작 시 `channels.zalouser.dangerouslyAllowNameMatching: true`가 활성화되어 있을 때만 이를 해석합니다. 이 옵트인이 없으면 런타임 발신자 검사는 ID 전용이며, 원시 이름은 권한 부여에서 무시됩니다. +원시 이름이 설정에 남아 있으면 시작 시 `channels.zalouser.dangerouslyAllowNameMatching: true`가 활성화된 경우에만 이를 확인합니다. 이 옵트인이 없으면 런타임 발신자 검사는 ID만 사용하며 원시 이름은 권한 부여에서 무시됩니다. -다음으로 승인합니다: +다음으로 승인합니다. - `openclaw pairing list zalouser` - `openclaw pairing approve zalouser ` -## 그룹 접근(선택 사항) +## 그룹 액세스(선택 사항) - 기본값: `channels.zalouser.groupPolicy = "open"`(그룹 허용). 설정되지 않은 경우 기본값을 재정의하려면 `channels.defaults.groupPolicy`를 사용하세요. -- 다음으로 허용 목록으로 제한합니다: +- allowlist로 제한: - `channels.zalouser.groupPolicy = "allowlist"` - - `channels.zalouser.groups`(키는 안정적인 그룹 ID여야 합니다. `channels.zalouser.dangerouslyAllowNameMatching: true`가 활성화된 경우에만 시작 시 이름이 ID로 확인됩니다) + - `channels.zalouser.groups`(키는 안정적인 그룹 ID여야 합니다. 이름은 `channels.zalouser.dangerouslyAllowNameMatching: true`가 활성화된 경우에만 시작 시 ID로 확인됩니다) - `channels.zalouser.groupAllowFrom`(허용된 그룹에서 어떤 발신자가 봇을 트리거할 수 있는지 제어) - 모든 그룹 차단: `channels.zalouser.groupPolicy = "disabled"`. -- 구성 마법사가 그룹 허용 목록을 요청할 수 있습니다. -- 시작 시 OpenClaw는 허용 목록의 그룹/사용자 이름을 ID로 확인하고, `channels.zalouser.dangerouslyAllowNameMatching: true`가 활성화된 경우에만 매핑을 로그에 기록합니다. -- 그룹 허용 목록 매칭은 기본적으로 ID 전용입니다. 확인되지 않은 이름은 `channels.zalouser.dangerouslyAllowNameMatching: true`가 활성화되지 않는 한 인증에서 무시됩니다. -- `channels.zalouser.dangerouslyAllowNameMatching: true`는 변경 가능한 시작 시 이름 확인과 런타임 그룹 이름 매칭을 다시 활성화하는 비상용 호환성 모드입니다. -- `groupAllowFrom`이 설정되지 않은 경우 런타임은 그룹 발신자 확인에 `allowFrom`을 대체값으로 사용합니다. -- 발신자 확인은 일반 그룹 메시지와 제어 명령(예: `/new`, `/reset`) 모두에 적용됩니다. +- 구성 마법사는 그룹 allowlist를 입력하도록 요청할 수 있습니다. +- 시작 시 OpenClaw는 `channels.zalouser.dangerouslyAllowNameMatching: true`가 활성화된 경우에만 allowlist의 그룹/사용자 이름을 ID로 확인하고 매핑을 로그에 기록합니다. +- 그룹 allowlist 매칭은 기본적으로 ID만 사용합니다. 확인되지 않은 이름은 `channels.zalouser.dangerouslyAllowNameMatching: true`가 활성화되지 않는 한 인증에서 무시됩니다. +- `channels.zalouser.dangerouslyAllowNameMatching: true`는 변경 가능한 시작 시 이름 확인 및 런타임 그룹 이름 매칭을 다시 활성화하는 비상 호환성 모드입니다. +- `groupAllowFrom`이 설정되지 않은 경우 런타임은 그룹 발신자 검사에 `allowFrom`으로 폴백합니다. +- 발신자 검사는 일반 그룹 메시지와 제어 명령(예: `/new`, `/reset`) 모두에 적용됩니다. -예: +예시: ```json5 { @@ -132,14 +132,14 @@ openclaw directory groups list --channel zalouser --query "work" ### 그룹 멘션 게이팅 - `channels.zalouser.groups..requireMention`은 그룹 답장에 멘션이 필요한지 제어합니다. -- 확인 순서: 정확한 그룹 id/이름 -> 정규화된 그룹 slug -> `*` -> 기본값(`true`). -- 이는 허용 목록에 있는 그룹과 열린 그룹 모드 모두에 적용됩니다. +- 확인 순서: 정확한 그룹 ID/이름 -> 정규화된 그룹 슬러그 -> `*` -> 기본값(`true`). +- 이는 allowlist에 있는 그룹과 열린 그룹 모드 모두에 적용됩니다. - 봇 메시지를 인용하면 그룹 활성화를 위한 암시적 멘션으로 간주됩니다. -- 승인된 제어 명령(예: `/new`)은 멘션 게이팅을 우회할 수 있습니다. -- 멘션이 필요해서 그룹 메시지를 건너뛰는 경우, OpenClaw는 이를 보류 중인 그룹 기록으로 저장하고 다음에 처리되는 그룹 메시지에 포함합니다. -- 그룹 기록 제한은 기본적으로 `messages.groupChat.historyLimit`(대체값 `50`)입니다. 계정별로 `channels.zalouser.historyLimit`로 재정의할 수 있습니다. +- 권한이 있는 제어 명령(예: `/new`)은 멘션 게이팅을 우회할 수 있습니다. +- 멘션이 필요해 그룹 메시지를 건너뛰면 OpenClaw는 이를 대기 중인 그룹 기록으로 저장하고 다음 처리된 그룹 메시지에 포함합니다. +- 그룹 기록 제한은 기본적으로 `messages.groupChat.historyLimit`입니다(폴백 `50`). `channels.zalouser.historyLimit`로 계정별로 재정의할 수 있습니다. -예: +예시: ```json5 { @@ -157,7 +157,7 @@ openclaw directory groups list --channel zalouser --query "work" ## 다중 계정 -계정은 OpenClaw 상태의 `zalouser` 프로필에 매핑됩니다. 예: +계정은 OpenClaw 상태의 `zalouser` 프로필에 매핑됩니다. 예시: ```json5 { @@ -173,34 +173,34 @@ openclaw directory groups list --channel zalouser --query "work" } ``` -## 입력 중 표시, 반응, 전달 승인 +## 입력 표시, 반응, 전달 확인 -- OpenClaw는 답장을 디스패치하기 전에 입력 중 이벤트를 전송합니다(최선의 노력). -- 메시지 반응 작업 `react`는 채널 작업의 `zalouser`에서 지원됩니다. +- OpenClaw는 답장을 디스패치하기 전에 입력 중 이벤트를 보냅니다(최선 노력). +- 메시지 반응 액션 `react`는 채널 액션에서 `zalouser`에 대해 지원됩니다. - 메시지에서 특정 반응 이모지를 제거하려면 `remove: true`를 사용하세요. - 반응 의미 체계: [반응](/ko/tools/reactions) -- 이벤트 메타데이터가 포함된 인바운드 메시지에 대해 OpenClaw는 전달됨 + 확인함 승인을 전송합니다(최선의 노력). +- 이벤트 메타데이터가 포함된 인바운드 메시지의 경우 OpenClaw는 전달됨 + 읽음 확인을 보냅니다(최선 노력). ## 문제 해결 -**로그인이 유지되지 않음:** +**로그인이 유지되지 않는 경우:** - `openclaw channels status --probe` - 다시 로그인: `openclaw channels logout --channel zalouser && openclaw channels login --channel zalouser` -**허용 목록/그룹 이름이 확인되지 않음:** +**Allowlist/그룹 이름이 확인되지 않은 경우:** - `allowFrom`/`groupAllowFrom`에는 숫자 ID를 사용하고 `groups`에는 안정적인 그룹 ID를 사용하세요. 정확한 친구/그룹 이름이 의도적으로 필요하다면 `channels.zalouser.dangerouslyAllowNameMatching: true`를 활성화하세요. -**이전 CLI 기반 설정에서 업그레이드함:** +**이전 CLI 기반 설정에서 업그레이드한 경우:** -- 이전 외부 `zca` 프로세스 가정을 모두 제거하세요. -- 이제 채널은 외부 CLI 바이너리 없이 OpenClaw 안에서 완전히 실행됩니다. +- 이전 외부 `zca` 프로세스 관련 가정을 모두 제거하세요. +- 이제 채널은 외부 CLI 바이너리 없이 OpenClaw 내부에서 완전히 실행됩니다. ## 관련 항목 - [채널 개요](/ko/channels) — 지원되는 모든 채널 - [페어링](/ko/channels/pairing) — DM 인증 및 페어링 흐름 - [그룹](/ko/channels/groups) — 그룹 채팅 동작 및 멘션 게이팅 -- [채널 라우팅](/ko/channels/channel-routing) — 메시지 세션 라우팅 -- [보안](/ko/gateway/security) — 접근 모델 및 강화 +- [채널 라우팅](/ko/channels/channel-routing) — 메시지의 세션 라우팅 +- [보안](/ko/gateway/security) — 액세스 모델 및 강화 diff --git a/docs/ko/cli/config.md b/docs/ko/cli/config.md index 5d2bc8812..22b39d0b6 100644 --- a/docs/ko/cli/config.md +++ b/docs/ko/cli/config.md @@ -1,24 +1,28 @@ --- read_when: - - 구성을 비대화형으로 읽거나 편집하려는 경우 + - 비대화식으로 구성을 읽거나 편집하려는 경우 sidebarTitle: Config -summary: '`openclaw config`의 CLI 참조 (get/set/patch/unset/file/schema/validate)' +summary: '`openclaw config`에 대한 CLI 참조 (get/set/patch/unset/file/schema/validate)' title: 설정 x-i18n: - generated_at: "2026-05-03T21:28:18Z" + generated_at: "2026-05-06T17:52:24Z" model: gpt-5.5 provider: openai - source_hash: 7be6a2ff8474fe78deb1d32dd822a4cf8a2b420dfb45306be5d7c5a1d54f0b4d + source_hash: e4e0d580347e162278277ddb33eed0e42105c5e85bac4325c07fa2cd700b831d source_path: cli/config.md workflow: 16 --- -`openclaw.json`에서 비대화형 편집을 위한 구성 도우미: 경로별로 값을 get/set/patch/unset/file/schema/validate하고 활성 구성 파일을 출력합니다. 하위 명령 없이 실행하면 구성 마법사가 열립니다(`openclaw configure`와 동일). +`openclaw.json`의 비대화형 편집을 위한 구성 도우미입니다. 경로별로 값을 get/set/patch/unset/file/schema/validate하고 활성 구성 파일을 출력합니다. 하위 명령 없이 실행하면 구성 마법사가 열립니다(`openclaw configure`와 동일). + + +`OPENCLAW_NIX_MODE=1`일 때 OpenClaw는 `openclaw.json`을 변경 불가능한 것으로 취급합니다. `config get`, `config file`, `config schema`, `config validate` 같은 읽기 전용 명령은 계속 동작하지만, 구성 쓰기 작업은 거부됩니다. 대신 Agents는 설치의 Nix 소스를 편집해야 합니다. 공식 nix-openclaw 배포판의 경우 [nix-openclaw 빠른 시작](https://github.com/openclaw/nix-openclaw#quick-start)을 사용하고 `programs.openclaw.config` 또는 `instances..config` 아래에 값을 설정하세요. + ## 루트 옵션 - 하위 명령 없이 `openclaw config`를 실행할 때 반복 지정 가능한 안내 설정 섹션 필터입니다. + 하위 명령 없이 `openclaw config`를 실행할 때 반복해서 지정할 수 있는 안내식 설정 섹션 필터입니다. 지원되는 안내 섹션: `workspace`, `model`, `web`, `gateway`, `daemon`, `channels`, `plugins`, `skills`, `health`. @@ -50,17 +54,17 @@ openclaw config validate --json `openclaw.json`용으로 생성된 JSON 스키마를 JSON으로 stdout에 출력합니다. - + - 현재 루트 구성 스키마와 편집기 도구용 루트 `$schema` 문자열 필드. - Control UI에서 사용하는 필드 `title` 및 `description` 문서 메타데이터. - - 중첩 객체, 와일드카드(`*`), 배열 항목(`[]`) 노드는 일치하는 필드 문서가 있으면 동일한 `title` / `description` 메타데이터를 상속합니다. - - `anyOf` / `oneOf` / `allOf` 분기도 일치하는 필드 문서가 있으면 동일한 문서 메타데이터를 상속합니다. - - 런타임 매니페스트를 로드할 수 있을 때 최선의 라이브 Plugin + 채널 스키마 메타데이터. - - 현재 구성이 유효하지 않아도 깔끔한 대체 스키마. + - 일치하는 필드 문서가 있으면 중첩 객체, 와일드카드(`*`), 배열 항목(`[]`) 노드가 동일한 `title` / `description` 메타데이터를 상속합니다. + - 일치하는 필드 문서가 있으면 `anyOf` / `oneOf` / `allOf` 분기도 동일한 문서 메타데이터를 상속합니다. + - 런타임 매니페스트를 로드할 수 있을 때 최선의 실시간 Plugin + 채널 스키마 메타데이터. + - 현재 구성이 유효하지 않은 경우에도 깔끔한 대체 스키마. - `config.schema.lookup`은 얕은 스키마 노드(`title`, `description`, `type`, `enum`, `const`, 공통 경계), 일치하는 UI 힌트 메타데이터, 즉시 하위 요약을 포함해 정규화된 구성 경로 하나를 반환합니다. Control UI 또는 사용자 지정 클라이언트에서 경로 범위 드릴다운에 사용하세요. + `config.schema.lookup`은 얕은 스키마 노드(`title`, `description`, `type`, `enum`, `const`, 공통 범위), 일치하는 UI 힌트 메타데이터, 즉시 하위 요약과 함께 정규화된 구성 경로 하나를 반환합니다. Control UI 또는 사용자 지정 클라이언트에서 경로 범위 드릴다운에 사용하세요. @@ -76,14 +80,14 @@ openclaw config schema > openclaw.schema.json ### 경로 -경로는 점 또는 대괄호 표기법을 사용합니다. +경로는 점 표기법 또는 대괄호 표기법을 사용합니다. ```bash openclaw config get agents.defaults.workspace openclaw config get agents.list[0].id ``` -특정 에이전트를 대상으로 지정하려면 에이전트 목록 인덱스를 사용하세요. +특정 agent를 대상으로 지정하려면 agent 목록 인덱스를 사용하세요. ```bash openclaw config get agents.list @@ -92,7 +96,7 @@ openclaw config set agents.list[1].tools.exec.node "node-id-or-name" ## 값 -값은 가능한 경우 JSON5로 파싱되며, 그렇지 않으면 문자열로 처리됩니다. JSON5 파싱을 요구하려면 `--strict-json`을 사용하세요. `--json`은 레거시 별칭으로 계속 지원됩니다. +값은 가능하면 JSON5로 파싱되고, 그렇지 않으면 문자열로 처리됩니다. JSON5 파싱을 요구하려면 `--strict-json`을 사용하세요. `--json`은 레거시 별칭으로 계속 지원됩니다. ```bash openclaw config set agents.defaults.heartbeat.every "0m" @@ -103,7 +107,7 @@ openclaw config set channels.whatsapp.groups '["*"]' --strict-json `config get --json`은 터미널 형식의 텍스트 대신 원시 값을 JSON으로 출력합니다. -객체 할당은 기본적으로 대상 경로를 대체합니다. `agents.defaults.models`, `models.providers`, `models.providers..models`, `plugins.entries`, `auth.profiles`처럼 사용자가 추가한 항목을 흔히 보관하는 보호된 맵/목록 경로는 `--replace`를 전달하지 않으면 기존 항목을 제거하는 대체를 거부합니다. +객체 할당은 기본적으로 대상 경로를 교체합니다. `agents.defaults.models`, `models.providers`, `models.providers..models`, `plugins.entries`, `auth.profiles`처럼 사용자가 추가한 항목을 흔히 보관하는 보호된 맵/목록 경로는 `--replace`를 전달하지 않는 한 기존 항목을 제거하는 교체를 거부합니다. 해당 맵에 항목을 추가할 때는 `--merge`를 사용하세요. @@ -113,7 +117,7 @@ openclaw config set agents.defaults.models '{"openai/gpt-5.4":{}}' --strict-json openclaw config set models.providers.ollama.models '[{"id":"llama3.2","name":"Llama 3.2"}]' --strict-json --merge ``` -제공한 값을 완전한 대상 값으로 만들려는 의도가 있을 때만 `--replace`를 사용하세요. +제공한 값이 완전한 대상 값이 되도록 의도한 경우에만 `--replace`를 사용하세요. ## `config set` 모드 @@ -171,18 +175,18 @@ openclaw config set models.providers.ollama.models '[{"id":"llama3.2","name":"Ll SecretRef 할당은 지원되지 않는 런타임 변경 가능 표면(예: `hooks.token`, `commands.ownerDisplaySecret`, Discord 스레드 바인딩 Webhook 토큰, WhatsApp 자격 증명 JSON)에서 거부됩니다. [SecretRef 자격 증명 표면](/ko/reference/secretref-credential-surface)을 참고하세요. -배치 파싱은 항상 배치 페이로드(`--batch-json`/`--batch-file`)를 기준 정보로 사용합니다. `--strict-json` / `--json`은 배치 파싱 동작을 변경하지 않습니다. +배치 파싱은 항상 배치 페이로드(`--batch-json`/`--batch-file`)를 신뢰 기준으로 사용합니다. `--strict-json` / `--json`은 배치 파싱 동작을 변경하지 않습니다. ## `config patch` -많은 경로 기반 `config set` 명령을 실행하는 대신 구성 형태의 패치를 붙여넣거나 파이프하려면 `config patch`를 사용하세요. 입력은 JSON5 객체입니다. 객체는 재귀적으로 병합되고, 배열과 스칼라 값은 대상 값을 대체하며, `null`은 대상 경로를 삭제합니다. +경로 기반 `config set` 명령을 여러 번 실행하는 대신 구성 형태의 패치를 붙여 넣거나 파이프하려면 `config patch`를 사용하세요. 입력은 JSON5 객체입니다. 객체는 재귀적으로 병합되고, 배열과 스칼라 값은 대상 값을 교체하며, `null`은 대상 경로를 삭제합니다. ```bash openclaw config patch --file ./openclaw.patch.json5 --dry-run openclaw config patch --file ./openclaw.patch.json5 ``` -stdin을 통해 패치를 파이프할 수도 있으며, 원격 설정 스크립트에 유용합니다. +원격 설정 스크립트에 유용하도록 stdin으로 패치를 파이프할 수도 있습니다. ```bash ssh openclaw-host 'openclaw config patch --stdin --dry-run' < ./openclaw.patch.json5 @@ -221,15 +225,15 @@ ssh openclaw-host 'openclaw config patch --stdin' < ./openclaw.patch.json5 } ``` -객체 또는 배열 하나가 재귀적으로 패치되는 대신 제공된 값과 정확히 같아야 할 때는 `--replace-path `를 사용하세요. +객체나 배열 하나가 재귀적으로 패치되는 대신 제공한 값과 정확히 같아져야 할 때는 `--replace-path `를 사용하세요. ```bash openclaw config patch --file ./discord.patch.json5 --replace-path 'channels.discord.guilds["123"].channels' ``` -`--dry-run`은 쓰기 없이 스키마 및 SecretRef 확인 가능성 검사를 실행합니다. exec 기반 SecretRef는 dry-run 중 기본적으로 건너뜁니다. dry-run에서 의도적으로 공급자 명령을 실행하려면 `--allow-exec`을 추가하세요. +`--dry-run`은 쓰기 없이 스키마 및 SecretRef 해석 가능성 검사를 실행합니다. exec 기반 SecretRefs는 dry-run 중 기본적으로 건너뜁니다. dry-run에서 provider 명령을 실행하도록 의도한 경우 `--allow-exec`를 추가하세요. -JSON 경로/값 모드는 SecretRef와 공급자 모두에서 계속 지원됩니다. +JSON 경로/값 모드는 SecretRefs와 providers 모두에 대해 계속 지원됩니다. ```bash openclaw config set channels.discord.token \ @@ -251,18 +255,18 @@ Provider 빌더 대상은 경로로 `secrets.providers.`를 사용해야 - `--provider-timeout-ms ` (`file`, `exec`) - + - `--provider-allowlist ` (반복 가능) - + - `--provider-path ` (필수) - `--provider-mode ` - `--provider-max-bytes ` - `--provider-allow-insecure-path` - + - `--provider-command ` (필수) - `--provider-arg ` (반복 가능) - `--provider-no-output-timeout-ms ` @@ -277,7 +281,7 @@ Provider 빌더 대상은 경로로 `secrets.providers.`를 사용해야 -강화된 exec 공급자 예시: +강화된 exec provider 예시: ```bash openclaw config set secrets.providers.vault \ @@ -319,25 +323,25 @@ openclaw config set channels.discord.token \ - - 빌더 모드: 변경된 refs/providers에 대해 SecretRef 확인 가능성 검사를 실행합니다. - - JSON 모드(`--strict-json`, `--json` 또는 배치 모드): 스키마 검증과 SecretRef 확인 가능성 검사를 실행합니다. + - 빌더 모드: 변경된 refs/providers에 대해 SecretRef 해석 가능성 검사를 실행합니다. + - JSON 모드(`--strict-json`, `--json` 또는 배치 모드): 스키마 검증과 SecretRef 해석 가능성 검사를 실행합니다. - 알려진 미지원 SecretRef 대상 표면에 대해서도 정책 검증이 실행됩니다. - - 정책 검사는 변경 후 전체 구성을 평가하므로, 부모 객체 쓰기(예: `hooks`를 객체로 설정)는 미지원 표면 검증을 우회할 수 없습니다. - - exec SecretRef 검사는 명령 부작용을 피하기 위해 dry-run 중 기본적으로 건너뜁니다. - - exec SecretRef 검사를 사용하려면 `--dry-run`과 함께 `--allow-exec`을 사용하세요. 이 경우 공급자 명령이 실행될 수 있습니다. - - `--allow-exec`은 dry-run 전용이며 `--dry-run` 없이 사용하면 오류가 발생합니다. + - 정책 검사는 변경 후 전체 구성을 평가하므로, 부모 객체 쓰기(예: `hooks`를 객체로 설정)가 미지원 표면 검증을 우회할 수 없습니다. + - Exec SecretRef 검사는 명령 부작용을 피하기 위해 dry-run 중 기본적으로 건너뜁니다. + - exec SecretRef 검사에 참여하려면 `--dry-run`과 함께 `--allow-exec`를 사용하세요. 이 경우 provider 명령이 실행될 수 있습니다. + - `--allow-exec`는 dry-run 전용이며 `--dry-run` 없이 사용하면 오류가 발생합니다. - `--dry-run --json`은 기계가 읽을 수 있는 보고서를 출력합니다. + `--dry-run --json`은 기계가 읽을 수 있는 보고서를 출력합니다: - - `ok`: dry-run 통과 여부 + - `ok`: 드라이런 통과 여부 - `operations`: 평가된 할당 수 - - `checks`: 스키마/확인 가능성 검사가 실행되었는지 여부 - - `checks.resolvabilityComplete`: 확인 가능성 검사가 완료될 때까지 실행되었는지 여부(exec refs를 건너뛰면 false) - - `refsChecked`: dry-run 중 실제로 확인된 refs 수 - - `skippedExecRefs`: `--allow-exec`이 설정되지 않아 건너뛴 exec refs 수 - - `errors`: `ok=false`일 때 구조화된 스키마/확인 가능성 실패 + - `checks`: 스키마/해결 가능성 검사가 실행되었는지 여부 + - `checks.resolvabilityComplete`: 해결 가능성 검사가 완료될 때까지 실행되었는지 여부(exec 참조를 건너뛴 경우 false) + - `refsChecked`: 드라이런 중 실제로 해결된 참조 수 + - `skippedExecRefs`: `--allow-exec`가 설정되지 않아 건너뛴 exec 참조 수 + - `errors`: `ok=false`일 때의 구조화된 스키마/해결 가능성 실패 @@ -412,11 +416,11 @@ openclaw config set channels.discord.token \ - - - `config schema validation failed`: 변경 후 config 형식이 유효하지 않습니다. 경로/값 또는 provider/ref 객체 형식을 수정하세요. - - `Config policy validation failed: unsupported SecretRef usage`: 해당 credential을 다시 일반 텍스트/문자열 입력으로 옮기고, SecretRef는 지원되는 표면에서만 유지하세요. - - `SecretRef assignment(s) could not be resolved`: 참조된 provider/ref를 현재 확인할 수 없습니다(누락된 env var, 잘못된 파일 포인터, exec provider 실패 또는 provider/source 불일치). - - `Dry run note: skipped exec SecretRef resolvability check(s)`: dry-run이 exec ref를 건너뛰었습니다. exec resolvability 검증이 필요하면 `--allow-exec`로 다시 실행하세요. + + - `config schema validation failed`: 변경 후 구성 형태가 유효하지 않습니다. 경로/값 또는 provider/ref 객체 형태를 수정하세요. + - `Config policy validation failed: unsupported SecretRef usage`: 해당 자격 증명을 평문/문자열 입력으로 되돌리고 SecretRef는 지원되는 표면에서만 유지하세요. + - `SecretRef assignment(s) could not be resolved`: 참조된 provider/ref를 현재 해결할 수 없습니다. env var 누락, 잘못된 파일 포인터, exec provider 실패 또는 provider/source 불일치가 원인일 수 있습니다. + - `Dry run note: skipped exec SecretRef resolvability check(s)`: 드라이런이 exec 참조를 건너뛰었습니다. exec 해결 가능성 검증이 필요하면 `--allow-exec`로 다시 실행하세요. - 배치 모드에서는 실패한 항목을 수정하고 쓰기 전에 `--dry-run`을 다시 실행하세요. @@ -424,10 +428,10 @@ openclaw config set channels.discord.token \ ## 쓰기 안전성 -`openclaw config set` 및 기타 OpenClaw 소유 config 작성기는 디스크에 커밋하기 전에 변경 후 전체 config를 검증합니다. 새 payload가 schema 검증에 실패하거나 파괴적인 덮어쓰기처럼 보이면 active config는 그대로 두고, 거부된 payload는 옆에 `openclaw.json.rejected.*`로 저장됩니다. +`openclaw config set` 및 기타 OpenClaw 소유 구성 작성기는 디스크에 커밋하기 전에 변경 후 전체 구성을 검증합니다. 새 페이로드가 스키마 검증에 실패하거나 파괴적인 덮어쓰기처럼 보이면 활성 구성은 그대로 두고 거부된 페이로드를 `openclaw.json.rejected.*`로 그 옆에 저장합니다. -active config 경로는 일반 파일이어야 합니다. symlink된 `openclaw.json` 레이아웃은 쓰기에 지원되지 않습니다. 대신 `OPENCLAW_CONFIG_PATH`를 사용해 실제 파일을 직접 가리키세요. +활성 구성 경로는 일반 파일이어야 합니다. 심볼릭 링크된 `openclaw.json` 레이아웃은 쓰기에 지원되지 않습니다. 대신 `OPENCLAW_CONFIG_PATH`를 사용해 실제 파일을 직접 가리키세요. 작은 편집에는 CLI 쓰기를 권장합니다. @@ -438,7 +442,7 @@ openclaw config set gateway.reload.mode hybrid openclaw config validate ``` -쓰기가 거부되면 저장된 payload를 검사하고 전체 config 형식을 수정하세요. +쓰기가 거부되면 저장된 페이로드를 확인하고 전체 구성 형태를 수정하세요. ```bash CONFIG="$(openclaw config file)" @@ -446,36 +450,36 @@ ls -lt "$CONFIG".rejected.* 2>/dev/null | head openclaw config validate ``` -직접 editor로 쓰는 것도 여전히 허용되지만, 실행 중인 Gateway는 검증될 때까지 이를 신뢰할 수 없는 것으로 취급합니다. 유효하지 않은 직접 편집은 시작에 실패하거나 hot reload에서 건너뛰어집니다. Gateway는 `openclaw.json`을 다시 쓰지 않습니다. 접두사가 붙었거나 덮어써진 config를 복구하거나 마지막으로 정상으로 알려진 복사본을 복원하려면 `openclaw doctor --fix`를 실행하세요. [Gateway 문제 해결](/ko/gateway/troubleshooting#gateway-rejected-invalid-config)을 참조하세요. +직접 편집기로 쓰는 것도 허용되지만, 실행 중인 Gateway는 검증이 완료될 때까지 이를 신뢰할 수 없는 것으로 취급합니다. 유효하지 않은 직접 편집은 시작에 실패하거나 핫 리로드에서 건너뜁니다. Gateway는 `openclaw.json`을 다시 쓰지 않습니다. 접두사가 붙었거나 덮어써진 구성을 복구하거나 마지막으로 정상인 복사본을 복원하려면 `openclaw doctor --fix`를 실행하세요. [Gateway 문제 해결](/ko/gateway/troubleshooting#gateway-rejected-invalid-config)을 참고하세요. -전체 파일 복구는 doctor 복구용으로만 예약되어 있습니다. Plugin schema 변경 또는 `minHostVersion` 불일치는 models, providers, auth profiles, channels, gateway exposure, tools, memory, browser, cron config 같은 관련 없는 사용자 설정을 롤백하는 대신 명확하게 드러납니다. +전체 파일 복구는 doctor 복구용으로만 예약되어 있습니다. Plugin 스키마 변경 또는 `minHostVersion` 불일치는 모델, provider, 인증 프로필, 채널, Gateway 노출, 도구, 메모리, 브라우저 또는 cron 구성 같은 관련 없는 사용자 설정을 롤백하는 대신 명확히 드러납니다. ## 하위 명령 -- `config file`: active config 파일 경로를 출력합니다(`OPENCLAW_CONFIG_PATH` 또는 기본 위치에서 확인됨). 경로는 symlink가 아니라 일반 파일이어야 합니다. +- `config file`: 활성 구성 파일 경로를 출력합니다(`OPENCLAW_CONFIG_PATH` 또는 기본 위치에서 해결됨). 경로는 심볼릭 링크가 아니라 일반 파일을 가리켜야 합니다. -편집 후 gateway를 다시 시작하세요. +편집 후 Gateway를 다시 시작하세요. ## 검증 -gateway를 시작하지 않고 현재 config를 active schema와 대조해 검증합니다. +Gateway를 시작하지 않고 현재 구성을 활성 스키마에 대해 검증합니다. ```bash openclaw config validate openclaw config validate --json ``` -`openclaw config validate`가 통과한 후에는 같은 터미널에서 각 변경 사항을 검증하는 동안, 내장 agent가 active config를 docs와 비교하도록 local TUI를 사용할 수 있습니다. +`openclaw config validate`가 통과한 후에는 로컬 TUI를 사용해 같은 터미널에서 각 변경 사항을 검증하는 동안 내장 에이전트가 활성 구성을 문서와 비교하도록 할 수 있습니다. -검증이 이미 실패하고 있다면 `openclaw configure` 또는 `openclaw doctor --fix`로 시작하세요. `openclaw chat`은 invalid-config guard를 우회하지 않습니다. +검증이 이미 실패하고 있다면 `openclaw configure` 또는 `openclaw doctor --fix`부터 시작하세요. `openclaw chat`은 유효하지 않은 구성 보호를 우회하지 않습니다. ```bash openclaw chat ``` -그런 다음 TUI 내부에서 실행합니다. +그런 다음 TUI 안에서: ```text !openclaw config file @@ -487,21 +491,21 @@ openclaw chat 일반적인 복구 루프: - - agent에게 현재 config를 관련 docs 페이지와 비교하고 가장 작은 수정 사항을 제안하도록 요청하세요. + + 에이전트에게 현재 구성을 관련 문서 페이지와 비교하고 가장 작은 수정 사항을 제안하도록 요청하세요. - - `openclaw config set` 또는 `openclaw configure`로 대상 편집을 적용하세요. + + `openclaw config set` 또는 `openclaw configure`로 대상 지정 편집을 적용하세요. 각 변경 후 `openclaw config validate`를 다시 실행하세요. - - 검증은 통과하지만 runtime이 여전히 정상적이지 않다면, migration 및 복구 도움을 위해 `openclaw doctor` 또는 `openclaw doctor --fix`를 실행하세요. + + 검증은 통과하지만 런타임이 여전히 정상적이지 않다면 마이그레이션 및 복구 도움말을 위해 `openclaw doctor` 또는 `openclaw doctor --fix`를 실행하세요. -## 관련 항목 +## 관련 - [CLI 참조](/ko/cli) -- [Configuration](/ko/gateway/configuration) +- [구성](/ko/gateway/configuration) diff --git a/docs/ko/cli/directory.md b/docs/ko/cli/directory.md index 85c01f1e5..0ee4f6fe9 100644 --- a/docs/ko/cli/directory.md +++ b/docs/ko/cli/directory.md @@ -1,21 +1,21 @@ --- read_when: - - 채널의 연락처/그룹/자기 ID를 조회하려고 합니다 - - 채널 디렉터리 어댑터를 개발하고 있습니다 -summary: '`openclaw directory`에 대한 CLI 참조(자신, 피어, 그룹)' + - 채널의 연락처/그룹/본인 ID를 조회하려는 경우 + - 채널 디렉터리 어댑터를 개발 중입니다 +summary: '`openclaw directory`용 CLI 참조 (자신, 피어, 그룹)' title: 디렉터리 x-i18n: - generated_at: "2026-05-02T20:44:49Z" + generated_at: "2026-05-06T17:52:29Z" model: gpt-5.5 provider: openai - source_hash: 011f762d6f53605a37bd12b31c767594c0efa5681da4b2aabe7fb358751b1542 + source_hash: 855f9312790134f2d1da53ffbb106167c190155510a7bdef212b5d38c2fba0b3 source_path: cli/directory.md workflow: 16 --- # `openclaw directory` -이를 지원하는 채널에 대한 디렉터리 조회(연락처/피어, 그룹, “나”). +이를 지원하는 채널의 디렉터리 조회(연락처/피어, 그룹 및 "나"). ## 공통 플래그 @@ -25,12 +25,12 @@ x-i18n: ## 참고 -- `directory`는 다른 명령어(특히 `openclaw message send --target ...`)에 붙여 넣을 수 있는 ID를 찾는 데 도움을 주기 위한 것입니다. -- 많은 채널에서 결과는 실시간 제공자 디렉터리가 아니라 설정 기반(허용 목록/구성된 그룹)입니다. -- 설치된 채널 Plugin은 디렉터리 지원을 생략할 수도 있습니다. 이 경우 명령어는 Plugin을 다시 설치하지 않고 지원되지 않는 디렉터리 작업을 보고합니다. -- 기본 출력은 탭으로 구분된 `id`(때로는 `name`)입니다. 스크립트 작성에는 `--json`을 사용하세요. +- `directory`는 다른 명령(특히 `openclaw message send --target ...`)에 붙여넣을 수 있는 ID를 찾는 데 도움을 주기 위한 것입니다. +- 많은 채널에서 결과는 라이브 제공자 디렉터리가 아니라 구성 기반(허용 목록 / 구성된 그룹)입니다. +- 설치된 채널 Plugin은 디렉터리 지원을 생략할 수도 있습니다. 이 경우 명령은 Plugin을 다시 설치하는 대신 지원되지 않는 디렉터리 작업을 보고합니다. +- 기본 출력은 탭으로 구분된 `id`(그리고 때로는 `name`)입니다. 스크립팅에는 `--json`을 사용하세요. -## `message send`에서 결과 사용하기 +## `message send`와 함께 결과 사용 ```bash openclaw directory peers list --channel slack --query "U0" @@ -39,8 +39,8 @@ openclaw message send --channel slack --target user:U012ABCDEF --message "hello" ## ID 형식(채널별) -- WhatsApp: `+15551234567`(DM), `1234567890-1234567890@g.us`(그룹), `120363123456789@newsletter`(Channel/Newsletter 발신 대상) -- Telegram: `@username` 또는 숫자 채팅 id. 그룹은 숫자 id입니다. +- WhatsApp: `+15551234567`(DM), `1234567890-1234567890@g.us`(그룹), `120363123456789@newsletter`(Channel/Newsletter 아웃바운드 대상) +- Telegram: `@username` 또는 숫자 채팅 id; 그룹은 숫자 id입니다 - Slack: `user:U…` 및 `channel:C…` - Discord: `user:` 및 `channel:` - Matrix(Plugin): `user:@user:server`, `room:!roomId:server` 또는 `#alias:server` @@ -48,7 +48,7 @@ openclaw message send --channel slack --target user:U012ABCDEF --message "hello" - Zalo(Plugin): 사용자 id(Bot API) - Zalo Personal / `zalouser`(Plugin): `zca`의 스레드 id(DM/그룹)(`me`, `friend list`, `group list`) -## 자신("me") +## 자신("나") ```bash openclaw directory self --channel zalouser diff --git a/docs/ko/cli/doctor.md b/docs/ko/cli/doctor.md index d613538dd..9104eae94 100644 --- a/docs/ko/cli/doctor.md +++ b/docs/ko/cli/doctor.md @@ -1,21 +1,21 @@ --- read_when: - - 연결/인증 문제가 있고 안내에 따른 해결 방법을 원합니다 - - 업데이트했고 간단한 점검을 원할 때 + - 연결 또는 인증 문제가 있고 단계별 해결 안내를 원함 + - 업데이트 후 간단한 점검이 필요한 경우 summary: '`openclaw doctor`에 대한 CLI 참조(상태 검사 + 안내형 복구)' title: 진단 x-i18n: - generated_at: "2026-05-06T06:19:09Z" + generated_at: "2026-05-06T17:53:07Z" model: gpt-5.5 provider: openai - source_hash: 20eff2f94b41315dbe1d393ebbbf6dce352a7f9e589db3b8fb51f423dd6fed28 + source_hash: eed73ecbec848ae3071448f2444735e2564680fee94cf1e22a73d1e7beaede80 source_path: cli/doctor.md workflow: 16 --- # `openclaw doctor` -Gateway와 채널의 상태 검사 + 빠른 수정. +Gateway 및 채널의 상태 검사와 빠른 수정. 관련 항목: @@ -35,46 +35,47 @@ openclaw doctor --generate-gateway-token ## 옵션 - `--no-workspace-suggestions`: 워크스페이스 메모리/검색 제안 비활성화 -- `--yes`: 묻지 않고 기본값 수락 -- `--repair`: 묻지 않고 권장 비서비스 복구 적용; Gateway 서비스 설치와 재작성은 여전히 대화형 확인 또는 명시적 Gateway 명령이 필요함 +- `--yes`: 프롬프트 없이 기본값 수락 +- `--repair`: 프롬프트 없이 권장되는 비서비스 복구 적용. Gateway 서비스 설치 및 재작성은 여전히 대화형 확인 또는 명시적인 Gateway 명령이 필요함 - `--fix`: `--repair`의 별칭 -- `--force`: 필요할 때 사용자 지정 서비스 구성을 덮어쓰는 것을 포함해 공격적인 복구 적용 -- `--non-interactive`: 프롬프트 없이 실행; 안전한 마이그레이션과 비서비스 복구만 수행 +- `--force`: 필요할 때 사용자 지정 서비스 설정 덮어쓰기를 포함해 적극적인 복구 적용 +- `--non-interactive`: 프롬프트 없이 실행. 안전한 마이그레이션 및 비서비스 복구만 수행 - `--generate-gateway-token`: Gateway 토큰 생성 및 구성 -- `--deep`: 추가 Gateway 설치를 찾기 위해 시스템 서비스를 스캔하고 최근 Gateway supervisor 재시작 인계를 보고 +- `--deep`: 추가 Gateway 설치를 찾기 위해 시스템 서비스를 스캔하고 최근 Gateway supervisor 재시작 핸드오프 보고 참고: -- 대화형 프롬프트(예: 키체인/OAuth 수정)는 stdin이 TTY이고 `--non-interactive`가 설정되어 **있지 않을 때만** 실행됩니다. 헤드리스 실행(cron, Telegram, 터미널 없음)은 프롬프트를 건너뜁니다. -- 성능: 비대화형 `doctor` 실행은 헤드리스 상태 검사가 빠르게 유지되도록 즉시 Plugin 로딩을 건너뜁니다. 대화형 세션은 검사가 Plugin의 기여를 필요로 할 때 여전히 Plugin을 완전히 로드합니다. -- `--fix`(`--repair`의 별칭)는 백업을 `~/.openclaw/openclaw.json.bak`에 쓰고 알 수 없는 구성 키를 제거하며, 제거 항목을 각각 나열합니다. -- `doctor --fix --non-interactive`는 누락되었거나 오래된 Gateway 서비스 정의를 보고하지만 업데이트 복구 모드 밖에서는 이를 설치하거나 재작성하지 않습니다. 서비스가 누락된 경우 `openclaw gateway install`을 실행하거나, 런처를 의도적으로 교체하려는 경우 `openclaw gateway install --force`를 실행하세요. -- 상태 무결성 검사는 이제 세션 디렉터리의 고아 transcript 파일을 감지합니다. 이를 `.deleted.`로 보관하려면 대화형 확인이 필요합니다. `--fix`, `--yes`, 헤드리스 실행은 해당 파일을 그대로 둡니다. -- Doctor는 또한 `~/.openclaw/cron/jobs.json`(또는 `cron.store`)에서 레거시 Cron 작업 형태를 스캔하고, 스케줄러가 런타임에 자동 정규화해야 하기 전에 제자리에서 재작성할 수 있습니다. -- Linux에서 doctor는 사용자의 crontab이 여전히 레거시 `~/.openclaw/bin/ensure-whatsapp.sh`를 실행할 때 경고합니다. 해당 스크립트는 더 이상 유지 관리되지 않으며 Cron에 systemd 사용자 버스 환경이 없을 때 잘못된 WhatsApp Gateway 중단을 로그로 남길 수 있습니다. -- WhatsApp이 활성화된 경우 doctor는 로컬 `openclaw-tui` 클라이언트가 계속 실행 중인 상태에서 성능이 저하된 Gateway 이벤트 루프를 확인합니다. `doctor --fix`는 WhatsApp 응답이 오래된 TUI 새로 고침 루프 뒤에 큐잉되지 않도록 검증된 로컬 TUI 클라이언트만 중지합니다. -- Doctor는 기본 모델, 폴백, Heartbeat/subagent/Compaction 재정의, 훅, 채널 모델 재정의, 오래된 세션 라우트 핀 전반에서 레거시 `openai-codex/*` 모델 참조를 표준 `openai/*` 참조로 재작성합니다. Codex Plugin이 설치되어 있고, 활성화되어 있으며, `codex` 하네스를 제공하고, 사용 가능한 OAuth가 있을 때만 `--fix`는 `agentRuntime.id: "codex"`를 선택합니다. 그렇지 않으면 라우트가 기본 OpenClaw 러너에 유지되도록 `agentRuntime.id: "pi"`를 선택합니다. -- Doctor는 이전 OpenClaw 버전이 만든 레거시 Plugin 의존성 스테이징 상태를 정리합니다. 또한 `plugins.entries`, 구성된 채널, 구성된 공급자/검색 설정, 구성된 에이전트 런타임처럼 구성에서 참조하는 다운로드 가능한 Plugin이 누락된 경우 복구합니다. 패키지 업데이트 중에는 패키지 교체가 완료될 때까지 doctor가 패키지 관리자 Plugin 복구를 건너뜁니다. 구성된 Plugin에 여전히 복구가 필요하면 이후 `openclaw doctor --fix`를 다시 실행하세요. 다운로드가 실패하면 doctor는 설치 오류를 보고하고 다음 복구 시도를 위해 구성된 Plugin 항목을 보존합니다. -- Plugin 발견이 정상일 때 Doctor는 `plugins.allow`/`plugins.entries`에서 누락된 Plugin id를 제거하고, 일치하는 매달린 채널 구성, Heartbeat 대상, 채널 모델 재정의도 함께 제거하여 오래된 Plugin 구성을 복구합니다. -- Doctor는 영향을 받는 `plugins.entries.` 항목을 비활성화하고 잘못된 `config` 페이로드를 제거하여 유효하지 않은 Plugin 구성을 격리합니다. Gateway 시작은 이미 문제가 있는 해당 Plugin만 건너뛰므로 다른 Plugins와 채널은 계속 실행될 수 있습니다. +- Nix 모드(`OPENCLAW_NIX_MODE=1`)에서는 읽기 전용 doctor 검사는 계속 작동하지만, `openclaw.json`이 변경 불가능하므로 `doctor --fix`, `doctor --repair`, `doctor --yes`, `doctor --generate-gateway-token`은 비활성화됩니다. 대신 이 설치의 Nix 소스를 편집하세요. nix-openclaw의 경우 agent-first [빠른 시작](https://github.com/openclaw/nix-openclaw#quick-start)을 사용하세요. +- 대화형 프롬프트(예: keychain/OAuth 수정)는 stdin이 TTY이고 `--non-interactive`가 설정되지 않은 경우에만 실행됩니다. headless 실행(cron, Telegram, 터미널 없음)은 프롬프트를 건너뜁니다. +- 성능: 비대화형 `doctor` 실행은 즉시 Plugin 로딩을 건너뛰어 headless 상태 검사를 빠르게 유지합니다. 대화형 세션은 검사가 Plugin 기여를 필요로 할 때 여전히 Plugin을 완전히 로드합니다. +- `--fix`(`--repair`의 별칭)는 `~/.openclaw/openclaw.json.bak`에 백업을 쓰고 알 수 없는 설정 키를 제거하며, 각 제거 항목을 나열합니다. +- `doctor --fix --non-interactive`는 누락되었거나 오래된 Gateway 서비스 정의를 보고하지만 업데이트 복구 모드 밖에서는 설치하거나 재작성하지 않습니다. 서비스가 누락된 경우 `openclaw gateway install`을 실행하고, launcher를 의도적으로 교체하려면 `openclaw gateway install --force`를 실행하세요. +- 상태 무결성 검사는 이제 sessions 디렉터리의 고아 transcript 파일을 감지합니다. 이를 `.deleted.`로 아카이브하려면 대화형 확인이 필요합니다. `--fix`, `--yes`, headless 실행은 그대로 둡니다. +- Doctor는 `~/.openclaw/cron/jobs.json`(또는 `cron.store`)도 스캔하여 레거시 cron 작업 형태를 찾고, 스케줄러가 런타임에 자동 정규화하기 전에 제자리에서 재작성할 수 있습니다. +- Linux에서 doctor는 사용자의 crontab이 여전히 레거시 `~/.openclaw/bin/ensure-whatsapp.sh`를 실행할 때 경고합니다. 이 스크립트는 더 이상 유지 관리되지 않으며, cron에 systemd 사용자 버스 환경이 없을 때 잘못된 WhatsApp Gateway 중단을 기록할 수 있습니다. +- WhatsApp이 활성화된 경우 doctor는 로컬 `openclaw-tui` 클라이언트가 계속 실행 중인 상태에서 성능이 저하된 Gateway 이벤트 루프를 확인합니다. `doctor --fix`는 검증된 로컬 TUI 클라이언트만 중지하여 WhatsApp 응답이 오래된 TUI 새로 고침 루프 뒤에 대기하지 않도록 합니다. +- Doctor는 기본 모델, 폴백, heartbeat/subagent/compaction override, hook, 채널 모델 override, 오래된 세션 route pin 전반에서 레거시 `openai-codex/*` 모델 참조를 표준 `openai/*` 참조로 재작성합니다. `--fix`는 Codex Plugin이 설치되어 있고, 활성화되어 있으며, `codex` harness를 기여하고, 사용 가능한 OAuth가 있을 때만 `agentRuntime.id: "codex"`를 선택합니다. 그렇지 않으면 route가 기본 OpenClaw runner에 머물도록 `agentRuntime.id: "pi"`를 선택합니다. +- Doctor는 이전 OpenClaw 버전에서 생성된 레거시 Plugin 의존성 staging 상태를 정리합니다. 또한 `plugins.entries`, 구성된 채널, 구성된 provider/search 설정, 구성된 agent runtime처럼 설정에서 참조하는 누락된 다운로드 가능 Plugin도 복구합니다. 패키지 업데이트 중에는 패키지 교체가 완료될 때까지 doctor가 package-manager Plugin 복구를 건너뜁니다. 구성된 Plugin에 여전히 복구가 필요하면 이후 `openclaw doctor --fix`를 다시 실행하세요. 다운로드가 실패하면 doctor는 설치 오류를 보고하고 다음 복구 시도를 위해 구성된 Plugin 항목을 보존합니다. +- Doctor는 Plugin 탐색이 정상일 때 누락된 Plugin ID를 `plugins.allow`/`plugins.entries`에서 제거하고, 일치하는 dangling 채널 설정, Heartbeat 대상, 채널 모델 override도 함께 제거하여 오래된 Plugin 설정을 복구합니다. +- Doctor는 영향을 받는 `plugins.entries.` 항목을 비활성화하고 잘못된 `config` payload를 제거하여 잘못된 Plugin 설정을 격리합니다. Gateway 시작은 이미 해당 잘못된 Plugin만 건너뛰므로 다른 Plugin과 채널은 계속 실행될 수 있습니다. - 다른 supervisor가 Gateway 수명 주기를 소유하는 경우 `OPENCLAW_SERVICE_REPAIR_POLICY=external`을 설정하세요. Doctor는 여전히 Gateway/서비스 상태를 보고하고 비서비스 복구를 적용하지만, 서비스 설치/시작/재시작/bootstrap 및 레거시 서비스 정리는 건너뜁니다. -- Linux에서 doctor는 비활성 추가 Gateway 유사 systemd 유닛을 무시하며, 복구 중 실행 중인 systemd Gateway 서비스의 명령/엔트리포인트 메타데이터를 재작성하지 않습니다. 활성 런처를 의도적으로 교체하려면 먼저 서비스를 중지하거나 `openclaw gateway install --force`를 사용하세요. -- Doctor는 레거시 평면 Talk 구성(`talk.voiceId`, `talk.modelId` 및 관련 항목)을 `talk.provider` + `talk.providers.`로 자동 마이그레이션합니다. -- 반복적인 `doctor --fix` 실행은 유일한 차이가 객체 키 순서일 때 더 이상 Talk 정규화를 보고/적용하지 않습니다. -- Doctor에는 메모리 검색 준비 상태 검사가 포함되며, 임베딩 자격 증명이 누락된 경우 `openclaw configure --section model`을 권장할 수 있습니다. -- Doctor는 구성된 명령 소유자가 없을 때 경고합니다. 명령 소유자는 소유자 전용 명령을 실행하고 위험한 작업을 승인할 수 있는 인간 운영자 계정입니다. DM 페어링은 누군가가 봇과 대화할 수 있게만 합니다. 첫 번째 소유자 bootstrap이 생기기 전에 발신자를 승인했다면 `commands.ownerAllowFrom`을 명시적으로 설정하세요. -- Doctor는 Codex 모드 에이전트가 구성되어 있고 운영자의 Codex 홈에 개인 Codex CLI 자산이 있을 때 경고합니다. 로컬 Codex 앱 서버 실행은 에이전트별로 격리된 홈을 사용하므로, 의도적으로 승격해야 할 자산 목록을 작성하려면 `openclaw migrate codex --dry-run`을 사용하세요. -- Doctor는 기본 에이전트에 허용된 Skills가 현재 런타임 환경에서 사용할 수 없을 때 경고합니다. 이는 bin, env var, config 또는 OS 요구 사항이 누락되었기 때문입니다. `doctor --fix`는 사용할 수 없는 Skills를 `skills.entries..enabled=false`로 비활성화할 수 있습니다. Skills를 활성 상태로 유지하려면 대신 누락된 요구 사항을 설치/구성하세요. -- 샌드박스 모드가 활성화되어 있지만 Docker를 사용할 수 없는 경우 doctor는 해결 방법(`install Docker` 또는 `openclaw config set agents.defaults.sandbox.mode off`)과 함께 신호가 높은 경고를 보고합니다. -- 레거시 샌드박스 레지스트리 파일(`~/.openclaw/sandbox/containers.json` 또는 `~/.openclaw/sandbox/browsers.json`)이 있으면 doctor가 이를 보고합니다. `openclaw doctor --fix`는 유효한 항목을 샤딩된 레지스트리 디렉터리로 마이그레이션하고 유효하지 않은 레거시 파일을 격리합니다. -- `gateway.auth.token`/`gateway.auth.password`가 SecretRef로 관리되고 현재 명령 경로에서 사용할 수 없는 경우 doctor는 읽기 전용 경고를 보고하며 일반 텍스트 폴백 자격 증명을 쓰지 않습니다. -- 수정 경로에서 채널 SecretRef 검사가 실패하면 doctor는 조기에 종료하는 대신 계속 진행하고 경고를 보고합니다. -- 상태 디렉터리 마이그레이션 후, 활성화된 기본 Telegram 또는 Discord 계정이 env 폴백에 의존하고 `TELEGRAM_BOT_TOKEN` 또는 `DISCORD_BOT_TOKEN`을 doctor 프로세스에서 사용할 수 없으면 doctor가 경고합니다. -- Telegram `allowFrom` 사용자 이름 자동 확인(`doctor --fix`)에는 현재 명령 경로에서 확인 가능한 Telegram 토큰이 필요합니다. 토큰 검사를 사용할 수 없으면 doctor는 경고를 보고하고 해당 실행에서는 자동 확인을 건너뜁니다. +- Linux에서 doctor는 비활성 추가 Gateway 유사 systemd unit을 무시하며, 복구 중 실행 중인 systemd Gateway 서비스의 command/entrypoint 메타데이터를 재작성하지 않습니다. 활성 launcher를 의도적으로 교체하려면 먼저 서비스를 중지하거나 `openclaw gateway install --force`를 사용하세요. +- Doctor는 레거시 flat Talk 설정(`talk.voiceId`, `talk.modelId` 등)을 `talk.provider` + `talk.providers.`로 자동 마이그레이션합니다. +- 반복되는 `doctor --fix` 실행은 유일한 차이가 객체 키 순서뿐이면 더 이상 Talk 정규화를 보고/적용하지 않습니다. +- Doctor에는 메모리 검색 준비 상태 검사가 포함되며 embedding 자격 증명이 누락된 경우 `openclaw configure --section model`을 권장할 수 있습니다. +- Doctor는 command owner가 구성되지 않은 경우 경고합니다. command owner는 owner 전용 명령을 실행하고 위험한 작업을 승인할 수 있는 사람 operator 계정입니다. DM pairing은 누군가가 bot과 대화할 수 있게만 합니다. first-owner bootstrap이 존재하기 전에 발신자를 승인했다면 `commands.ownerAllowFrom`을 명시적으로 설정하세요. +- Doctor는 Codex 모드 agent가 구성되어 있고 operator의 Codex home에 개인 Codex CLI 자산이 있는 경우 경고합니다. 로컬 Codex app-server 실행은 agent별로 격리된 home을 사용하므로, 의도적으로 승격해야 하는 자산을 목록화하려면 `openclaw migrate codex --dry-run`을 사용하세요. +- Doctor는 기본 agent에 허용된 Skills가 bins, env vars, config, OS 요구 사항 누락 때문에 현재 런타임 환경에서 사용할 수 없는 경우 경고합니다. `doctor --fix`는 `skills.entries..enabled=false`로 이러한 사용할 수 없는 Skills를 비활성화할 수 있습니다. 해당 Skills를 활성 상태로 유지하려면 대신 누락된 요구 사항을 설치/구성하세요. +- sandbox 모드가 활성화되어 있지만 Docker를 사용할 수 없는 경우 doctor는 remediation(`install Docker` 또는 `openclaw config set agents.defaults.sandbox.mode off`)과 함께 핵심 경고를 보고합니다. +- 레거시 sandbox registry 파일(`~/.openclaw/sandbox/containers.json` 또는 `~/.openclaw/sandbox/browsers.json`)이 있는 경우 doctor가 이를 보고합니다. `openclaw doctor --fix`는 유효한 항목을 sharded registry 디렉터리로 마이그레이션하고 잘못된 레거시 파일을 격리합니다. +- `gateway.auth.token`/`gateway.auth.password`가 SecretRef로 관리되고 현재 명령 경로에서 사용할 수 없는 경우 doctor는 읽기 전용 경고를 보고하고 평문 fallback 자격 증명을 쓰지 않습니다. +- fix 경로에서 채널 SecretRef 검사가 실패하면 doctor는 조기 종료하지 않고 계속 진행하며 경고를 보고합니다. +- 상태 디렉터리 마이그레이션 후 활성화된 기본 Telegram 또는 Discord 계정이 env fallback에 의존하고 `TELEGRAM_BOT_TOKEN` 또는 `DISCORD_BOT_TOKEN`을 doctor 프로세스에서 사용할 수 없는 경우 doctor가 경고합니다. +- Telegram `allowFrom` username 자동 해석(`doctor --fix`)에는 현재 명령 경로에서 해석 가능한 Telegram 토큰이 필요합니다. 토큰 검사를 사용할 수 없는 경우 doctor는 경고를 보고하고 해당 pass의 자동 해석을 건너뜁니다. -## macOS: `launchctl` env 재정의 +## macOS: `launchctl` env override -이전에 `launchctl setenv OPENCLAW_GATEWAY_TOKEN ...`(또는 `...PASSWORD`)을 실행했다면, 해당 값이 구성 파일보다 우선하며 지속적인 “unauthorized” 오류를 일으킬 수 있습니다. +이전에 `launchctl setenv OPENCLAW_GATEWAY_TOKEN ...`(또는 `...PASSWORD`)을 실행했다면, 해당 값이 설정 파일보다 우선하며 지속적인 "unauthorized" 오류를 유발할 수 있습니다. ```bash launchctl getenv OPENCLAW_GATEWAY_TOKEN @@ -87,4 +88,4 @@ launchctl unsetenv OPENCLAW_GATEWAY_PASSWORD ## 관련 항목 - [CLI 참조](/ko/cli) -- [Gateway doctor](/ko/gateway/doctor) +- [Gateway 진단](/ko/gateway/doctor) diff --git a/docs/ko/cli/hooks.md b/docs/ko/cli/hooks.md index b70a8cda3..c9f1e9779 100644 --- a/docs/ko/cli/hooks.md +++ b/docs/ko/cli/hooks.md @@ -1,23 +1,23 @@ --- read_when: - - 에이전트 훅을 관리하려는 경우 - - 훅 사용 가능 여부를 검사하거나 워크스페이스 훅을 활성화하려는 경우 -summary: '`openclaw hooks`(에이전트 훅)에 대한 CLI 참조' + - 에이전트 후크를 관리하려고 합니다 + - 훅 사용 가능 여부를 확인하거나 워크스페이스 훅을 활성화하려는 경우 +summary: '`openclaw hooks`의 CLI 참조(에이전트 훅)' title: 후크 x-i18n: - generated_at: "2026-05-05T08:25:34Z" + generated_at: "2026-05-06T17:53:16Z" model: gpt-5.5 provider: openai - source_hash: 8e860d4a20a09526e804fa1aff8c983a75396fcd1e6e24f742252fdf1812f6b7 + source_hash: 56dd1ef82458dde3280e2cdfb4f3835211726517416e90625d3272d128eb9e0e source_path: cli/hooks.md workflow: 16 --- # `openclaw hooks` -에이전트 훅(`/new`, `/reset`, Gateway 시작 같은 명령에 대한 이벤트 기반 자동화)을 관리합니다. +에이전트 훅(`/new`, `/reset`, Gateway 시작 같은 명령용 이벤트 기반 자동화)을 관리합니다. -하위 명령 없이 `openclaw hooks`를 실행하는 것은 `openclaw hooks list`와 동일합니다. +하위 명령 없이 `openclaw hooks`를 실행하는 것은 `openclaw hooks list`와 같습니다. 관련 항목: @@ -30,14 +30,14 @@ x-i18n: openclaw hooks list ``` -워크스페이스, 관리형, 추가, 번들 디렉터리에서 발견된 모든 훅을 나열합니다. -Gateway 시작 시에는 내부 훅이 하나 이상 구성될 때까지 내부 훅 핸들러를 로드하지 않습니다. +워크스페이스, 관리형, 추가 및 번들 디렉터리에서 발견된 모든 훅을 나열합니다. +Gateway 시작은 내부 훅이 하나 이상 구성될 때까지 내부 훅 핸들러를 로드하지 않습니다. **옵션:** -- `--eligible`: 요구사항을 충족한 적격 훅만 표시 +- `--eligible`: 적격한 훅만 표시(요구 사항 충족) - `--json`: JSON으로 출력 -- `-v, --verbose`: 누락된 요구사항을 포함한 자세한 정보 표시 +- `-v, --verbose`: 누락된 요구 사항을 포함한 자세한 정보 표시 **예시 출력:** @@ -57,7 +57,7 @@ Ready: openclaw hooks list --verbose ``` -부적격 훅의 누락된 요구사항을 표시합니다. +적격하지 않은 훅의 누락된 요구 사항을 표시합니다. **예시(JSON):** @@ -113,7 +113,7 @@ Requirements: openclaw hooks check ``` -훅 적격성 상태 요약(준비됨과 준비되지 않음의 개수)을 표시합니다. +훅 적격성 상태 요약(준비됨과 준비되지 않음의 수)을 표시합니다. **옵션:** @@ -135,9 +135,9 @@ Not ready: 0 openclaw hooks enable ``` -구성(기본값은 `~/.openclaw/openclaw.json`)에 추가하여 특정 훅을 활성화합니다. +구성(기본값: `~/.openclaw/openclaw.json`)에 특정 훅을 추가하여 활성화합니다. -**참고:** 워크스페이스 훅은 여기 또는 구성에서 활성화하기 전까지 기본적으로 비활성화됩니다. Plugin이 관리하는 훅은 `openclaw hooks list`에 `plugin:`로 표시되며 여기서는 활성화/비활성화할 수 없습니다. 대신 Plugin을 활성화/비활성화하세요. +**참고:** 워크스페이스 훅은 여기 또는 구성에서 활성화할 때까지 기본적으로 비활성화되어 있습니다. Plugin이 관리하는 훅은 `openclaw hooks list`에 `plugin:`로 표시되며 여기서 활성화/비활성화할 수 없습니다. 대신 해당 Plugin을 활성화/비활성화하세요. **인수:** @@ -157,15 +157,16 @@ openclaw hooks enable session-memory **수행 작업:** -- 훅이 존재하고 적격인지 확인 -- 구성에서 `hooks.internal.entries..enabled = true`로 업데이트 +- 훅이 존재하고 적격한지 확인 +- 구성에서 `hooks.internal.entries..enabled = true` 업데이트 - 구성을 디스크에 저장 -훅이 `/hooks/`에서 온 경우, Gateway가 이를 로드하려면 이 옵트인 단계가 필요합니다. +훅이 `/hooks/`에서 온 경우, Gateway가 이를 로드하기 전에 +이 옵트인 단계가 필요합니다. **활성화 후:** -- 훅이 다시 로드되도록 Gateway를 다시 시작합니다(macOS에서는 메뉴 막대 앱 재시작, 또는 개발 환경에서는 Gateway 프로세스 재시작). +- 훅이 다시 로드되도록 Gateway를 재시작합니다(macOS에서는 메뉴 막대 앱 재시작, 또는 개발 환경에서는 Gateway 프로세스 재시작). ## 훅 비활성화 @@ -193,7 +194,7 @@ openclaw hooks disable command-logger **비활성화 후:** -- 훅이 다시 로드되도록 Gateway를 다시 시작합니다. +- 훅이 다시 로드되도록 Gateway를 재시작합니다 ## 참고 @@ -211,24 +212,28 @@ openclaw plugins install # local path 통합 Plugin 설치 관리자를 통해 훅 팩을 설치합니다. -`openclaw hooks install`은 호환성 별칭으로 계속 동작하지만, 사용 중단 경고를 출력하고 `openclaw plugins install`로 전달합니다. +`openclaw hooks install`은 호환성 별칭으로 계속 작동하지만, 지원 중단 경고를 출력하고 `openclaw plugins install`로 전달합니다. -Npm 명세는 **레지스트리 전용**입니다(패키지 이름 + 선택적 **정확한 버전** 또는 **dist-tag**). Git/URL/file 명세와 semver 범위는 거부됩니다. 종속성 설치는 셸에 전역 npm 설치 설정이 있더라도 안전을 위해 `--ignore-scripts`와 함께 프로젝트 로컬로 실행됩니다. +Npm 사양은 **레지스트리 전용**입니다(패키지 이름 + 선택적 **정확한 버전** 또는 +**dist-tag**). Git/URL/file 사양과 semver 범위는 거부됩니다. 종속성 +설치는 안전을 위해 프로젝트 로컬에서 `--ignore-scripts`로 실행되며, 셸에 전역 npm 설치 설정이 있어도 동일합니다. -Bare 명세와 `@latest`는 안정 트랙에 유지됩니다. npm이 이 둘 중 하나를 프리릴리스로 해석하면 OpenClaw는 중단하고 `@beta`/`@rc` 같은 프리릴리스 태그 또는 정확한 프리릴리스 버전으로 명시적으로 옵트인하라고 요청합니다. +기본 사양과 `@latest`는 안정 트랙에 유지됩니다. npm이 이 둘 중 하나를 +프리릴리스로 해석하면 OpenClaw는 중단하고 `@beta`/`@rc` 같은 +프리릴리스 태그 또는 정확한 프리릴리스 버전으로 명시적으로 옵트인하라고 요청합니다. **수행 작업:** - 훅 팩을 `~/.openclaw/hooks/`로 복사 - 설치된 훅을 `hooks.internal.entries.*`에서 활성화 -- 설치를 `hooks.internal.installs` 아래에 기록 +- 설치 내역을 `hooks.internal.installs` 아래에 기록 **옵션:** -- `-l, --link`: 복사하는 대신 로컬 디렉터리를 링크합니다(`hooks.internal.load.extraDirs`에 추가) -- `--pin`: npm 설치를 `hooks.internal.installs`에 정확히 해석된 `name@version`으로 기록 +- `-l, --link`: 로컬 디렉터리를 복사하는 대신 연결합니다(`hooks.internal.load.extraDirs`에 추가) +- `--pin`: npm 설치를 정확히 해석된 `name@version`으로 `hooks.internal.installs`에 기록 -**지원 아카이브:** `.zip`, `.tgz`, `.tar.gz`, `.tar` +**지원되는 아카이브:** `.zip`, `.tgz`, `.tar.gz`, `.tar` **예시:** @@ -246,7 +251,7 @@ openclaw plugins install @openclaw/my-hook-pack openclaw plugins install -l ./my-hook-pack ``` -링크된 훅 팩은 워크스페이스 훅이 아니라 운영자가 구성한 디렉터리의 관리형 훅으로 처리됩니다. +연결된 훅 팩은 워크스페이스 훅이 아니라, 운영자가 구성한 디렉터리의 관리형 훅으로 취급됩니다. ## 훅 팩 업데이트 @@ -255,16 +260,17 @@ openclaw plugins update openclaw plugins update --all ``` -통합 Plugin 업데이트 도구를 통해 추적 중인 npm 기반 훅 팩을 업데이트합니다. +통합 Plugin 업데이트 관리자를 통해 추적 중인 npm 기반 훅 팩을 업데이트합니다. -`openclaw hooks update`는 호환성 별칭으로 계속 동작하지만, 사용 중단 경고를 출력하고 `openclaw plugins update`로 전달합니다. +`openclaw hooks update`는 호환성 별칭으로 계속 작동하지만, 지원 중단 경고를 출력하고 `openclaw plugins update`로 전달합니다. **옵션:** - `--all`: 추적 중인 모든 훅 팩 업데이트 -- `--dry-run`: 쓰기 없이 변경될 내용을 표시 +- `--dry-run`: 쓰지 않고 변경될 내용을 표시 -저장된 무결성 해시가 있고 가져온 아티팩트 해시가 변경되면 OpenClaw는 경고를 출력하고 계속 진행하기 전에 확인을 요청합니다. CI/비대화형 실행에서 프롬프트를 건너뛰려면 전역 `--yes`를 사용하세요. +저장된 무결성 해시가 있고 가져온 아티팩트 해시가 변경되면, +OpenClaw는 경고를 출력하고 계속하기 전에 확인을 요청합니다. CI/비대화형 실행에서 프롬프트를 우회하려면 전역 `--yes`를 사용하세요. ## 번들 훅 @@ -284,7 +290,7 @@ openclaw hooks enable session-memory ### bootstrap-extra-files -`agent:bootstrap` 중에 추가 부트스트랩 파일(예: 모노레포 로컬 `AGENTS.md` / `TOOLS.md`)을 주입합니다. +`agent:bootstrap` 중 추가 부트스트랩 파일(예: 모노레포 로컬 `AGENTS.md` / `TOOLS.md`)을 주입합니다. **활성화:** @@ -296,7 +302,7 @@ openclaw hooks enable bootstrap-extra-files ### command-logger -모든 명령 이벤트를 중앙 감사 파일에 기록합니다. +모든 명령 이벤트를 중앙 집중식 감사 파일에 기록합니다. **활성화:** @@ -323,7 +329,7 @@ grep '"action":"new"' ~/.openclaw/logs/commands.log | jq . ### boot-md -Gateway가 시작될 때(채널이 시작된 후) `BOOT.md`를 실행합니다. +Gateway가 시작될 때(채널 시작 후) `BOOT.md`를 실행합니다. **이벤트**: `gateway:startup` diff --git a/docs/ko/cli/memory.md b/docs/ko/cli/memory.md index 6f2a55f5f..1cad4163d 100644 --- a/docs/ko/cli/memory.md +++ b/docs/ko/cli/memory.md @@ -1,32 +1,32 @@ --- read_when: - - 의미 메모리를 색인화하거나 검색하려는 경우 + - 의미 메모리를 인덱싱하거나 검색하려는 경우 - 메모리 가용성 또는 인덱싱을 디버깅하는 중입니다 - - 불러온 단기 기억을 `MEMORY.md`(으)로 승격하려고 합니다 + - 회상된 단기 기억을 `MEMORY.md`로 승격하려는 경우 summary: '`openclaw memory`에 대한 CLI 참조 (status/index/search/promote/promote-explain/rem-harness)' title: 메모리 x-i18n: - generated_at: "2026-05-03T21:28:49Z" + generated_at: "2026-05-06T17:53:34Z" model: gpt-5.5 provider: openai - source_hash: a33b848272c8853dd1a83e942124f0df30e096312e58a395c0ea08058e41f8fe + source_hash: 7137f8a9529095204699de5fee7a0baf5d5a377792dc93b4059145d0eefab737 source_path: cli/memory.md workflow: 16 --- # `openclaw memory` -의미 기반 메모리 인덱싱 및 검색을 관리합니다. +시맨틱 메모리 인덱싱과 검색을 관리합니다. Active Memory Plugin에서 제공합니다(기본값: `memory-core`; 비활성화하려면 `plugins.slots.memory = "none"` 설정). 관련 항목: -- 메모리 개념: [메모리](/ko/concepts/memory) -- 메모리 위키: [메모리 위키](/ko/plugins/memory-wiki) -- 위키 CLI: [wiki](/ko/cli/wiki) +- 메모리 개념: [Memory](/ko/concepts/memory) +- 메모리 위키: [Memory Wiki](/ko/plugins/memory-wiki) +- Wiki CLI: [wiki](/ko/cli/wiki) - Plugins: [Plugins](/ko/tools/plugin) -## 예제 +## 예시 ```bash openclaw memory status @@ -53,17 +53,17 @@ openclaw memory index --agent main --verbose `memory status` 및 `memory index`: -- `--agent `: 단일 에이전트로 범위를 제한합니다. 이 옵션이 없으면 이러한 명령은 구성된 각 에이전트에 대해 실행됩니다. 에이전트 목록이 구성되어 있지 않으면 기본 에이전트로 대체됩니다. -- `--verbose`: 프로브 및 인덱싱 중 자세한 로그를 출력합니다. +- `--agent `: 단일 에이전트로 범위를 제한합니다. 지정하지 않으면 이러한 명령은 구성된 각 에이전트에 대해 실행됩니다. 에이전트 목록이 구성되어 있지 않으면 기본 에이전트로 대체됩니다. +- `--verbose`: 프로브와 인덱싱 중 자세한 로그를 출력합니다. `memory status`: -- `--deep`: 로컬 벡터 저장소 준비 상태, 임베딩 제공자 준비 상태, 의미 기반 벡터 검색 준비 상태를 프로브합니다. 일반 `memory status`는 빠르게 유지되며 라이브 임베딩 또는 제공자 탐색 작업을 실행하지 않습니다. 알 수 없는 벡터 저장소 또는 의미 기반 벡터 상태는 해당 명령에서 프로브되지 않았다는 뜻입니다. QMD 어휘 `searchMode: "search"`는 `--deep`을 사용하더라도 의미 기반 벡터 프로브와 임베딩 유지 관리를 건너뜁니다. -- `--index`: 저장소가 dirty 상태이면 재인덱싱을 실행합니다(`--deep`을 암시). -- `--fix`: 오래된 recall lock을 복구하고 promotion 메타데이터를 정규화합니다. -- `--json`: JSON 출력을 인쇄합니다. +- `--deep`: 로컬 벡터 저장소 준비 상태, 임베딩 제공자 준비 상태, 시맨틱 벡터 검색 준비 상태를 프로브합니다. 일반 `memory status`는 빠르게 유지되며 라이브 임베딩 또는 제공자 검색 작업을 실행하지 않습니다. 알 수 없는 벡터 저장소 또는 시맨틱 벡터 상태는 해당 명령에서 프로브되지 않았다는 의미입니다. QMD 어휘 `searchMode: "search"`는 `--deep`을 사용하더라도 시맨틱 벡터 프로브와 임베딩 유지 관리를 건너뜁니다. +- `--index`: 저장소가 더티 상태이면 재인덱싱을 실행합니다(`--deep`을 내포). +- `--fix`: 오래된 회상 잠금을 복구하고 승격 메타데이터를 정규화합니다. +- `--json`: JSON 출력을 표시합니다. -`memory status`에 `Dreaming status: blocked`가 표시되면 관리형 Dreaming Cron은 활성화되어 있지만 이를 구동하는 Heartbeat가 기본 에이전트에 대해 실행되고 있지 않은 것입니다. 두 가지 일반적인 원인은 [Dreaming이 실행되지 않음](/ko/concepts/dreaming#dreaming-never-runs-status-shows-blocked)을 참조하세요. +`memory status`에 `Dreaming status: blocked`가 표시되면 관리형 Dreaming Cron이 활성화되어 있지만, 이를 구동하는 Heartbeat가 기본 에이전트에서 실행되고 있지 않은 것입니다. 두 가지 일반적인 원인은 [Dreaming이 실행되지 않음](/ko/concepts/dreaming#dreaming-never-runs-status-shows-blocked)을 참조하세요. `memory index`: @@ -77,37 +77,37 @@ openclaw memory index --agent main --verbose - `--agent `: 단일 에이전트로 범위를 제한합니다(기본값: 기본 에이전트). - `--max-results `: 반환되는 결과 수를 제한합니다. - `--min-score `: 낮은 점수의 일치를 필터링합니다. -- `--json`: JSON 결과를 인쇄합니다. +- `--json`: JSON 결과를 표시합니다. `memory promote`: -단기 메모리 promotion을 미리 보고 적용합니다. +단기 메모리 승격을 미리 보고 적용합니다. ```bash openclaw memory promote [--apply] [--limit ] [--include-promoted] ``` -- `--apply` -- promotion을 `MEMORY.md`에 씁니다(기본값: 미리 보기만). +- `--apply` -- 승격 항목을 `MEMORY.md`에 씁니다(기본값: 미리 보기만). - `--limit ` -- 표시할 후보 수를 제한합니다. -- `--include-promoted` -- 이전 주기에서 이미 promoted된 항목을 포함합니다. +- `--include-promoted` -- 이전 주기에 이미 승격된 항목을 포함합니다. 전체 옵션: -- 가중 promotion 신호(`frequency`, `relevance`, `query diversity`, `recency`, `consolidation`, `conceptual richness`)를 사용해 `memory/YYYY-MM-DD.md`의 단기 후보 순위를 매깁니다. -- 메모리 recall과 일일 수집 패스의 단기 신호, 그리고 light/REM 단계 강화 신호를 사용합니다. -- Dreaming이 활성화되면 `memory-core`는 백그라운드에서 전체 스윕(`light -> REM -> deep`)을 실행하는 하나의 Cron 작업을 자동 관리합니다(수동 `openclaw cron add` 필요 없음). +- 가중 승격 신호(`frequency`, `relevance`, `query diversity`, `recency`, `consolidation`, `conceptual richness`)를 사용하여 `memory/YYYY-MM-DD.md`의 단기 후보 순위를 매깁니다. +- 메모리 회상과 일일 수집 패스의 단기 신호, 그리고 light/REM 단계 강화 신호를 사용합니다. +- Dreaming이 활성화되면 `memory-core`가 백그라운드에서 전체 스윕(`light -> REM -> deep`)을 실행하는 Cron 작업 하나를 자동 관리합니다(수동 `openclaw cron add` 필요 없음). - `--agent `: 단일 에이전트로 범위를 제한합니다(기본값: 기본 에이전트). - `--limit `: 반환/적용할 최대 후보 수입니다. -- `--min-score `: 최소 가중 promotion 점수입니다. -- `--min-recall-count `: 후보에 필요한 최소 recall 횟수입니다. +- `--min-score `: 최소 가중 승격 점수입니다. +- `--min-recall-count `: 후보에 필요한 최소 회상 수입니다. - `--min-unique-queries `: 후보에 필요한 최소 고유 쿼리 수입니다. -- `--apply`: 선택한 후보를 `MEMORY.md`에 추가하고 promoted로 표시합니다. -- `--include-promoted`: 이미 promoted된 후보를 출력에 포함합니다. -- `--json`: JSON 출력을 인쇄합니다. +- `--apply`: 선택된 후보를 `MEMORY.md`에 추가하고 승격됨으로 표시합니다. +- `--include-promoted`: 이미 승격된 후보를 출력에 포함합니다. +- `--json`: JSON 출력을 표시합니다. `memory promote-explain`: -특정 promotion 후보와 해당 점수 분해를 설명합니다. +특정 승격 후보와 그 점수 세부 내역을 설명합니다. ```bash openclaw memory promote-explain [--agent ] [--include-promoted] [--json] @@ -115,43 +115,43 @@ openclaw memory promote-explain [--agent ] [--include-promoted] [ - ``: 조회할 후보 키, 경로 조각 또는 스니펫 조각입니다. - `--agent `: 단일 에이전트로 범위를 제한합니다(기본값: 기본 에이전트). -- `--include-promoted`: 이미 promoted된 후보를 포함합니다. -- `--json`: JSON 출력을 인쇄합니다. +- `--include-promoted`: 이미 승격된 후보를 포함합니다. +- `--json`: JSON 출력을 표시합니다. `memory rem-harness`: -아무것도 쓰지 않고 REM reflections, 후보 truths, deep promotion 출력을 미리 봅니다. +아무것도 쓰지 않고 REM 성찰, 후보 진실, deep 승격 출력을 미리 봅니다. ```bash openclaw memory rem-harness [--agent ] [--include-promoted] [--json] ``` - `--agent `: 단일 에이전트로 범위를 제한합니다(기본값: 기본 에이전트). -- `--include-promoted`: 이미 promoted된 deep 후보를 포함합니다. -- `--json`: JSON 출력을 인쇄합니다. +- `--include-promoted`: 이미 승격된 deep 후보를 포함합니다. +- `--json`: JSON 출력을 표시합니다. ## Dreaming -Dreaming은 세 가지 협력 단계로 구성된 백그라운드 메모리 통합 시스템입니다. -**light**(단기 자료 정렬/스테이징), **deep**(지속 가능한 사실을 -`MEMORY.md`로 promote), **REM**(성찰 및 주제 표면화). +Dreaming은 세 가지 협력 단계로 이루어진 백그라운드 메모리 통합 시스템입니다. +단계는 **light**(단기 자료 정렬/스테이징), **deep**(지속 가능한 +사실을 `MEMORY.md`로 승격), **REM**(성찰 및 주제 표면화)입니다. - `plugins.entries.memory-core.config.dreaming.enabled: true`로 활성화합니다. - 채팅에서 `/dreaming on|off`로 전환합니다(또는 `/dreaming status`로 확인). -- Dreaming은 하나의 관리형 스윕 일정(`dreaming.frequency`)으로 실행되며 light, REM, deep 순서로 단계를 실행합니다. +- Dreaming은 하나의 관리형 스윕 일정(`dreaming.frequency`)에서 실행되며 light, REM, deep 순서로 단계를 실행합니다. - deep 단계만 지속 메모리를 `MEMORY.md`에 씁니다. -- 사람이 읽을 수 있는 단계 출력과 일기 항목은 `DREAMS.md`(또는 기존 `dreams.md`)에 쓰이며, 선택적으로 단계별 보고서는 `memory/dreaming//YYYY-MM-DD.md`에 기록됩니다. -- 순위 지정은 recall 빈도, 검색 관련성, 쿼리 다양성, 시간적 최신성, 날짜 간 통합, 파생 개념 풍부도라는 가중 신호를 사용합니다. -- Promotion은 `MEMORY.md`에 쓰기 전에 라이브 일일 노트를 다시 읽으므로, 편집되거나 삭제된 단기 스니펫은 오래된 recall-store 스냅샷에서 promoted되지 않습니다. -- 예약 및 수동 `memory promote` 실행은 CLI 임계값 오버라이드를 전달하지 않는 한 동일한 deep 단계 기본값을 공유합니다. -- 자동 실행은 구성된 메모리 워크스페이스 전체로 fan out됩니다. +- 사람이 읽을 수 있는 단계 출력과 일기 항목은 `DREAMS.md`(또는 기존 `dreams.md`)에 작성되며, 선택적으로 단계별 보고서가 `memory/dreaming//YYYY-MM-DD.md`에 작성됩니다. +- 순위 매기기는 회상 빈도, 검색 관련성, 쿼리 다양성, 시간적 최신성, 여러 날에 걸친 통합, 파생 개념 풍부도라는 가중 신호를 사용합니다. +- 승격은 `MEMORY.md`에 쓰기 전에 라이브 일일 노트를 다시 읽으므로, 편집되었거나 삭제된 단기 스니펫이 오래된 회상 저장소 스냅샷에서 승격되지 않습니다. +- 예약 실행과 수동 `memory promote` 실행은 CLI 임계값 재정의를 전달하지 않는 한 동일한 deep 단계 기본값을 공유합니다. +- 자동 실행은 구성된 메모리 워크스페이스 전체로 확장됩니다. 기본 일정: - **스윕 주기**: `dreaming.frequency = 0 3 * * *` - **Deep 임계값**: `minScore=0.8`, `minRecallCount=3`, `minUniqueQueries=3`, `recencyHalfLifeDays=14`, `maxAgeDays=30` -예제: +예시: ```json { @@ -171,16 +171,16 @@ Dreaming은 세 가지 협력 단계로 구성된 백그라운드 메모리 통 참고: -- `memory index --verbose`는 단계별 세부 정보(제공자, 모델, 소스, 배치 활동)를 인쇄합니다. +- `memory index --verbose`는 단계별 세부 정보(제공자, 모델, 소스, 배치 활동)를 출력합니다. - `memory status`는 `memorySearch.extraPaths`를 통해 구성된 추가 경로를 포함합니다. -- 실제로 활성화된 Active Memory 원격 API 키 필드가 SecretRefs로 구성된 경우, 명령은 활성 Gateway 스냅샷에서 해당 값을 확인합니다. Gateway를 사용할 수 없으면 명령이 빠르게 실패합니다. -- Gateway 버전 불일치 참고: 이 명령 경로에는 `secrets.resolve`를 지원하는 Gateway가 필요합니다. 이전 Gateway는 알 수 없는 메서드 오류를 반환합니다. -- 예약된 스윕 주기는 `dreaming.frequency`로 조정합니다. Deep promotion 정책은 그 외에는 내부 정책입니다. 일회성 수동 오버라이드가 필요할 때는 `memory promote`에서 CLI 플래그를 사용하세요. +- 사실상 활성 상태인 메모리 원격 API 키 필드가 SecretRefs로 구성되어 있으면 명령은 활성 Gateway 스냅샷에서 해당 값을 해석합니다. Gateway를 사용할 수 없으면 명령은 빠르게 실패합니다. +- Gateway 버전 차이 참고: 이 명령 경로에는 `secrets.resolve`를 지원하는 Gateway가 필요합니다. 이전 Gateway는 알 수 없는 메서드 오류를 반환합니다. +- 예약 스윕 주기는 `dreaming.frequency`로 조정합니다. Deep 승격 정책은 그 외에는 내부적으로 관리됩니다. 일회성 수동 재정의가 필요하면 `memory promote`에서 CLI 플래그를 사용하세요. - `memory rem-harness --path --grounded`는 아무것도 쓰지 않고 과거 일일 노트에서 근거 기반 `What Happened`, `Reflections`, `Possible Lasting Updates`를 미리 봅니다. - `memory rem-backfill --path `는 UI 검토를 위해 되돌릴 수 있는 근거 기반 일기 항목을 `DREAMS.md`에 씁니다. -- `memory rem-backfill --path --stage-short-term`은 근거 기반 지속 후보도 라이브 단기 promotion 저장소에 시드하여 일반 deep 단계가 순위를 매길 수 있게 합니다. -- `memory rem-backfill --rollback`은 이전에 쓴 근거 기반 일기 항목을 제거하고, `memory rem-backfill --rollback-short-term`은 이전에 스테이징한 근거 기반 단기 후보를 제거합니다. -- 전체 단계 설명 및 구성 참조는 [Dreaming](/ko/concepts/dreaming)을 참조하세요. +- `memory rem-backfill --path --stage-short-term`는 일반 deep 단계가 순위를 매길 수 있도록 근거 기반 지속 후보를 라이브 단기 승격 저장소에도 시드합니다. +- `memory rem-backfill --rollback`은 이전에 작성된 근거 기반 일기 항목을 제거하고, `memory rem-backfill --rollback-short-term`은 이전에 스테이징된 근거 기반 단기 후보를 제거합니다. +- 전체 단계 설명과 구성 참조는 [Dreaming](/ko/concepts/dreaming)을 참조하세요. ## 관련 항목 diff --git a/docs/ko/cli/node.md b/docs/ko/cli/node.md index a330ffd44..82eb0b389 100644 --- a/docs/ko/cli/node.md +++ b/docs/ko/cli/node.md @@ -1,41 +1,41 @@ --- read_when: - - headless Node 호스트 실행하기 - - '`system.run`용 비-macOS Node 페어링하기' -summary: '`openclaw node`용 CLI 참조(headless node host)' + - 헤드리스 Node 호스트 실행 + - system.run용 macOS가 아닌 Node 페어링 +summary: '`openclaw node`용 CLI 참조(헤드리스 Node 호스트)' title: Node x-i18n: - generated_at: "2026-04-26T11:26:23Z" - model: gpt-5.4 + generated_at: "2026-05-06T17:53:42Z" + model: gpt-5.5 provider: openai - source_hash: 40f623b163a3c3bcd2d3ff218c5e62a4acba45f7e3f16694d8da62a004b77706 + source_hash: af4735ac4961dc36fd3f11299eb3ec4e156835e7257b21a79bb1d4b467445faa source_path: cli/node.md - workflow: 15 + workflow: 16 --- # `openclaw node` -Gateway WebSocket에 연결하고 이 머신에서 `system.run` / `system.which`를 노출하는 **headless Node 호스트**를 실행합니다. +Gateway WebSocket에 연결하고 이 머신에서 `system.run` / `system.which`를 노출하는 **헤드리스 Node 호스트**를 실행합니다. -## 왜 Node 호스트를 사용하나요? +## Node 호스트를 사용하는 이유 -네트워크의 **다른 머신에서 명령을 실행**하도록 에이전트를 사용하고 싶지만, 해당 머신에 전체 macOS companion 앱을 설치하고 싶지 않을 때 Node 호스트를 사용하세요. +네트워크의 다른 머신에서 전체 macOS 컴패니언 앱을 설치하지 않고 에이전트가 **명령을 실행**하게 하려면 Node 호스트를 사용하세요. 일반적인 사용 사례: -- 원격 Linux/Windows 머신(빌드 서버, 랩 머신, NAS)에서 명령 실행 -- exec는 Gateway에서 **샌드박스 처리**하고, 승인된 실행만 다른 호스트에 위임 -- 자동화 또는 CI node용 경량 headless 실행 대상 제공 +- 원격 Linux/Windows 머신(빌드 서버, 랩 머신, NAS)에서 명령을 실행합니다. +- Gateway에서 exec를 **샌드박스화**한 상태로 유지하되, 승인된 실행을 다른 호스트에 위임합니다. +- 자동화 또는 CI Node를 위한 가벼운 헤드리스 실행 대상을 제공합니다. -실행은 여전히 Node 호스트의 **exec 승인**과 에이전트별 allowlist로 보호되므로, 명령 접근 범위를 명시적으로 제한할 수 있습니다. +실행은 여전히 Node 호스트의 **exec 승인**과 에이전트별 허용 목록으로 보호되므로, 명령 접근 범위를 제한적이고 명시적으로 유지할 수 있습니다. -## 브라우저 프록시(구성 불필요) +## 브라우저 프록시(무설정) -Node 호스트는 node에서 `browser.enabled`가 비활성화되지 않은 경우 자동으로 브라우저 프록시를 알립니다. 이를 통해 추가 구성 없이도 에이전트가 해당 node에서 브라우저 자동화를 사용할 수 있습니다. +Node 호스트는 Node에서 `browser.enabled`가 비활성화되어 있지 않으면 브라우저 프록시를 자동으로 알립니다. 이를 통해 에이전트는 추가 구성 없이 해당 Node에서 브라우저 자동화를 사용할 수 있습니다. -기본적으로 프록시는 node의 일반 브라우저 프로필 표면을 노출합니다. `nodeHost.browserProxy.allowProfiles`를 설정하면 프록시는 제한적으로 동작합니다. allowlist에 없는 프로필 대상 지정은 거부되며, 영구 프로필 생성/삭제 경로는 프록시를 통해 차단됩니다. +기본적으로 프록시는 Node의 일반 브라우저 프로필 표면을 노출합니다. `nodeHost.browserProxy.allowProfiles`를 설정하면 프록시가 제한적으로 동작합니다. 허용 목록에 없는 프로필 타기팅은 거부되고, 영구 프로필 생성/삭제 라우트는 프록시를 통해 차단됩니다. -필요한 경우 node에서 비활성화하세요: +필요하면 Node에서 비활성화하세요. ```json5 { @@ -59,25 +59,27 @@ openclaw node run --host --port 18789 - `--port `: Gateway WebSocket 포트(기본값: `18789`) - `--tls`: Gateway 연결에 TLS 사용 - `--tls-fingerprint `: 예상 TLS 인증서 지문(sha256) -- `--node-id `: node id 재정의(pairing 토큰 삭제) -- `--display-name `: node 표시 이름 재정의 +- `--node-id `: Node ID 재정의(페어링 토큰 지움) +- `--display-name `: Node 표시 이름 재정의 ## Node 호스트용 Gateway 인증 -`openclaw node run`과 `openclaw node install`은 구성/env에서 Gateway 인증을 확인합니다(node 명령에는 `--token`/`--password` 플래그가 없음): +`openclaw node run` 및 `openclaw node install`은 config/env에서 Gateway 인증을 해석합니다(Node 명령에는 `--token`/`--password` 플래그 없음). -- 먼저 `OPENCLAW_GATEWAY_TOKEN` / `OPENCLAW_GATEWAY_PASSWORD`를 확인합니다. -- 그다음 로컬 구성 폴백: `gateway.auth.token` / `gateway.auth.password`. +- `OPENCLAW_GATEWAY_TOKEN` / `OPENCLAW_GATEWAY_PASSWORD`를 먼저 확인합니다. +- 그런 다음 로컬 구성 폴백: `gateway.auth.token` / `gateway.auth.password`. - 로컬 모드에서 Node 호스트는 의도적으로 `gateway.remote.token` / `gateway.remote.password`를 상속하지 않습니다. -- `gateway.auth.token` / `gateway.auth.password`가 SecretRef를 통해 명시적으로 구성되었지만 확인되지 않으면, node 인증 확인은 fail closed로 실패합니다(원격 폴백으로 가려지지 않음). -- `gateway.mode=remote`에서는 원격 클라이언트 필드(`gateway.remote.token` / `gateway.remote.password`)도 원격 우선순위 규칙에 따라 사용할 수 있습니다. -- Node 호스트 인증 확인은 `OPENCLAW_GATEWAY_*` env vars만 인정합니다. +- `gateway.auth.token` / `gateway.auth.password`가 SecretRef를 통해 명시적으로 구성되어 있고 해석되지 않으면, Node 인증 해석은 안전하게 실패합니다(원격 폴백으로 가려지지 않음). +- `gateway.mode=remote`에서는 원격 우선순위 규칙에 따라 원격 클라이언트 필드(`gateway.remote.token` / `gateway.remote.password`)도 사용할 수 있습니다. +- Node 호스트 인증 해석은 `OPENCLAW_GATEWAY_*` env var만 따릅니다. -신뢰할 수 있는 사설 네트워크에서 non-loopback `ws://` Gateway에 연결하는 node의 경우 `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`을 설정하세요. 그렇지 않으면 node 시작은 fail closed로 실패하며 `wss://`, SSH 터널, 또는 Tailscale 사용을 요구합니다. 이는 `openclaw.json` 구성 키가 아니라 프로세스 환경 opt-in입니다. `openclaw node install`은 설치 명령 환경에 이 값이 있으면 감독되는 node 서비스에 이를 영구 저장합니다. +신뢰할 수 있는 사설 네트워크에서 local loopback이 아닌 `ws://` Gateway에 Node를 연결하려면 `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`을 설정하세요. 설정하지 않으면 Node 시작은 안전하게 실패하고 `wss://`, SSH 터널 또는 Tailscale 사용을 요청합니다. +이는 프로세스 환경 옵트인이며 `openclaw.json` 구성 키가 아닙니다. +`openclaw node install`은 설치 명령 환경에 이 값이 있으면 감독되는 Node 서비스에 이를 유지합니다. ## 서비스(백그라운드) -headless Node 호스트를 사용자 서비스로 설치합니다. +헤드리스 Node 호스트를 사용자 서비스로 설치합니다. ```bash openclaw node install --host --port 18789 @@ -89,10 +91,10 @@ openclaw node install --host --port 18789 - `--port `: Gateway WebSocket 포트(기본값: `18789`) - `--tls`: Gateway 연결에 TLS 사용 - `--tls-fingerprint `: 예상 TLS 인증서 지문(sha256) -- `--node-id `: node id 재정의(pairing 토큰 삭제) -- `--display-name `: node 표시 이름 재정의 +- `--node-id `: Node ID 재정의(페어링 토큰 지움) +- `--display-name `: Node 표시 이름 재정의 - `--runtime `: 서비스 런타임(`node` 또는 `bun`) -- `--force`: 이미 설치된 경우 재설치/덮어쓰기 +- `--force`: 이미 설치되어 있으면 다시 설치/덮어쓰기 서비스 관리: @@ -104,23 +106,23 @@ openclaw node restart openclaw node uninstall ``` -포그라운드 Node 호스트(서비스 없음)에는 `openclaw node run`을 사용하세요. +포그라운드 Node 호스트에는 `openclaw node run`을 사용하세요(서비스 아님). -서비스 명령은 기계가 읽을 수 있는 출력을 위해 `--json`을 지원합니다. +서비스 명령은 머신이 읽을 수 있는 출력을 위해 `--json`을 허용합니다. -Node 호스트는 프로세스 내에서 Gateway 재시작과 네트워크 종료를 재시도합니다. Gateway가 최종 token/password/bootstrap 인증 일시 중지를 보고하면, Node 호스트는 종료 세부 정보를 기록하고 0이 아닌 값으로 종료하므로 launchd/systemd가 새 구성과 자격 증명으로 다시 시작할 수 있습니다. pairing 필요 일시 중지는 보류 중인 요청을 승인할 수 있도록 포그라운드 흐름에 유지됩니다. +Node 호스트는 Gateway 재시작과 네트워크 종료를 프로세스 내에서 재시도합니다. Gateway가 최종적인 토큰/비밀번호/부트스트랩 인증 일시 중지를 보고하면, Node 호스트는 종료 상세 정보를 로그에 남기고 0이 아닌 코드로 종료하여 launchd/systemd가 새 구성과 자격 증명으로 다시 시작할 수 있게 합니다. 페어링이 필요한 일시 중지는 대기 중인 요청을 승인할 수 있도록 포그라운드 흐름에 남아 있습니다. ## 페어링 -첫 연결 시 Gateway에 보류 중인 device pairing 요청(`role: node`)이 생성됩니다. -다음으로 승인하세요: +첫 연결은 Gateway에 대기 중인 기기 페어링 요청(`role: node`)을 생성합니다. +다음으로 승인하세요. ```bash openclaw devices list openclaw devices approve ``` -엄격하게 제어되는 node 네트워크에서는 Gateway 운영자가 신뢰된 CIDR에서의 최초 node pairing 자동 승인을 명시적으로 opt-in할 수 있습니다: +엄격하게 제어되는 Node 네트워크에서는 Gateway 운영자가 신뢰할 수 있는 CIDR에서 처음 발생하는 Node 페어링을 자동 승인하도록 명시적으로 옵트인할 수 있습니다. ```json5 { @@ -134,23 +136,23 @@ openclaw devices approve } ``` -이는 기본적으로 비활성화되어 있습니다. 요청된 scope가 없는 새 `role: node` pairing에만 적용됩니다. 운영자/브라우저 클라이언트, Control UI, WebChat, 그리고 role, scope, metadata 또는 공개 키 업그레이드는 여전히 수동 승인이 필요합니다. +이는 기본적으로 비활성화되어 있습니다. 요청된 범위가 없는 새 `role: node` 페어링에만 적용됩니다. 운영자/브라우저 클라이언트, Control UI, WebChat, 그리고 역할, 범위, 메타데이터 또는 공개 키 업그레이드는 여전히 수동 승인이 필요합니다. -Node가 변경된 인증 세부 정보(role/scopes/public key)로 pairing을 재시도하면 이전 보류 요청은 대체되고 새 `requestId`가 생성됩니다. 승인 전에 `openclaw devices list`를 다시 실행하세요. +Node가 변경된 인증 세부 정보(역할/범위/공개 키)로 페어링을 다시 시도하면, 이전 대기 요청은 대체되고 새 `requestId`가 생성됩니다. 승인하기 전에 `openclaw devices list`를 다시 실행하세요. -Node 호스트는 node id, token, 표시 이름, Gateway 연결 정보를 `~/.openclaw/node.json`에 저장합니다. +Node 호스트는 Node ID, 토큰, 표시 이름, Gateway 연결 정보를 `~/.openclaw/node.json`에 저장합니다. ## Exec 승인 -`system.run`은 로컬 exec 승인에 의해 제한됩니다: +`system.run`은 로컬 exec 승인으로 게이트됩니다. - `~/.openclaw/exec-approvals.json` - [Exec 승인](/ko/tools/exec-approvals) - `openclaw approvals --node `(Gateway에서 편집) -승인된 비동기 node exec의 경우 OpenClaw는 프롬프트 전에 정식 `systemRunPlan`을 준비합니다. 이후 승인된 `system.run` 전달은 저장된 해당 plan을 재사용하므로, 승인 요청이 생성된 이후의 command/cwd/session 필드 편집은 node가 실행할 내용을 바꾸는 대신 거부됩니다. +승인된 비동기 Node exec의 경우 OpenClaw는 프롬프트를 표시하기 전에 표준 `systemRunPlan`을 준비합니다. 이후 승인된 `system.run` 전달은 저장된 해당 계획을 재사용하므로, 승인 요청이 생성된 후 command/cwd/session 필드가 수정되면 Node가 실행하는 내용을 변경하는 대신 거부됩니다. -## 관련 +## 관련 항목 - [CLI 참조](/ko/cli) -- [Nodes](/ko/nodes) +- [Node](/ko/nodes) diff --git a/docs/ko/cli/nodes.md b/docs/ko/cli/nodes.md index 0a268cbfb..bb561861b 100644 --- a/docs/ko/cli/nodes.md +++ b/docs/ko/cli/nodes.md @@ -2,26 +2,26 @@ read_when: - 페어링된 노드(카메라, 화면, 캔버스)를 관리하고 있습니다 - 요청을 승인하거나 node 명령을 호출해야 합니다 -summary: '`openclaw nodes`용 CLI 참조 (status, pairing, invoke, camera/canvas/screen)' +summary: '`openclaw nodes`용 CLI 참조(상태, 페어링, 호출, 카메라/캔버스/화면)' title: Node x-i18n: - generated_at: "2026-04-30T06:24:02Z" + generated_at: "2026-05-06T17:54:00Z" model: gpt-5.5 provider: openai - source_hash: 3229db91d7e64b0d37bee29bd51895d90796f5fd33b67e3d900fd8bda2b6e7e9 + source_hash: f3eb0d23037c939e4022115a2d65e0e9cb25a872daed715b8652979ce6707cf7 source_path: cli/nodes.md workflow: 16 --- # `openclaw nodes` -페어링된 노드(기기)를 관리하고 노드 기능을 호출합니다. +페어링된 Node(디바이스)를 관리하고 Node 기능을 호출합니다. 관련 항목: -- 노드 개요: [노드](/ko/nodes) -- 카메라: [카메라 노드](/ko/nodes/camera) -- 이미지: [이미지 노드](/ko/nodes/images) +- Node 개요: [Node](/ko/nodes) +- 카메라: [카메라 Node](/ko/nodes/camera) +- 이미지: [이미지 Node](/ko/nodes/images) 공통 옵션: @@ -43,21 +43,21 @@ openclaw nodes status --connected openclaw nodes status --last-connected 24h ``` -`nodes list`는 보류 중/페어링된 테이블을 출력합니다. 페어링된 행에는 가장 최근 연결 경과 시간(마지막 연결)이 포함됩니다. -현재 연결된 노드만 표시하려면 `--connected`를 사용합니다. 지정한 기간 내에 연결된 노드로 -필터링하려면 `--last-connected `을 사용합니다(예: `24h`, `7d`). -오래된 Gateway 소유 노드 페어링 레코드를 삭제하려면 `nodes remove --node `를 사용합니다. +`nodes list`는 보류 중/페어링된 항목 테이블을 출력합니다. 페어링된 행에는 가장 최근 연결 경과 시간(Last Connect)이 포함됩니다. +현재 연결된 Node만 표시하려면 `--connected`를 사용하세요. 특정 기간(예: `24h`, `7d`) 내에 +연결된 Node로 필터링하려면 `--last-connected `를 사용하세요. +오래된 Gateway 소유 Node 페어링 레코드를 삭제하려면 `nodes remove --node `를 사용하세요. 승인 참고 사항: - `openclaw nodes pending`에는 페어링 범위만 필요합니다. -- `gateway.nodes.pairing.autoApproveCidrs`는 명시적으로 신뢰된 최초 `role: node` 기기 페어링에 대해서만 - 보류 단계를 건너뛸 수 있습니다. 기본적으로 꺼져 있으며 - 업그레이드를 승인하지 않습니다. +- `gateway.nodes.pairing.autoApproveCidrs`는 + 명시적으로 신뢰된 최초 `role: node` 디바이스 페어링에 대해서만 보류 단계를 건너뛸 수 있습니다. 기본적으로 꺼져 있으며 + 업그레이드는 승인하지 않습니다. - `openclaw nodes approve `는 보류 중인 요청에서 추가 범위 요구 사항을 - 상속합니다. + 상속합니다: - 명령 없는 요청: 페어링만 - - 실행이 아닌 노드 명령: 페어링 + 쓰기 + - exec가 아닌 Node 명령: 페어링 + 쓰기 - `system.run` / `system.run.prepare` / `system.which`: 페어링 + 관리자 ## 호출 @@ -69,15 +69,15 @@ openclaw nodes invoke --node --command --params 호출 플래그: - `--params `: JSON 객체 문자열(기본값 `{}`). -- `--invoke-timeout `: 노드 호출 제한 시간(기본값 `15000`). +- `--invoke-timeout `: Node 호출 제한 시간(기본값 `15000`). - `--idempotency-key `: 선택적 멱등성 키. - `system.run` 및 `system.run.prepare`는 여기에서 차단됩니다. 셸 실행에는 `host=node`와 함께 `exec` 도구를 사용하세요. -노드에서 셸을 실행하려면 `openclaw nodes run` 대신 `host=node`와 함께 `exec` 도구를 사용하세요. -`nodes` CLI는 이제 기능 중심입니다. 즉, 페어링, 카메라, 화면, -위치, 캔버스, 알림에 더해 `nodes invoke`를 통한 직접 RPC를 제공합니다. +Node에서 셸을 실행하려면 `openclaw nodes run` 대신 `host=node`와 함께 `exec` 도구를 사용하세요. +이제 `nodes` CLI는 기능 중심입니다: `nodes invoke`를 통한 직접 RPC와 페어링, 카메라, +화면, 위치, 캔버스, 알림을 제공합니다. ## 관련 항목 - [CLI 참조](/ko/cli) -- [노드](/ko/nodes) +- [Node](/ko/nodes) diff --git a/docs/ko/cli/pairing.md b/docs/ko/cli/pairing.md index ab991af9a..427242090 100644 --- a/docs/ko/cli/pairing.md +++ b/docs/ko/cli/pairing.md @@ -4,17 +4,17 @@ read_when: summary: '`openclaw pairing`의 CLI 참조(페어링 요청 승인/목록 조회)' title: 페어링 x-i18n: - generated_at: "2026-04-30T06:24:22Z" + generated_at: "2026-05-06T17:54:03Z" model: gpt-5.5 provider: openai - source_hash: bffc70a8c08e298f42c8fbc2238fce06993572e72f333e87ad18dea3cf33fab5 + source_hash: 022018239ab1134b18986be42b8e019f412a1a730a9671f422979909c4a31dc5 source_path: cli/pairing.md workflow: 16 --- # `openclaw pairing` -DM 페어링 요청을 승인하거나 검사합니다(페어링을 지원하는 채널용). +DM 페어링 요청을 승인하거나 확인합니다(페어링을 지원하는 채널용). 관련 항목: @@ -40,13 +40,13 @@ openclaw pairing approve --channel telegram --account work --notify - `[channel]`: 위치 인수 채널 ID - `--channel `: 명시적 채널 ID -- `--account `: 다중 계정 채널의 계정 ID -- `--json`: 기계 판독 가능 출력 +- `--account `: 다중 계정 채널용 계정 ID +- `--json`: 기계가 읽을 수 있는 출력 참고: -- 페어링 가능 채널이 여러 개 구성된 경우 위치 인수로든 `--channel`로든 채널을 제공해야 합니다. -- 채널 ID가 유효하기만 하면 확장 채널도 허용됩니다. +- 페어링을 지원하는 채널이 여러 개 구성된 경우, 위치 인수로 또는 `--channel`을 사용해 채널을 제공해야 합니다. +- 채널 ID가 유효하면 확장 채널도 허용됩니다. ## `pairing approve` @@ -56,27 +56,27 @@ openclaw pairing approve --channel telegram --account work --notify - `openclaw pairing approve ` - `openclaw pairing approve --channel ` -- 정확히 하나의 페어링 가능 채널만 구성된 경우 `openclaw pairing approve ` +- 페어링을 지원하는 채널이 정확히 하나만 구성된 경우 `openclaw pairing approve ` 옵션: - `--channel `: 명시적 채널 ID -- `--account `: 다중 계정 채널의 계정 ID -- `--notify`: 같은 채널에서 요청자에게 확인 메시지를 다시 보냅니다. +- `--account `: 다중 계정 채널용 계정 ID +- `--notify`: 같은 채널에서 요청자에게 확인 메시지 보내기 소유자 부트스트랩: -- 페어링 코드를 승인할 때 `commands.ownerAllowFrom`이 비어 있으면 OpenClaw는 승인된 발신자도 명령 소유자로 기록하며, `telegram:123456789` 같은 채널 범위 항목을 사용합니다. -- 이는 첫 번째 소유자만 부트스트랩합니다. 이후 페어링 승인은 `commands.ownerAllowFrom`을 대체하거나 확장하지 않습니다. -- 명령 소유자는 `/diagnostics`, `/export-trajectory`, `/config`, exec 승인 같은 소유자 전용 명령을 실행하고 위험한 작업을 승인할 수 있는 사람 운영자 계정입니다. +- 페어링 코드를 승인할 때 `commands.ownerAllowFrom`이 비어 있으면, OpenClaw는 승인된 발신자도 `telegram:123456789` 같은 채널 범위 항목을 사용해 명령 소유자로 기록합니다. +- 이는 첫 번째 소유자만 부트스트랩합니다. 이후의 페어링 승인은 `commands.ownerAllowFrom`을 대체하거나 확장하지 않습니다. +- 명령 소유자는 소유자 전용 명령을 실행하고 `/diagnostics`, `/export-trajectory`, `/config`, 실행 승인 같은 위험한 작업을 승인할 수 있는 인간 운영자 계정입니다. ## 참고 -- 채널 입력: 위치 인수(`pairing list telegram`)로 전달하거나 `--channel `로 전달합니다. -- `pairing list`는 다중 계정 채널에 대해 `--account `를 지원합니다. +- 채널 입력: 위치 인수로 전달하거나(`pairing list telegram`) `--channel `을 사용합니다. +- `pairing list`는 다중 계정 채널용 `--account `를 지원합니다. - `pairing approve`는 `--account `와 `--notify`를 지원합니다. -- 페어링 가능 채널이 하나만 구성된 경우 `pairing approve `가 허용됩니다. -- 이 부트스트랩이 생기기 전에 발신자를 승인했다면 `openclaw doctor`를 실행하세요. 명령 소유자가 구성되지 않은 경우 경고하고, 이를 수정하기 위한 `openclaw config set commands.ownerAllowFrom ...` 명령을 보여 줍니다. +- 페어링을 지원하는 채널이 하나만 구성된 경우 `pairing approve `가 허용됩니다. +- 이 부트스트랩이 생기기 전에 발신자를 승인했다면 `openclaw doctor`를 실행하세요. 명령 소유자가 구성되지 않았을 때 경고하고 이를 수정할 `openclaw config set commands.ownerAllowFrom ...` 명령을 표시합니다. ## 관련 항목 diff --git a/docs/ko/cli/plugins.md b/docs/ko/cli/plugins.md index bcf3a3c79..7c25969cd 100644 --- a/docs/ko/cli/plugins.md +++ b/docs/ko/cli/plugins.md @@ -1,27 +1,27 @@ --- read_when: - Gateway Plugin 또는 호환 번들을 설치하거나 관리하려는 경우 - - Plugin 로드 실패를 디버그하려고 합니다 + - Plugin 로드 실패를 디버그하려는 경우 sidebarTitle: Plugins -summary: '`openclaw plugins` CLI 참조(목록, 설치, 마켓플레이스, 제거, 활성화/비활성화, 진단)' +summary: '`openclaw plugins`에 대한 CLI 참조 (list, install, marketplace, uninstall, enable/disable, doctor)' title: Plugin x-i18n: - generated_at: "2026-05-06T09:02:28Z" + generated_at: "2026-05-06T17:54:30Z" model: gpt-5.5 provider: openai - source_hash: e584092c6cdaf87681aef2ed106c299e3bab0552305b669c66b05deb61bf25ce + source_hash: 734366b6bbee5f036fdc2cfac5197ae86d2e8fbc7c977ccc4e22add2f4206951 source_path: cli/plugins.md workflow: 16 --- -Gateway Plugin, 훅 팩, 호환 번들을 관리합니다. +Manage Gateway Plugin, 훅 팩, 호환 번들을 관리합니다. - Plugin 설치, 활성화, 문제 해결을 위한 최종 사용자 가이드입니다. + Plugin 설치, 활성화 및 문제 해결을 위한 최종 사용자 가이드입니다. - 설치, 목록 보기, 업데이트, 제거, 게시에 대한 빠른 예시입니다. + 설치, 목록 표시, 업데이트, 제거 및 게시를 위한 빠른 예시입니다. 번들 호환성 모델입니다. @@ -62,14 +62,18 @@ openclaw plugins marketplace list openclaw plugins marketplace list --json ``` -느린 설치, 검사, 제거, 또는 레지스트리 새로 고침 조사를 위해서는 -`OPENCLAW_PLUGIN_LIFECYCLE_TRACE=1`로 명령을 실행하세요. 추적은 단계별 타이밍을 -stderr에 기록하고 JSON 출력을 파싱 가능한 상태로 유지합니다. [디버깅](/ko/help/debugging#plugin-lifecycle-trace)을 참고하세요. +느린 설치, 검사, 제거 또는 레지스트리 새로 고침 조사에는 +`OPENCLAW_PLUGIN_LIFECYCLE_TRACE=1`로 명령을 실행하세요. 추적은 단계별 시간을 +stderr에 기록하며 JSON 출력을 파싱 가능하게 유지합니다. [디버깅](/ko/help/debugging#plugin-lifecycle-trace)을 참조하세요. -번들된 Plugin은 OpenClaw와 함께 제공됩니다. 일부는 기본적으로 활성화되어 있으며(예: 번들된 모델 제공자, 번들된 음성 제공자, 번들된 브라우저 Plugin), 나머지는 `plugins enable`이 필요합니다. +Nix 모드(`OPENCLAW_NIX_MODE=1`)에서는 Plugin 수명 주기 변경 명령이 비활성화됩니다. 이 설치에는 `plugins install`, `plugins update`, `plugins uninstall`, `plugins enable`, `plugins disable` 대신 Nix 소스를 사용하세요. nix-openclaw의 경우 에이전트 우선 [빠른 시작](https://github.com/openclaw/nix-openclaw#quick-start)을 사용하세요. + -네이티브 OpenClaw Plugin은 인라인 JSON Schema(`configSchema`, 비어 있더라도 포함)와 함께 `openclaw.plugin.json`을 제공해야 합니다. 호환 번들은 대신 자체 번들 매니페스트를 사용합니다. + +번들 Plugin은 OpenClaw와 함께 제공됩니다. 일부는 기본적으로 활성화되어 있으며(예: 번들 모델 공급자, 번들 음성 공급자, 번들 브라우저 Plugin), 나머지는 `plugins enable`이 필요합니다. + +네이티브 OpenClaw Plugin은 인라인 JSON Schema(`configSchema`, 비어 있더라도)를 포함한 `openclaw.plugin.json`을 제공해야 합니다. 호환 번들은 대신 자체 번들 매니페스트를 사용합니다. `plugins list`는 `Format: openclaw` 또는 `Format: bundle`을 표시합니다. 자세한 목록/정보 출력에는 번들 하위 유형(`codex`, `claude`, 또는 `cursor`)과 감지된 번들 기능도 표시됩니다. @@ -94,84 +98,86 @@ openclaw plugins install --marketplace https://github.com// -단순 패키지 이름은 출시 전환 기간 동안 기본적으로 npm에서 설치됩니다. ClawHub에는 `clawhub:`를 사용하세요. Plugin 설치를 코드 실행처럼 다루세요. 고정된 버전을 사용하는 것을 권장합니다. +출시 전환 기간에는 단순 패키지 이름이 기본적으로 npm에서 설치됩니다. ClawHub에는 `clawhub:`를 사용하세요. Plugin 설치를 코드 실행처럼 취급하세요. 고정된 버전을 선호하세요. -`plugins search`는 ClawHub에서 설치 가능한 Plugin 패키지를 쿼리하고 -설치 준비가 된 패키지 이름을 출력합니다. Skills가 아니라 code-plugin 및 bundle-plugin 패키지를 검색합니다. ClawHub Skills에는 `openclaw skills search`를 사용하세요. +`plugins search`는 설치 가능한 Plugin 패키지를 ClawHub에서 쿼리하고 +설치 준비가 된 패키지 이름을 출력합니다. Skills가 아니라 코드 Plugin 및 번들 Plugin 패키지를 검색합니다. ClawHub Skills에는 `openclaw skills search`를 사용하세요. -ClawHub는 대부분의 Plugin에 대한 기본 배포 및 검색 표면입니다. Npm은 +ClawHub는 대부분 Plugin의 기본 배포 및 검색 표면입니다. Npm은 지원되는 대체 경로이자 직접 설치 경로로 유지됩니다. OpenClaw 소유 `@openclaw/*` Plugin 패키지는 npm에 다시 게시됩니다. 현재 목록은 [npmjs.com/org/openclaw](https://www.npmjs.com/org/openclaw) 또는 -[Plugin 인벤토리](/ko/plugins/plugin-inventory)를 참고하세요. 안정 설치는 `latest`를 사용합니다. -베타 채널 설치 및 업데이트는 해당 태그가 있을 때 npm `beta` dist-tag를 -우선 사용한 다음 `latest`로 폴백합니다. +[Plugin 인벤토리](/ko/plugins/plugin-inventory)를 참조하세요. 안정 설치는 `latest`를 사용합니다. +베타 채널 설치 및 업데이트는 해당 태그가 사용 가능하면 npm `beta` dist-tag를 +우선 사용하고, 그다음 `latest`로 대체합니다. - `plugins` 섹션이 단일 파일 `$include`로 지원되는 경우, `plugins install/update/enable/disable/uninstall`은 해당 포함 파일에 기록하고 `openclaw.json`은 그대로 둡니다. 루트 include, include 배열, 형제 override가 있는 include는 평탄화하지 않고 닫힌 상태로 실패합니다. 지원되는 형태는 [구성 include](/ko/gateway/configuration)를 참고하세요. + `plugins` 섹션이 단일 파일 `$include`로 지원되는 경우, `plugins install/update/enable/disable/uninstall`은 해당 포함 파일에 쓰고 `openclaw.json`은 그대로 둡니다. 루트 include, include 배열, 형제 재정의가 있는 include는 평탄화하는 대신 닫힌 상태로 실패합니다. 지원되는 형태는 [구성 include](/ko/gateway/configuration)를 참조하세요. - 설치 중 구성이 잘못된 경우, `plugins install`은 일반적으로 닫힌 상태로 실패하며 먼저 `openclaw doctor --fix`를 실행하라고 안내합니다. Gateway 시작 및 핫 리로드 중에는 잘못된 Plugin 구성이 다른 잘못된 구성과 마찬가지로 닫힌 상태로 실패합니다. `openclaw doctor --fix`는 잘못된 Plugin 항목을 격리할 수 있습니다. 문서화된 유일한 설치 시점 예외는 `openclaw.install.allowInvalidConfigRecovery`를 명시적으로 선택한 Plugin을 위한 좁은 범위의 번들 Plugin 복구 경로입니다. + 설치 중 구성이 잘못된 경우, `plugins install`은 일반적으로 닫힌 상태로 실패하고 먼저 `openclaw doctor --fix`를 실행하라고 안내합니다. Gateway 시작 및 핫 리로드 중에는 잘못된 Plugin 구성이 다른 잘못된 구성과 마찬가지로 닫힌 상태로 실패합니다. `openclaw doctor --fix`는 잘못된 Plugin 항목을 격리할 수 있습니다. 문서화된 유일한 설치 시 예외는 명시적으로 `openclaw.install.allowInvalidConfigRecovery`를 선택한 Plugin을 위한 좁은 범위의 번들 Plugin 복구 경로입니다. - - `--force`는 기존 설치 대상을 재사용하고 이미 설치된 Plugin 또는 훅 팩을 제자리에서 덮어씁니다. 새 로컬 경로, 아카이브, ClawHub 패키지 또는 npm 아티팩트에서 같은 ID를 의도적으로 다시 설치할 때 사용하세요. 이미 추적 중인 npm Plugin의 일반 업그레이드에는 `openclaw plugins update `를 사용하는 것이 좋습니다. + + `--force`는 기존 설치 대상을 재사용하고 이미 설치된 Plugin 또는 훅 팩을 제자리에서 덮어씁니다. 새 로컬 경로, 아카이브, ClawHub 패키지 또는 npm 아티팩트에서 같은 ID를 의도적으로 재설치할 때 사용하세요. 이미 추적 중인 npm Plugin의 일반 업그레이드에는 `openclaw plugins update `를 선호하세요. - 이미 설치된 Plugin ID에 대해 `plugins install`을 실행하면 OpenClaw가 중지하고 일반 업그레이드에는 `plugins update `를, 현재 설치를 다른 소스로 정말 덮어쓰려는 경우에는 `plugins install --force`를 사용하라고 안내합니다. + 이미 설치된 Plugin ID에 대해 `plugins install`을 실행하면 OpenClaw가 중지되고 일반 업그레이드에는 `plugins update `를, 다른 소스에서 현재 설치를 정말로 덮어쓰려는 경우에는 `plugins install --force`를 안내합니다. - `--pin`은 npm 설치에만 적용됩니다. `git:` 설치에서는 지원되지 않습니다. 고정된 소스를 원할 때는 `git:github.com/acme/plugin@v1.2.3` 같은 명시적 git ref를 사용하세요. `--marketplace`와도 함께 사용할 수 없습니다. marketplace 설치는 npm spec 대신 marketplace 소스 메타데이터를 유지하기 때문입니다. + `--pin`은 npm 설치에만 적용됩니다. `git:` 설치에서는 지원되지 않습니다. 고정된 소스를 원하면 `git:github.com/acme/plugin@v1.2.3`처럼 명시적 git ref를 사용하세요. 마켓플레이스 설치는 npm spec 대신 마켓플레이스 소스 메타데이터를 저장하므로 `--marketplace`와 함께 지원되지 않습니다. - `--dangerously-force-unsafe-install`은 내장 위험 코드 스캐너의 오탐에 대한 비상 옵션입니다. 내장 스캐너가 `critical` 결과를 보고하더라도 설치를 계속할 수 있게 하지만, Plugin `before_install` 훅 정책 차단을 우회하지는 않으며 스캔 실패도 우회하지 않습니다. + `--dangerously-force-unsafe-install`은 내장 위험 코드 스캐너의 오탐을 위한 비상 옵션입니다. 내장 스캐너가 `critical` 결과를 보고하더라도 설치를 계속할 수 있게 하지만, Plugin `before_install` 훅 정책 차단을 우회하지 **않으며** 스캔 실패도 우회하지 **않습니다**. - 이 CLI 플래그는 Plugin 설치/업데이트 흐름에 적용됩니다. Gateway 기반 Skills 종속성 설치는 대응되는 `dangerouslyForceUnsafeInstall` 요청 override를 사용하며, `openclaw skills install`은 별도의 ClawHub Skill 다운로드/설치 흐름으로 유지됩니다. + 이 CLI 플래그는 Plugin 설치/업데이트 흐름에 적용됩니다. Gateway 기반 Skill 종속성 설치는 대응되는 `dangerouslyForceUnsafeInstall` 요청 재정의를 사용하며, `openclaw skills install`은 별도의 ClawHub Skill 다운로드/설치 흐름으로 남습니다. - ClawHub에 게시한 Plugin이 레지스트리 스캔으로 차단된 경우 [ClawHub](/ko/tools/clawhub)의 게시자 단계를 사용하세요. + ClawHub에 게시한 Plugin이 레지스트리 스캔에 의해 차단된 경우 [ClawHub](/ko/tools/clawhub)의 게시자 단계를 사용하세요. - `plugins install`은 `package.json`에 `openclaw.hooks`를 노출하는 훅 팩의 설치 표면이기도 합니다. 패키지 설치가 아니라 필터링된 훅 표시와 훅별 활성화에는 `openclaw hooks`를 사용하세요. + `plugins install`은 `package.json`에서 `openclaw.hooks`를 노출하는 훅 팩의 설치 표면이기도 합니다. 패키지 설치가 아니라 필터링된 훅 가시성과 훅별 활성화에는 `openclaw hooks`를 사용하세요. - Npm spec은 **레지스트리 전용**입니다(패키지 이름 + 선택적 **정확한 버전** 또는 **dist-tag**). Git/URL/file spec과 semver 범위는 거부됩니다. 셸에 전역 npm 설치 설정이 있더라도, 종속성 설치는 안전을 위해 `--ignore-scripts`와 함께 프로젝트 로컬로 실행됩니다. + Npm spec은 **레지스트리 전용**입니다(패키지 이름 + 선택적 **정확한 버전** 또는 **dist-tag**). Git/URL/file spec과 semver 범위는 거부됩니다. 종속성 설치는 안전을 위해 `--ignore-scripts`로 프로젝트 로컬에서 실행되며, 셸에 전역 npm 설치 설정이 있어도 동일합니다. 관리형 Plugin npm 루트는 OpenClaw의 패키지 수준 npm `overrides`를 상속하므로 호스트 보안 pin이 호이스팅된 Plugin 종속성에도 적용됩니다. - npm 해석을 명시적으로 만들고 싶을 때는 `npm:`를 사용하세요. 단순 패키지 spec도 출시 전환 기간 동안 npm에서 직접 설치됩니다. + npm 해석을 명시하려면 `npm:`를 사용하세요. 출시 전환 기간에는 단순 패키지 spec도 npm에서 직접 설치됩니다. - 단순 spec과 `@latest`는 안정 트랙에 머뭅니다. `2026.5.3-1` 같은 OpenClaw 날짜가 찍힌 수정 버전은 이 검사에서 안정 릴리스입니다. npm이 이 중 하나를 prerelease로 해석하면 OpenClaw는 중지하고 `@beta`/`@rc` 같은 prerelease 태그 또는 `@1.2.3-beta.4` 같은 정확한 prerelease 버전으로 명시적으로 선택하라고 요청합니다. + 단순 spec과 `@latest`는 안정 트랙에 유지됩니다. `2026.5.3-1` 같은 OpenClaw 날짜 표기 수정 버전은 이 검사에서 안정 릴리스입니다. npm이 이 중 하나를 prerelease로 해석하면 OpenClaw는 중지하고 `@beta`/`@rc` 같은 prerelease 태그 또는 `@1.2.3-beta.4` 같은 정확한 prerelease 버전으로 명시적으로 선택하라고 요청합니다. 단순 설치 spec이 공식 Plugin ID(예: `diffs`)와 일치하면 OpenClaw는 카탈로그 항목을 직접 설치합니다. 같은 이름의 npm 패키지를 설치하려면 명시적 scoped spec(예: `@scope/diffs`)을 사용하세요. - - git 저장소에서 직접 설치하려면 `git:`를 사용하세요. 지원되는 형식에는 `git:github.com/owner/repo`, `git:owner/repo`, 전체 `https://`, `ssh://`, `git://`, `file://`, 및 `git@host:owner/repo.git` 클론 URL이 포함됩니다. 설치 전에 브랜치, 태그 또는 커밋을 체크아웃하려면 `@` 또는 `#`를 추가하세요. + + git 리포지토리에서 직접 설치하려면 `git:`를 사용하세요. 지원되는 형식에는 `git:github.com/owner/repo`, `git:owner/repo`, 전체 `https://`, `ssh://`, `git://`, `file://`, `git@host:owner/repo.git` 클론 URL이 포함됩니다. 설치 전에 브랜치, 태그 또는 커밋을 체크아웃하려면 `@` 또는 `#`를 추가하세요. - Git 설치는 임시 디렉터리에 클론하고, 요청된 ref가 있으면 체크아웃한 다음, 일반 Plugin 디렉터리 설치 프로그램을 사용합니다. 즉 매니페스트 검증, 위험 코드 스캔, 패키지 관리자 설치 작업, 설치 기록이 npm 설치처럼 동작합니다. 기록된 git 설치에는 소스 URL/ref와 해석된 커밋이 포함되므로 `openclaw plugins update`가 나중에 소스를 다시 해석할 수 있습니다. + Git 설치는 임시 디렉터리에 클론하고, 요청된 ref가 있으면 체크아웃한 다음, 일반 Plugin 디렉터리 설치 프로그램을 사용합니다. 즉 매니페스트 검증, 위험 코드 스캔, 패키지 관리자 설치 작업 및 설치 기록이 npm 설치처럼 동작합니다. 기록된 git 설치에는 소스 URL/ref와 해석된 커밋이 포함되므로 `openclaw plugins update`가 나중에 소스를 다시 해석할 수 있습니다. - git에서 설치한 후에는 `openclaw plugins inspect --runtime --json`을 사용하여 gateway 메서드 및 CLI 명령 같은 런타임 등록을 확인하세요. Plugin이 `api.registerCli`로 CLI 루트를 등록했다면, 예를 들어 `openclaw demo-plugin ping`처럼 OpenClaw 루트 CLI를 통해 해당 명령을 직접 실행하세요. + git에서 설치한 후 `openclaw plugins inspect --runtime --json`을 사용하여 Gateway 메서드 및 CLI 명령 같은 런타임 등록을 확인하세요. Plugin이 `api.registerCli`로 CLI 루트를 등록한 경우, 예를 들어 `openclaw demo-plugin ping`처럼 OpenClaw 루트 CLI를 통해 해당 명령을 직접 실행하세요. 지원되는 아카이브: `.zip`, `.tgz`, `.tar.gz`, `.tar`. 네이티브 OpenClaw Plugin 아카이브는 추출된 Plugin 루트에 유효한 `openclaw.plugin.json`을 포함해야 합니다. `package.json`만 포함한 아카이브는 OpenClaw가 설치 기록을 쓰기 전에 거부됩니다. - 파일이 npm-pack tarball이고, 레지스트리 설치에서 사용하는 것과 동일한 관리형 npm 루트 설치 경로를 테스트하려면 `npm-pack:`를 사용하세요. 여기에는 `package-lock.json` 검증, hoisted 종속성 스캔, npm 설치 기록이 포함됩니다. 일반 아카이브 경로는 여전히 Plugin 확장 루트 아래에 로컬 아카이브로 설치됩니다. + 파일이 npm-pack tarball이고 레지스트리 설치에 사용되는 것과 동일한 관리형 npm 루트 설치 경로를 테스트하려면 + `npm-pack:`를 사용하세요. 여기에는 `package-lock.json` 검증, 호이스팅된 종속성 스캔 및 + npm 설치 기록이 포함됩니다. 일반 아카이브 경로는 여전히 Plugin 확장 루트 아래에 로컬 아카이브로 설치됩니다. - Claude marketplace 설치도 지원됩니다. + Claude 마켓플레이스 설치도 지원됩니다. -ClawHub 설치는 명시적 `clawhub:` locator를 사용합니다. +ClawHub 설치는 명시적 `clawhub:` 로케이터를 사용합니다. ```bash openclaw plugins install clawhub:openclaw-codex-app-server openclaw plugins install clawhub:openclaw-codex-app-server@1.2.3 ``` -단순 npm 안전 Plugin spec은 출시 전환 기간 동안 기본적으로 npm에서 설치됩니다. +출시 전환 기간에는 단순 npm 안전 Plugin spec이 기본적으로 npm에서 설치됩니다. ```bash openclaw plugins install openclaw-codex-app-server @@ -184,19 +190,19 @@ openclaw plugins install npm:openclaw-codex-app-server openclaw plugins install npm:@scope/plugin-name@1.0.1 ``` -OpenClaw는 설치 전에 게시된 Plugin API / 최소 Gateway 호환성을 확인합니다. 선택한 ClawHub 버전이 ClawPack 아티팩트를 게시하는 경우, OpenClaw는 버전이 지정된 npm-pack `.tgz`를 다운로드하고 ClawHub digest 헤더와 아티팩트 digest를 검증한 다음 일반 아카이브 경로를 통해 설치합니다. ClawPack 메타데이터가 없는 이전 ClawHub 버전은 여전히 레거시 패키지 아카이브 검증 경로를 통해 설치됩니다. 기록된 설치는 이후 업데이트를 위해 ClawHub 소스 메타데이터, 아티팩트 종류, npm integrity, npm shasum, tarball 이름, ClawPack digest 정보를 유지합니다. -버전이 지정되지 않은 ClawHub 설치는 버전이 지정되지 않은 기록 spec을 유지하므로 `openclaw plugins update`가 더 새 ClawHub 릴리스를 따라갈 수 있습니다. `clawhub:pkg@1.2.3` 및 `clawhub:pkg@beta` 같은 명시적 버전 또는 태그 selector는 해당 selector에 고정된 상태로 유지됩니다. +OpenClaw는 설치 전에 광고된 Plugin API / 최소 Gateway 호환성을 확인합니다. 선택한 ClawHub 버전이 ClawPack 아티팩트를 게시하면, OpenClaw는 버전이 지정된 npm-pack `.tgz`를 다운로드하고 ClawHub 다이제스트 헤더와 아티팩트 다이제스트를 검증한 뒤 일반 아카이브 경로를 통해 설치합니다. ClawPack 메타데이터가 없는 이전 ClawHub 버전은 여전히 레거시 패키지 아카이브 검증 경로를 통해 설치됩니다. 기록된 설치는 이후 업데이트를 위해 ClawHub 소스 메타데이터, 아티팩트 종류, npm 무결성, npm shasum, tarball 이름, ClawPack 다이제스트 정보를 보관합니다. +버전이 지정되지 않은 ClawHub 설치는 버전 없는 기록된 사양을 유지하므로 `openclaw plugins update`가 더 새로운 ClawHub 릴리스를 따라갈 수 있습니다. `clawhub:pkg@1.2.3` 및 `clawhub:pkg@beta` 같은 명시적 버전 또는 태그 선택자는 해당 선택자에 고정된 상태로 유지됩니다. #### Marketplace 약식 표기 -marketplace 이름이 `~/.claude/plugins/known_marketplaces.json`의 Claude 로컬 레지스트리 캐시에 있을 때는 `plugin@marketplace` 약식 표기를 사용하세요. +Marketplace 이름이 Claude의 로컬 레지스트리 캐시 `~/.claude/plugins/known_marketplaces.json`에 있으면 `plugin@marketplace` 약식 표기를 사용하세요. ```bash openclaw plugins marketplace list openclaw plugins install @ ``` -marketplace 소스를 명시적으로 전달하려면 `--marketplace`를 사용하세요. +Marketplace 소스를 명시적으로 전달하려면 `--marketplace`를 사용하세요. ```bash openclaw plugins install --marketplace @@ -206,16 +212,16 @@ openclaw plugins install --marketplace ./my-marketplace ``` - - - `~/.claude/plugins/known_marketplaces.json`에 있는 Claude 알려진 마켓플레이스 이름 - - 로컬 마켓플레이스 루트 또는 `marketplace.json` 경로 - - `owner/repo` 같은 GitHub 저장소 축약형 + + - `~/.claude/plugins/known_marketplaces.json`의 Claude 알려진 Marketplace 이름 + - 로컬 Marketplace 루트 또는 `marketplace.json` 경로 + - `owner/repo` 같은 GitHub 저장소 약식 표기 - `https://github.com/owner/repo` 같은 GitHub 저장소 URL - git URL - - GitHub 또는 git에서 로드된 원격 마켓플레이스의 경우 Plugin 항목은 복제된 마켓플레이스 저장소 안에 있어야 합니다. OpenClaw는 해당 저장소의 상대 경로 소스를 허용하고, 원격 매니페스트의 HTTP(S), 절대 경로, git, GitHub 및 기타 비경로 Plugin 소스를 거부합니다. + + GitHub 또는 git에서 로드되는 원격 Marketplace의 경우, Plugin 항목은 복제된 Marketplace 저장소 안에 있어야 합니다. OpenClaw는 해당 저장소의 상대 경로 소스를 허용하고, 원격 매니페스트의 HTTP(S), 절대 경로, git, GitHub 및 기타 경로가 아닌 Plugin 소스를 거부합니다. @@ -227,7 +233,7 @@ openclaw plugins install --marketplace ./my-marketplace - Cursor 호환 번들(`.cursor-plugin/plugin.json`) -호환 번들은 일반 Plugin 루트에 설치되며 동일한 list/info/enable/disable 흐름에 참여합니다. 현재 번들 Skills, Claude command-skills, Claude `settings.json` 기본값, Claude `.lsp.json` / 매니페스트 선언 `lspServers` 기본값, Cursor command-skills, 호환 Codex 훅 디렉터리가 지원됩니다. 감지된 다른 번들 기능은 diagnostics/info에 표시되지만 아직 런타임 실행에는 연결되지 않았습니다. +호환 번들은 일반 Plugin 루트에 설치되며 동일한 list/info/enable/disable 흐름에 참여합니다. 현재 번들 Skills, Claude 명령 Skills, Claude `settings.json` 기본값, Claude `.lsp.json` / 매니페스트 선언 `lspServers` 기본값, Cursor 명령 Skills, 호환 Codex hook 디렉터리가 지원됩니다. 감지된 다른 번들 기능은 진단/info에 표시되지만 아직 런타임 실행에 연결되어 있지는 않습니다. ### 목록 @@ -246,45 +252,45 @@ openclaw plugins search --json 활성화된 Plugin만 표시합니다. - 표 보기에서 Plugin별 소스/출처/버전/활성화 메타데이터 상세 줄로 전환합니다. + 표 보기에서 Plugin별 소스/출처/버전/활성화 메타데이터가 포함된 상세 줄로 전환합니다. - 기계가 읽을 수 있는 인벤터리와 레지스트리 진단 및 패키지 의존성 설치 상태입니다. + 레지스트리 진단 및 패키지 의존성 설치 상태가 포함된 기계 판독 가능 인벤토리입니다. -`plugins list`는 먼저 영구 저장된 로컬 Plugin 레지스트리를 읽고, 레지스트리가 없거나 유효하지 않으면 매니페스트만으로 파생한 폴백을 사용합니다. Plugin이 설치, 활성화되었고 콜드 스타트업 계획에 표시되는지 확인하는 데 유용하지만, 이미 실행 중인 Gateway 프로세스의 라이브 런타임 프로브는 아닙니다. Plugin 코드, 활성화 상태, 훅 정책 또는 `plugins.load.paths`를 변경한 뒤에는 새 `register(api)` 코드나 훅이 실행되기를 기대하기 전에 채널을 제공하는 Gateway를 다시 시작하세요. 원격/컨테이너 배포의 경우 래퍼 프로세스만이 아니라 실제 `openclaw gateway run` 자식을 다시 시작하고 있는지 확인하세요. +`plugins list`는 먼저 지속 저장된 로컬 Plugin 레지스트리를 읽고, 레지스트리가 없거나 유효하지 않으면 매니페스트만으로 파생한 fallback을 사용합니다. Plugin이 설치되고 활성화되었으며 콜드 스타트업 계획에서 보이는지 확인하는 데 유용하지만, 이미 실행 중인 Gateway 프로세스의 라이브 런타임 probe는 아닙니다. Plugin 코드, 활성화 상태, hook 정책 또는 `plugins.load.paths`를 변경한 뒤에는 새 `register(api)` 코드나 hook이 실행되기를 기대하기 전에 채널을 제공하는 Gateway를 다시 시작하세요. 원격/컨테이너 배포에서는 wrapper 프로세스만이 아니라 실제 `openclaw gateway run` child를 다시 시작하고 있는지 확인하세요. -`plugins list --json`에는 `package.json` `dependencies` 및 `optionalDependencies`에서 가져온 각 Plugin의 `dependencyStatus`가 포함됩니다. OpenClaw는 해당 패키지 이름이 Plugin의 일반 Node `node_modules` 조회 경로에 있는지 확인합니다. Plugin 런타임 코드를 가져오거나, 패키지 관리자를 실행하거나, 누락된 의존성을 복구하지 않습니다. +`plugins list --json`에는 `package.json`의 `dependencies` 및 `optionalDependencies`에서 가져온 각 Plugin의 `dependencyStatus`가 포함됩니다. OpenClaw는 해당 패키지 이름이 Plugin의 일반적인 Node `node_modules` 조회 경로에 있는지 확인합니다. Plugin 런타임 코드를 import하거나, 패키지 관리자를 실행하거나, 누락된 의존성을 복구하지 않습니다. -`plugins search`는 원격 ClawHub 카탈로그 조회입니다. 로컬 상태를 검사하거나, 구성을 변경하거나, 패키지를 설치하거나, Plugin 런타임 코드를 로드하지 않습니다. 검색 결과에는 ClawHub 패키지 이름, 패밀리, 채널, 버전, 요약 및 `openclaw plugins install clawhub:` 같은 설치 힌트가 포함됩니다. +`plugins search`는 원격 ClawHub 카탈로그 조회입니다. 로컬 상태를 검사하거나, config를 변경하거나, 패키지를 설치하거나, Plugin 런타임 코드를 로드하지 않습니다. 검색 결과에는 ClawHub 패키지 이름, family, channel, version, summary 및 `openclaw plugins install clawhub:` 같은 설치 힌트가 포함됩니다. -패키징된 Docker 이미지 안에서 번들 Plugin 작업을 하려면 `/app/extensions/synology-chat` 같은 일치하는 패키징된 소스 경로 위에 Plugin 소스 디렉터리를 바인드 마운트하세요. OpenClaw는 `/app/dist/extensions/synology-chat`보다 먼저 해당 마운트된 소스 오버레이를 발견합니다. 단순히 복사한 소스 디렉터리는 비활성 상태로 남으므로 일반 패키징 설치는 계속 컴파일된 dist를 사용합니다. +패키징된 Docker 이미지 안에서 번들 Plugin 작업을 하려면 Plugin 소스 디렉터리를 `/app/extensions/synology-chat` 같은 일치하는 패키징된 소스 경로 위에 bind-mount하세요. OpenClaw는 `/app/dist/extensions/synology-chat`보다 먼저 해당 mount된 소스 overlay를 발견합니다. 단순히 복사된 소스 디렉터리는 inert 상태로 남으므로 일반 패키징 설치는 계속 컴파일된 dist를 사용합니다. -런타임 훅 디버깅의 경우: +런타임 hook 디버깅의 경우: -- `openclaw plugins inspect --runtime --json`은 모듈 로드 검사 패스에서 등록된 훅과 진단을 표시합니다. 런타임 검사는 의존성을 절대 설치하지 않습니다. 레거시 의존성 상태를 정리하거나 구성에서 참조되는 누락된 다운로드 가능 Plugin을 복구하려면 `openclaw doctor --fix`를 사용하세요. -- `openclaw gateway status --deep --require-rpc`는 도달 가능한 Gateway, 서비스/프로세스 힌트, 구성 경로 및 RPC 상태를 확인합니다. -- 번들되지 않은 대화 훅(`llm_input`, `llm_output`, `before_agent_finalize`, `agent_end`)에는 `plugins.entries..hooks.allowConversationAccess=true`가 필요합니다. +- `openclaw plugins inspect --runtime --json`은 모듈 로드 검사 패스에서 등록된 hook과 진단을 표시합니다. 런타임 검사는 의존성을 설치하지 않습니다. 레거시 의존성 상태를 정리하거나 config에서 참조하는 누락된 다운로드 가능 Plugin을 복구하려면 `openclaw doctor --fix`를 사용하세요. +- `openclaw gateway status --deep --require-rpc`는 도달 가능한 Gateway, 서비스/프로세스 힌트, config 경로 및 RPC 상태를 확인합니다. +- 번들되지 않은 대화 hook(`llm_input`, `llm_output`, `before_model_resolve`, `before_agent_reply`, `before_agent_run`, `before_agent_finalize`, `agent_end`)에는 `plugins.entries..hooks.allowConversationAccess=true`가 필요합니다. -로컬 디렉터리 복사를 피하려면 `--link`를 사용하세요(`plugins.load.paths`에 추가됨). +로컬 디렉터리를 복사하지 않으려면 `--link`를 사용하세요(`plugins.load.paths`에 추가됨). ```bash openclaw plugins install -l ./my-plugin ``` -링크된 설치는 관리되는 설치 대상 위에 복사하는 대신 소스 경로를 재사용하므로 `--force`는 `--link`와 함께 지원되지 않습니다. +연결된 설치는 관리형 설치 대상 위에 복사하는 대신 소스 경로를 재사용하므로 `--force`는 `--link`와 함께 지원되지 않습니다. -npm 설치에서 `--pin`을 사용하면 기본 동작은 고정하지 않은 상태로 유지하면서, 해석된 정확한 spec(`name@version`)을 관리되는 Plugin 인덱스에 저장합니다. +npm 설치에서 `--pin`을 사용하면 기본 동작은 고정하지 않은 상태로 유지하면서, 해결된 정확한 사양(`name@version`)을 관리형 Plugin 인덱스에 저장합니다. ### Plugin 인덱스 -Plugin 설치 메타데이터는 사용자가 설정하는 구성이 아니라 기계가 관리하는 상태입니다. 설치와 업데이트는 활성 OpenClaw 상태 디렉터리 아래 `plugins/installs.json`에 이를 기록합니다. 최상위 `installRecords` 맵은 손상되었거나 누락된 Plugin 매니페스트의 레코드를 포함해 설치 메타데이터의 지속 소스입니다. `plugins` 배열은 매니페스트에서 파생된 콜드 레지스트리 캐시입니다. 이 파일에는 편집 금지 경고가 포함되며 `openclaw plugins update`, uninstall, diagnostics 및 콜드 Plugin 레지스트리에서 사용됩니다. +Plugin 설치 메타데이터는 사용자가 관리하는 config가 아니라 기계가 관리하는 상태입니다. 설치와 업데이트는 이를 활성 OpenClaw 상태 디렉터리 아래 `plugins/installs.json`에 기록합니다. 최상위 `installRecords` 맵은 깨졌거나 누락된 Plugin 매니페스트에 대한 기록을 포함한 설치 메타데이터의 지속 소스입니다. `plugins` 배열은 매니페스트에서 파생된 콜드 레지스트리 캐시입니다. 이 파일에는 편집 금지 경고가 포함되어 있으며 `openclaw plugins update`, uninstall, 진단 및 콜드 Plugin 레지스트리에서 사용됩니다. -OpenClaw가 구성에서 제공된 레거시 `plugins.installs` 레코드를 발견하면 이를 Plugin 인덱스로 옮기고 구성 키를 제거합니다. 두 쓰기 중 하나라도 실패하면 설치 메타데이터가 손실되지 않도록 구성 레코드를 유지합니다. +OpenClaw가 config에서 제공된 레거시 `plugins.installs` 기록을 발견하면, 런타임 읽기는 `openclaw.json`을 다시 쓰지 않고 이를 호환성 입력으로 처리합니다. 명시적 Plugin 쓰기와 `openclaw doctor --fix`는 config 쓰기가 허용되는 경우 해당 기록을 Plugin 인덱스로 이동하고 config 키를 제거합니다. 둘 중 하나라도 쓰기에 실패하면 설치 메타데이터가 손실되지 않도록 config 기록을 유지합니다. ### 제거 @@ -294,10 +300,10 @@ openclaw plugins uninstall --dry-run openclaw plugins uninstall --keep-files ``` -`uninstall`은 해당하는 경우 `plugins.entries`, 영구 저장된 Plugin 인덱스, Plugin 허용/거부 목록 항목, 링크된 `plugins.load.paths` 항목에서 Plugin 레코드를 제거합니다. `--keep-files`가 설정되지 않은 한, 제거는 OpenClaw의 Plugin 확장 루트 안에 있는 추적된 관리 설치 디렉터리도 제거합니다. Active Memory Plugin의 경우 메모리 슬롯이 `memory-core`로 재설정됩니다. +`uninstall`은 해당되는 경우 `plugins.entries`, 지속 저장된 Plugin 인덱스, Plugin allow/deny list 항목 및 연결된 `plugins.load.paths` 항목에서 Plugin 기록을 제거합니다. `--keep-files`가 설정되지 않은 한, uninstall은 추적되는 관리형 설치 디렉터리가 OpenClaw의 Plugin extensions 루트 안에 있을 때 해당 디렉터리도 제거합니다. Active Memory Plugin의 경우 메모리 슬롯이 `memory-core`로 재설정됩니다. -`--keep-config`는 `--keep-files`의 사용 중단된 별칭으로 지원됩니다. +`--keep-config`는 `--keep-files`의 사용 중단된 alias로 지원됩니다. ### 업데이트 @@ -310,29 +316,29 @@ openclaw plugins update @openclaw/voice-call openclaw plugins update openclaw-codex-app-server --dangerously-force-unsafe-install ``` -업데이트는 관리되는 Plugin 인덱스의 추적된 Plugin 설치와 `hooks.internal.installs`의 추적된 hook-pack 설치에 적용됩니다. +업데이트는 관리형 Plugin 인덱스에서 추적되는 Plugin 설치와 `hooks.internal.installs`에서 추적되는 hook-pack 설치에 적용됩니다. - - Plugin id를 전달하면 OpenClaw는 해당 Plugin에 기록된 설치 spec을 재사용합니다. 즉, 이전에 저장된 `@beta` 같은 dist-tag와 정확히 고정된 버전은 이후 `update ` 실행에서도 계속 사용됩니다. + + Plugin id를 전달하면 OpenClaw는 해당 Plugin에 대해 기록된 설치 사양을 재사용합니다. 즉 이전에 저장된 `@beta` 같은 dist-tag와 정확히 고정된 버전은 이후 `update ` 실행에서도 계속 사용됩니다. - npm 설치의 경우 dist-tag 또는 정확한 버전이 포함된 명시적 npm 패키지 spec도 전달할 수 있습니다. OpenClaw는 해당 패키지 이름을 추적된 Plugin 레코드로 다시 해석하고, 설치된 해당 Plugin을 업데이트하며, 향후 id 기반 업데이트를 위해 새 npm spec을 기록합니다. + npm 설치의 경우 dist-tag 또는 정확한 버전이 포함된 명시적 npm 패키지 사양을 전달할 수도 있습니다. OpenClaw는 해당 패키지 이름을 추적 중인 Plugin 기록으로 다시 해석하고, 설치된 해당 Plugin을 업데이트한 뒤, 향후 id 기반 업데이트를 위해 새 npm 사양을 기록합니다. - 버전이나 태그 없이 npm 패키지 이름을 전달해도 추적된 Plugin 레코드로 다시 해석됩니다. Plugin이 정확한 버전에 고정되어 있었고 이를 레지스트리의 기본 릴리스 라인으로 되돌리고 싶을 때 사용하세요. + 버전이나 태그 없이 npm 패키지 이름을 전달해도 추적 중인 Plugin 기록으로 다시 해석됩니다. Plugin이 정확한 버전에 고정되어 있었고 이를 레지스트리의 기본 릴리스 라인으로 되돌리고 싶을 때 사용하세요. - - `openclaw plugins update`는 새 spec을 전달하지 않는 한 추적된 Plugin spec을 재사용합니다. `openclaw update`는 추가로 활성 OpenClaw 업데이트 채널을 알고 있습니다. 베타 채널에서는 기본 라인 npm 및 ClawHub Plugin 레코드가 먼저 `@beta`를 시도한 다음, Plugin 베타 릴리스가 없으면 기록된 default/latest spec으로 폴백합니다. 정확한 버전과 명시적 태그는 해당 선택자에 고정된 상태를 유지합니다. + + `openclaw plugins update`는 새 사양을 전달하지 않는 한 추적 중인 Plugin 사양을 재사용합니다. `openclaw update`는 추가로 활성 OpenClaw 업데이트 채널을 알고 있습니다. beta 채널에서는 기본 라인의 npm 및 ClawHub Plugin 기록이 먼저 `@beta`를 시도한 뒤, Plugin beta 릴리스가 없으면 기록된 default/latest 사양으로 fallback합니다. 정확한 버전과 명시적 태그는 해당 선택자에 고정된 상태로 유지됩니다. - - 라이브 npm 업데이트 전에 OpenClaw는 설치된 패키지 버전을 npm 레지스트리 메타데이터와 비교합니다. 설치된 버전과 기록된 아티팩트 식별자가 이미 해석된 대상과 일치하면 다운로드, 재설치 또는 `openclaw.json` 재작성 없이 업데이트를 건너뜁니다. + + 라이브 npm 업데이트 전에 OpenClaw는 설치된 패키지 버전을 npm 레지스트리 메타데이터와 비교합니다. 설치된 버전과 기록된 아티팩트 식별자가 이미 해결된 대상과 일치하면 다운로드, 재설치 또는 `openclaw.json` 재작성 없이 업데이트를 건너뜁니다. - 저장된 무결성 해시가 있고 가져온 아티팩트 해시가 변경되면 OpenClaw는 이를 npm 아티팩트 드리프트로 처리합니다. 대화형 `openclaw plugins update` 명령은 예상 해시와 실제 해시를 출력하고 계속하기 전에 확인을 요청합니다. 비대화형 업데이트 헬퍼는 호출자가 명시적 계속 정책을 제공하지 않는 한 닫힌 상태로 실패합니다. + 저장된 무결성 해시가 있고 가져온 아티팩트 해시가 변경되면 OpenClaw는 이를 npm 아티팩트 drift로 처리합니다. 대화형 `openclaw plugins update` 명령은 예상 해시와 실제 해시를 출력하고 계속 진행하기 전에 확인을 요청합니다. 비대화형 업데이트 helper는 호출자가 명시적 계속 진행 정책을 제공하지 않는 한 fail closed로 실패합니다. - - `--dangerously-force-unsafe-install`는 Plugin 업데이트 중 내장 위험 코드 스캔의 오탐에 대한 비상 우회로 `plugins update`에서도 사용할 수 있습니다. 그래도 Plugin `before_install` 정책 차단이나 스캔 실패 차단은 우회하지 않으며, hook-pack 업데이트가 아니라 Plugin 업데이트에만 적용됩니다. + + `--dangerously-force-unsafe-install`은 Plugin 업데이트 중 내장 위험 코드 scan의 false positive에 대한 break-glass override로 `plugins update`에서도 사용할 수 있습니다. 그래도 Plugin `before_install` 정책 차단이나 scan 실패 차단을 우회하지 않으며, hook-pack 업데이트가 아니라 Plugin 업데이트에만 적용됩니다. @@ -344,34 +350,34 @@ openclaw plugins inspect --runtime openclaw plugins inspect --json ``` -Inspect는 기본적으로 Plugin 런타임을 가져오지 않고 식별 정보, 로드 상태, 소스, 매니페스트 기능, 정책 플래그, 진단, 설치 메타데이터, 번들 기능, 감지된 MCP 또는 LSP 서버 지원을 표시합니다. `--runtime`을 추가하면 Plugin 모듈을 로드하고 등록된 훅, 도구, 명령, 서비스, Gateway 메서드 및 HTTP 라우트를 포함합니다. 런타임 검사는 누락된 Plugin 의존성을 직접 보고합니다. 설치와 복구는 `openclaw plugins install`, `openclaw plugins update`, `openclaw doctor --fix`에 남아 있습니다. +Inspect는 기본적으로 Plugin 런타임을 import하지 않고 identity, load status, source, manifest capabilities, policy flags, diagnostics, install metadata, bundle capabilities 및 감지된 MCP 또는 LSP server support를 표시합니다. `--runtime`을 추가하면 Plugin 모듈을 로드하고 등록된 hook, tool, command, service, gateway method 및 HTTP route를 포함합니다. 런타임 검사는 누락된 Plugin 의존성을 직접 보고합니다. 설치와 복구는 `openclaw plugins install`, `openclaw plugins update`, `openclaw doctor --fix`에 유지됩니다. -Plugin 소유 CLI 명령은 루트 `openclaw` 명령 그룹으로 설치됩니다. `inspect --runtime`이 `cliCommands` 아래에 명령을 표시한 뒤에는 `openclaw ...`로 실행하세요. 예를 들어 `demo-git`을 등록하는 Plugin은 `openclaw demo-git ping`으로 확인할 수 있습니다. +Plugin 소유 CLI 명령은 루트 `openclaw` command group으로 설치됩니다. `inspect --runtime`이 `cliCommands` 아래에 명령을 표시한 뒤에는 `openclaw ...`로 실행하세요. 예를 들어 `demo-git`를 등록하는 Plugin은 `openclaw demo-git ping`으로 검증할 수 있습니다. -각 Plugin은 런타임에 실제로 등록하는 항목에 따라 분류됩니다. +각 Plugin은 런타임에서 실제로 등록하는 항목에 따라 분류됩니다: -- **plain-capability** — 한 가지 기능 유형(예: provider 전용 Plugin) +- **plain-capability** — 하나의 기능 유형(예: provider 전용 Plugin) - **hybrid-capability** — 여러 기능 유형(예: 텍스트 + 음성 + 이미지) -- **hook-only** — 훅만 있고 기능 또는 표면 없음 -- **non-capability** — 도구/명령/서비스는 있지만 기능 없음 +- **hook-only** — 훅만 있으며 기능이나 표면은 없음 +- **non-capability** — 도구/명령/서비스는 있지만 기능은 없음 기능 모델에 대한 자세한 내용은 [Plugin 형태](/ko/plugins/architecture#plugin-shapes)를 참조하세요. -`--json` 플래그는 스크립팅과 감사에 적합한 기계가 읽을 수 있는 보고서를 출력합니다. `inspect --all`은 shape, capability 종류, 호환성 알림, 번들 기능, 훅 요약 열이 포함된 전체 플릿 표를 렌더링합니다. `info`는 `inspect`의 별칭입니다. +`--json` 플래그는 스크립팅과 감사에 적합한 기계 판독 가능 보고서를 출력합니다. `inspect --all`은 형태, 기능 종류, 호환성 알림, 번들 기능, 훅 요약 열을 포함한 전체 플릿 표를 렌더링합니다. `info`는 `inspect`의 별칭입니다. -### Doctor +### 진단 ```bash openclaw plugins doctor ``` -`doctor`는 Plugin 로드 오류, 매니페스트/검색 진단 및 호환성 알림을 보고합니다. 모든 것이 깨끗하면 `No plugin issues detected.`를 출력합니다. +`doctor`는 Plugin 로드 오류, 매니페스트/디스커버리 진단, 호환성 알림을 보고합니다. 모든 것이 정상이면 `No plugin issues detected.`를 출력합니다. -구성된 Plugin이 디스크에 있지만 로더의 경로 안전성 검사에 의해 차단된 경우, 구성 검증은 Plugin 항목을 유지하고 `present but blocked`로 보고합니다. `plugins.entries.` 또는 `plugins.allow` 구성을 제거하는 대신, 경로 소유권이나 world-writable 권한 같은 앞선 차단된 Plugin 진단을 수정하세요. +구성된 Plugin이 디스크에 있지만 로더의 경로 안전성 검사에 의해 차단된 경우, 구성 검증은 Plugin 항목을 유지하고 이를 `present but blocked`로 보고합니다. `plugins.entries.` 또는 `plugins.allow` 구성을 제거하지 말고, 경로 소유권이나 world-writable 권한 같은 앞선 차단된 Plugin 진단을 수정하세요. -`register`/`activate` export 누락 같은 모듈 형태 실패의 경우 `OPENCLAW_PLUGIN_LOAD_DEBUG=1`로 다시 실행하여 진단 출력에 간단한 export 형태 요약을 포함하세요. +누락된 `register`/`activate` 내보내기 같은 모듈 형태 실패의 경우, `OPENCLAW_PLUGIN_LOAD_DEBUG=1`로 다시 실행하여 진단 출력에 간결한 내보내기 형태 요약을 포함하세요. ### 레지스트리 @@ -381,14 +387,14 @@ openclaw plugins registry --refresh openclaw plugins registry --json ``` -로컬 Plugin 레지스트리는 설치된 Plugin ID, 활성화 상태, 소스 메타데이터, 기여 소유권에 대한 OpenClaw의 영속화된 콜드 읽기 모델입니다. 일반 시작, 제공자 소유자 조회, 채널 설정 분류, Plugin 인벤토리는 Plugin 런타임 모듈을 가져오지 않고도 이를 읽을 수 있습니다. +로컬 Plugin 레지스트리는 설치된 Plugin ID, 활성화 상태, 소스 메타데이터, 기여 소유권에 대한 OpenClaw의 영속화된 콜드 읽기 모델입니다. 일반 시작, provider 소유자 조회, 채널 설정 분류, Plugin 인벤토리는 Plugin 런타임 모듈을 가져오지 않고도 이를 읽을 수 있습니다. -`plugins registry`를 사용해 영속화된 레지스트리가 있는지, 최신인지, 오래되었는지 검사하세요. `--refresh`를 사용해 영속화된 Plugin 인덱스, 구성 정책, 매니페스트/패키지 메타데이터에서 다시 빌드하세요. 이는 복구 경로이지, 런타임 활성화 경로가 아닙니다. +`plugins registry`를 사용하여 영속화된 레지스트리가 존재하는지, 최신인지, 오래되었는지 검사하세요. `--refresh`를 사용하여 영속화된 Plugin 인덱스, 구성 정책, 매니페스트/패키지 메타데이터에서 이를 다시 빌드하세요. 이는 복구 경로이며, 런타임 활성화 경로가 아닙니다. -`openclaw doctor --fix`는 레지스트리와 인접한 관리형 npm 드리프트도 복구합니다. 관리형 Plugin npm 루트 아래의 고아 상태이거나 복구된 `@openclaw/*` 패키지가 번들 Plugin을 가리는 경우, doctor는 해당 오래된 패키지를 제거하고 레지스트리를 다시 빌드하여 시작 시 번들 매니페스트를 기준으로 검증하게 합니다. +`openclaw doctor --fix`는 레지스트리 인접 관리형 npm 드리프트도 복구합니다. 관리형 Plugin npm 루트 아래의 고아 또는 복구된 `@openclaw/*` 패키지가 번들 Plugin을 가리는 경우, doctor는 해당 오래된 패키지를 제거하고 레지스트리를 다시 빌드하여 시작 시 번들 매니페스트 기준으로 검증되도록 합니다. -`OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY=1`은 레지스트리 읽기 실패에 대비한 더 이상 권장되지 않는 긴급 호환성 스위치입니다. `plugins registry --refresh` 또는 `openclaw doctor --fix`를 우선 사용하세요. env 폴백은 마이그레이션이 배포되는 동안 긴급 시작 복구에만 사용됩니다. +`OPENCLAW_DISABLE_PERSISTED_PLUGIN_REGISTRY=1`은 레지스트리 읽기 실패를 위한 더 이상 권장되지 않는 비상용 호환성 스위치입니다. `plugins registry --refresh` 또는 `openclaw doctor --fix`를 우선 사용하세요. env 폴백은 마이그레이션이 배포되는 동안의 긴급 시작 복구용으로만 사용하세요. ### 마켓플레이스 @@ -398,9 +404,9 @@ openclaw plugins marketplace list openclaw plugins marketplace list --json ``` -마켓플레이스 목록은 로컬 마켓플레이스 경로, `marketplace.json` 경로, `owner/repo` 같은 GitHub 축약형, GitHub 저장소 URL, 또는 git URL을 받습니다. `--json`은 확인된 소스 레이블과 함께 파싱된 마켓플레이스 매니페스트 및 Plugin 항목을 출력합니다. +마켓플레이스 목록은 로컬 마켓플레이스 경로, `marketplace.json` 경로, `owner/repo` 같은 GitHub 축약형, GitHub repo URL 또는 git URL을 허용합니다. `--json`은 해석된 소스 레이블과 파싱된 마켓플레이스 매니페스트 및 Plugin 항목을 출력합니다. -## 관련 항목 +## 관련 - [Plugin 빌드](/ko/plugins/building-plugins) - [CLI 참조](/ko/cli) diff --git a/docs/ko/cli/security.md b/docs/ko/cli/security.md index e6cc92e69..91f8baab3 100644 --- a/docs/ko/cli/security.md +++ b/docs/ko/cli/security.md @@ -1,14 +1,14 @@ --- read_when: - - 구성/상태에 대한 빠른 보안 감사를 실행하려는 경우 - - 안전한 “수정” 제안(권한, 기본값 강화)을 적용하려는 경우 -summary: '`openclaw security`에 대한 CLI 참조(일반적인 보안 위험 요소 감사 및 수정)' + - config/state에 대한 빠른 보안 감사를 실행하려고 합니다 + - 안전한 "fix" 제안(권한, 기본값 강화)을 적용하려는 경우 +summary: '`openclaw security`에 대한 CLI 참조(일반적인 보안 함정 감사 및 수정)' title: 보안 x-i18n: - generated_at: "2026-05-02T20:46:17Z" + generated_at: "2026-05-06T17:54:30Z" model: gpt-5.5 provider: openai - source_hash: 44eb50368cb54441782a7c4e20fab24d0488b80c9a1eedf8e1eb31dc8d7a9cf6 + source_hash: 0e70c9ea085bc9c0edebe801e4feb876d1cb776848d693e9699f4d238fc9b60f source_path: cli/security.md workflow: 16 --- @@ -32,30 +32,30 @@ openclaw security audit --fix openclaw security audit --json ``` -일반 `security audit`는 콜드 설정/파일 시스템/읽기 전용 경로에 머뭅니다. 기본적으로 Plugin 런타임 보안 수집기를 탐색하지 않으므로, 일상적인 감사가 설치된 모든 Plugin 런타임을 로드하지 않습니다. 최선 노력 방식의 라이브 Gateway 프로브와 Plugin 소유 보안 감사 수집기를 포함하려면 `--deep`를 사용하세요. 명시적인 내부 호출자도 적절한 런타임 범위를 이미 가지고 있을 때 이러한 Plugin 소유 수집기를 선택적으로 사용할 수 있습니다. +일반 `security audit`는 콜드 구성/파일 시스템/읽기 전용 경로에 머뭅니다. 기본적으로 Plugin 런타임 보안 수집기를 발견하지 않으므로, 일상적인 감사에서 설치된 모든 Plugin 런타임을 로드하지 않습니다. 최선 노력 방식의 라이브 Gateway 프로브와 Plugin 소유 보안 감사 수집기를 포함하려면 `--deep`을 사용하세요. 명시적인 내부 호출자는 이미 적절한 런타임 범위가 있는 경우 해당 Plugin 소유 수집기를 사용하도록 선택할 수도 있습니다. -감사는 여러 DM 발신자가 기본 세션을 공유할 때 경고하고 **보안 DM 모드**를 권장합니다. 공유 inbox에는 `session.dmScope="per-channel-peer"`(또는 다중 계정 채널의 경우 `per-account-channel-peer`)를 사용하세요. -이는 협력적/공유 inbox 강화용입니다. 서로 신뢰할 수 없거나 적대적인 운영자가 단일 Gateway를 공유하는 구성은 권장되지 않습니다. 별도 Gateway(또는 별도 OS 사용자/호스트)로 신뢰 경계를 분리하세요. -또한 설정이 공유 사용자 인그레스를 시사할 때(예: 공개 DM/그룹 정책, 구성된 그룹 대상, 와일드카드 발신자 규칙) `security.trust_model.multi_user_heuristic`을 내보내며, OpenClaw가 기본적으로 개인 비서 신뢰 모델임을 알려줍니다. -의도적인 공유 사용자 구성의 경우, 감사 가이드는 모든 세션을 샌드박스화하고, 파일 시스템 접근을 워크스페이스 범위로 제한하며, 개인/비공개 ID 또는 자격 증명을 해당 런타임에서 제외하라고 안내합니다. -또한 소형 모델(`<=300B`)이 샌드박스 없이 웹/브라우저 도구가 활성화된 상태로 사용될 때 경고합니다. -Webhook 인그레스의 경우, `hooks.token`이 Gateway 토큰을 재사용할 때, `hooks.token`이 짧을 때, `hooks.path="/"`일 때, `hooks.defaultSessionKey`가 설정되지 않았을 때, `hooks.allowedAgentIds`가 제한되지 않았을 때, 요청 `sessionKey` override가 활성화되었을 때, 그리고 `hooks.allowedSessionKeyPrefixes` 없이 override가 활성화되었을 때 경고합니다. -또한 샌드박스 모드가 꺼져 있는데 샌드박스 Docker 설정이 구성된 경우, `gateway.nodes.denyCommands`가 효과 없는 패턴형/알 수 없는 항목을 사용하는 경우(정확한 Node 명령 이름 일치만 가능하며 셸 텍스트 필터링이 아님), `gateway.nodes.allowCommands`가 위험한 Node 명령을 명시적으로 활성화한 경우, 전역 `tools.profile="minimal"`이 에이전트 도구 프로필에 의해 override되는 경우, 공개 그룹이 샌드박스/워크스페이스 보호 없이 런타임/파일 시스템 도구를 노출하는 경우, 그리고 설치된 Plugin 도구가 허용적인 도구 정책 아래에서 도달 가능할 수 있는 경우 경고합니다. -또한 `gateway.allowRealIpFallback=true`(프록시가 잘못 구성된 경우 헤더 스푸핑 위험)와 `discovery.mdns.mode="full"`(mDNS TXT 레코드를 통한 메타데이터 누출)을 플래그합니다. +감사는 여러 DM 발신자가 기본 세션을 공유할 때 경고하고 **보안 DM 모드**를 권장합니다. 공유 받은 편지함에는 `session.dmScope="per-channel-peer"`(또는 다중 계정 채널에는 `per-account-channel-peer`)를 사용하세요. +이는 협력적/공유 받은 편지함 강화를 위한 것입니다. 서로 신뢰하지 않거나 적대적인 운영자가 단일 Gateway를 공유하는 구성은 권장되지 않습니다. 별도 Gateway(또는 별도 OS 사용자/호스트)로 신뢰 경계를 분리하세요. +또한 구성에서 공유 사용자 유입 가능성이 보일 때(예: 열린 DM/그룹 정책, 구성된 그룹 대상 또는 와일드카드 발신자 규칙) `security.trust_model.multi_user_heuristic`을 출력하고, OpenClaw가 기본적으로 개인 비서 신뢰 모델이라는 점을 상기시킵니다. +의도적인 공유 사용자 구성의 경우, 감사 지침은 모든 세션을 샌드박스화하고, 파일 시스템 접근을 작업 영역 범위로 제한하며, 개인/비공개 ID 또는 자격 증명을 해당 런타임에서 제외하는 것입니다. +또한 작은 모델(`<=300B`)이 샌드박스 없이 웹/브라우저 도구가 활성화된 상태로 사용될 때 경고합니다. +Webhook 유입의 경우 `hooks.token`이 Gateway 토큰을 재사용할 때, `hooks.token`이 짧을 때, `hooks.path="/"`일 때, `hooks.defaultSessionKey`가 설정되지 않았을 때, `hooks.allowedAgentIds`가 제한되지 않았을 때, 요청 `sessionKey` 재정의가 활성화되었을 때, 그리고 `hooks.allowedSessionKeyPrefixes` 없이 재정의가 활성화되었을 때 경고합니다. +또한 샌드박스 모드가 꺼져 있는데 샌드박스 Docker 설정이 구성된 경우, `gateway.nodes.denyCommands`가 효과 없는 패턴형/알 수 없는 항목을 사용하는 경우(셸 텍스트 필터링이 아니라 정확한 Node 명령 이름 매칭만 해당), `gateway.nodes.allowCommands`가 위험한 Node 명령을 명시적으로 활성화하는 경우, 전역 `tools.profile="minimal"`이 에이전트 도구 프로필에 의해 재정의되는 경우, 열린 그룹이 샌드박스/작업 영역 보호 없이 런타임/파일 시스템 도구를 노출하는 경우, 그리고 설치된 Plugin 도구가 허용적인 도구 정책 아래에서 도달 가능할 수 있는 경우 경고합니다. +또한 `gateway.allowRealIpFallback=true`(프록시가 잘못 구성된 경우 헤더 스푸핑 위험)와 `discovery.mdns.mode="full"`(mDNS TXT 레코드를 통한 메타데이터 유출)을 표시합니다. 또한 샌드박스 브라우저가 `sandbox.browser.cdpSourceRange` 없이 Docker `bridge` 네트워크를 사용할 때 경고합니다. -또한 위험한 샌드박스 Docker 네트워크 모드(`host` 및 `container:*` 네임스페이스 조인 포함)를 플래그합니다. -또한 기존 샌드박스 브라우저 Docker 컨테이너에 누락되었거나 오래된 해시 레이블이 있을 때(예: `openclaw.browserConfigEpoch`가 없는 마이그레이션 이전 컨테이너) 경고하고 `openclaw sandbox recreate --browser --all`을 권장합니다. -또한 npm 기반 Plugin/훅 설치 레코드가 고정되지 않았거나, 무결성 메타데이터가 없거나, 현재 설치된 패키지 버전과 드리프트가 있을 때 경고합니다. +또한 위험한 샌드박스 Docker 네트워크 모드(`host` 및 `container:*` 네임스페이스 조인 포함)를 표시합니다. +또한 기존 샌드박스 브라우저 Docker 컨테이너에 누락되었거나 오래된 해시 라벨이 있을 때(예: `openclaw.browserConfigEpoch`가 없는 마이그레이션 이전 컨테이너) 경고하고 `openclaw sandbox recreate --browser --all`을 권장합니다. +또한 npm 기반 Plugin/훅 설치 기록이 고정되지 않았거나, 무결성 메타데이터가 없거나, 현재 설치된 패키지 버전과 달라졌을 때 경고합니다. 채널 허용 목록이 안정적인 ID 대신 변경 가능한 이름/이메일/태그에 의존할 때 경고합니다(해당되는 경우 Discord, Slack, Google Chat, Microsoft Teams, Mattermost, IRC 범위). -`gateway.auth.mode="none"`이 공유 시크릿 없이 Gateway HTTP API에 접근할 수 있게 둘 때 경고합니다(`/tools/invoke` 및 활성화된 모든 `/v1/*` 엔드포인트). -`dangerous`/`dangerously` 접두사가 붙은 설정은 명시적인 비상 운영자 override입니다. 이를 활성화하는 것 자체가 보안 취약점 보고는 아닙니다. -전체 위험 매개변수 목록은 [보안](/ko/gateway/security)의 "안전하지 않거나 위험한 플래그 요약" 섹션을 참조하세요. +`gateway.auth.mode="none"`가 공유 비밀 없이 Gateway HTTP API에 접근 가능하게 둘 때 경고합니다(`/tools/invoke`와 활성화된 모든 `/v1/*` 엔드포인트). +`dangerous`/`dangerously` 접두사가 붙은 설정은 명시적인 비상용 운영자 재정의입니다. 이를 활성화하는 것만으로는 보안 취약점 보고가 아닙니다. +전체 위험 매개변수 인벤토리는 [보안](/ko/gateway/security)의 "안전하지 않거나 위험한 플래그 요약" 섹션을 참조하세요. SecretRef 동작: -- `security audit`는 대상 경로에 대해 읽기 전용 모드에서 지원되는 SecretRef를 해석합니다. -- 현재 명령 경로에서 SecretRef를 사용할 수 없으면, 감사는 계속 진행되고 충돌하는 대신 `secretDiagnostics`를 보고합니다. -- `--token` 및 `--password`는 해당 명령 호출의 심층 프로브 인증만 override합니다. 설정이나 SecretRef 매핑을 다시 쓰지 않습니다. +- `security audit`는 대상 경로에서 지원되는 SecretRef를 읽기 전용 모드로 해석합니다. +- 현재 명령 경로에서 SecretRef를 사용할 수 없으면 감사는 계속 진행되며 충돌하는 대신 `secretDiagnostics`를 보고합니다. +- `--token`과 `--password`는 해당 명령 호출의 심층 프로브 인증만 재정의합니다. 구성이나 SecretRef 매핑을 다시 작성하지 않습니다. ## JSON 출력 @@ -66,7 +66,7 @@ openclaw security audit --json | jq '.summary' openclaw security audit --deep --json | jq '.findings[] | select(.severity=="critical") | .checkId' ``` -`--fix`와 `--json`을 함께 사용하면, 출력에 수정 작업과 최종 보고서가 모두 포함됩니다. +`--fix`와 `--json`을 함께 사용하면 출력에 수정 작업과 최종 보고서가 모두 포함됩니다. ```bash openclaw security audit --fix --json | jq '{fix: .fix.ok, summary: .report.summary}' @@ -74,23 +74,23 @@ openclaw security audit --fix --json | jq '{fix: .fix.ok, summary: .report.summa ## `--fix`가 변경하는 내용 -`--fix`는 안전하고 결정적인 수정을 적용합니다. +`--fix`는 안전하고 결정적인 수정 조치를 적용합니다. - 일반적인 `groupPolicy="open"`을 `groupPolicy="allowlist"`로 전환합니다(지원되는 채널의 계정 변형 포함). -- WhatsApp 그룹 정책이 `allowlist`로 전환될 때, 해당 목록이 존재하고 설정에 이미 `allowFrom`이 정의되어 있지 않으면 저장된 `allowFrom` 파일에서 `groupAllowFrom`을 시드합니다. +- WhatsApp 그룹 정책이 `allowlist`로 전환될 때, 해당 목록이 존재하고 구성에 아직 `allowFrom`이 정의되어 있지 않으면 저장된 `allowFrom` 파일에서 `groupAllowFrom`을 시드합니다. - `logging.redactSensitive`를 `"off"`에서 `"tools"`로 설정합니다. -- 상태/설정 및 일반적인 민감 파일의 권한을 강화합니다 +- 상태/구성과 일반적인 민감 파일의 권한을 강화합니다. (`credentials/*.json`, `auth-profiles.json`, `sessions.json`, 세션 `*.jsonl`) -- `openclaw.json`에서 참조되는 설정 include 파일도 강화합니다. +- `openclaw.json`에서 참조된 구성 include 파일도 강화합니다. - POSIX 호스트에서는 `chmod`를 사용하고 Windows에서는 `icacls` 재설정을 사용합니다. `--fix`는 다음을 수행하지 **않습니다**. -- 토큰/비밀번호/API 키 회전 +- 토큰/비밀번호/API 키 순환 - 도구 비활성화(`gateway`, `cron`, `exec` 등) - Gateway 바인드/인증/네트워크 노출 선택 변경 -- Plugin/Skills 제거 또는 다시 쓰기 +- Plugin/Skills 제거 또는 다시 작성 ## 관련 항목 diff --git a/docs/ko/cli/setup.md b/docs/ko/cli/setup.md index e06b99f59..a7763ac99 100644 --- a/docs/ko/cli/setup.md +++ b/docs/ko/cli/setup.md @@ -1,28 +1,32 @@ --- read_when: - - 전체 CLI 온보딩 없이 첫 실행 설정을 진행하고 있습니다 - - 기본 작업 영역 경로를 설정하려고 합니다 -summary: '`openclaw setup`용 CLI 참조(구성 + 작업 영역 초기화)' + - 전체 CLI 온보딩 없이 최초 실행 설정을 진행하고 있습니다 + - 기본 작업공간 경로를 설정하려는 경우 +summary: '`openclaw setup`용 CLI 참조(구성 + 작업 공간 초기화)' title: 설정 x-i18n: - generated_at: "2026-05-02T20:46:41Z" + generated_at: "2026-05-06T17:54:35Z" model: gpt-5.5 provider: openai - source_hash: 805f60c81f5fc216fc446641efe0bcb60bb6c34b3a50a6fc9e767461206e5f90 + source_hash: 9a47d41f8c6c59395eaa4bc6055fa09f863af819c7920e29969793904180c910 source_path: cli/setup.md workflow: 16 --- # `openclaw setup` -`~/.openclaw/openclaw.json` 및 에이전트 작업 영역을 초기화합니다. +`~/.openclaw/openclaw.json`과 에이전트 작업 공간을 초기화합니다. + + +`openclaw setup`은 변경 가능한 구성 설치용입니다. Nix 모드(`OPENCLAW_NIX_MODE=1`)에서는 구성 파일이 Nix에서 관리되므로 OpenClaw가 설정 쓰기를 거부합니다. 에이전트는 공식 [nix-openclaw 빠른 시작](https://github.com/openclaw/nix-openclaw#quick-start) 또는 다른 Nix 패키지에 해당하는 소스 구성을 사용해야 합니다. + 관련 항목: - 시작하기: [시작하기](/ko/start/getting-started) - CLI 온보딩: [온보딩(CLI)](/ko/start/wizard) -## 예시 +## 예제 ```bash openclaw setup @@ -34,7 +38,7 @@ openclaw setup --non-interactive --mode remote --remote-url wss://gateway-host:1 ## 옵션 -- `--workspace `: 에이전트 작업 영역 디렉터리(`agents.defaults.workspace`로 저장됨) +- `--workspace `: 에이전트 작업 공간 디렉터리(`agents.defaults.workspace`로 저장됨) - `--wizard`: 온보딩 실행 - `--non-interactive`: 프롬프트 없이 온보딩 실행 - `--mode `: 온보딩 모드 @@ -52,9 +56,9 @@ openclaw setup --wizard 참고: -- 일반 `openclaw setup`은 전체 온보딩 흐름 없이 구성 + 작업 영역을 초기화합니다. -- 일반 설정 후에는 `openclaw configure`를 실행하여 모델, 채널, Gateway, Plugin, Skills 또는 상태 검사를 선택합니다. -- 온보딩 플래그가 있으면 온보딩이 자동 실행됩니다(`--wizard`, `--non-interactive`, `--mode`, `--import-from`, `--import-source`, `--import-secrets`, `--remote-url`, `--remote-token`). +- 단순 `openclaw setup`은 전체 온보딩 흐름 없이 구성과 작업 공간을 초기화합니다. +- 단순 설정 후 `openclaw configure`를 실행하여 모델, 채널, Gateway, Plugin, Skills 또는 상태 검사를 선택합니다. +- 온보딩 플래그가 하나라도 있으면 온보딩이 자동 실행됩니다(`--wizard`, `--non-interactive`, `--mode`, `--import-from`, `--import-source`, `--import-secrets`, `--remote-url`, `--remote-token`). - Hermes 상태가 감지되면 대화형 온보딩에서 마이그레이션을 자동으로 제안할 수 있습니다. 가져오기 온보딩에는 새 설정이 필요합니다. 온보딩 외부에서 드라이런 계획, 백업, 덮어쓰기 모드를 사용하려면 [마이그레이션](/ko/cli/migrate)을 사용하세요. ## 관련 항목 diff --git a/docs/ko/cli/update.md b/docs/ko/cli/update.md index 2fbbfebab..897686f56 100644 --- a/docs/ko/cli/update.md +++ b/docs/ko/cli/update.md @@ -1,15 +1,15 @@ --- read_when: - - 소스 체크아웃을 안전하게 업데이트하려고 합니다 + - 소스 체크아웃을 안전하게 업데이트하려는 경우 - '`openclaw update` 출력 또는 옵션을 디버깅하고 있습니다' - - '`--update` 약식 동작을 이해해야 합니다' -summary: '`openclaw update`용 CLI 참조(비교적 안전한 소스 업데이트 + Gateway 자동 재시작)' + - '`--update` 축약형 동작을 이해해야 합니다' +summary: '`openclaw update`에 대한 CLI 참조(비교적 안전한 소스 업데이트 + Gateway 자동 재시작)' title: 업데이트 x-i18n: - generated_at: "2026-05-06T06:20:16Z" + generated_at: "2026-05-06T17:54:52Z" model: gpt-5.5 provider: openai - source_hash: 92eff9aeaecd4bf4eaa98fa511a3b9ebaedaf5872ff9407398665f2a8c2ab7d9 + source_hash: 483e702dfe7f1d1b2f4bcd1037a93ba794fc6a24ff2060afcb3a825c3dc165c7 source_path: cli/update.md workflow: 16 --- @@ -40,31 +40,27 @@ openclaw --update ## 옵션 -- `--no-restart`: 업데이트가 성공한 후 Gateway 서비스를 다시 시작하지 않습니다. Gateway를 다시 시작하는 패키지 관리자 업데이트는 명령이 성공하기 전에 다시 시작된 서비스가 예상한 업데이트 버전을 보고하는지 확인합니다. -- `--channel `: 업데이트 채널을 설정합니다(git + npm, config에 유지됨). -- `--tag `: 이번 업데이트에만 패키지 대상을 재정의합니다. 패키지 설치의 경우 `main`은 `github:openclaw/openclaw#main`에 매핑됩니다. -- `--dry-run`: config 쓰기, 설치, plugins 동기화 또는 재시작 없이 계획된 업데이트 작업(채널/태그/대상/재시작 흐름)을 미리 봅니다. -- `--json`: 손상되었거나 로드할 수 없는 관리형 plugins가 core 업데이트 성공 후 복구를 필요로 할 때의 - `postUpdate.plugins.warnings`와, 업데이트 후 Plugin 동기화 중 npm Plugin 아티팩트 드리프트가 감지될 때의 - `postUpdate.plugins.integrityDrifts`를 포함하여, 기계가 읽을 수 있는 `UpdateRunResult` JSON을 출력합니다. -- `--timeout `: 단계별 제한 시간(기본값은 1800초). +- `--no-restart`: 업데이트가 성공한 뒤 Gateway 서비스를 다시 시작하지 않습니다. Gateway를 다시 시작하는 패키지 관리자 업데이트는 명령이 성공하기 전에 다시 시작된 서비스가 예상 업데이트 버전을 보고하는지 확인합니다. +- `--channel `: 업데이트 채널을 설정합니다(git + npm, 구성에 유지됨). +- `--tag `: 이 업데이트에 한해 패키지 대상을 재정의합니다. 패키지 설치의 경우 `main`은 `github:openclaw/openclaw#main`에 매핑됩니다. +- `--dry-run`: 구성 쓰기, 설치, Plugin 동기화 또는 다시 시작 없이 계획된 업데이트 작업(채널/태그/대상/다시 시작 흐름)을 미리 봅니다. +- `--json`: 손상되었거나 언로드할 수 없는 관리형 Plugin이 코어 업데이트 성공 후 복구가 필요할 때의 `postUpdate.plugins.warnings`와 업데이트 후 Plugin 동기화 중 npm Plugin 아티팩트 드리프트가 감지될 때의 `postUpdate.plugins.integrityDrifts`를 포함해, 기계가 읽을 수 있는 `UpdateRunResult` JSON을 출력합니다. +- `--timeout `: 단계별 제한 시간입니다(기본값은 1800초). - `--yes`: 확인 프롬프트를 건너뜁니다(예: 다운그레이드 확인). -`openclaw update`에는 `--verbose` 플래그가 없습니다. 계획된 -채널/태그/설치/재시작 작업을 미리 보려면 `--dry-run`을, 기계가 읽을 수 있는 -결과를 보려면 `--json`을, 채널 및 사용 가능성 세부 정보만 필요하면 -`openclaw update status --json`을 사용하세요. 업데이트 전후의 Gateway 로그를 디버깅하는 경우, -콘솔 상세도와 파일 로그 수준은 별개입니다. Gateway `--verbose`는 -터미널/WebSocket 출력에 영향을 주며, 파일 로그에는 config의 `logging.level: "debug"` 또는 -`"trace"`가 필요합니다. [Gateway 로깅](/ko/gateway/logging)을 참조하세요. +`openclaw update`에는 `--verbose` 플래그가 없습니다. 계획된 채널/태그/설치/다시 시작 작업을 미리 보려면 `--dry-run`을, 기계가 읽을 수 있는 결과가 필요하면 `--json`을, 채널과 사용 가능 여부 세부 정보만 필요하면 `openclaw update status --json`을 사용하세요. 업데이트 전후의 Gateway 로그를 디버깅하는 경우 콘솔 상세 출력과 파일 로그 수준은 별도입니다. Gateway `--verbose`는 터미널/WebSocket 출력에 영향을 주며, 파일 로그에는 구성의 `logging.level: "debug"` 또는 `"trace"`가 필요합니다. [Gateway 로깅](/ko/gateway/logging)을 참고하세요. + + +Nix 모드(`OPENCLAW_NIX_MODE=1`)에서는 변경을 수행하는 `openclaw update` 실행이 비활성화됩니다. 대신 이 설치의 Nix 소스 또는 flake 입력을 업데이트하세요. nix-openclaw의 경우 에이전트 우선 [빠른 시작](https://github.com/openclaw/nix-openclaw#quick-start)을 사용하세요. `openclaw update status`와 `openclaw update --dry-run`은 읽기 전용으로 유지됩니다. + -다운그레이드는 이전 버전이 구성을 손상시킬 수 있으므로 확인이 필요합니다. +이전 버전은 구성을 손상시킬 수 있으므로 다운그레이드에는 확인이 필요합니다. ## `update status` -활성 업데이트 채널 + git 태그/브랜치/SHA(소스 checkout의 경우)와 업데이트 사용 가능 여부를 표시합니다. +활성 업데이트 채널과 git 태그/브랜치/SHA(소스 체크아웃의 경우), 그리고 업데이트 가능 여부를 표시합니다. ```bash openclaw update status @@ -75,125 +71,91 @@ openclaw update status --timeout 10 옵션: - `--json`: 기계가 읽을 수 있는 상태 JSON을 출력합니다. -- `--timeout `: 검사 제한 시간(기본값은 3초). +- `--timeout `: 검사 제한 시간입니다(기본값은 3초). ## `update wizard` -업데이트 채널을 선택하고 업데이트 후 Gateway를 다시 시작할지 확인하는 대화형 흐름입니다 -(기본값은 재시작). git checkout 없이 `dev`를 선택하면 새로 만들도록 제안합니다. +업데이트 채널을 선택하고 업데이트 후 Gateway를 다시 시작할지 확인하는 대화형 흐름입니다(기본값은 다시 시작). git 체크아웃 없이 `dev`를 선택하면 하나를 만들도록 제안합니다. 옵션: -- `--timeout `: 각 업데이트 단계의 제한 시간(기본값 `1800`) +- `--timeout `: 각 업데이트 단계의 제한 시간입니다(기본값 `1800`). ## 수행 내용 -채널을 명시적으로 전환하면(`--channel ...`) OpenClaw는 설치 방식도 -일치하도록 유지합니다. +명시적으로 채널을 전환하면(`--channel ...`) OpenClaw는 설치 방식도 함께 정렬합니다. -- `dev` → git checkout을 보장합니다(기본값: `~/openclaw`, `OPENCLAW_GIT_DIR`로 재정의), - 이를 업데이트하고, 해당 checkout에서 전역 CLI를 설치합니다. -- `stable` → `latest`를 사용하여 npm에서 설치합니다. -- `beta` → npm dist-tag `beta`를 우선 사용하지만, beta가 없거나 현재 stable 릴리스보다 오래된 경우 - `latest`로 대체합니다. +- `dev` → git 체크아웃을 보장하고(기본값: `~/openclaw`, `OPENCLAW_GIT_DIR`로 재정의), 이를 업데이트한 뒤 해당 체크아웃에서 전역 CLI를 설치합니다. +- `stable` → `latest`를 사용해 npm에서 설치합니다. +- `beta` → npm dist-tag `beta`를 우선 사용하지만, beta가 없거나 현재 stable 릴리스보다 오래된 경우 `latest`로 대체합니다. -Gateway core 자동 업데이트 프로그램(config를 통해 활성화된 경우)은 라이브 Gateway 요청 핸들러 -외부에서 CLI 업데이트 경로를 실행합니다. Control-plane `update.run` 패키지 관리자 -업데이트는 패키지 교체 후 지연되지 않고 쿨다운이 없는 업데이트 재시작을 강제합니다. -이전 Gateway 프로세스가 새 패키지에서 제거된 파일을 가리키는 -인메모리 청크를 여전히 보유할 수 있기 때문입니다. +Gateway 코어 자동 업데이트 기능(구성으로 활성화된 경우)은 실행 중인 Gateway 요청 핸들러 밖에서 CLI 업데이트 경로를 시작합니다. 제어 플레인 `update.run` 패키지 관리자 업데이트는 패키지 교체 후 지연되지 않고 쿨다운 없는 업데이트 다시 시작을 강제합니다. 이전 Gateway 프로세스가 새 패키지에서 제거된 파일을 가리키는 메모리 내 청크를 아직 가지고 있을 수 있기 때문입니다. -패키지 관리자 설치의 경우 `openclaw update`는 패키지 관리자를 호출하기 전에 대상 패키지 -버전을 해석합니다. npm 전역 설치는 단계적 설치를 사용합니다. OpenClaw는 새 패키지를 임시 npm prefix에 설치하고, -그곳에서 패키지된 `dist` 인벤토리를 검증한 다음, 깨끗한 패키지 트리를 -실제 전역 prefix로 교체합니다. 검증에 실패하면 업데이트 후 doctor, Plugin 동기화 및 -재시작 작업은 의심스러운 트리에서 실행되지 않습니다. 설치된 버전이 이미 -대상과 일치하더라도, 명령은 전역 패키지 설치를 새로 고친 다음 -Plugin 동기화, core 명령 완료 새로 고침 및 재시작 작업을 실행합니다. 이렇게 하면 -전체 Plugin 명령 완료 재빌드는 명시적인 `openclaw completion --write-state` 실행에 맡기면서, -패키지된 sidecar와 채널 소유 Plugin 레코드가 설치된 OpenClaw 빌드와 일치하도록 유지됩니다. +패키지 관리자 설치의 경우 `openclaw update`는 패키지 관리자를 호출하기 전에 대상 패키지 버전을 확인합니다. npm 전역 설치는 단계적 설치를 사용합니다. OpenClaw는 새 패키지를 임시 npm prefix에 설치하고, 그곳에서 패키징된 `dist` 인벤토리를 확인한 다음, 해당 깨끗한 패키지 트리를 실제 전역 prefix로 교체합니다. 확인이 실패하면 업데이트 후 doctor, Plugin 동기화, 다시 시작 작업은 의심스러운 트리에서 실행되지 않습니다. 설치된 버전이 이미 대상과 일치하더라도 명령은 전역 패키지 설치를 새로 고친 다음 Plugin 동기화, 코어 명령 완료 새로 고침, 다시 시작 작업을 실행합니다. 이렇게 하면 전체 Plugin 명령 완료 재빌드는 명시적인 `openclaw completion --write-state` 실행에 맡기면서, 패키징된 사이드카와 채널 소유 Plugin 레코드를 설치된 OpenClaw 빌드와 정렬된 상태로 유지합니다. -로컬 관리형 Gateway 서비스가 설치되어 있고 재시작이 활성화된 경우, -패키지 관리자 업데이트는 패키지 트리를 교체하기 전에 실행 중인 서비스를 중지한 다음, -업데이트된 설치에서 서비스 메타데이터를 새로 고치고, 서비스를 재시작하며, -성공을 보고하기 전에 재시작된 Gateway가 예상 버전을 보고하는지 확인합니다. macOS에서는 -업데이트 후 검사에서 활성 프로필의 LaunchAgent가 로드/실행 중인지와 구성된 loopback 포트가 -정상인지도 확인합니다. plist가 설치되어 있지만 launchd가 이를 감독하지 않는 경우 OpenClaw는 -LaunchAgent를 자동으로 다시 부트스트랩한 다음 -상태/버전/채널 준비 검사를 다시 실행합니다. 새 부트스트랩은 RunAtLoad -작업을 직접 로드하므로, 업데이트 복구는 새로 생성된 Gateway를 즉시 -`kickstart -k`하지 않습니다. Gateway가 여전히 정상 상태가 되지 않으면, 명령은 -0이 아닌 값으로 종료되고 재시작 로그 경로와 명시적인 재시작, 재설치 및 -패키지 롤백 지침을 출력합니다. `--no-restart`를 사용하면 -패키지 교체는 여전히 실행되지만 관리형 서비스는 중지되거나 -재시작되지 않으므로, 실행 중인 Gateway는 수동으로 재시작할 때까지 -이전 코드를 계속 사용할 수 있습니다. +로컬 관리형 Gateway 서비스가 설치되어 있고 다시 시작이 활성화된 경우, 패키지 관리자 업데이트는 패키지 트리를 교체하기 전에 실행 중인 서비스를 중지한 다음, 업데이트된 설치에서 서비스 메타데이터를 새로 고치고 서비스를 다시 시작하며, 성공을 보고하기 전에 다시 시작된 Gateway가 예상 버전을 보고하는지 확인합니다. macOS에서는 업데이트 후 검사에서 활성 프로필에 대해 LaunchAgent가 로드/실행 중인지, 구성된 루프백 포트가 정상인지도 확인합니다. plist가 설치되어 있지만 launchd가 이를 감독하지 않는 경우 OpenClaw는 LaunchAgent를 자동으로 다시 부트스트랩한 뒤 상태/버전/채널 준비 검사를 다시 실행합니다. 새 부트스트랩은 RunAtLoad 작업을 직접 로드하므로, 업데이트 복구는 새로 생성된 Gateway에 즉시 `kickstart -k`를 수행하지 않습니다. Gateway가 여전히 정상 상태가 되지 않으면 명령은 0이 아닌 코드로 종료되고 다시 시작 로그 경로와 명시적인 다시 시작, 재설치, 패키지 롤백 지침을 출력합니다. `--no-restart`를 사용하면 패키지 교체는 계속 실행되지만 관리형 서비스는 중지되거나 다시 시작되지 않으므로, 실행 중인 Gateway는 수동으로 다시 시작할 때까지 이전 코드를 계속 사용할 수 있습니다. -## Git checkout 흐름 +## Git 체크아웃 흐름 ### 채널 선택 -- `stable`: 최신 non-beta 태그를 checkout한 다음 빌드하고 doctor를 실행합니다. +- `stable`: 최신 비 beta 태그를 체크아웃한 다음 빌드하고 doctor를 실행합니다. - `beta`: 최신 `-beta` 태그를 우선 사용하지만, beta가 없거나 더 오래된 경우 최신 stable 태그로 대체합니다. -- `dev`: `main`을 checkout한 다음 fetch 및 rebase를 수행합니다. +- `dev`: `main`을 체크아웃한 다음 fetch 및 rebase를 수행합니다. ### 업데이트 단계 - + 커밋되지 않은 변경 사항이 없어야 합니다. - + 선택한 채널(태그 또는 브랜치)로 전환합니다. - + Dev 전용입니다. - - 임시 worktree에서 TypeScript 빌드를 실행합니다. tip이 실패하면 최대 10개 커밋까지 거슬러 올라가 가장 최신의 빌드 가능한 커밋을 찾습니다. 이 사전 검사 중 lint도 실행하려면 `OPENCLAW_UPDATE_PREFLIGHT_LINT=1`을 설정하세요. 사용자 업데이트 호스트는 CI runner보다 작은 경우가 많으므로 lint는 제한된 직렬 모드로 실행됩니다. + + 임시 worktree에서 TypeScript 빌드를 실행합니다. 팁이 실패하면 최대 10개 커밋까지 뒤로 이동해 빌드 가능한 최신 커밋을 찾습니다. 이 사전 검사 중 lint도 실행하려면 `OPENCLAW_UPDATE_PREFLIGHT_LINT=1`을 설정하세요. 사용자 업데이트 호스트는 CI 러너보다 작은 경우가 많기 때문에 lint는 제한된 직렬 모드로 실행됩니다. 선택한 커밋 위로 rebase합니다(dev 전용). - - repo 패키지 관리자를 사용합니다. pnpm checkout의 경우, 업데이트 프로그램은 pnpm workspace 안에서 `npm run build`를 실행하는 대신 필요할 때 `pnpm`을 부트스트랩합니다(`corepack`을 먼저 사용한 다음 임시 `npm install pnpm@10` 대체 경로 사용). + + 저장소 패키지 관리자를 사용합니다. pnpm 체크아웃의 경우 업데이트 프로그램은 pnpm workspace 내부에서 `npm run build`를 실행하는 대신, 필요할 때 `pnpm`을 부트스트랩합니다(먼저 `corepack`을 사용하고, 이후 임시 `npm install pnpm@10` 대체 경로 사용). - - Gateway와 Control UI를 빌드합니다. + + Gateway와 제어 UI를 빌드합니다. - - `openclaw doctor`를 최종 안전 업데이트 검사로 실행합니다. + + 최종 안전 업데이트 검사로 `openclaw doctor`를 실행합니다. - - plugins를 활성 채널에 동기화합니다. Dev는 bundled plugins를 사용하고, stable 및 beta는 npm을 사용합니다. 추적 중인 Plugin 설치를 업데이트합니다. + + Plugin을 활성 채널에 동기화합니다. Dev는 번들 Plugin을 사용하고, stable 및 beta는 npm을 사용합니다. 추적 중인 Plugin 설치를 업데이트합니다. -beta 업데이트 채널에서는 기본/latest 라인을 따르는 추적된 npm 및 ClawHub Plugin 설치가 -먼저 Plugin `@beta` 릴리스를 시도합니다. Plugin에 beta 릴리스가 없으면 -OpenClaw는 기록된 기본/latest spec으로 대체합니다. npm plugins의 경우, -beta 패키지가 존재하지만 설치 검증에 실패할 때도 OpenClaw가 대체합니다. -정확한 버전과 명시적 태그는 다시 쓰지 않습니다. +beta 업데이트 채널에서는 기본/latest 라인을 따르는 추적된 npm 및 ClawHub Plugin 설치가 먼저 Plugin `@beta` 릴리스를 시도합니다. Plugin에 beta 릴리스가 없으면 OpenClaw는 기록된 기본/latest 사양으로 대체합니다. npm Plugin의 경우 beta 패키지가 존재하지만 설치 검증에 실패할 때도 OpenClaw가 대체합니다. 정확한 버전과 명시적 태그는 다시 작성되지 않습니다. -정확히 고정된 npm Plugin 업데이트가 저장된 설치 레코드와 무결성이 다른 아티팩트로 해석되면, `openclaw update`는 해당 Plugin 아티팩트 업데이트를 설치하는 대신 중단합니다. 새 아티팩트를 신뢰할 수 있는지 확인한 후에만 Plugin을 명시적으로 다시 설치하거나 업데이트하세요. +정확히 고정된 npm Plugin 업데이트가 저장된 설치 레코드와 무결성이 다른 아티팩트로 확인되면, `openclaw update`는 해당 Plugin 아티팩트 업데이트를 설치하는 대신 중단합니다. 새 아티팩트를 신뢰할 수 있다고 확인한 뒤에만 Plugin을 명시적으로 다시 설치하거나 업데이트하세요. -관리형 Plugin에 범위가 한정된 업데이트 후 Plugin 동기화 실패는 core 업데이트가 성공한 후 경고로 보고됩니다. JSON 결과는 최상위 업데이트 `status: "ok"`를 유지하고, `openclaw doctor --fix` 및 `openclaw plugins inspect --runtime --json` 안내와 함께 `postUpdate.plugins.status: "warning"`을 보고합니다. 예기치 않은 업데이트 프로그램 또는 동기화 예외는 여전히 업데이트 결과를 실패로 처리합니다. Plugin 설치 또는 업데이트 오류를 수정한 다음 `openclaw doctor --fix` 또는 `openclaw update`를 다시 실행하세요. +관리형 Plugin으로 범위가 한정된 업데이트 후 Plugin 동기화 실패는 코어 업데이트가 성공한 뒤 경고로 보고됩니다. JSON 결과는 최상위 업데이트 `status: "ok"`를 유지하고, `openclaw doctor --fix` 및 `openclaw plugins inspect --runtime --json` 안내와 함께 `postUpdate.plugins.status: "warning"`을 보고합니다. 예상치 못한 업데이트 프로그램 또는 동기화 예외는 여전히 업데이트 결과를 실패로 처리합니다. Plugin 설치 또는 업데이트 오류를 수정한 다음 `openclaw doctor --fix` 또는 `openclaw update`를 다시 실행하세요. -업데이트된 Gateway가 시작될 때 Plugin 로딩은 검증 전용입니다. 시작 과정은 패키지 관리자를 실행하거나 의존성 트리를 변경하지 않습니다. 패키지 관리자 `update.run` 재시작은 패키지 트리가 교체된 후 일반적인 유휴 지연과 재시작 쿨다운을 우회하므로, 이전 프로세스가 제거된 청크를 지연 로드하는 상태를 유지할 수 없습니다. +업데이트된 Gateway가 시작될 때 Plugin 로딩은 확인 전용입니다. 시작 과정은 패키지 관리자를 실행하거나 의존성 트리를 변경하지 않습니다. 패키지 관리자 `update.run` 다시 시작은 패키지 트리가 교체된 뒤 일반 유휴 지연과 다시 시작 쿨다운을 우회하므로, 이전 프로세스가 제거된 청크를 지연 로딩한 채 유지할 수 없습니다. -pnpm 부트스트랩이 계속 실패하면, 업데이트 프로그램은 checkout 안에서 `npm run build`를 시도하는 대신 패키지 관리자별 오류와 함께 조기에 중지합니다. +pnpm 부트스트랩이 여전히 실패하면 업데이트 프로그램은 체크아웃 내부에서 `npm run build`를 시도하는 대신, 패키지 관리자별 오류와 함께 조기에 중지합니다. -## `--update` 약어 +## `--update` 단축형 -`openclaw --update`는 `openclaw update`로 다시 작성됩니다(shell 및 launcher 스크립트에 유용). +`openclaw --update`는 `openclaw update`로 다시 작성됩니다(셸 및 런처 스크립트에 유용). ## 관련 항목 -- `openclaw doctor`(git checkout에서 먼저 update 실행을 제안) +- `openclaw doctor`(git 체크아웃에서 먼저 업데이트를 실행하도록 제안) - [개발 채널](/ko/install/development-channels) - [업데이트](/ko/install/updating) - [CLI 참조](/ko/cli) diff --git a/docs/ko/concepts/streaming.md b/docs/ko/concepts/streaming.md index 67f3d8f1b..57f4b9077 100644 --- a/docs/ko/concepts/streaming.md +++ b/docs/ko/concepts/streaming.md @@ -1,15 +1,15 @@ --- read_when: - 채널에서 스트리밍 또는 청킹이 작동하는 방식 설명 - - 블록 스트리밍 또는 채널 청크 분할 동작 변경 + - 블록 스트리밍 또는 채널 청크 처리 동작 변경 - 중복/조기 블록 응답 또는 채널 미리보기 스트리밍 디버깅 -summary: 스트리밍 + 청킹 동작 (블록 응답, 채널 미리보기 스트리밍, 모드 매핑) -title: 스트리밍 및 청크 처리 +summary: 스트리밍 + 청크 처리 동작(블록 응답, 채널 미리보기 스트리밍, 모드 매핑) +title: 스트리밍 및 청크 분할 x-i18n: - generated_at: "2026-05-06T06:23:13Z" + generated_at: "2026-05-06T17:54:54Z" model: gpt-5.5 provider: openai - source_hash: 7ccf763c5904b9b01d127d6e9a914e73100137eba9d791654581a2ec7d4949ed + source_hash: e43dc87211e764f9721c4e6c0aa69088441344e1f7c34084fd711a780a852a17 source_path: concepts/streaming.md workflow: 16 --- @@ -17,13 +17,13 @@ x-i18n: OpenClaw에는 두 개의 별도 스트리밍 계층이 있습니다. - **블록 스트리밍(채널):** 어시스턴트가 작성하는 동안 완료된 **블록**을 내보냅니다. 이는 일반 채널 메시지입니다(토큰 델타가 아님). -- **미리보기 스트리밍(Telegram/Discord/Slack):** 생성하는 동안 임시 **미리보기 메시지**를 업데이트합니다. +- **미리보기 스트리밍(Telegram/Discord/Slack):** 생성 중에 임시 **미리보기 메시지**를 업데이트합니다. -현재 채널 메시지에는 **진정한 토큰 델타 스트리밍이 없습니다**. 미리보기 스트리밍은 메시지 기반입니다(전송 + 편집/추가). +현재 채널 메시지에는 **진정한 토큰 델타 스트리밍**이 없습니다. 미리보기 스트리밍은 메시지 기반입니다(전송 + 편집/추가). ## 블록 스트리밍(채널 메시지) -블록 스트리밍은 어시스턴트 출력을 사용 가능해지는 대로 큰 단위의 청크로 보냅니다. +블록 스트리밍은 어시스턴트 출력을 사용할 수 있게 되는 대로 굵직한 청크 단위로 보냅니다. ``` Model output @@ -37,163 +37,162 @@ Model output 범례: -- `text_delta/events`: 모델 스트림 이벤트(비스트리밍 모델에서는 드물 수 있음). -- `chunker`: 최소/최대 경계 + 나누기 선호도를 적용하는 `EmbeddedBlockChunker`. -- `channel send`: 실제 발신 메시지(블록 답장). +- `text_delta/events`: 모델 스트림 이벤트입니다(비스트리밍 모델에서는 드물 수 있음). +- `chunker`: 최소/최대 경계와 분할 선호도를 적용하는 `EmbeddedBlockChunker`입니다. +- `channel send`: 실제 발신 메시지입니다(블록 답장). **제어 항목:** -- `agents.defaults.blockStreamingDefault`: `"on"`/`"off"`(기본값은 꺼짐). +- `agents.defaults.blockStreamingDefault`: `"on"`/`"off"`(기본값 꺼짐). - 채널 재정의: 채널별로 `"on"`/`"off"`를 강제하는 `*.blockStreaming`(및 계정별 변형). - `agents.defaults.blockStreamingBreak`: `"text_end"` 또는 `"message_end"`. - `agents.defaults.blockStreamingChunk`: `{ minChars, maxChars, breakPreference? }`. -- `agents.defaults.blockStreamingCoalesce`: `{ minChars?, maxChars?, idleMs? }`(전송 전에 스트리밍된 블록 병합). -- 채널 하드 한도: `*.textChunkLimit`(예: `channels.whatsapp.textChunkLimit`). -- 채널 청크 모드: `*.chunkMode`(`length`가 기본값, `newline`은 길이 기준 청킹 전에 빈 줄(문단 경계)에서 분할). -- Discord 소프트 한도: `channels.discord.maxLinesPerMessage`(기본값 17)는 UI 잘림을 피하기 위해 긴 답장을 분할합니다. +- `agents.defaults.blockStreamingCoalesce`: `{ minChars?, maxChars?, idleMs? }`(전송 전 스트리밍된 블록 병합). +- 채널 하드 상한: `*.textChunkLimit`(예: `channels.whatsapp.textChunkLimit`). +- 채널 청크 모드: `*.chunkMode`(기본값은 `length`, `newline`은 길이 청킹 전에 빈 줄(문단 경계)에서 분할). +- Discord 소프트 상한: `channels.discord.maxLinesPerMessage`(기본값 17)는 UI 잘림을 피하기 위해 긴 답장을 분할합니다. -**경계 의미론:** +**경계 의미:** -- `text_end`: 청커가 내보내는 즉시 블록을 스트리밍하고, 각 `text_end`에서 플러시합니다. -- `message_end`: 어시스턴트 메시지가 끝날 때까지 기다린 뒤 버퍼링된 출력을 플러시합니다. +- `text_end`: 청커가 내보내는 즉시 블록을 스트리밍하며, 각 `text_end`에서 플러시합니다. +- `message_end`: 어시스턴트 메시지가 끝날 때까지 기다린 다음 버퍼링된 출력을 플러시합니다. -버퍼링된 텍스트가 `maxChars`를 초과하면 `message_end`도 여전히 청커를 사용하므로, 끝에서 여러 청크를 내보낼 수 있습니다. +버퍼링된 텍스트가 `maxChars`를 초과하면 `message_end`도 청커를 사용하므로, 마지막에 여러 청크를 내보낼 수 있습니다. -### 블록 스트리밍에서의 미디어 전달 +### 블록 스트리밍을 통한 미디어 전달 -`MEDIA:` 지시문은 일반 전달 메타데이터입니다. 블록 스트리밍이 미디어 블록을 일찍 보내면 OpenClaw는 해당 턴의 전달을 기억합니다. 최종 어시스턴트 페이로드가 같은 미디어 URL을 반복하면, 최종 전달은 첨부 파일을 다시 보내는 대신 중복 미디어를 제거합니다. +`MEDIA:` 지시문은 일반 전달 메타데이터입니다. 블록 스트리밍이 미디어 블록을 일찍 보내면 OpenClaw는 해당 턴의 전달을 기억합니다. 최종 어시스턴트 페이로드가 동일한 미디어 URL을 반복하면, 최종 전달은 첨부 파일을 다시 보내는 대신 중복 미디어를 제거합니다. -완전히 중복되는 최종 페이로드는 억제됩니다. 최종 페이로드가 이미 스트리밍된 미디어 주변에 별도의 텍스트를 추가하는 경우, OpenClaw는 미디어를 한 번만 전달하도록 유지하면서 새 텍스트는 계속 보냅니다. 이는 에이전트가 스트리밍 중 `MEDIA:`를 내보내고 공급자도 완료된 답장에 이를 포함하는 경우 Telegram 같은 채널에서 음성 메모나 파일이 중복되는 것을 방지합니다. +완전히 중복되는 최종 페이로드는 억제됩니다. 최종 페이로드가 이미 스트리밍된 미디어 주변에 구별되는 텍스트를 추가하면, OpenClaw는 미디어는 한 번만 전달되도록 유지하면서 새 텍스트를 계속 보냅니다. 이는 에이전트가 스트리밍 중 `MEDIA:`를 내보내고 공급자가 완료된 답장에도 이를 포함할 때 Telegram 같은 채널에서 음성 메모나 파일이 중복되는 것을 방지합니다. -## 청킹 알고리즘(하한/상한 경계) +## 청킹 알고리즘(낮은/높은 경계) 블록 청킹은 `EmbeddedBlockChunker`로 구현됩니다. -- **하한 경계:** 버퍼 >= `minChars`가 될 때까지 내보내지 않습니다(강제된 경우 제외). -- **상한 경계:** `maxChars` 전에 분할하는 것을 선호하며, 강제된 경우 `maxChars`에서 분할합니다. -- **나누기 선호도:** `paragraph` → `newline` → `sentence` → `whitespace` → 강제 나누기. -- **코드 펜스:** 펜스 내부에서는 절대 분할하지 않습니다. `maxChars`에서 강제될 때는 Markdown이 유효하게 유지되도록 펜스를 닫고 다시 엽니다. +- **낮은 경계:** 버퍼 >= `minChars`가 될 때까지 내보내지 않습니다(강제된 경우 제외). +- **높은 경계:** `maxChars` 전에 분할하는 것을 선호합니다. 강제된 경우 `maxChars`에서 분할합니다. +- **분할 선호도:** `paragraph` → `newline` → `sentence` → `whitespace` → 하드 분할. +- **코드 펜스:** 펜스 내부에서는 절대 분할하지 않습니다. `maxChars`에서 강제될 때는 Markdown이 유효하도록 펜스를 닫았다가 다시 엽니다. -`maxChars`는 채널 `textChunkLimit`로 제한되므로, 채널별 한도를 초과할 수 없습니다. +`maxChars`는 채널 `textChunkLimit`로 제한되므로 채널별 상한을 초과할 수 없습니다. ## 병합(스트리밍된 블록 병합) -블록 스트리밍이 활성화되면 OpenClaw는 내보내기 전에 **연속된 블록 청크를 병합**할 수 있습니다. 이를 통해 진행형 출력을 제공하면서도 "한 줄 스팸"을 줄입니다. +블록 스트리밍이 활성화되면 OpenClaw는 내보내기 전에 **연속된 블록 청크를 병합**할 수 있습니다. 이를 통해 점진적 출력을 제공하면서도 "한 줄 스팸"을 줄일 수 있습니다. - 병합은 플러시하기 전에 **유휴 간격**(`idleMs`)을 기다립니다. - 버퍼는 `maxChars`로 제한되며 이를 초과하면 플러시됩니다. -- `minChars`는 충분한 텍스트가 누적될 때까지 작은 조각이 전송되지 않도록 합니다(최종 플러시는 항상 남은 텍스트를 보냄). -- 조이너는 `blockStreamingChunk.breakPreference`에서 파생됩니다 - (`paragraph` → `\n\n`, `newline` → `\n`, `sentence` → 공백). +- `minChars`는 충분한 텍스트가 누적될 때까지 아주 작은 조각이 전송되지 않게 합니다(최종 플러시는 항상 남은 텍스트를 보냄). +- 조이너는 `blockStreamingChunk.breakPreference`에서 파생됩니다(`paragraph` → `\n\n`, `newline` → `\n`, `sentence` → 공백). - 채널 재정의는 `*.blockStreamingCoalesce`를 통해 사용할 수 있습니다(계정별 설정 포함). -- 기본 병합 `minChars`는 재정의하지 않는 한 Signal/Slack/Discord에서 1500으로 올라갑니다. +- 기본 병합 `minChars`는 재정의하지 않는 한 Signal/Slack/Discord에서 1500으로 높아집니다. -## 블록 사이의 사람 같은 속도 조절 +## 블록 사이의 사람 같은 페이싱 -블록 스트리밍이 활성화되면 블록 답장 사이(첫 번째 블록 이후)에 **무작위 일시정지**를 추가할 수 있습니다. 이렇게 하면 여러 말풍선 응답이 더 자연스럽게 느껴집니다. +블록 스트리밍이 활성화되면 블록 답장 사이(첫 번째 블록 이후)에 **무작위 일시 중지**를 추가할 수 있습니다. 이렇게 하면 여러 말풍선으로 된 응답이 더 자연스럽게 느껴집니다. -- 설정: `agents.defaults.humanDelay`(`agents.list[].humanDelay`를 통해 에이전트별로 재정의). +- 설정: `agents.defaults.humanDelay`(에이전트별로 `agents.list[].humanDelay`를 통해 재정의). - 모드: `off`(기본값), `natural`(800-2500ms), `custom`(`minMs`/`maxMs`). - **블록 답장**에만 적용되며, 최종 답장이나 도구 요약에는 적용되지 않습니다. -## "청크를 스트리밍하거나 전체를 스트리밍" +## "청크 스트리밍 또는 전체 스트리밍" 이는 다음에 매핑됩니다. - **청크 스트리밍:** `blockStreamingDefault: "on"` + `blockStreamingBreak: "text_end"`(진행하면서 내보냄). Telegram이 아닌 채널에는 `*.blockStreaming: true`도 필요합니다. -- **끝에서 전체 스트리밍:** `blockStreamingBreak: "message_end"`(한 번 플러시, 매우 길면 여러 청크일 수 있음). +- **마지막에 전체 스트리밍:** `blockStreamingBreak: "message_end"`(한 번 플러시하며, 매우 길면 여러 청크일 수 있음). - **블록 스트리밍 없음:** `blockStreamingDefault: "off"`(최종 답장만). -**채널 참고:** `*.blockStreaming`이 명시적으로 `true`로 설정되지 않은 한 블록 스트리밍은 **꺼져 있습니다**. 채널은 블록 답장 없이 실시간 미리보기(`channels..streaming`)를 스트리밍할 수 있습니다. +**채널 참고:** `*.blockStreaming`이 명시적으로 `true`로 설정되지 않으면 블록 스트리밍은 **꺼져 있습니다**. 채널은 블록 답장 없이 실시간 미리보기(`channels..streaming`)를 스트리밍할 수 있습니다. 설정 위치 알림: `blockStreaming*` 기본값은 루트 설정이 아니라 `agents.defaults` 아래에 있습니다. ## 미리보기 스트리밍 모드 -표준 키: `channels..streaming` +정식 키: `channels..streaming` 모드: - `off`: 미리보기 스트리밍을 비활성화합니다. -- `partial`: 최신 텍스트로 대체되는 단일 미리보기. -- `block`: 청크/추가 단계로 미리보기를 업데이트합니다. -- `progress`: 생성 중 진행률/상태 미리보기, 완료 시 최종 답변. +- `partial`: 최신 텍스트로 대체되는 단일 미리보기입니다. +- `block`: 청크/추가 단계로 미리보기가 업데이트됩니다. +- `progress`: 생성 중 진행 상황/상태 미리보기, 완료 시 최종 답변입니다. -`streaming.mode: "block"`은 Discord 및 Telegram처럼 편집 가능한 채널을 위한 미리보기 스트리밍 모드입니다. 그곳에서 채널 블록 전달을 활성화하지 않습니다. 일반 블록 답장을 원하면 `streaming.block.enabled` 또는 레거시 `blockStreaming` 채널 키를 사용하세요. Microsoft Teams는 예외입니다. 초안 미리보기 블록 전송이 없으므로 `streaming.mode: "block"`은 네이티브 partial/progress 스트리밍 대신 Teams 블록 전달에 매핑됩니다. +`streaming.mode: "block"`은 Discord 및 Telegram처럼 편집 가능한 채널을 위한 미리보기 스트리밍 모드입니다. 이것이 해당 채널에서 채널 블록 전달을 활성화하지는 않습니다. 일반 블록 답장을 원하면 `streaming.block.enabled` 또는 레거시 `blockStreaming` 채널 키를 사용하세요. Microsoft Teams는 예외입니다. 초안 미리보기 블록 전송이 없으므로, `streaming.mode: "block"`은 네이티브 부분/진행 상황 스트리밍 대신 Teams 블록 전달에 매핑됩니다. ### 채널 매핑 | 채널 | `off` | `partial` | `block` | `progress` | | ---------- | ----- | --------- | ------- | ----------------------- | -| Telegram | ✅ | ✅ | ✅ | 편집 가능한 진행률 초안 | -| Discord | ✅ | ✅ | ✅ | 편집 가능한 진행률 초안 | +| Telegram | ✅ | ✅ | ✅ | 편집 가능한 진행 상황 초안 | +| Discord | ✅ | ✅ | ✅ | 편집 가능한 진행 상황 초안 | | Slack | ✅ | ✅ | ✅ | ✅ | | Mattermost | ✅ | ✅ | ✅ | ✅ | -| MS Teams | ✅ | ✅ | ✅ | 네이티브 진행률 스트림 | +| MS Teams | ✅ | ✅ | ✅ | 네이티브 진행 상황 스트림 | Slack 전용: - `channels.slack.streaming.nativeTransport`는 `channels.slack.streaming.mode="partial"`일 때 Slack 네이티브 스트리밍 API 호출을 전환합니다(기본값: `true`). -- Slack 네이티브 스트리밍과 Slack 어시스턴트 스레드 상태에는 답장 스레드 대상이 필요합니다. 최상위 DM은 해당 스레드 스타일 미리보기를 표시하지 않지만, Slack 초안 미리보기 게시물과 편집은 계속 사용할 수 있습니다. +- Slack 네이티브 스트리밍과 Slack 어시스턴트 스레드 상태에는 답장 스레드 대상이 필요합니다. 최상위 DM에는 해당 스레드 스타일 미리보기가 표시되지 않지만, Slack 초안 미리보기 게시물과 편집은 계속 사용할 수 있습니다. 레거시 키 마이그레이션: -- Telegram: 레거시 `streamMode` 및 스칼라/불리언 `streaming` 값은 doctor/config 호환성 경로에서 감지되어 `streaming.mode`로 마이그레이션됩니다. -- Discord: `streamMode` + 불리언 `streaming`은 `streaming` 열거형으로 자동 마이그레이션됩니다. -- Slack: `streamMode`는 `streaming.mode`로 자동 마이그레이션됩니다. 불리언 `streaming`은 `streaming.mode`와 `streaming.nativeTransport`로 자동 마이그레이션됩니다. 레거시 `nativeStreaming`은 `streaming.nativeTransport`로 자동 마이그레이션됩니다. +- Telegram: 레거시 `streamMode`와 스칼라/불리언 `streaming` 값은 doctor/config 호환성 경로에서 감지되어 `streaming.mode`로 마이그레이션됩니다. +- Discord: `streamMode` + 불리언 `streaming`은 `streaming` 열거형의 런타임 별칭으로 유지됩니다. 유지된 설정을 다시 쓰려면 `openclaw doctor --fix`를 실행하세요. +- Slack: `streamMode`는 `streaming.mode`의 런타임 별칭으로 유지됩니다. 불리언 `streaming`은 `streaming.mode`와 `streaming.nativeTransport`의 런타임 별칭으로 유지됩니다. 레거시 `nativeStreaming`은 `streaming.nativeTransport`의 런타임 별칭으로 유지됩니다. 유지된 설정을 다시 쓰려면 `openclaw doctor --fix`를 실행하세요. ### 런타임 동작 Telegram: -- DM 및 그룹/토픽 전반에서 `sendMessage` + `editMessageText` 미리보기 업데이트를 사용합니다. +- DM과 그룹/토픽 전반에서 `sendMessage` + `editMessageText` 미리보기 업데이트를 사용합니다. - 최종 텍스트는 활성 미리보기를 제자리에서 편집합니다. 긴 최종 답변은 첫 번째 청크에 해당 메시지를 재사용하고 남은 청크만 보냅니다. -- `progress` 모드는 도구 진행률을 편집 가능한 상태 초안에 유지하고, 완료 시 해당 초안을 지운 뒤 일반 전달을 통해 최종 답변을 보냅니다. -- 완료된 텍스트가 확인되기 전에 최종 편집이 실패하면, OpenClaw는 일반 최종 전달을 사용하고 오래된 미리보기를 정리합니다. -- Telegram 블록 스트리밍이 명시적으로 활성화된 경우 미리보기 스트리밍은 건너뜁니다(이중 스트리밍 방지). +- `progress` 모드는 편집 가능한 상태 초안에 도구 진행 상황을 유지하고, 완료 시 해당 초안을 지운 뒤 정상 전달을 통해 최종 답변을 보냅니다. +- 완료된 텍스트가 확인되기 전에 최종 편집이 실패하면 OpenClaw는 정상 최종 전달을 사용하고 오래된 미리보기를 정리합니다. +- Telegram 블록 스트리밍이 명시적으로 활성화되어 있으면 이중 스트리밍을 피하기 위해 미리보기 스트리밍을 건너뜁니다. - `/reasoning stream`은 최종 전달 후 삭제되는 임시 미리보기에 추론을 쓸 수 있습니다. Discord: - 전송 + 편집 미리보기 메시지를 사용합니다. - `block` 모드는 초안 청킹(`draftChunk`)을 사용합니다. -- Discord 블록 스트리밍이 명시적으로 활성화된 경우 미리보기 스트리밍은 건너뜁니다. -- 최종 미디어, 오류, 명시적 답장 페이로드는 새 초안을 플러시하지 않고 보류 중인 미리보기를 취소한 다음 일반 전달을 사용합니다. +- Discord 블록 스트리밍이 명시적으로 활성화되어 있으면 미리보기 스트리밍을 건너뜁니다. +- 최종 미디어, 오류, 명시적 답장 페이로드는 새 초안을 플러시하지 않고 대기 중인 미리보기를 취소한 다음 정상 전달을 사용합니다. Slack: -- `partial`은 사용 가능할 때 Slack 네이티브 스트리밍(`chat.startStream`/`append`/`stop`)을 사용할 수 있습니다. -- `block`은 추가 스타일 초안 미리보기를 사용합니다. +- `partial`은 사용 가능한 경우 Slack 네이티브 스트리밍(`chat.startStream`/`append`/`stop`)을 사용할 수 있습니다. +- `block`은 추가 방식 초안 미리보기를 사용합니다. - `progress`는 상태 미리보기 텍스트를 사용한 다음 최종 답변을 사용합니다. - 답장 스레드가 없는 최상위 DM은 Slack 네이티브 스트리밍 대신 초안 미리보기 게시물과 편집을 사용합니다. -- 네이티브 및 초안 미리보기 스트리밍은 해당 턴의 블록 답장을 억제하므로, Slack 답장은 하나의 전달 경로로만 스트리밍됩니다. -- 최종 미디어/오류 페이로드와 진행률 최종 답변은 버리는 용도의 초안 메시지를 만들지 않습니다. 미리보기를 편집할 수 있는 텍스트/블록 최종 답변만 보류 중인 초안 텍스트를 플러시합니다. +- 네이티브 및 초안 미리보기 스트리밍은 해당 턴의 블록 답장을 억제하므로 Slack 답장은 하나의 전달 경로로만 스트리밍됩니다. +- 최종 미디어/오류 페이로드와 진행 상황 최종 답변은 일회용 초안 메시지를 만들지 않습니다. 미리보기를 편집할 수 있는 텍스트/블록 최종 답변만 대기 중인 초안 텍스트를 플러시합니다. Mattermost: -- 사고 과정, 도구 활동, 부분 답장 텍스트를 단일 초안 미리보기 게시물로 스트리밍하며, 최종 답변을 안전하게 보낼 수 있을 때 제자리에서 최종화합니다. -- 미리보기 게시물이 삭제되었거나 최종화 시점에 사용할 수 없는 경우 새 최종 게시물을 보내는 방식으로 폴백합니다. -- 최종 미디어/오류 페이로드는 임시 미리보기 게시물을 플러시하는 대신 일반 전달 전에 보류 중인 미리보기 업데이트를 취소합니다. +- 생각, 도구 활동, 부분 답장 텍스트를 단일 초안 미리보기 게시물로 스트리밍하고, 최종 답변을 보내도 안전할 때 제자리에서 최종화합니다. +- 최종화 시점에 미리보기 게시물이 삭제되었거나 사용할 수 없으면 새 최종 게시물을 보내는 방식으로 폴백합니다. +- 최종 미디어/오류 페이로드는 임시 미리보기 게시물을 플러시하는 대신 정상 전달 전에 대기 중인 미리보기 업데이트를 취소합니다. Matrix: -- 초안 미리보기는 최종 텍스트가 미리보기 이벤트를 재사용할 수 있을 때 제자리에서 최종화됩니다. -- 미디어만 있는 최종 답변, 오류, 답장 대상 불일치 최종 답변은 일반 전달 전에 보류 중인 미리보기 업데이트를 취소합니다. 이미 보이는 오래된 미리보기는 정정됩니다. +- 최종 텍스트가 미리보기 이벤트를 재사용할 수 있으면 초안 미리보기가 제자리에서 최종화됩니다. +- 미디어 전용, 오류, 답장 대상 불일치 최종 답변은 정상 전달 전에 대기 중인 미리보기 업데이트를 취소합니다. 이미 보이는 오래된 미리보기는 삭제 처리됩니다. -### 도구 진행률 미리보기 업데이트 +### 도구 진행 상황 미리보기 업데이트 -미리보기 스트리밍에는 **도구 진행률** 업데이트도 포함될 수 있습니다. 이는 "웹 검색 중", "파일 읽는 중", "도구 호출 중" 같은 짧은 상태 줄로, 도구가 실행되는 동안 최종 답장에 앞서 같은 미리보기 메시지에 표시됩니다. 이렇게 하면 여러 단계의 도구 턴이 첫 사고 미리보기와 최종 답변 사이에서 조용히 멈춘 것처럼 보이지 않고 시각적으로 계속 살아 있게 됩니다. +미리보기 스트리밍에는 도구가 실행되는 동안 최종 답장보다 앞서 같은 미리보기 메시지에 표시되는 "웹 검색 중", "파일 읽는 중", "도구 호출 중" 같은 짧은 상태 줄인 **도구 진행 상황** 업데이트도 포함될 수 있습니다. 이렇게 하면 여러 단계의 도구 턴이 첫 생각 미리보기와 최종 답변 사이에서 조용히 멈춰 있는 대신 시각적으로 살아 있게 됩니다. 지원되는 표면: -- **Discord**, **Slack**, **Telegram**, **Matrix**는 미리 보기 스트리밍이 활성화되어 있을 때 기본적으로 도구 진행 상황을 라이브 미리 보기 편집에 스트리밍합니다. Microsoft Teams는 개인 채팅에서 기본 진행 상황 스트림을 사용합니다. -- Telegram은 `v2026.4.22`부터 도구 진행 상황 미리 보기 업데이트가 활성화된 상태로 제공되었습니다. 이를 계속 활성화하면 해당 릴리스 동작이 유지됩니다. -- **Mattermost**는 이미 도구 활동을 단일 초안 미리 보기 게시물에 접어 넣습니다(위 참조). -- 도구 진행 상황 편집은 활성 미리 보기 스트리밍 모드를 따릅니다. 미리 보기 스트리밍이 `off`이거나 블록 스트리밍이 메시지를 대신 처리하는 경우 건너뜁니다. Telegram에서는 `streaming.mode: "off"`가 최종 응답 전용입니다. 일반 진행 상황 잡담도 독립 상태 메시지로 전달되지 않고 억제되며, 승인 프롬프트, 미디어 페이로드, 오류는 여전히 정상적으로 라우팅됩니다. -- 미리 보기 스트리밍은 유지하되 도구 진행 상황 줄을 숨기려면 해당 채널의 `streaming.preview.toolProgress`를 `false`로 설정하세요. 도구 진행 상황 줄은 보이게 유지하면서 명령/실행 텍스트를 숨기려면 `streaming.preview.commandText`를 `"status"`로 설정하거나 `streaming.progress.commandText`를 `"status"`로 설정하세요. 기본값은 릴리스된 동작을 유지하기 위한 `"raw"`입니다. 이 정책은 Discord, Matrix, Microsoft Teams, Mattermost, Slack 초안 미리 보기, Telegram을 포함하여 OpenClaw의 간결한 진행 상황 렌더러를 사용하는 초안/진행 상황 채널에서 공유됩니다. 미리 보기 편집을 완전히 비활성화하려면 `streaming.mode`를 `off`로 설정하세요. -- Telegram 선택 인용 답장은 예외입니다. `replyToMode`가 `"off"`가 아니고 선택된 인용 텍스트가 있으면, OpenClaw는 해당 턴의 답변 미리 보기 스트림을 건너뛰므로 도구 진행 상황 미리 보기 줄을 렌더링할 수 없습니다. 선택된 인용 텍스트가 없는 현재 메시지 답장은 여전히 미리 보기 스트리밍을 유지합니다. 자세한 내용은 [Telegram 채널 문서](/ko/channels/telegram)를 참조하세요. +- **Discord**, **Slack**, **Telegram**, **Matrix**는 미리보기 스트리밍이 활성화되어 있을 때 기본적으로 도구 진행 상황을 실시간 미리보기 편집에 스트리밍합니다. Microsoft Teams는 개인 채팅에서 네이티브 진행 상황 스트림을 사용합니다. +- Telegram은 `v2026.4.22`부터 도구 진행 상황 미리보기 업데이트가 활성화된 상태로 제공되었습니다. 이를 계속 활성화해 두면 이미 릴리스된 동작이 유지됩니다. +- **Mattermost**는 이미 도구 활동을 단일 초안 미리보기 게시물에 접어 넣습니다(위 참조). +- 도구 진행 상황 편집은 활성 미리보기 스트리밍 모드를 따릅니다. 미리보기 스트리밍이 `off`이거나 블록 스트리밍이 메시지를 이어받은 경우에는 건너뜁니다. Telegram에서 `streaming.mode: "off"`는 최종 메시지만 전송합니다. 일반 진행 상황 메시지도 독립 상태 메시지로 전달되지 않고 억제되며, 승인 프롬프트, 미디어 페이로드, 오류는 계속 정상적으로 라우팅됩니다. +- 미리보기 스트리밍은 유지하되 도구 진행 상황 줄을 숨기려면 해당 채널의 `streaming.preview.toolProgress`를 `false`로 설정하세요. 명령/실행 텍스트는 숨기면서 도구 진행 상황 줄을 계속 표시하려면 `streaming.preview.commandText`를 `"status"`로 설정하거나 `streaming.progress.commandText`를 `"status"`로 설정하세요. 기본값은 릴리스된 동작을 유지하기 위해 `"raw"`입니다. 이 정책은 Discord, Matrix, Microsoft Teams, Mattermost, Slack 초안 미리보기, Telegram을 포함해 OpenClaw의 간결한 진행 상황 렌더러를 사용하는 초안/진행 상황 채널이 공유합니다. 미리보기 편집을 완전히 비활성화하려면 `streaming.mode`를 `off`로 설정하세요. +- Telegram의 선택된 인용 답장은 예외입니다. `replyToMode`가 `"off"`가 아니고 선택된 인용 텍스트가 있으면, OpenClaw는 해당 턴의 답변 미리보기 스트림을 건너뛰므로 도구 진행 상황 미리보기 줄을 렌더링할 수 없습니다. 선택된 인용 텍스트가 없는 현재 메시지 답장은 여전히 미리보기 스트리밍을 유지합니다. 자세한 내용은 [Telegram 채널 문서](/ko/channels/telegram)를 참조하세요. -진행 상황 줄은 보이게 유지하되 원시 명령/실행 텍스트는 숨깁니다. +진행 상황 줄은 표시하되 원시 명령/실행 텍스트는 숨깁니다. ```json { @@ -211,7 +210,7 @@ Matrix: } ``` -예를 들어 `channels.discord`, `channels.matrix`, `channels.msteams`, `channels.mattermost` 또는 Slack 초안 미리 보기처럼 다른 간결한 진행 상황 채널 키 아래에서도 같은 구조를 사용하세요. 진행 상황 초안 모드에서는 같은 정책을 `streaming.progress` 아래에 넣으세요. +다른 간결한 진행 상황 채널 키 아래에서도 같은 구조를 사용하세요. 예를 들어 `channels.discord`, `channels.matrix`, `channels.msteams`, `channels.mattermost` 또는 Slack 초안 미리보기에서 사용할 수 있습니다. 진행 상황 초안 모드의 경우 같은 정책을 `streaming.progress` 아래에 둡니다. ```json { @@ -231,8 +230,8 @@ Matrix: ## 관련 항목 -- [메시지 수명 주기 리팩터링](/ko/concepts/message-lifecycle-refactor) - 공유 미리 보기, 편집, 스트림, 최종화 설계 대상 -- [진행 상황 초안](/ko/concepts/progress-drafts) - 긴 턴 동안 업데이트되는 보이는 진행 중 작업 메시지 +- [메시지 수명 주기 리팩터링](/ko/concepts/message-lifecycle-refactor) - 공유 미리보기, 편집, 스트림, 최종화 설계 대상 +- [진행 상황 초안](/ko/concepts/progress-drafts) - 긴 턴 중 업데이트되는, 표시되는 진행 중 작업 메시지 - [메시지](/ko/concepts/messages) - 메시지 수명 주기와 전달 - [재시도](/ko/concepts/retry) - 전달 실패 시 재시도 동작 - [채널](/ko/channels) - 채널별 스트리밍 지원 diff --git a/docs/ko/debug/node-issue.md b/docs/ko/debug/node-issue.md index af33dc440..82a0a99bb 100644 --- a/docs/ko/debug/node-issue.md +++ b/docs/ko/debug/node-issue.md @@ -1,23 +1,23 @@ --- read_when: - - Node 전용 개발 스크립트 또는 watch 모드 실패를 디버깅하는 중입니다. - - OpenClaw에서 tsx/esbuild 로더 충돌을 조사하는 중입니다. -summary: Node + tsx `"__name is not a function"` 충돌 참고 및 해결 방법 + - Node 전용 개발 스크립트 또는 감시 모드 실패 디버깅 + - OpenClaw에서 tsx/esbuild 로더 충돌 조사 +summary: Node + tsx "__name is not a function" 크래시 참고 사항 및 우회 방법 title: Node + tsx 충돌 x-i18n: - generated_at: "2026-04-24T06:12:46Z" - model: gpt-5.4 + generated_at: "2026-05-06T17:54:49Z" + model: gpt-5.5 provider: openai - source_hash: 7d043466f71eae223fa568a3db82e424580ce3269ca11d0e84368beefc25bd25 + source_hash: 808f04959c70c96c983fb2517234d4c06712049d7afebb9b1b4b340df75d7d70 source_path: debug/node-issue.md - workflow: 15 + workflow: 16 --- -# Node + tsx `__name is not a function` 충돌 +# Node + tsx "\_\_name is not a function" 크래시 ## 요약 -`tsx`와 함께 Node로 OpenClaw를 실행하면 시작 시 다음 오류와 함께 실패합니다. +`tsx`와 함께 Node를 통해 OpenClaw를 실행하면 시작 시 다음 오류로 실패합니다. ``` [openclaw] Failed to start CLI: TypeError: __name is not a function @@ -25,24 +25,24 @@ x-i18n: at .../src/agents/auth-profiles/constants.ts:25:20 ``` -이 문제는 개발 스크립트를 Bun에서 `tsx`로 전환한 뒤(커밋 `2871657e`, 2026-01-06) 시작되었습니다. 동일한 런타임 경로는 Bun에서는 정상 동작했습니다. +이 문제는 개발 스크립트를 Bun에서 `tsx`로 전환한 뒤 시작되었습니다(커밋 `2871657e`, 2026-01-06). 동일한 런타임 경로는 Bun에서는 작동했습니다. ## 환경 -- Node: v25.x (v25.3.0에서 관찰됨) +- Node: v25.x(v25.3.0에서 관찰됨) - tsx: 4.21.0 -- OS: macOS (Node 25를 실행하는 다른 플랫폼에서도 재현될 가능성 높음) +- OS: macOS(Node 25를 실행하는 다른 플랫폼에서도 재현될 가능성이 있음) -## 재현(Node 전용) +## 재현 방법(Node 전용) ```bash -# repo 루트에서 +# in repo root node --version pnpm install node --import tsx src/entry.ts status ``` -## repo 내 최소 재현 +## 저장소의 최소 재현 ```bash node --import tsx scripts/repro/tsx-name-repro.ts @@ -51,33 +51,33 @@ node --import tsx scripts/repro/tsx-name-repro.ts ## Node 버전 확인 - Node 25.3.0: 실패 -- Node 22.22.0 (Homebrew `node@22`): 실패 -- Node 24: 아직 여기에 설치되지 않음, 확인 필요 +- Node 22.22.0(Homebrew `node@22`): 실패 +- Node 24: 아직 여기에 설치되어 있지 않음; 확인 필요 ## 참고 / 가설 -- `tsx`는 TS/ESM을 변환하기 위해 esbuild를 사용합니다. esbuild의 `keepNames`는 `__name` 헬퍼를 생성하고 함수 정의를 `__name(...)`으로 감쌉니다. -- 이 충돌은 런타임에 `__name`이 존재하지만 함수가 아님을 뜻하므로, Node 25 로더 경로에서 이 모듈에 대해 해당 헬퍼가 누락되었거나 덮어써졌음을 시사합니다. -- 비슷한 `__name` 헬퍼 문제는 헬퍼가 누락되거나 다시 작성되는 경우 다른 esbuild 사용 사례에서도 보고된 바 있습니다. +- `tsx`는 esbuild를 사용해 TS/ESM을 변환합니다. esbuild의 `keepNames`는 `__name` 헬퍼를 내보내고 함수 정의를 `__name(...)`로 감쌉니다. +- 이 크래시는 런타임에 `__name`이 존재하지만 함수가 아님을 나타내며, 이는 Node 25 로더 경로에서 이 모듈의 헬퍼가 누락되었거나 덮어써졌음을 의미합니다. +- 유사한 `__name` 헬퍼 문제는 헬퍼가 누락되거나 다시 작성될 때 다른 esbuild 소비자에서도 보고된 바 있습니다. ## 회귀 이력 -- `2871657e` (2026-01-06): Bun을 선택 사항으로 만들기 위해 스크립트를 Bun에서 tsx로 변경 -- 그 이전(Bun 경로): `openclaw status`와 `gateway:watch`가 동작했음 +- `2871657e`(2026-01-06): Bun을 선택 사항으로 만들기 위해 스크립트가 Bun에서 tsx로 변경되었습니다. +- 그 전에는(Bun 경로) `openclaw status`와 `gateway:watch`가 작동했습니다. -## 해결 방법 +## 우회 방법 -- 개발 스크립트에는 Bun 사용(현재 임시 되돌림) -- repo 타입 검사는 `tsgo`를 사용한 뒤 빌드된 출력을 실행 +- 개발 스크립트에 Bun을 사용합니다(현재 임시 되돌림). +- 저장소 타입 검사는 `tsgo`를 사용한 다음 빌드된 출력을 실행합니다. ```bash pnpm tsgo node openclaw.mjs status ``` -- 기록 참고: 이 Node/tsx 문제를 디버깅하는 동안 여기서는 `tsc`를 사용했지만, 현재 repo 타입 검사 레인은 `tsgo`를 사용합니다. -- 가능하다면 TS 로더에서 esbuild `keepNames`를 비활성화(`__name` 헬퍼 삽입 방지). 현재 tsx는 이를 노출하지 않습니다. -- Node LTS(22/24)에서 `tsx`를 테스트해 이 문제가 Node 25 전용인지 확인 +- 과거 참고: 이 Node/tsx 문제를 디버깅하는 동안 여기서 `tsc`가 사용되었지만, 저장소 타입 검사 레인은 이제 `tsgo`를 사용합니다. +- 가능하다면 TS 로더에서 esbuild keepNames를 비활성화합니다(`__name` 헬퍼 삽입 방지). tsx는 현재 이를 노출하지 않습니다. +- Node LTS(22/24)를 `tsx`와 함께 테스트해 이 문제가 Node 25에만 해당하는지 확인합니다. ## 참고 자료 @@ -87,11 +87,11 @@ node --import tsx scripts/repro/tsx-name-repro.ts ## 다음 단계 -- Node 22/24에서 재현해 Node 25 회귀인지 확인 -- 알려진 회귀가 있다면 `tsx` nightly를 테스트하거나 이전 버전으로 고정 -- Node LTS에서도 재현되면 `__name` 스택 트레이스와 함께 최소 재현 사례를 업스트림에 제출 +- Node 22/24에서 재현해 Node 25 회귀인지 확인합니다. +- 알려진 회귀가 있는 경우 `tsx` nightly를 테스트하거나 이전 버전으로 고정합니다. +- Node LTS에서 재현되면 `__name` 스택 추적과 함께 최소 재현을 upstream에 제출합니다. -## 관련 항목 +## 관련 문서 - [Node.js 설치](/ko/install/node) - [Gateway 문제 해결](/ko/gateway/troubleshooting) diff --git a/docs/ko/gateway/bridge-protocol.md b/docs/ko/gateway/bridge-protocol.md index 119e8c73e..5a4829221 100644 --- a/docs/ko/gateway/bridge-protocol.md +++ b/docs/ko/gateway/bridge-protocol.md @@ -1,93 +1,88 @@ --- read_when: - - Node 클라이언트(iOS/Android/macOS node mode) 빌드 또는 디버깅하기 + - node 클라이언트 빌드 또는 디버깅(iOS/Android/macOS node 모드) - 페어링 또는 브리지 인증 실패 조사하기 - - Gateway가 노출하는 Node 표면 감사하기 -summary: '레거시 브리지 프로토콜(legacy nodes): TCP JSONL, 페어링, 범위 지정 RPC' + - Gateway가 노출하는 Node 표면 감사 +summary: '과거 bridge protocol(레거시 Node): TCP JSONL, 페어링, 범위 지정 RPC' title: 브리지 프로토콜 x-i18n: - generated_at: "2026-04-25T06:00:05Z" - model: gpt-5.4 + generated_at: "2026-05-06T17:55:22Z" + model: gpt-5.5 provider: openai - source_hash: cb07ec4dab4394dd03b4c0002d6a842a9d77d12a1fc2f141f01d5a306fab1615 + source_hash: f84c4b5c344d880d4283eebd8596e8b5b0aad5cae747694784011deb1547db30 source_path: gateway/bridge-protocol.md - workflow: 15 + workflow: 16 --- -TCP 브리지는 **제거되었습니다**. 현재 OpenClaw 빌드에는 브리지 리스너가 포함되지 않으며 `bridge.*` 구성 키도 더 이상 스키마에 존재하지 않습니다. 이 페이지는 역사적 참고용으로만 유지됩니다. 모든 node/operator 클라이언트에는 [Gateway Protocol](/ko/gateway/protocol)을 사용하세요. +TCP 브리지는 **제거되었습니다**. 현재 OpenClaw 빌드는 브리지 리스너를 제공하지 않으며 `bridge.*` 구성 키는 더 이상 스키마에 없습니다. 이 페이지는 역사적 참고용으로만 유지됩니다. 모든 노드/운영자 클라이언트에는 [Gateway 프로토콜](/ko/gateway/protocol)을 사용하세요. ## 존재했던 이유 -- **보안 경계**: 브리지는 전체 gateway API 표면 대신 작은 허용 목록만 노출합니다. -- **페어링 + node ID**: node 승인 절차는 gateway가 소유하며 node별 토큰에 연결됩니다. -- **탐색 UX**: node는 LAN에서 Bonjour를 통해 gateway를 탐색하거나 tailnet을 통해 직접 연결할 수 있습니다. +- **보안 경계**: 브리지는 전체 Gateway API 표면 대신 작은 허용 목록을 노출합니다. +- **페어링 + 노드 ID**: 노드 승인은 Gateway가 소유하며 노드별 토큰에 연결됩니다. +- **검색 UX**: 노드는 LAN에서 Bonjour를 통해 Gateway를 검색하거나 tailnet을 통해 직접 연결할 수 있습니다. - **루프백 WS**: 전체 WS 제어 평면은 SSH를 통해 터널링하지 않는 한 로컬에 유지됩니다. ## 전송 -- TCP, 줄마다 하나의 JSON 객체(JSONL). -- 선택적 TLS (`bridge.tls.enabled`가 true일 때). -- 과거 기본 리스너 포트는 `18790`이었습니다(현재 빌드는 TCP 브리지를 시작하지 않음). +- TCP, 한 줄에 JSON 객체 하나(JSONL). +- 선택적 TLS(`bridge.tls.enabled`가 true일 때). +- 역사적 기본 리스너 포트는 `18790`이었습니다(현재 빌드는 TCP 브리지를 시작하지 않음). -TLS가 활성화되면 탐색 TXT 레코드에는 `bridgeTls=1`과 -비밀이 아닌 힌트로 `bridgeTlsSha256`이 포함되었습니다. Bonjour/mDNS TXT 레코드는 -인증되지 않으므로, 클라이언트는 명시적인 사용자 의도나 다른 대역 외 검증 없이 -광고된 fingerprint를 권위 있는 pin으로 취급해서는 안 됩니다. +TLS가 활성화되면 검색 TXT 레코드에 비밀이 아닌 힌트로 `bridgeTls=1`과 `bridgeTlsSha256`이 포함됩니다. Bonjour/mDNS TXT 레코드는 인증되지 않습니다. 클라이언트는 명시적인 사용자 의도나 다른 대역 외 검증 없이 광고된 지문을 신뢰할 수 있는 핀으로 취급해서는 안 됩니다. ## 핸드셰이크 + 페어링 -1. 클라이언트가 node 메타데이터 + 토큰(이미 페어링된 경우)을 포함한 `hello`를 보냅니다. -2. 페어링되지 않은 경우 gateway는 `error`(`NOT_PAIRED`/`UNAUTHORIZED`)로 응답합니다. +1. 클라이언트가 노드 메타데이터 + 토큰(이미 페어링된 경우)을 포함해 `hello`를 보냅니다. +2. 페어링되지 않은 경우 Gateway가 `error`(`NOT_PAIRED`/`UNAUTHORIZED`)로 응답합니다. 3. 클라이언트가 `pair-request`를 보냅니다. -4. Gateway는 승인을 기다린 후 `pair-ok`와 `hello-ok`를 보냅니다. +4. Gateway가 승인을 기다린 다음 `pair-ok`와 `hello-ok`를 보냅니다. -과거에는 `hello-ok`가 `serverName`을 반환했고 -`canvasHostUrl`을 포함할 수도 있었습니다. +역사적으로 `hello-ok`는 `serverName`을 반환했으며 `canvasHostUrl`을 포함할 수 있었습니다. ## 프레임 클라이언트 → Gateway: -- `req` / `res`: 범위 지정 gateway RPC (`chat`, `sessions`, `config`, `health`, `voicewake`, `skills.bins`) -- `event`: node 신호(음성 transcript, agent 요청, chat 구독, exec 수명 주기) +- `req` / `res`: 범위가 지정된 Gateway RPC(chat, sessions, config, health, voicewake, skills.bins) +- `event`: 노드 신호(음성 전사, 에이전트 요청, 채팅 구독, exec 수명 주기) Gateway → 클라이언트: -- `invoke` / `invoke-res`: node 명령어 (`canvas.*`, `camera.*`, `screen.record`, +- `invoke` / `invoke-res`: 노드 명령(`canvas.*`, `camera.*`, `screen.record`, `location.get`, `sms.send`) -- `event`: 구독된 세션의 chat 업데이트 +- `event`: 구독된 세션의 채팅 업데이트 - `ping` / `pong`: keepalive -레거시 허용 목록 강제 적용은 `src/gateway/server-bridge.ts`에 있었습니다(현재 제거됨). +레거시 허용 목록 강제 적용은 `src/gateway/server-bridge.ts`에 있었습니다(제거됨). ## Exec 수명 주기 이벤트 -Node는 `exec.finished` 또는 `exec.denied` 이벤트를 내보내 system.run 활동을 표시할 수 있습니다. -이들은 gateway에서 시스템 이벤트로 매핑됩니다. (레거시 node는 여전히 `exec.started`를 내보낼 수 있습니다.) +노드는 system.run 활동을 표시하기 위해 `exec.finished` 또는 `exec.denied` 이벤트를 내보낼 수 있습니다. +이 이벤트는 Gateway에서 시스템 이벤트로 매핑됩니다. (레거시 노드는 여전히 `exec.started`를 내보낼 수 있습니다.) -페이로드 필드(명시되지 않은 경우 모두 선택 사항): +페이로드 필드(별도 표시가 없으면 모두 선택 사항): -- `sessionKey` (필수): 시스템 이벤트를 받을 agent 세션. +- `sessionKey`(필수): 시스템 이벤트를 받을 에이전트 세션. - `runId`: 그룹화를 위한 고유 exec ID. -- `command`: 원시 또는 포맷된 명령어 문자열. -- `exitCode`, `timedOut`, `success`, `output`: 완료 세부 정보(finished만 해당). -- `reason`: 거부 사유(denied만 해당). +- `command`: 원시 또는 형식화된 명령 문자열. +- `exitCode`, `timedOut`, `success`, `output`: 완료 세부 정보(완료된 경우만). +- `reason`: 거부 이유(거부된 경우만). -## 과거 tailnet 사용 방식 +## 역사적 tailnet 사용 -- 브리지를 tailnet IP에 바인딩: `~/.openclaw/openclaw.json`에서 `bridge.bind: "tailnet"` 설정(역사적 정보 전용이며, `bridge.*`는 더 이상 유효하지 않음). -- 클라이언트는 MagicDNS 이름 또는 tailnet IP로 연결했습니다. -- Bonjour는 **네트워크를 넘지 않으므로**, 필요 시 수동 host/port 또는 광역 DNS‑SD를 사용해야 합니다. +- 브리지를 tailnet IP에 바인딩: `~/.openclaw/openclaw.json`에서 + `bridge.bind: "tailnet"`(역사적 용도만 해당, `bridge.*`는 더 이상 유효하지 않음). +- 클라이언트는 MagicDNS 이름 또는 tailnet IP를 통해 연결합니다. +- Bonjour는 네트워크를 넘지 **않습니다**. 필요한 경우 수동 호스트/포트 또는 광역 DNS-SD를 사용하세요. ## 버전 관리 -브리지는 **암묵적 v1**이었습니다(최소/최대 협상 없음). 이 섹션은 -역사적 참고용일 뿐이며, 현재 node/operator 클라이언트는 WebSocket -[Gateway Protocol](/ko/gateway/protocol)을 사용합니다. +브리지는 **암시적 v1**이었습니다(최소/최대 협상 없음). 이 섹션은 역사적 참고용일 뿐입니다. 현재 노드/운영자 클라이언트는 WebSocket [Gateway 프로토콜](/ko/gateway/protocol)을 사용합니다. ## 관련 항목 -- [Gateway protocol](/ko/gateway/protocol) -- [Nodes](/ko/nodes) +- [Gateway 프로토콜](/ko/gateway/protocol) +- [노드](/ko/nodes) diff --git a/docs/ko/gateway/config-agents.md b/docs/ko/gateway/config-agents.md index 43d805df6..37d586e3a 100644 --- a/docs/ko/gateway/config-agents.md +++ b/docs/ko/gateway/config-agents.md @@ -1,20 +1,22 @@ --- read_when: - - 에이전트 기본값 조정(모델, 추론, 작업 공간, Heartbeat, 미디어, Skills) + - 에이전트 기본값 조정(모델, 추론, 작업 영역, Heartbeat, 미디어, Skills) - 다중 에이전트 라우팅 및 바인딩 구성 - 세션, 메시지 전달 및 대화 모드 동작 조정 -summary: 에이전트 기본값, 다중 에이전트 라우팅, 세션, 메시지 및 대화 설정 -title: 구성 — 에이전트 +summary: 에이전트 기본값, 멀티 에이전트 라우팅, 세션, 메시지 및 대화 설정 +title: 설정 — 에이전트 x-i18n: - generated_at: "2026-05-06T06:24:42Z" + generated_at: "2026-05-06T17:55:27Z" model: gpt-5.5 provider: openai - source_hash: b864cc3985db2f3ab2e82b18bcd1b1590a387d7474f5f0d0da3a1d36d9a276b9 + source_hash: e0467260ad61f3d2a0b52cd952154d617a9341a588cdeda38f54bfae5985fa4f source_path: gateway/config-agents.md workflow: 16 --- -`agents.*`, `multiAgent.*`, `session.*`, `messages.*`, `talk.*` 아래의 에이전트 범위 구성 키입니다. 채널, 도구, Gateway 런타임 및 기타 최상위 키는 [구성 참조](/ko/gateway/configuration-reference)를 참조하세요. +`agents.*`, `multiAgent.*`, `session.*`, +`messages.*`, `talk.*` 아래의 에이전트 범위 구성 키입니다. 채널, 도구, Gateway 런타임, 기타 +최상위 키는 [구성 참조](/ko/gateway/configuration-reference)를 참조하세요. ## 에이전트 기본값 @@ -30,7 +32,7 @@ x-i18n: ### `agents.defaults.repoRoot` -시스템 프롬프트의 런타임 줄에 표시되는 선택적 저장소 루트입니다. 설정하지 않으면 OpenClaw가 워크스페이스에서 위로 이동하며 자동 감지합니다. +시스템 프롬프트의 런타임 줄에 표시되는 선택적 리포지토리 루트입니다. 설정하지 않으면 OpenClaw가 워크스페이스에서 위쪽으로 이동하며 자동 감지합니다. ```json5 { @@ -58,7 +60,7 @@ x-i18n: - 기본적으로 제한 없는 Skills를 사용하려면 `agents.defaults.skills`를 생략하세요. - 기본값을 상속하려면 `agents.list[].skills`를 생략하세요. - Skills를 사용하지 않으려면 `agents.list[].skills: []`를 설정하세요. -- 비어 있지 않은 `agents.list[].skills` 목록은 해당 에이전트의 최종 집합이며, 기본값과 병합되지 않습니다. +- 비어 있지 않은 `agents.list[].skills` 목록은 해당 에이전트의 최종 집합입니다. 기본값과 병합되지 않습니다. ### `agents.defaults.skipBootstrap` @@ -86,10 +88,10 @@ x-i18n: ### `agents.defaults.contextInjection` -워크스페이스 부트스트랩 파일을 시스템 프롬프트에 주입할 시점을 제어합니다. 기본값: `"always"`. +워크스페이스 부트스트랩 파일이 시스템 프롬프트에 주입되는 시점을 제어합니다. 기본값: `"always"`. -- `"continuation-skip"`: 안전한 이어가기 턴(완료된 어시스턴트 응답 이후)에서는 워크스페이스 부트스트랩 재주입을 건너뛰어 프롬프트 크기를 줄입니다. Heartbeat 실행 및 Compaction 이후 재시도는 여전히 컨텍스트를 다시 빌드합니다. -- `"never"`: 모든 턴에서 워크스페이스 부트스트랩 및 컨텍스트 파일 주입을 비활성화합니다. 프롬프트 수명 주기를 완전히 자체적으로 소유하는 에이전트(사용자 지정 컨텍스트 엔진, 자체 컨텍스트를 빌드하는 네이티브 런타임, 또는 특수한 부트스트랩 없는 워크플로)에만 사용하세요. Heartbeat 및 Compaction 복구 턴에서도 주입을 건너뜁니다. +- `"continuation-skip"`: 안전한 이어가기 턴에서는(완료된 어시스턴트 응답 뒤) 워크스페이스 부트스트랩 재주입을 건너뛰어 프롬프트 크기를 줄입니다. Heartbeat 실행과 Compaction 후 재시도는 여전히 컨텍스트를 다시 빌드합니다. +- `"never"`: 모든 턴에서 워크스페이스 부트스트랩과 컨텍스트 파일 주입을 비활성화합니다. 프롬프트 수명 주기를 완전히 직접 소유하는 에이전트(사용자 지정 컨텍스트 엔진, 자체 컨텍스트를 빌드하는 네이티브 런타임, 특수한 부트스트랩 없는 워크플로)에만 사용하세요. Heartbeat 및 Compaction 복구 턴도 주입을 건너뜁니다. ```json5 { @@ -109,7 +111,7 @@ x-i18n: ### `agents.defaults.bootstrapTotalMaxChars` -모든 워크스페이스 부트스트랩 파일에 걸쳐 주입되는 총 최대 문자 수입니다. 기본값: `60000`. +모든 워크스페이스 부트스트랩 파일에 걸쳐 주입되는 최대 총 문자 수입니다. 기본값: `60000`. ```json5 { @@ -122,11 +124,11 @@ x-i18n: 부트스트랩 컨텍스트가 잘릴 때 에이전트에 표시되는 시스템 프롬프트 알림을 제어합니다. 기본값: `"once"`. -- `"off"`: 자르기 알림 텍스트를 시스템 프롬프트에 주입하지 않습니다. -- `"once"`: 고유한 자르기 서명마다 간결한 알림을 한 번 주입합니다(권장). -- `"always"`: 자르기가 있을 때마다 모든 실행에서 간결한 알림을 주입합니다. +- `"off"`: 잘림 알림 텍스트를 시스템 프롬프트에 절대 주입하지 않습니다. +- `"once"`: 고유한 잘림 시그니처마다 간결한 알림을 한 번 주입합니다(권장). +- `"always"`: 잘림이 있으면 매 실행마다 간결한 알림을 주입합니다. -상세한 원본/주입 카운트와 구성 튜닝 필드는 컨텍스트/상태 보고서 및 로그 같은 진단 정보에 남습니다. 일반적인 WebChat 사용자/런타임 컨텍스트에는 간결한 복구 알림만 제공됩니다. +상세한 원시/주입 카운트와 구성 조정 필드는 컨텍스트/상태 보고서 및 로그 같은 진단 정보에 남습니다. 일반적인 웹 채팅 사용자/런타임 컨텍스트에는 간결한 복구 알림만 제공됩니다. ```json5 { @@ -136,19 +138,19 @@ x-i18n: ### 컨텍스트 예산 소유권 맵 -OpenClaw에는 여러 개의 대용량 프롬프트/컨텍스트 예산이 있으며, 이들은 하나의 일반 노브를 모두 거치지 않고 의도적으로 하위 시스템별로 분리되어 있습니다. +OpenClaw에는 대용량 프롬프트/컨텍스트 예산이 여러 개 있으며, 이들은 하나의 일반 노브를 모두 통과하지 않고 하위 시스템별로 의도적으로 분리되어 있습니다. - `agents.defaults.bootstrapMaxChars` / `agents.defaults.bootstrapTotalMaxChars`: - 일반 워크스페이스 부트스트랩 주입. + 일반 워크스페이스 부트스트랩 주입입니다. - `agents.defaults.startupContext.*`: - 최근 일일 `memory/*.md` 파일을 포함한 일회성 재설정/시작 모델 실행 프렐류드입니다. 단순 채팅 `/new` 및 `/reset` 명령은 모델을 호출하지 않고 확인만 합니다. + 최근 일일 `memory/*.md` 파일을 포함하는 일회성 재설정/시작 모델 실행 프렐류드입니다. 베어 채팅 `/new` 및 `/reset` 명령은 모델을 호출하지 않고 확인됩니다. - `skills.limits.*`: - 시스템 프롬프트에 주입되는 압축된 Skills 목록. + 시스템 프롬프트에 주입되는 압축된 Skills 목록입니다. - `agents.defaults.contextLimits.*`: - 제한된 런타임 발췌 및 주입된 런타임 소유 블록. + 제한된 런타임 발췌와 런타임 소유 주입 블록입니다. - `memory.qmd.limits.*`: - 인덱싱된 메모리 검색 스니펫 및 주입 크기. + 인덱싱된 메모리 검색 스니펫 및 주입 크기입니다. 한 에이전트에 다른 예산이 필요할 때만 일치하는 에이전트별 재정의를 사용하세요. @@ -157,7 +159,8 @@ OpenClaw에는 여러 개의 대용량 프롬프트/컨텍스트 예산이 있 #### `agents.defaults.startupContext` -재설정/시작 모델 실행에서 첫 번째 턴 시작 프렐류드 주입을 제어합니다. 단순 채팅 `/new` 및 `/reset` 명령은 모델을 호출하지 않고 재설정을 확인하므로 이 프렐류드를 로드하지 않습니다. +재설정/시작 모델 실행에서 첫 턴 시작 프렐류드 주입을 제어합니다. +베어 채팅 `/new` 및 `/reset` 명령은 모델을 호출하지 않고 재설정을 확인하므로 이 프렐류드를 로드하지 않습니다. ```json5 { @@ -178,7 +181,7 @@ OpenClaw에는 여러 개의 대용량 프롬프트/컨텍스트 예산이 있 #### `agents.defaults.contextLimits` -제한된 런타임 컨텍스트 표면의 공유 기본값입니다. +제한된 런타임 컨텍스트 표면에 대한 공유 기본값입니다. ```json5 { @@ -195,10 +198,10 @@ OpenClaw에는 여러 개의 대용량 프롬프트/컨텍스트 예산이 있 } ``` -- `memoryGetMaxChars`: 자르기 메타데이터와 이어가기 알림이 추가되기 전 기본 `memory_get` 발췌 상한입니다. -- `memoryGetDefaultLines`: `lines`가 생략되었을 때 기본 `memory_get` 줄 창입니다. -- `toolResultMaxChars`: 지속된 결과와 오버플로 복구에 사용되는 라이브 도구 결과 상한입니다. -- `postCompactionMaxChars`: Compaction 이후 새로고침 주입 중 사용되는 AGENTS.md 발췌 상한입니다. +- `memoryGetMaxChars`: 잘림 메타데이터와 이어가기 알림이 추가되기 전 기본 `memory_get` 발췌 상한입니다. +- `memoryGetDefaultLines`: `lines`가 생략될 때 기본 `memory_get` 줄 창입니다. +- `toolResultMaxChars`: 유지된 결과와 오버플로 복구에 사용되는 라이브 도구 결과 상한입니다. +- `postCompactionMaxChars`: Compaction 후 새로 고침 주입 중 사용되는 AGENTS.md 발췌 상한입니다. #### `agents.list[].contextLimits` @@ -228,7 +231,7 @@ OpenClaw에는 여러 개의 대용량 프롬프트/컨텍스트 예산이 있 #### `skills.limits.maxSkillsPromptChars` -시스템 프롬프트에 주입되는 압축된 Skills 목록의 전역 상한입니다. 이는 필요할 때 `SKILL.md` 파일을 읽는 동작에는 영향을 주지 않습니다. +시스템 프롬프트에 주입되는 압축된 Skills 목록의 전역 상한입니다. 이는 요청 시 `SKILL.md` 파일을 읽는 데 영향을 주지 않습니다. ```json5 { @@ -261,11 +264,11 @@ Skills 프롬프트 예산에 대한 에이전트별 재정의입니다. ### `agents.defaults.imageMaxDimensionPx` -제공자 호출 전 트랜스크립트/도구 이미지 블록에서 이미지의 가장 긴 변에 대한 최대 픽셀 크기입니다. +제공자 호출 전 대화 기록/도구 이미지 블록에서 가장 긴 이미지 변의 최대 픽셀 크기입니다. 기본값: `1200`. -값을 낮추면 보통 스크린샷이 많은 실행에서 비전 토큰 사용량과 요청 페이로드 크기가 줄어듭니다. -값을 높이면 더 많은 시각적 세부 정보를 보존합니다. +낮은 값은 보통 스크린샷이 많은 실행에서 비전 토큰 사용량과 요청 페이로드 크기를 줄입니다. +높은 값은 더 많은 시각적 디테일을 보존합니다. ```json5 { @@ -275,7 +278,7 @@ Skills 프롬프트 예산에 대한 에이전트별 재정의입니다. ### `agents.defaults.userTimezone` -시스템 프롬프트 컨텍스트의 시간대입니다(메시지 타임스탬프 아님). 호스트 시간대로 대체됩니다. +시스템 프롬프트 컨텍스트의 시간대입니다(메시지 타임스탬프가 아님). 호스트 시간대로 대체됩니다. ```json5 { @@ -285,7 +288,7 @@ Skills 프롬프트 예산에 대한 에이전트별 재정의입니다. ### `agents.defaults.timeFormat` -시스템 프롬프트의 시간 형식입니다. 기본값: `auto`(OS 기본 설정). +시스템 프롬프트의 시간 형식입니다. 기본값: `auto`(OS 환경설정). ```json5 { @@ -345,57 +348,57 @@ Skills 프롬프트 예산에 대한 에이전트별 재정의입니다. - `model`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 허용합니다. - 문자열 형식은 기본 모델만 설정합니다. - - 객체 형식은 기본 모델과 순서가 있는 장애 조치 모델을 설정합니다. + - 객체 형식은 기본 모델과 순서가 지정된 장애 조치 모델을 함께 설정합니다. - `imageModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 허용합니다. - `image` 도구 경로에서 비전 모델 구성으로 사용됩니다. - 선택된/기본 모델이 이미지 입력을 받을 수 없을 때 대체 라우팅에도 사용됩니다. - - 명시적 `provider/model` 참조를 권장합니다. 호환성을 위해 접두사 없는 ID도 허용됩니다. 접두사 없는 ID가 `models.providers.*.models`에서 구성된 이미지 지원 항목 하나와 고유하게 일치하면 OpenClaw가 해당 제공자로 한정합니다. 구성된 일치 항목이 모호하면 명시적 제공자 접두사가 필요합니다. + - 명시적인 `provider/model` 참조를 권장합니다. 호환성을 위해 bare ID도 허용됩니다. bare ID가 `models.providers.*.models`에 구성된 이미지 지원 항목과 유일하게 일치하면 OpenClaw가 해당 제공자로 한정합니다. 구성된 일치 항목이 모호한 경우 명시적인 제공자 접두사가 필요합니다. - `imageGenerationModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 허용합니다. - 공유 이미지 생성 기능과 이미지를 생성하는 향후 도구/Plugin 표면에서 사용됩니다. - 일반적인 값: 네이티브 Gemini 이미지 생성용 `google/gemini-3.1-flash-image-preview`, fal용 `fal/fal-ai/flux/dev`, OpenAI Images용 `openai/gpt-image-2`, 또는 투명 배경 OpenAI PNG/WebP 출력용 `openai/gpt-image-1.5`. - - 제공자/모델을 직접 선택하는 경우 일치하는 제공자 인증도 구성하세요(예: `google/*`용 `GEMINI_API_KEY` 또는 `GOOGLE_API_KEY`, `openai/gpt-image-2` / `openai/gpt-image-1.5`용 `OPENAI_API_KEY` 또는 OpenAI Codex OAuth, `fal/*`용 `FAL_KEY`). - - 생략하면 `image_generate`가 인증이 지원되는 제공자 기본값을 여전히 추론할 수 있습니다. 먼저 현재 기본 제공자를 시도한 다음, 나머지 등록된 이미지 생성 제공자를 제공자 ID 순서로 시도합니다. + - 제공자/모델을 직접 선택하는 경우 일치하는 제공자 인증도 구성하세요(예: `google/*`에는 `GEMINI_API_KEY` 또는 `GOOGLE_API_KEY`, `openai/gpt-image-2` / `openai/gpt-image-1.5`에는 `OPENAI_API_KEY` 또는 OpenAI Codex OAuth, `fal/*`에는 `FAL_KEY`). + - 생략하면 `image_generate`가 인증 기반 제공자 기본값을 여전히 추론할 수 있습니다. 현재 기본 제공자를 먼저 시도한 뒤, 남은 등록된 이미지 생성 제공자를 제공자 ID 순서대로 시도합니다. - `musicGenerationModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 허용합니다. - - 공유 음악 생성 기능과 기본 제공 `music_generate` 도구에서 사용됩니다. + - 공유 음악 생성 기능과 내장 `music_generate` 도구에서 사용됩니다. - 일반적인 값: `google/lyria-3-clip-preview`, `google/lyria-3-pro-preview`, 또는 `minimax/music-2.6`. - - 생략하면 `music_generate`가 인증이 지원되는 제공자 기본값을 여전히 추론할 수 있습니다. 먼저 현재 기본 제공자를 시도한 다음, 나머지 등록된 음악 생성 제공자를 제공자 ID 순서로 시도합니다. + - 생략하면 `music_generate`가 인증 기반 제공자 기본값을 여전히 추론할 수 있습니다. 현재 기본 제공자를 먼저 시도한 뒤, 남은 등록된 음악 생성 제공자를 제공자 ID 순서대로 시도합니다. - 제공자/모델을 직접 선택하는 경우 일치하는 제공자 인증/API 키도 구성하세요. - `videoGenerationModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 허용합니다. - - 공유 비디오 생성 기능과 기본 제공 `video_generate` 도구에서 사용됩니다. + - 공유 동영상 생성 기능과 내장 `video_generate` 도구에서 사용됩니다. - 일반적인 값: `qwen/wan2.6-t2v`, `qwen/wan2.6-i2v`, `qwen/wan2.6-r2v`, `qwen/wan2.6-r2v-flash`, 또는 `qwen/wan2.7-r2v`. - - 생략하면 `video_generate`가 인증이 지원되는 제공자 기본값을 여전히 추론할 수 있습니다. 먼저 현재 기본 제공자를 시도한 다음, 나머지 등록된 비디오 생성 제공자를 제공자 ID 순서로 시도합니다. + - 생략하면 `video_generate`가 인증 기반 제공자 기본값을 여전히 추론할 수 있습니다. 현재 기본 제공자를 먼저 시도한 뒤, 남은 등록된 동영상 생성 제공자를 제공자 ID 순서대로 시도합니다. - 제공자/모델을 직접 선택하는 경우 일치하는 제공자 인증/API 키도 구성하세요. - - 번들 Qwen 비디오 생성 제공자는 출력 비디오 최대 1개, 입력 이미지 1개, 입력 비디오 4개, 10초 길이, 그리고 제공자 수준 `size`, `aspectRatio`, `resolution`, `audio`, `watermark` 옵션을 지원합니다. + - 번들 Qwen 동영상 생성 제공자는 최대 출력 동영상 1개, 입력 이미지 1개, 입력 동영상 4개, 10초 길이, 그리고 제공자 수준의 `size`, `aspectRatio`, `resolution`, `audio`, `watermark` 옵션을 지원합니다. - `pdfModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 허용합니다. - `pdf` 도구에서 모델 라우팅에 사용됩니다. - - 생략하면 PDF 도구는 `imageModel`로 대체하고, 그다음 해석된 세션/기본 모델로 대체합니다. -- `pdfMaxBytesMb`: 호출 시 `maxBytesMb`가 전달되지 않은 경우 `pdf` 도구의 기본 PDF 크기 제한입니다. -- `pdfMaxPages`: `pdf` 도구의 추출 대체 모드에서 고려되는 기본 최대 페이지 수입니다. -- `verboseDefault`: 에이전트의 기본 자세한 출력 수준입니다. 값: `"off"`, `"on"`, `"full"`. 기본값: `"off"`. -- `toolProgressDetail`: `/verbose` 도구 요약과 진행 초안 도구 줄의 세부 모드입니다. 값: `"explain"`(기본값, 간결한 사람이 읽기 쉬운 레이블) 또는 `"raw"`(사용 가능한 경우 원시 명령/세부 정보 추가). 에이전트별 `agents.list[].toolProgressDetail`은 이 기본값을 재정의합니다. -- `reasoningDefault`: 에이전트의 기본 추론 표시 여부입니다. 값: `"off"`, `"on"`, `"stream"`. 에이전트별 `agents.list[].reasoningDefault`는 이 기본값을 재정의합니다. 구성된 추론 기본값은 메시지별 또는 세션 추론 재정의가 설정되지 않은 경우에만 소유자, 승인된 발신자, 또는 운영자 관리자 Gateway 컨텍스트에 적용됩니다. -- `elevatedDefault`: 에이전트의 기본 승격 출력 수준입니다. 값: `"off"`, `"on"`, `"ask"`, `"full"`. 기본값: `"on"`. -- `model.primary`: 형식은 `provider/model`입니다(예: API 키 액세스용 `openai/gpt-5.5` 또는 Codex OAuth용 `openai-codex/gpt-5.5`). 제공자를 생략하면 OpenClaw는 먼저 별칭을 시도하고, 그다음 정확한 모델 ID에 대한 고유한 구성 제공자 일치를 시도하며, 그 후에야 구성된 기본 제공자로 대체합니다(더 이상 권장되지 않는 호환성 동작이므로 명시적 `provider/model`을 권장합니다). 해당 제공자가 구성된 기본 모델을 더 이상 노출하지 않으면 OpenClaw는 오래된 제거된 제공자 기본값을 표시하는 대신 첫 번째로 구성된 제공자/모델로 대체합니다. -- `models`: `/model`의 구성된 모델 카탈로그 및 허용 목록입니다. 각 항목에는 `alias`(바로가기)와 `params`(제공자별, 예: `temperature`, `maxTokens`, `cacheRetention`, `context1m`, `responsesServerCompaction`, `responsesCompactThreshold`, `chat_template_kwargs`, `extra_body`/`extraBody`)를 포함할 수 있습니다. - - 안전한 편집: 항목을 추가하려면 `openclaw config set agents.defaults.models '' --strict-json --merge`를 사용하세요. `config set`은 `--replace`를 전달하지 않는 한 기존 허용 목록 항목을 제거하는 교체를 거부합니다. - - 제공자 범위 구성/온보딩 흐름은 선택한 제공자 모델을 이 맵에 병합하고 이미 구성된 관련 없는 제공자는 보존합니다. - - 직접 OpenAI Responses 모델의 경우 서버 측 Compaction이 자동으로 활성화됩니다. `context_management` 삽입을 중단하려면 `params.responsesServerCompaction: false`를 사용하거나, 임계값을 재정의하려면 `params.responsesCompactThreshold`를 사용하세요. [OpenAI 서버 측 Compaction](/ko/providers/openai#server-side-compaction-responses-api)을 참고하세요. + - 생략하면 PDF 도구가 `imageModel`로 대체하고, 그다음 해석된 세션/기본 모델로 대체합니다. +- `pdfMaxBytesMb`: 호출 시 `maxBytesMb`가 전달되지 않았을 때 `pdf` 도구의 기본 PDF 크기 제한입니다. +- `pdfMaxPages`: `pdf` 도구의 추출 대체 모드에서 고려하는 기본 최대 페이지 수입니다. +- `verboseDefault`: 에이전트의 기본 verbose 수준입니다. 값: `"off"`, `"on"`, `"full"`. 기본값: `"off"`. +- `toolProgressDetail`: `/verbose` 도구 요약과 진행 초안 도구 줄의 세부 모드입니다. 값: `"explain"`(기본값, 간결한 사람이 읽기 쉬운 레이블) 또는 `"raw"`(사용 가능한 경우 원시 명령/세부 정보 추가). 에이전트별 `agents.list[].toolProgressDetail`이 이 기본값을 재정의합니다. +- `reasoningDefault`: 에이전트의 기본 추론 표시 여부입니다. 값: `"off"`, `"on"`, `"stream"`. 에이전트별 `agents.list[].reasoningDefault`가 이 기본값을 재정의합니다. 구성된 추론 기본값은 메시지별 또는 세션 추론 재정의가 설정되지 않은 경우에만 소유자, 승인된 발신자 또는 운영자 관리자 Gateway 컨텍스트에 적용됩니다. +- `elevatedDefault`: 에이전트의 기본 elevated-output 수준입니다. 값: `"off"`, `"on"`, `"ask"`, `"full"`. 기본값: `"on"`. +- `model.primary`: 형식은 `provider/model`입니다(예: API 키 액세스용 `openai/gpt-5.5` 또는 Codex OAuth용 `openai-codex/gpt-5.5`). 제공자를 생략하면 OpenClaw는 먼저 별칭을 시도한 뒤, 해당 정확한 모델 ID에 대해 유일하게 구성된 제공자 일치를 시도하고, 그다음에야 구성된 기본 제공자로 대체합니다(사용 중단된 호환성 동작이므로 명시적인 `provider/model`을 권장). 해당 제공자가 구성된 기본 모델을 더 이상 노출하지 않으면 OpenClaw는 오래되어 제거된 제공자 기본값을 드러내는 대신 첫 번째로 구성된 제공자/모델로 대체합니다. +- `models`: `/model`에 대해 구성된 모델 카탈로그와 허용 목록입니다. 각 항목에는 `alias`(바로가기)와 `params`(제공자별, 예: `temperature`, `maxTokens`, `cacheRetention`, `context1m`, `responsesServerCompaction`, `responsesCompactThreshold`, `chat_template_kwargs`, `extra_body`/`extraBody`)를 포함할 수 있습니다. + - 안전한 편집: 항목을 추가하려면 `openclaw config set agents.defaults.models '' --strict-json --merge`를 사용하세요. `config set`은 `--replace`를 전달하지 않는 한 기존 허용 목록 항목을 제거하는 대체를 거부합니다. + - 제공자 범위 구성/온보딩 흐름은 선택된 제공자 모델을 이 맵에 병합하고 이미 구성된 관련 없는 제공자를 보존합니다. + - 직접 OpenAI Responses 모델의 경우 서버 측 Compaction이 자동으로 활성화됩니다. `context_management` 주입을 중지하려면 `params.responsesServerCompaction: false`를 사용하거나, 임계값을 재정의하려면 `params.responsesCompactThreshold`를 사용하세요. [OpenAI 서버 측 Compaction](/ko/providers/openai#server-side-compaction-responses-api)을 참조하세요. - `params`: 모든 모델에 적용되는 전역 기본 제공자 매개변수입니다. `agents.defaults.params`에서 설정합니다(예: `{ cacheRetention: "long" }`). -- `params` 병합 우선순위(구성): `agents.defaults.params`(전역 기반)는 `agents.defaults.models["provider/model"].params`(모델별)로 재정의되고, 그다음 `agents.list[].params`(일치하는 에이전트 ID)가 키별로 재정의합니다. 자세한 내용은 [프롬프트 캐싱](/ko/reference/prompt-caching)을 참고하세요. -- `params.extra_body`/`params.extraBody`: OpenAI 호환 프록시를 위해 `api: "openai-completions"` 요청 본문에 병합되는 고급 패스스루 JSON입니다. 생성된 요청 키와 충돌하면 추가 본문이 우선합니다. 네이티브가 아닌 completions 경로는 이후에도 OpenAI 전용 `store`를 제거합니다. -- `params.chat_template_kwargs`: 최상위 `api: "openai-completions"` 요청 본문에 병합되는 vLLM/OpenAI 호환 채팅 템플릿 인수입니다. 사고가 꺼진 `vllm/nemotron-3-*`의 경우 번들 vLLM Plugin이 자동으로 `enable_thinking: false`와 `force_nonempty_content: true`를 보냅니다. 명시적 `chat_template_kwargs`는 생성된 기본값을 재정의하고, `extra_body.chat_template_kwargs`는 여전히 최종 우선순위를 가집니다. vLLM Qwen 사고 제어의 경우 해당 모델 항목에서 `params.qwenThinkingFormat`을 `"chat-template"` 또는 `"top-level"`로 설정하세요. -- `compat.supportedReasoningEfforts`: 모델별 OpenAI 호환 추론 노력 수준 목록입니다. 이를 실제로 허용하는 사용자 지정 엔드포인트에는 `"xhigh"`를 포함하세요. 그러면 OpenClaw는 해당 구성된 제공자/모델에 대해 명령 메뉴, Gateway 세션 행, 세션 패치 검증, 에이전트 CLI 검증, `llm-task` 검증에서 `/think xhigh`를 노출합니다. 백엔드가 표준 수준에 대해 제공자별 값을 원하는 경우 `compat.reasoningEffortMap`을 사용하세요. -- `params.preserveThinking`: 보존된 사고를 위한 Z.AI 전용 옵트인입니다. 활성화되고 사고가 켜져 있으면 OpenClaw는 `thinking.clear_thinking: false`를 보내고 이전 `reasoning_content`를 다시 재생합니다. [Z.AI 사고 및 보존된 사고](/ko/providers/zai#thinking-and-preserved-thinking)를 참고하세요. -- `agentRuntime`: 기본 저수준 에이전트 런타임 정책입니다. 생략된 ID는 기본적으로 OpenClaw Pi가 됩니다. 기본 제공 PI 하네스를 강제하려면 `id: "pi"`를 사용하고, 등록된 Plugin 하네스가 지원 모델을 클레임하고 일치하는 항목이 없을 때 PI를 사용하게 하려면 `id: "auto"`를 사용하며, 해당 하네스를 요구하려면 `id: "codex"` 같은 등록된 하네스 ID를 사용하거나, `id: "claude-cli"` 같은 지원되는 CLI 백엔드 별칭을 사용하세요. 명시적 Plugin 런타임은 하네스를 사용할 수 없거나 실패하면 닫힌 상태로 실패합니다. 모델 참조는 `provider/model`로 정규화된 형식을 유지하세요. 레거시 런타임 제공자 접두사 대신 런타임 구성을 통해 Codex, Claude CLI, Gemini CLI 및 기타 실행 백엔드를 선택하세요. 이것이 제공자/모델 선택과 어떻게 다른지는 [에이전트 런타임](/ko/concepts/agent-runtimes)을 참고하세요. -- 이 필드를 변경하는 구성 작성기(예: `/models set`, `/models set-image`, 대체 추가/제거 명령)는 정규 객체 형식으로 저장하고 가능한 경우 기존 대체 목록을 보존합니다. -- `maxConcurrent`: 세션 전체에서 병렬 에이전트 실행의 최대 수입니다(각 세션은 여전히 직렬화됩니다). 기본값: 4. +- `params` 병합 우선순위(구성): `agents.defaults.params`(전역 기준)는 `agents.defaults.models["provider/model"].params`(모델별)에 의해 재정의되고, 그다음 `agents.list[].params`(일치하는 에이전트 ID)가 키별로 재정의합니다. 자세한 내용은 [프롬프트 캐싱](/ko/reference/prompt-caching)을 참조하세요. +- `params.extra_body`/`params.extraBody`: OpenAI 호환 프록시의 `api: "openai-completions"` 요청 본문에 병합되는 고급 pass-through JSON입니다. 생성된 요청 키와 충돌하면 extra body가 우선합니다. 비네이티브 completions 경로는 이후에도 OpenAI 전용 `store`를 제거합니다. +- `params.chat_template_kwargs`: 최상위 `api: "openai-completions"` 요청 본문에 병합되는 vLLM/OpenAI 호환 채팅 템플릿 인수입니다. thinking이 꺼진 `vllm/nemotron-3-*`의 경우, 번들 vLLM Plugin은 자동으로 `enable_thinking: false`와 `force_nonempty_content: true`를 보냅니다. 명시적인 `chat_template_kwargs`는 생성된 기본값을 재정의하고, `extra_body.chat_template_kwargs`는 여전히 최종 우선순위를 가집니다. vLLM Qwen thinking 제어의 경우 해당 모델 항목에서 `params.qwenThinkingFormat`을 `"chat-template"` 또는 `"top-level"`로 설정하세요. +- `compat.supportedReasoningEfforts`: 모델별 OpenAI 호환 추론 노력 목록입니다. 실제로 이를 허용하는 사용자 지정 엔드포인트에는 `"xhigh"`를 포함하세요. 그러면 OpenClaw가 구성된 해당 제공자/모델에 대해 명령 메뉴, Gateway 세션 행, 세션 패치 검증, 에이전트 CLI 검증, `llm-task` 검증에서 `/think xhigh`를 노출합니다. 백엔드가 정규 수준에 대해 제공자별 값을 원할 때는 `compat.reasoningEffortMap`을 사용하세요. +- `params.preserveThinking`: 보존된 thinking을 위한 Z.AI 전용 옵트인입니다. 활성화되고 thinking이 켜져 있으면 OpenClaw는 `thinking.clear_thinking: false`를 보내고 이전 `reasoning_content`를 재생합니다. [Z.AI thinking과 보존된 thinking](/ko/providers/zai#thinking-and-preserved-thinking)을 참조하세요. +- `agentRuntime`: 기본 저수준 에이전트 런타임 정책입니다. 생략된 ID는 기본적으로 OpenClaw Pi가 됩니다. 내장 PI 하네스를 강제하려면 `id: "pi"`를 사용하고, 등록된 Plugin 하네스가 지원되는 모델을 클레임하게 하되 일치 항목이 없을 때 PI를 사용하려면 `id: "auto"`를 사용하고, 해당 하네스를 요구하려면 `id: "codex"` 같은 등록된 하네스 ID를 사용하거나, `id: "claude-cli"` 같은 지원되는 CLI 백엔드 별칭을 사용하세요. 명시적인 Plugin 런타임은 하네스를 사용할 수 없거나 실패하면 닫힌 상태로 실패합니다. 모델 참조는 `provider/model`로 정규화해 유지하세요. 레거시 런타임 제공자 접두사 대신 런타임 구성을 통해 Codex, Claude CLI, Gemini CLI 및 기타 실행 백엔드를 선택하세요. 이것이 제공자/모델 선택과 어떻게 다른지는 [에이전트 런타임](/ko/concepts/agent-runtimes)을 참조하세요. +- 이 필드를 변경하는 구성 작성기(예: `/models set`, `/models set-image`, fallback 추가/제거 명령)는 정규 객체 형식으로 저장하고 가능한 경우 기존 fallback 목록을 보존합니다. +- `maxConcurrent`: 세션 전체의 최대 병렬 에이전트 실행 수입니다(각 세션은 여전히 직렬화됨). 기본값: 4. ### `agents.defaults.agentRuntime` `agentRuntime`은 에이전트 턴을 실행하는 저수준 실행기를 제어합니다. 대부분의 -배포에서는 기본 OpenClaw Pi 런타임을 유지해야 합니다. 번들 Codex 앱 서버 하네스처럼 신뢰할 수 있는 -Plugin이 네이티브 하네스를 제공하거나, Claude CLI 같은 지원되는 CLI 백엔드를 사용하려는 경우 사용하세요. 개념적 -모델은 [에이전트 런타임](/ko/concepts/agent-runtimes)을 참고하세요. +배포는 기본 OpenClaw Pi 런타임을 유지해야 합니다. 번들 Codex 앱 서버 하네스처럼 신뢰할 수 있는 +Plugin이 네이티브 하네스를 제공하거나 Claude CLI 같은 지원되는 CLI 백엔드를 원할 때 사용하세요. 개념 +모델은 [에이전트 런타임](/ko/concepts/agent-runtimes)을 참조하세요. ```json5 { @@ -411,15 +414,15 @@ Plugin이 네이티브 하네스를 제공하거나, Claude CLI 같은 지원되 ``` - `id`: `"auto"`, `"pi"`, 등록된 Plugin 하네스 ID, 또는 지원되는 CLI 백엔드 별칭입니다. 번들 Codex Plugin은 `codex`를 등록하고, 번들 Anthropic Plugin은 `claude-cli` CLI 백엔드를 제공합니다. -- `id: "auto"`는 등록된 Plugin 하네스가 지원되는 턴을 클레임하게 하고 일치하는 하네스가 없으면 PI를 사용합니다. `id: "codex"` 같은 명시적 Plugin 런타임은 해당 하네스를 요구하며, 사용할 수 없거나 실패하면 닫힌 상태로 실패합니다. +- `id: "auto"`는 등록된 Plugin 하네스가 지원되는 턴을 클레임하게 하고 일치하는 하네스가 없을 때 PI를 사용합니다. `id: "codex"` 같은 명시적인 Plugin 런타임은 해당 하네스를 요구하며, 사용할 수 없거나 실패하면 닫힌 상태로 실패합니다. - 환경 재정의: `OPENCLAW_AGENT_RUNTIME=`는 해당 프로세스의 `id`를 재정의합니다. - Codex 전용 배포의 경우 `model: "openai/gpt-5.5"`와 `agentRuntime.id: "codex"`를 설정하세요. - Claude CLI 배포의 경우 `model: "anthropic/claude-opus-4-7"`와 `agentRuntime.id: "claude-cli"`를 권장합니다. 레거시 `claude-cli/claude-opus-4-7` 모델 참조도 호환성을 위해 계속 작동하지만, 새 구성은 제공자/모델 선택을 정규 형식으로 유지하고 실행 백엔드를 `agentRuntime.id`에 넣어야 합니다. - 이전 런타임 정책 키는 `openclaw doctor --fix`에 의해 `agentRuntime`으로 다시 작성됩니다. -- 하네스 선택은 첫 번째 임베디드 실행 이후 세션 ID별로 고정됩니다. 구성/env 변경은 새 세션 또는 재설정된 세션에 영향을 주며, 기존 트랜스크립트에는 영향을 주지 않습니다. 트랜스크립트 기록은 있지만 기록된 고정값이 없는 레거시 세션은 PI 고정으로 처리됩니다. `/status`는 유효 런타임을 보고합니다. 예: `Runtime: OpenClaw Pi Default` 또는 `Runtime: OpenAI Codex`. -- 이는 텍스트 에이전트 턴 실행만 제어합니다. 미디어 생성, 비전, PDF, 음악, 비디오, TTS는 여전히 해당 제공자/모델 설정을 사용합니다. +- 하네스 선택은 첫 번째 임베디드 실행 후 세션 ID별로 고정됩니다. 구성/env 변경은 기존 transcript가 아니라 새 세션 또는 재설정된 세션에 영향을 줍니다. transcript 기록은 있지만 기록된 pin이 없는 레거시 세션은 PI에 고정된 것으로 처리됩니다. `/status`는 유효 런타임을 보고합니다. 예: `Runtime: OpenClaw Pi Default` 또는 `Runtime: OpenAI Codex`. +- 이는 텍스트 에이전트 턴 실행만 제어합니다. 미디어 생성, 비전, PDF, 음악, 동영상, TTS는 계속 해당 제공자/모델 설정을 사용합니다. -**기본 제공 별칭 축약형**(`agents.defaults.models`에 모델이 있을 때만 적용): +**내장 별칭 약어**(`agents.defaults.models`에 모델이 있을 때만 적용): | 별칭 | 모델 | | ------------------- | ------------------------------------------ | @@ -432,15 +435,15 @@ Plugin이 네이티브 하네스를 제공하거나, Claude CLI 같은 지원되 | `gemini-flash` | `google/gemini-3-flash-preview` | | `gemini-flash-lite` | `google/gemini-3.1-flash-lite-preview` | -구성된 별칭은 항상 기본값보다 우선합니다. +구성한 별칭은 항상 기본값보다 우선합니다. Z.AI GLM-4.x 모델은 `--thinking off`를 설정하거나 `agents.defaults.models["zai/"].params.thinking`을 직접 정의하지 않는 한 thinking 모드를 자동으로 활성화합니다. Z.AI 모델은 도구 호출 스트리밍을 위해 기본적으로 `tool_stream`을 활성화합니다. 비활성화하려면 `agents.defaults.models["zai/"].params.tool_stream`을 `false`로 설정하세요. -Anthropic Claude 4.6 모델은 명시적인 thinking 수준이 설정되지 않은 경우 기본적으로 `adaptive` thinking을 사용합니다. +Anthropic Claude 4.6 모델은 명시적인 thinking 수준이 설정되지 않은 경우 기본값으로 `adaptive` thinking을 사용합니다. ### `agents.defaults.cliBackends` -텍스트 전용 폴백 실행을 위한 선택적 CLI 백엔드입니다(도구 호출 없음). API 제공자가 실패할 때 백업으로 유용합니다. +텍스트 전용 대체 실행을 위한 선택적 CLI 백엔드입니다(도구 호출 없음). API 제공자가 실패할 때 백업으로 유용합니다. ```json5 { @@ -469,13 +472,13 @@ Anthropic Claude 4.6 모델은 명시적인 thinking 수준이 설정되지 않 } ``` -- CLI 백엔드는 텍스트 우선입니다. 도구는 항상 비활성화됩니다. -- `sessionArg`가 설정된 경우 세션이 지원됩니다. -- `imageArg`가 파일 경로를 허용하는 경우 이미지 전달이 지원됩니다. +- CLI 백엔드는 텍스트 우선이며, 도구는 항상 비활성화됩니다. +- `sessionArg`가 설정되어 있으면 세션이 지원됩니다. +- `imageArg`가 파일 경로를 허용하면 이미지 패스스루가 지원됩니다. ### `agents.defaults.systemPromptOverride` -OpenClaw가 조립한 전체 시스템 프롬프트를 고정 문자열로 대체합니다. 기본 수준(`agents.defaults.systemPromptOverride`) 또는 에이전트별(`agents.list[].systemPromptOverride`)로 설정하세요. 에이전트별 값이 우선합니다. 비어 있거나 공백뿐인 값은 무시됩니다. 제어된 프롬프트 실험에 유용합니다. +OpenClaw가 조립한 전체 시스템 프롬프트를 고정 문자열로 대체합니다. 기본 수준(`agents.defaults.systemPromptOverride`) 또는 에이전트별(`agents.list[].systemPromptOverride`)로 설정하세요. 에이전트별 값이 우선합니다. 비어 있거나 공백만 있는 값은 무시됩니다. 제어된 프롬프트 실험에 유용합니다. ```json5 { @@ -489,7 +492,7 @@ OpenClaw가 조립한 전체 시스템 프롬프트를 고정 문자열로 대 ### `agents.defaults.promptOverlays` -모델 계열별로 적용되는 제공자 독립 프롬프트 오버레이입니다. GPT-5 계열 모델 ID는 제공자 전반에서 공유 동작 계약을 받습니다. `personality`는 친근한 상호작용 스타일 계층만 제어합니다. +모델 패밀리별로 적용되는 제공자 독립 프롬프트 오버레이입니다. GPT-5 패밀리 모델 ID는 제공자 전반에서 공유 동작 계약을 받으며, `personality`는 친근한 상호작용 스타일 레이어만 제어합니다. ```json5 { @@ -505,9 +508,9 @@ OpenClaw가 조립한 전체 시스템 프롬프트를 고정 문자열로 대 } ``` -- `"friendly"`(기본값)와 `"on"`은 친근한 상호작용 스타일 계층을 활성화합니다. -- `"off"`는 친근한 계층만 비활성화합니다. 태그가 지정된 GPT-5 동작 계약은 계속 활성화됩니다. -- 이 공유 설정이 지정되지 않은 경우 기존 `plugins.entries.openai.config.personality`도 계속 읽습니다. +- `"friendly"`(기본값)와 `"on"`은 친근한 상호작용 스타일 레이어를 활성화합니다. +- `"off"`는 친근한 레이어만 비활성화하며, 태그가 지정된 GPT-5 동작 계약은 계속 활성화됩니다. +- 공유 설정이 설정되지 않은 경우 기존 `plugins.entries.openai.config.personality`도 계속 읽습니다. ### `agents.defaults.heartbeat` @@ -539,16 +542,16 @@ OpenClaw가 조립한 전체 시스템 프롬프트를 고정 문자열로 대 } ``` -- `every`: 기간 문자열(ms/s/m/h)입니다. 기본값은 `30m`(API 키 인증) 또는 `1h`(OAuth 인증)입니다. 비활성화하려면 `0m`으로 설정하세요. -- `includeSystemPromptSection`: false이면 시스템 프롬프트에서 Heartbeat 섹션을 생략하고 부트스트랩 컨텍스트에 `HEARTBEAT.md`를 주입하지 않습니다. 기본값은 `true`입니다. +- `every`: 기간 문자열(ms/s/m/h)입니다. 기본값: `30m`(API 키 인증) 또는 `1h`(OAuth 인증). 비활성화하려면 `0m`으로 설정하세요. +- `includeSystemPromptSection`: false이면 시스템 프롬프트에서 Heartbeat 섹션을 생략하고 부트스트랩 컨텍스트에 `HEARTBEAT.md`를 주입하지 않습니다. 기본값: `true`. - `suppressToolErrorWarnings`: true이면 Heartbeat 실행 중 도구 오류 경고 페이로드를 억제합니다. -- `timeoutSeconds`: Heartbeat 에이전트 턴이 중단되기 전까지 허용되는 최대 시간(초)입니다. 설정하지 않으면 `agents.defaults.timeoutSeconds`를 사용합니다. +- `timeoutSeconds`: Heartbeat 에이전트 턴이 중단되기 전에 허용되는 최대 시간(초)입니다. 설정하지 않으면 `agents.defaults.timeoutSeconds`를 사용합니다. - `directPolicy`: 직접/DM 전달 정책입니다. `allow`(기본값)는 직접 대상 전달을 허용합니다. `block`은 직접 대상 전달을 억제하고 `reason=dm-blocked`를 내보냅니다. - `lightContext`: true이면 Heartbeat 실행은 경량 부트스트랩 컨텍스트를 사용하고 워크스페이스 부트스트랩 파일 중 `HEARTBEAT.md`만 유지합니다. -- `isolatedSession`: true이면 각 Heartbeat가 이전 대화 기록이 없는 새 세션에서 실행됩니다. cron `sessionTarget: "isolated"`와 동일한 격리 패턴입니다. Heartbeat당 토큰 비용을 약 100K에서 약 2~5K 토큰으로 줄입니다. -- `skipWhenBusy`: true이면 Heartbeat 실행이 추가 바쁜 레인, 즉 서브에이전트 또는 중첩 명령 작업에서 지연됩니다. Cron 레인은 이 플래그가 없어도 항상 Heartbeat를 지연합니다. -- 에이전트별: `agents.list[].heartbeat`를 설정하세요. 에이전트 중 하나라도 `heartbeat`를 정의하면 **해당 에이전트들만** Heartbeat를 실행합니다. -- Heartbeat는 전체 에이전트 턴을 실행합니다. 간격이 짧을수록 더 많은 토큰을 소모합니다. +- `isolatedSession`: true이면 각 Heartbeat는 이전 대화 기록이 없는 새 세션에서 실행됩니다. cron `sessionTarget: "isolated"`와 동일한 격리 패턴입니다. Heartbeat당 토큰 비용을 약 100K에서 약 2-5K 토큰으로 줄입니다. +- `skipWhenBusy`: true이면 Heartbeat 실행은 추가로 바쁜 레인, 즉 하위 에이전트 또는 중첩 명령 작업에서도 연기됩니다. 이 플래그가 없어도 Cron 레인은 항상 Heartbeat를 연기합니다. +- 에이전트별: `agents.list[].heartbeat`를 설정하세요. 어떤 에이전트든 `heartbeat`를 정의하면 **해당 에이전트만** Heartbeat를 실행합니다. +- Heartbeat는 전체 에이전트 턴을 실행하므로, 간격이 짧을수록 더 많은 토큰을 소모합니다. ### `agents.defaults.compaction` @@ -584,23 +587,23 @@ OpenClaw가 조립한 전체 시스템 프롬프트를 고정 문자열로 대 } ``` -- `mode`: `default` 또는 `safeguard`(긴 기록에 대한 청크 단위 요약)입니다. [Compaction](/ko/concepts/compaction)을 참고하세요. -- `provider`: 등록된 Compaction 제공자 Plugin의 ID입니다. 설정하면 내장 LLM 요약 대신 제공자의 `summarize()`가 호출됩니다. 실패하면 내장 방식으로 폴백합니다. 제공자를 설정하면 `mode: "safeguard"`가 강제됩니다. [Compaction](/ko/concepts/compaction)을 참고하세요. -- `timeoutSeconds`: OpenClaw가 단일 Compaction 작업을 중단하기 전까지 허용되는 최대 초입니다. 기본값은 `900`입니다. -- `keepRecentTokens`: 가장 최근 transcript 꼬리를 그대로 유지하기 위한 Pi 절단 지점 예산입니다. 수동 `/compact`는 명시적으로 설정된 경우 이를 따르며, 그렇지 않으면 수동 Compaction은 하드 체크포인트입니다. -- `identifierPolicy`: `strict`(기본값), `off` 또는 `custom`입니다. `strict`는 Compaction 요약 중 내장 불투명 식별자 보존 지침을 앞에 추가합니다. +- `mode`: `default` 또는 `safeguard`(긴 기록에 대한 청크 요약)입니다. [Compaction](/ko/concepts/compaction)을 참조하세요. +- `provider`: 등록된 Compaction 제공자 Plugin의 ID입니다. 설정하면 기본 제공 LLM 요약 대신 제공자의 `summarize()`가 호출됩니다. 실패 시 기본 제공 방식으로 폴백합니다. 제공자를 설정하면 `mode: "safeguard"`가 강제됩니다. [Compaction](/ko/concepts/compaction)을 참조하세요. +- `timeoutSeconds`: OpenClaw가 단일 Compaction 작업을 중단하기 전에 허용되는 최대 시간(초)입니다. 기본값: `900`. +- `keepRecentTokens`: 가장 최근 transcript 꼬리를 그대로 유지하기 위한 Pi 절단 지점 예산입니다. 수동 `/compact`는 명시적으로 설정된 경우 이를 준수하며, 그렇지 않으면 수동 Compaction은 하드 체크포인트입니다. +- `identifierPolicy`: `strict`(기본값), `off` 또는 `custom`입니다. `strict`는 Compaction 요약 중 기본 제공 불투명 식별자 보존 지침을 앞에 추가합니다. - `identifierInstructions`: `identifierPolicy=custom`일 때 사용되는 선택적 사용자 지정 식별자 보존 텍스트입니다. -- `qualityGuard`: safeguard 요약에 대한 잘못된 출력 재시도 검사입니다. safeguard 모드에서 기본적으로 활성화됩니다. 감사를 건너뛰려면 `enabled: false`를 설정하세요. -- `midTurnPrecheck`: 선택적 Pi 도구 루프 압력 검사입니다. `enabled: true`이면 OpenClaw는 도구 결과가 추가된 뒤 다음 모델 호출 전에 컨텍스트 압력을 확인합니다. 컨텍스트가 더 이상 맞지 않으면 프롬프트를 제출하기 전에 현재 시도를 중단하고 기존 사전 검사 복구 경로를 재사용해 도구 결과를 잘라내거나 compact한 뒤 재시도합니다. `default`와 `safeguard` Compaction 모드 모두에서 동작합니다. 기본값은 비활성화입니다. -- `postCompactionSections`: Compaction 이후 다시 주입할 선택적 AGENTS.md H2/H3 섹션 이름입니다. 기본값은 `["Session Startup", "Red Lines"]`입니다. 재주입을 비활성화하려면 `[]`로 설정하세요. 설정하지 않았거나 명시적으로 해당 기본 쌍으로 설정한 경우, 기존 `Every Session`/`Safety` 제목도 레거시 폴백으로 허용됩니다. -- `model`: Compaction 요약에만 적용되는 선택적 `provider/model-id` 재정의입니다. 기본 세션은 한 모델을 유지하되 Compaction 요약은 다른 모델에서 실행해야 할 때 사용하세요. 설정하지 않으면 Compaction은 세션의 기본 모델을 사용합니다. -- `maxActiveTranscriptBytes`: 실행 전에 활성 JSONL이 임계값을 넘으면 일반 로컬 Compaction을 트리거하는 선택적 바이트 임계값(`number` 또는 `"20mb"` 같은 문자열)입니다. 성공한 Compaction이 더 작은 후속 transcript로 회전할 수 있도록 `truncateAfterCompaction`이 필요합니다. 설정하지 않거나 `0`이면 비활성화됩니다. -- `notifyUser`: `true`이면 Compaction이 시작될 때와 완료될 때 사용자에게 짧은 알림을 보냅니다(예: "컨텍스트를 compact하는 중..." 및 "Compaction 완료"). Compaction을 조용히 유지하기 위해 기본적으로 비활성화되어 있습니다. -- `memoryFlush`: 자동 Compaction 전에 지속 메모리를 저장하기 위한 조용한 에이전트 턴입니다. 이 정리 턴이 로컬 모델에 머물러야 하는 경우 `model`을 `ollama/qwen3:8b` 같은 정확한 제공자/모델로 설정하세요. 이 재정의는 활성 세션 폴백 체인을 상속하지 않습니다. 워크스페이스가 읽기 전용이면 건너뜁니다. +- `qualityGuard`: safeguard 요약에 대한 잘못된 형식 출력 재시도 검사입니다. safeguard 모드에서는 기본적으로 활성화됩니다. 감사를 건너뛰려면 `enabled: false`를 설정하세요. +- `midTurnPrecheck`: 선택적 Pi 도구 루프 압력 검사입니다. `enabled: true`이면 OpenClaw는 도구 결과가 추가된 뒤 다음 모델 호출 전에 컨텍스트 압력을 확인합니다. 컨텍스트가 더 이상 맞지 않으면 프롬프트를 제출하기 전에 현재 시도를 중단하고 기존 사전 검사 복구 경로를 재사용해 도구 결과를 자르거나 Compaction한 뒤 재시도합니다. `default` 및 `safeguard` Compaction 모드 모두에서 작동합니다. 기본값: 비활성화. +- `postCompactionSections`: Compaction 후 다시 주입할 선택적 AGENTS.md H2/H3 섹션 이름입니다. 기본값은 `["Session Startup", "Red Lines"]`입니다. 재주입을 비활성화하려면 `[]`로 설정하세요. 설정되지 않았거나 명시적으로 해당 기본 쌍으로 설정된 경우, 이전 `Every Session`/`Safety` 제목도 레거시 폴백으로 허용됩니다. +- `model`: Compaction 요약에만 사용하는 선택적 `provider/model-id` 재정의입니다. 기본 세션은 한 모델을 유지하되 Compaction 요약은 다른 모델에서 실행해야 할 때 사용하세요. 설정하지 않으면 Compaction은 세션의 기본 모델을 사용합니다. +- `maxActiveTranscriptBytes`: 활성 JSONL이 임계값을 넘었을 때 실행 전 일반 로컬 Compaction을 트리거하는 선택적 바이트 임계값(`number` 또는 `"20mb"` 같은 문자열)입니다. 성공한 Compaction이 더 작은 후속 transcript로 회전할 수 있도록 `truncateAfterCompaction`이 필요합니다. 설정하지 않았거나 `0`이면 비활성화됩니다. +- `notifyUser`: `true`이면 Compaction이 시작될 때와 완료될 때 사용자에게 짧은 알림을 보냅니다(예: "Compacting context..." 및 "Compaction complete"). Compaction을 조용히 유지하기 위해 기본적으로 비활성화되어 있습니다. +- `memoryFlush`: 자동 Compaction 전에 지속 기억을 저장하기 위한 조용한 에이전트 턴입니다. 이 정리 턴을 로컬 모델에 유지해야 하는 경우 `model`을 `ollama/qwen3:8b` 같은 정확한 제공자/모델로 설정하세요. 이 재정의는 활성 세션 폴백 체인을 상속하지 않습니다. 워크스페이스가 읽기 전용이면 건너뜁니다. ### `agents.defaults.contextPruning` -LLM으로 보내기 전에 인메모리 컨텍스트에서 **오래된 도구 결과**를 가지치기합니다. 디스크의 세션 기록은 수정하지 **않습니다**. +LLM에 보내기 전에 메모리 내 컨텍스트에서 **오래된 도구 결과**를 잘라냅니다. 디스크의 세션 기록은 수정하지 **않습니다**. ```json5 { @@ -625,22 +628,22 @@ LLM으로 보내기 전에 인메모리 컨텍스트에서 **오래된 도구 - `mode: "cache-ttl"`은 가지치기 패스를 활성화합니다. -- `ttl`은 가지치기를 다시 실행할 수 있는 빈도(마지막 캐시 터치 이후)를 제어합니다. -- 가지치기는 먼저 과도하게 큰 도구 결과를 소프트 트림한 뒤, 필요한 경우 더 오래된 도구 결과를 하드 클리어합니다. +- `ttl`은 가지치기를 다시 실행할 수 있는 빈도를 제어합니다(마지막 캐시 터치 이후). +- 가지치기는 먼저 너무 큰 도구 결과를 소프트 트림한 다음, 필요하면 더 오래된 도구 결과를 하드 클리어합니다. -**소프트 트림**은 시작 부분과 끝부분을 유지하고 중간에 `...`을 삽입합니다. +**소프트 트림**은 시작 부분과 끝 부분을 유지하고 중간에 `...`을 삽입합니다. -**하드 클리어**는 전체 도구 결과를 자리 표시자로 대체합니다. +**하드 클리어**는 전체 도구 결과를 자리표시자로 대체합니다. 참고: -- 이미지 블록은 절대 트림되거나 클리어되지 않습니다. -- 비율은 문자 기반(근사치)이며 정확한 토큰 수가 아닙니다. -- 어시스턴트 메시지가 `keepLastAssistants`보다 적으면 가지치기를 건너뜁니다. +- 이미지 블록은 절대 트림/클리어되지 않습니다. +- 비율은 정확한 토큰 수가 아니라 문자 기반(근사값)입니다. +- `keepLastAssistants`보다 assistant 메시지가 적으면 가지치기를 건너뜁니다. -동작 세부 정보는 [세션 가지치기](/ko/concepts/session-pruning)를 참고하세요. +동작 세부 정보는 [세션 가지치기](/ko/concepts/session-pruning)를 참조하세요. ### 블록 스트리밍 @@ -660,9 +663,9 @@ LLM으로 보내기 전에 인메모리 컨텍스트에서 **오래된 도구 - Telegram이 아닌 채널은 블록 응답을 활성화하려면 명시적으로 `*.blockStreaming: true`가 필요합니다. - 채널 재정의: `channels..blockStreamingCoalesce`(및 계정별 변형). Signal/Slack/Discord/Google Chat의 기본값은 `minChars: 1500`입니다. -- `humanDelay`: 블록 응답 사이의 무작위 일시 중지입니다. `natural` = 800~2500ms. 에이전트별 재정의: `agents.list[].humanDelay`. +- `humanDelay`: 블록 응답 사이의 무작위 일시정지입니다. `natural` = 800-2500ms. 에이전트별 재정의: `agents.list[].humanDelay`. -동작 및 청킹 세부 정보는 [스트리밍](/ko/concepts/streaming)을 참고하세요. +동작 및 청킹 세부 정보는 [스트리밍](/ko/concepts/streaming)을 참조하세요. ### 입력 표시기 @@ -783,13 +786,13 @@ LLM으로 보내기 전에 인메모리 컨텍스트에서 **오래된 도구 -**백엔드:** +**Backend:** - `docker`: 로컬 Docker 런타임(기본값) - `ssh`: 일반 SSH 기반 원격 런타임 - `openshell`: OpenShell 런타임 -`backend: "openshell"`이 선택되면 런타임별 설정은 +`backend: "openshell"`을 선택하면 런타임별 설정이 `plugins.entries.openshell.config`로 이동합니다. **SSH 백엔드 구성:** @@ -799,7 +802,7 @@ LLM으로 보내기 전에 인메모리 컨텍스트에서 **오래된 도구 - `workspaceRoot`: 범위별 워크스페이스에 사용되는 절대 원격 루트 - `identityFile` / `certificateFile` / `knownHostsFile`: OpenSSH에 전달되는 기존 로컬 파일 - `identityData` / `certificateData` / `knownHostsData`: OpenClaw가 런타임에 임시 파일로 구체화하는 인라인 콘텐츠 또는 SecretRef -- `strictHostKeyChecking` / `updateHostKeys`: OpenSSH 호스트 키 정책 조절 옵션 +- `strictHostKeyChecking` / `updateHostKeys`: OpenSSH 호스트 키 정책 조정값 **SSH 인증 우선순위:** @@ -811,12 +814,12 @@ LLM으로 보내기 전에 인메모리 컨텍스트에서 **오래된 도구 **SSH 백엔드 동작:** - 생성 또는 재생성 후 원격 워크스페이스를 한 번 시드합니다 -- 그런 다음 원격 SSH 워크스페이스를 기준으로 유지합니다 +- 그런 다음 원격 SSH 워크스페이스를 정본으로 유지합니다 - `exec`, 파일 도구, 미디어 경로를 SSH를 통해 라우팅합니다 - 원격 변경 사항을 호스트로 자동 동기화하지 않습니다 - 샌드박스 브라우저 컨테이너를 지원하지 않습니다 -**워크스페이스 액세스:** +**워크스페이스 접근:** - `none`: `~/.openclaw/sandboxes` 아래의 범위별 샌드박스 워크스페이스 - `ro`: `/workspace`의 샌드박스 워크스페이스, `/agent`에 읽기 전용으로 마운트된 에이전트 워크스페이스 @@ -825,10 +828,10 @@ LLM으로 보내기 전에 인메모리 컨텍스트에서 **오래된 도구 **범위:** - `session`: 세션별 컨테이너 + 워크스페이스 -- `agent`: 에이전트별 컨테이너 + 워크스페이스 하나(기본값) +- `agent`: 에이전트별 하나의 컨테이너 + 워크스페이스(기본값) - `shared`: 공유 컨테이너 및 워크스페이스(세션 간 격리 없음) -**OpenShell 플러그인 구성:** +**OpenShell Plugin 구성:** ```json5 { @@ -856,30 +859,30 @@ LLM으로 보내기 전에 인메모리 컨텍스트에서 **오래된 도구 **OpenShell 모드:** -- `mirror`: exec 전에 로컬에서 원격으로 시드하고, exec 후 다시 동기화합니다. 로컬 워크스페이스가 기준으로 유지됩니다 -- `remote`: 샌드박스가 생성될 때 원격을 한 번 시드한 다음, 원격 워크스페이스를 기준으로 유지합니다 +- `mirror`: 실행 전에 로컬에서 원격으로 시드하고, 실행 후 다시 동기화합니다. 로컬 워크스페이스가 정본으로 유지됩니다 +- `remote`: 샌드박스가 생성될 때 원격을 한 번 시드한 다음, 원격 워크스페이스를 정본으로 유지합니다 -`remote` 모드에서는 시드 단계 이후 OpenClaw 외부에서 수행한 호스트 로컬 편집 사항이 샌드박스로 자동 동기화되지 않습니다. -전송은 OpenShell 샌드박스로의 SSH를 사용하지만, 샌드박스 수명 주기와 선택적 미러 동기화는 플러그인이 소유합니다. +`remote` 모드에서는 시드 단계 이후 OpenClaw 외부에서 수행한 호스트 로컬 편집이 샌드박스로 자동 동기화되지 않습니다. +전송은 SSH를 통해 OpenShell 샌드박스로 이루어지지만, Plugin이 샌드박스 수명 주기와 선택적 미러 동기화를 소유합니다. -**`setupCommand`**는 컨테이너 생성 후 한 번 실행됩니다(`sh -lc` 경유). 네트워크 이그레스, 쓰기 가능한 루트, 루트 사용자가 필요합니다. +**`setupCommand`**는 컨테이너 생성 후 한 번 실행됩니다(`sh -lc` 사용). 네트워크 송신, 쓰기 가능한 루트, 루트 사용자가 필요합니다. -**컨테이너의 기본값은 `network: "none"`입니다** — 에이전트에 아웃바운드 액세스가 필요하면 `"bridge"`(또는 사용자 지정 브리지 네트워크)로 설정하세요. +**컨테이너는 기본적으로 `network: "none"`입니다** — 에이전트에 아웃바운드 접근이 필요하면 `"bridge"`(또는 사용자 지정 브리지 네트워크)로 설정하세요. `"host"`는 차단됩니다. `"container:"`는 -`sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true`(비상용)를 명시적으로 설정하지 않는 한 기본적으로 차단됩니다. +`sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true`를 명시적으로 설정하지 않는 한 기본적으로 차단됩니다(긴급 우회). **인바운드 첨부 파일**은 활성 워크스페이스의 `media/inbound/*`에 스테이징됩니다. -**`docker.binds`**는 추가 호스트 디렉터리를 마운트합니다. 전역 바인드와 에이전트별 바인드는 병합됩니다. +**`docker.binds`**는 추가 호스트 디렉터리를 마운트합니다. 전역 바인드와 에이전트별 바인드가 병합됩니다. -**샌드박스 브라우저**(`sandbox.browser.enabled`): 컨테이너 안의 Chromium + CDP입니다. noVNC URL이 시스템 프롬프트에 주입됩니다. `openclaw.json`의 `browser.enabled`가 필요하지 않습니다. -noVNC 관찰자 액세스는 기본적으로 VNC 인증을 사용하며, OpenClaw는 공유 URL에 비밀번호를 노출하는 대신 수명이 짧은 토큰 URL을 내보냅니다. +**샌드박스 브라우저**(`sandbox.browser.enabled`): 컨테이너의 Chromium + CDP입니다. noVNC URL이 시스템 프롬프트에 삽입됩니다. `openclaw.json`에서 `browser.enabled`가 필요하지 않습니다. +noVNC 관찰자 접근은 기본적으로 VNC 인증을 사용하며, OpenClaw는 공유 URL에 비밀번호를 노출하는 대신 수명이 짧은 토큰 URL을 내보냅니다. -- `allowHostControl: false`(기본값)는 샌드박스 세션이 호스트 브라우저를 대상으로 삼지 못하게 차단합니다. -- `network`의 기본값은 `openclaw-sandbox-browser`(전용 브리지 네트워크)입니다. 전역 브리지 연결을 명시적으로 원할 때만 `bridge`로 설정하세요. +- `allowHostControl: false`(기본값)는 샌드박스 세션이 호스트 브라우저를 대상으로 지정하지 못하게 차단합니다. +- `network`는 기본적으로 `openclaw-sandbox-browser`(전용 브리지 네트워크)입니다. 전역 브리지 연결을 명시적으로 원하는 경우에만 `bridge`로 설정하세요. - `cdpSourceRange`는 선택적으로 컨테이너 경계에서 CDP 인그레스를 CIDR 범위로 제한합니다(예: `172.21.0.1/32`). -- `sandbox.browser.binds`는 샌드박스 브라우저 컨테이너에만 추가 호스트 디렉터리를 마운트합니다. 설정하면(`[]` 포함) 브라우저 컨테이너에 대해 `docker.binds`를 대체합니다. -- 실행 기본값은 `scripts/sandbox-browser-entrypoint.sh`에 정의되어 있으며 컨테이너 호스트에 맞게 조정되어 있습니다. +- `sandbox.browser.binds`는 추가 호스트 디렉터리를 샌드박스 브라우저 컨테이너에만 마운트합니다. 설정되면(`[]` 포함) 브라우저 컨테이너에 대해 `docker.binds`를 대체합니다. +- 실행 기본값은 `scripts/sandbox-browser-entrypoint.sh`에 정의되어 있으며 컨테이너 호스트에 맞게 조정되어 있습니다: - `--remote-debugging-address=127.0.0.1` - `--remote-debugging-port=` - `--user-data-dir=${HOME}/.chrome` @@ -896,22 +899,22 @@ noVNC 관찰자 액세스는 기본적으로 VNC 인증을 사용하며, OpenCla - `--renderer-process-limit=2` - `--no-zygote` - `--metrics-recording-only` - - `--disable-extensions`(기본 활성화) + - `--disable-extensions`(기본적으로 활성화됨) - `--disable-3d-apis`, `--disable-software-rasterizer`, `--disable-gpu`는 - 기본적으로 활성화되며, WebGL/3D 사용에 필요하면 + 기본적으로 활성화되어 있으며 WebGL/3D 사용에 필요한 경우 `OPENCLAW_BROWSER_DISABLE_GRAPHICS_FLAGS=0`으로 비활성화할 수 있습니다. - 워크플로가 확장 프로그램에 의존하는 경우 `OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0`으로 - 확장 프로그램을 다시 활성화합니다. + 확장 프로그램을 다시 활성화할 수 있습니다. - `--renderer-process-limit=2`는 `OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=`으로 변경할 수 있습니다. Chromium의 기본 프로세스 제한을 사용하려면 `0`으로 설정하세요. - - `noSandbox`가 활성화된 경우 `--no-sandbox`도 추가됩니다. - - 기본값은 컨테이너 이미지 기준입니다. 컨테이너 기본값을 변경하려면 사용자 지정 + - `noSandbox`가 활성화된 경우 `--no-sandbox`가 추가됩니다. + - 기본값은 컨테이너 이미지 기준선입니다. 컨테이너 기본값을 변경하려면 사용자 지정 엔트리포인트가 있는 사용자 지정 브라우저 이미지를 사용하세요. -브라우저 샌드박싱과 `sandbox.docker.binds`는 Docker에서만 사용할 수 있습니다. +브라우저 샌드박싱과 `sandbox.docker.binds`는 Docker 전용입니다. 이미지 빌드(소스 체크아웃에서): @@ -920,13 +923,13 @@ scripts/sandbox-setup.sh # main sandbox image scripts/sandbox-browser-setup.sh # optional browser image ``` -소스 체크아웃이 없는 npm 설치의 경우 인라인 `docker build` 명령은 [샌드박싱 § 이미지 및 설정](/ko/gateway/sandboxing#images-and-setup)을 참조하세요. +소스 체크아웃 없이 npm 설치를 사용하는 경우, 인라인 `docker build` 명령은 [샌드박싱 § 이미지 및 설정](/ko/gateway/sandboxing#images-and-setup)을 참조하세요. ### `agents.list`(에이전트별 재정의) -`agents.list[].tts`를 사용해 에이전트에 자체 TTS 제공자, 음성, 모델, -스타일 또는 자동 TTS 모드를 지정하세요. 에이전트 블록은 전역 -`messages.tts` 위에 깊은 병합되므로, 공유 자격 증명은 한곳에 유지하면서 개별 +에이전트에 자체 TTS 제공자, 음성, 모델, +스타일 또는 자동 TTS 모드를 지정하려면 `agents.list[].tts`를 사용하세요. 에이전트 블록은 전역 +`messages.tts` 위에 깊게 병합되므로 공유 자격 증명은 한곳에 유지하면서 개별 에이전트는 필요한 음성 또는 제공자 필드만 재정의할 수 있습니다. 활성 에이전트의 재정의는 자동 음성 응답, `/tts audio`, `/tts status`, 그리고 `tts` 에이전트 도구에 적용됩니다. 제공자 예시와 우선순위는 [텍스트 음성 변환](/ko/tools/tts#per-agent-voice-overrides)을 @@ -984,22 +987,22 @@ scripts/sandbox-browser-setup.sh # optional browser image } ``` -- `id`: 안정적인 에이전트 id(필수). -- `default`: 여러 개가 설정된 경우 첫 번째가 우선합니다(경고 로그 기록). 아무것도 설정되지 않으면 목록의 첫 번째 항목이 기본값입니다. -- `model`: 문자열 형식은 모델 fallback 없이 에이전트별 기본 모델을 엄격하게 설정합니다. 객체 형식 `{ primary }`도 `fallbacks`를 추가하지 않는 한 엄격합니다. `{ primary, fallbacks: [...] }`를 사용하면 해당 에이전트가 fallback을 사용하도록 선택할 수 있고, `{ primary, fallbacks: [] }`를 사용하면 엄격한 동작을 명시할 수 있습니다. `primary`만 재정의하는 Cron 작업은 `fallbacks: []`를 설정하지 않는 한 여전히 기본 fallback을 상속합니다. -- `params`: `agents.defaults.models`에서 선택된 모델 항목 위에 병합되는 에이전트별 스트림 매개변수입니다. 전체 모델 카탈로그를 복제하지 않고 `cacheRetention`, `temperature`, `maxTokens` 같은 에이전트별 재정의에 사용하세요. -- `tts`: 선택적 에이전트별 텍스트 음성 변환 재정의입니다. 이 블록은 `messages.tts` 위에 깊은 병합되므로, 공유 Provider 자격 증명과 fallback 정책은 `messages.tts`에 두고 Provider, 음성, 모델, 스타일, 자동 모드 같은 페르소나별 값만 여기에서 설정하세요. -- `skills`: 선택적 에이전트별 Skills 허용 목록입니다. 생략하면 설정된 경우 에이전트가 `agents.defaults.skills`를 상속합니다. 명시적 목록은 기본값과 병합하는 대신 기본값을 대체하며, `[]`는 Skills가 없음을 의미합니다. -- `thinkingDefault`: 선택적 에이전트별 기본 thinking 수준(`off | minimal | low | medium | high | xhigh | adaptive | max`)입니다. 메시지별 또는 세션별 재정의가 설정되지 않은 경우 이 에이전트에 대해 `agents.defaults.thinkingDefault`를 재정의합니다. 선택된 Provider/모델 프로필이 유효한 값을 제어합니다. Google Gemini의 경우 `adaptive`는 Provider가 소유한 동적 thinking을 유지합니다(Gemini 3/3.1에서는 `thinkingLevel` 생략, Gemini 2.5에서는 `thinkingBudget: -1`). -- `reasoningDefault`: 선택적 에이전트별 기본 reasoning 표시 여부(`on | off | stream`)입니다. 메시지별 또는 세션별 reasoning 재정의가 설정되지 않은 경우 이 에이전트에 대해 `agents.defaults.reasoningDefault`를 재정의합니다. -- `fastModeDefault`: fast mode의 선택적 에이전트별 기본값(`true | false`)입니다. 메시지별 또는 세션별 fast-mode 재정의가 설정되지 않은 경우 적용됩니다. -- `agentRuntime`: 선택적 에이전트별 저수준 런타임 정책 재정의입니다. `{ id: "codex" }`를 사용하면 다른 에이전트는 `auto` 모드에서 기본 PI fallback을 유지하는 동안 한 에이전트만 Codex 전용으로 만들 수 있습니다. +- `id`: 안정적인 에이전트 ID(필수). +- `default`: 여러 개가 설정된 경우 첫 번째 항목이 우선합니다(경고가 기록됨). 아무것도 설정되지 않으면 목록의 첫 번째 항목이 기본값입니다. +- `model`: 문자열 형식은 모델 폴백 없이 에이전트별 주 모델을 엄격하게 설정합니다. 객체 형식 `{ primary }`도 `fallbacks`를 추가하지 않는 한 엄격합니다. 해당 에이전트에 폴백을 사용하려면 `{ primary, fallbacks: [...] }`를 사용하고, 엄격한 동작을 명시하려면 `{ primary, fallbacks: [] }`를 사용하세요. `primary`만 재정의하는 Cron 작업은 `fallbacks: []`를 설정하지 않는 한 기본 폴백을 계속 상속합니다. +- `params`: `agents.defaults.models`에서 선택된 모델 항목 위에 병합되는 에이전트별 스트림 매개변수입니다. 전체 모델 카탈로그를 중복하지 않고 `cacheRetention`, `temperature`, `maxTokens` 같은 에이전트별 재정의에 사용하세요. +- `tts`: 선택적 에이전트별 텍스트 음성 변환 재정의입니다. 이 블록은 `messages.tts` 위에 깊게 병합되므로 공유 공급자 자격 증명과 폴백 정책은 `messages.tts`에 두고, 공급자, 음성, 모델, 스타일 또는 자동 모드 같은 페르소나별 값만 여기에서 설정하세요. +- `skills`: 선택적 에이전트별 Skills 허용 목록입니다. 생략하면 에이전트는 설정된 경우 `agents.defaults.skills`를 상속합니다. 명시적 목록은 기본값과 병합되지 않고 대체하며, `[]`는 Skills 없음을 의미합니다. +- `thinkingDefault`: 선택적 에이전트별 기본 사고 수준(`off | minimal | low | medium | high | xhigh | adaptive | max`)입니다. 메시지별 또는 세션 재정의가 설정되지 않은 경우 이 에이전트에 대해 `agents.defaults.thinkingDefault`를 재정의합니다. 선택된 공급자/모델 프로필이 어떤 값이 유효한지 제어합니다. Google Gemini의 경우 `adaptive`는 공급자가 소유한 동적 사고를 유지합니다(Gemini 3/3.1에서는 `thinkingLevel` 생략, Gemini 2.5에서는 `thinkingBudget: -1`). +- `reasoningDefault`: 선택적 에이전트별 기본 추론 표시 여부(`on | off | stream`)입니다. 메시지별 또는 세션 추론 재정의가 설정되지 않은 경우 이 에이전트에 대해 `agents.defaults.reasoningDefault`를 재정의합니다. +- `fastModeDefault`: 선택적 에이전트별 빠른 모드 기본값(`true | false`)입니다. 메시지별 또는 세션 빠른 모드 재정의가 설정되지 않은 경우 적용됩니다. +- `agentRuntime`: 선택적 에이전트별 저수준 런타임 정책 재정의입니다. `{ id: "codex" }`를 사용하면 다른 에이전트는 `auto` 모드에서 기본 PI 폴백을 유지하는 동안 하나의 에이전트만 Codex 전용으로 만들 수 있습니다. - `runtime`: 선택적 에이전트별 런타임 설명자입니다. 에이전트가 ACP 하네스 세션을 기본값으로 사용해야 할 때 `runtime.acp` 기본값(`agent`, `backend`, `mode`, `cwd`)과 함께 `type: "acp"`를 사용하세요. -- `identity.avatar`: 워크스페이스 상대 경로, `http(s)` URL 또는 `data:` URI입니다. -- `identity`는 기본값을 파생합니다. `ackReaction`은 `emoji`에서, `mentionPatterns`는 `name`/`emoji`에서 가져옵니다. -- `subagents.allowAgents`: 명시적 `sessions_spawn.agentId` 대상에 대한 에이전트 id 허용 목록입니다(`["*"]` = 임의, 기본값: 동일 에이전트만). 자체 대상 `agentId` 호출을 허용해야 하는 경우 요청자 id를 포함하세요. -- 샌드박스 상속 가드: 요청자 세션이 샌드박스 처리되어 있으면 `sessions_spawn`은 샌드박스 없이 실행될 대상을 거부합니다. -- `subagents.requireAgentId`: true인 경우 `agentId`를 생략한 `sessions_spawn` 호출을 차단합니다(명시적 프로필 선택 강제, 기본값: false). +- `identity.avatar`: 작업 공간 기준 상대 경로, `http(s)` URL 또는 `data:` URI입니다. +- `identity`는 기본값을 파생합니다. `ackReaction`은 `emoji`에서, `mentionPatterns`는 `name`/`emoji`에서 파생됩니다. +- `subagents.allowAgents`: 명시적 `sessions_spawn.agentId` 대상에 대한 에이전트 ID 허용 목록(`["*"]` = 임의 항목, 기본값: 동일 에이전트만). 자체 대상 `agentId` 호출을 허용해야 하는 경우 요청자 ID를 포함하세요. +- 샌드박스 상속 가드: 요청자 세션이 샌드박스 처리된 경우 `sessions_spawn`은 샌드박스 없이 실행될 대상을 거부합니다. +- `subagents.requireAgentId`: true이면 `agentId`를 생략한 `sessions_spawn` 호출을 차단합니다(명시적 프로필 선택 강제, 기본값: false). --- @@ -1022,31 +1025,31 @@ scripts/sandbox-browser-setup.sh # optional browser image } ``` -### 바인딩 매치 필드 +### 바인딩 일치 필드 -- `type`(선택 사항): 일반 라우팅에는 `route`(type이 없으면 기본값은 route), 영구 ACP 대화 바인딩에는 `acp`입니다. +- `type`(선택 사항): 일반 라우팅은 `route`(유형이 없으면 기본값은 route), 영구 ACP 대화 바인딩은 `acp`입니다. - `match.channel`(필수) -- `match.accountId`(선택 사항, `*` = 모든 계정, 생략 = 기본 계정) +- `match.accountId`(선택 사항, `*` = 임의 계정, 생략 = 기본 계정) - `match.peer`(선택 사항, `{ kind: direct|group|channel, id }`) - `match.guildId` / `match.teamId`(선택 사항, 채널별) - `acp`(선택 사항, `type: "acp"`에만 해당): `{ mode, label, cwd, backend }` -**결정적 매치 순서:** +**결정적 일치 순서:** 1. `match.peer` 2. `match.guildId` 3. `match.teamId` -4. `match.accountId`(정확히 일치, peer/guild/team 없음) +4. `match.accountId`(정확히 일치, 피어/길드/팀 없음) 5. `match.accountId: "*"`(채널 전체) 6. 기본 에이전트 각 계층 안에서는 처음 일치하는 `bindings` 항목이 우선합니다. -`type: "acp"` 항목의 경우 OpenClaw는 정확한 대화 ID(`match.channel` + 계정 + `match.peer.id`)로 해석하며, 위의 route 바인딩 계층 순서를 사용하지 않습니다. +`type: "acp"` 항목의 경우 OpenClaw는 정확한 대화 ID(`match.channel` + 계정 + `match.peer.id`)로 확인하며, 위의 라우트 바인딩 계층 순서를 사용하지 않습니다. -### 에이전트별 접근 프로필 +### 에이전트별 액세스 프로필 - + ```json5 { @@ -1064,7 +1067,7 @@ scripts/sandbox-browser-setup.sh # optional browser image - + ```json5 { @@ -1093,7 +1096,7 @@ scripts/sandbox-browser-setup.sh # optional browser image - + ```json5 { @@ -1139,7 +1142,7 @@ scripts/sandbox-browser-setup.sh # optional browser image -우선순위 세부 정보는 [멀티 에이전트 샌드박스 및 도구](/ko/tools/multi-agent-sandbox-tools)를 참조하세요. +우선순위 세부 정보는 [다중 에이전트 Sandbox 및 도구](/ko/tools/multi-agent-sandbox-tools)를 참조하세요. --- @@ -1193,31 +1196,31 @@ scripts/sandbox-browser-setup.sh # optional browser image - **`scope`**: 그룹 채팅 컨텍스트의 기본 세션 그룹화 전략입니다. - `per-sender`(기본값): 각 발신자가 채널 컨텍스트 안에서 격리된 세션을 받습니다. - `global`: 채널 컨텍스트의 모든 참여자가 단일 세션을 공유합니다(공유 컨텍스트가 의도된 경우에만 사용). -- **`dmScope`**: DM을 그룹화하는 방식입니다. +- **`dmScope`**: DM이 그룹화되는 방식입니다. - `main`: 모든 DM이 기본 세션을 공유합니다. - `per-peer`: 채널 전체에서 발신자 ID별로 격리합니다. - - `per-channel-peer`: 채널 + 발신자별로 격리합니다(다중 사용자 받은 편지함에 권장). + - `per-channel-peer`: 채널 + 발신자별로 격리합니다(다중 사용자 받은편지함에 권장). - `per-account-channel-peer`: 계정 + 채널 + 발신자별로 격리합니다(다중 계정에 권장). -- **`identityLinks`**: 채널 간 세션 공유를 위해 정규 ID를 제공자 접두사가 붙은 피어에 매핑합니다. `/dock_discord` 같은 도킹 명령은 동일한 맵을 사용해 활성 세션의 답장 경로를 다른 연결된 채널 피어로 전환합니다. [채널 도킹](/ko/concepts/channel-docking)을 참조하세요. -- **`reset`**: 기본 재설정 정책입니다. `daily`는 현지 시간 `atHour`에 재설정하고, `idle`은 `idleMinutes` 이후 재설정합니다. 둘 다 구성된 경우 먼저 만료되는 쪽이 적용됩니다. 일일 재설정 최신성은 세션 행의 `sessionStartedAt`을 사용하고, 유휴 재설정 최신성은 `lastInteractionAt`을 사용합니다. Heartbeat, Cron wakeup, 실행 알림, Gateway 부기 작업 같은 백그라운드/시스템 이벤트 쓰기는 `updatedAt`을 업데이트할 수 있지만, 일일/유휴 세션을 최신 상태로 유지하지는 않습니다. +- **`identityLinks`**: 교차 채널 세션 공유를 위해 정규 ID를 제공자 접두사가 붙은 피어에 매핑합니다. `/dock_discord` 같은 도킹 명령은 동일한 맵을 사용해 활성 세션의 응답 경로를 연결된 다른 채널 피어로 전환합니다. [채널 도킹](/ko/concepts/channel-docking)을 참조하세요. +- **`reset`**: 기본 재설정 정책입니다. `daily`는 현지 시간 `atHour`에 재설정하고, `idle`은 `idleMinutes` 이후 재설정합니다. 둘 다 구성된 경우 먼저 만료되는 쪽이 적용됩니다. 일일 재설정 신선도는 세션 행의 `sessionStartedAt`을 사용하고, 유휴 재설정 신선도는 `lastInteractionAt`을 사용합니다. Heartbeat, Cron 깨우기, 실행 알림, Gateway 장부 처리 같은 백그라운드/시스템 이벤트 쓰기는 `updatedAt`을 업데이트할 수 있지만, 일일/유휴 세션을 신선하게 유지하지는 않습니다. - **`resetByType`**: 유형별 재정의(`direct`, `group`, `thread`)입니다. 레거시 `dm`은 `direct`의 별칭으로 허용됩니다. - **`mainKey`**: 레거시 필드입니다. 런타임은 기본 직접 채팅 버킷에 항상 `"main"`을 사용합니다. -- **`agentToAgent.maxPingPongTurns`**: 에이전트 간 교환 중 에이전트 사이에서 주고받을 수 있는 최대 답장 턴 수입니다(정수, 범위: `0`~`5`). `0`은 핑퐁 체이닝을 비활성화합니다. -- **`sendPolicy`**: `channel`, `chatType`(`direct|group|channel`, 레거시 `dm` 별칭 포함), `keyPrefix` 또는 `rawKeyPrefix`로 매칭합니다. 첫 번째 거부가 적용됩니다. +- **`agentToAgent.maxPingPongTurns`**: 에이전트 간 교환 중 에이전트 사이의 최대 응답 왕복 턴 수입니다(정수, 범위: `0`~`5`). `0`은 핑퐁 체이닝을 비활성화합니다. +- **`sendPolicy`**: `channel`, `chatType`(`direct|group|channel`, 레거시 `dm` 별칭 포함), `keyPrefix` 또는 `rawKeyPrefix`로 매칭합니다. 첫 번째 거부가 우선합니다. - **`maintenance`**: 세션 저장소 정리 + 보존 제어입니다. - `mode`: `warn`은 경고만 내보내고, `enforce`는 정리를 적용합니다. - `pruneAfter`: 오래된 항목의 나이 기준값입니다(기본값 `30d`). - - `maxEntries`: `sessions.json`의 최대 항목 수입니다(기본값 `500`). 런타임은 프로덕션 규모 상한을 위해 작은 하이워터 버퍼를 두고 일괄 정리를 기록합니다. `openclaw sessions cleanup --enforce`는 상한을 즉시 적용합니다. + - `maxEntries`: `sessions.json`의 최대 항목 수입니다(기본값 `500`). 런타임은 프로덕션 규모 제한을 위해 작은 high-water 버퍼로 일괄 정리를 기록합니다. `openclaw sessions cleanup --enforce`는 제한을 즉시 적용합니다. - `rotateBytes`: 사용 중단되었으며 무시됩니다. `openclaw doctor --fix`는 이전 구성에서 이를 제거합니다. - - `resetArchiveRetention`: `*.reset.` 대화 기록 아카이브의 보존 기간입니다. 기본값은 `pruneAfter`이며, 비활성화하려면 `false`로 설정합니다. - - `maxDiskBytes`: 선택 사항인 세션 디렉터리 디스크 예산입니다. `warn` 모드에서는 경고를 기록하고, `enforce` 모드에서는 가장 오래된 아티팩트/세션부터 제거합니다. - - `highWaterBytes`: 예산 정리 후 선택 사항인 목표값입니다. 기본값은 `maxDiskBytes`의 `80%`입니다. + - `resetArchiveRetention`: `*.reset.` 트랜스크립트 아카이브의 보존 기간입니다. 기본값은 `pruneAfter`입니다. 비활성화하려면 `false`로 설정합니다. + - `maxDiskBytes`: 선택 사항인 세션 디렉터리 디스크 예산입니다. `warn` 모드에서는 경고를 기록하고, `enforce` 모드에서는 가장 오래된 아티팩트/세션을 먼저 제거합니다. + - `highWaterBytes`: 예산 정리 후의 선택 사항 목표값입니다. 기본값은 `maxDiskBytes`의 `80%`입니다. - **`threadBindings`**: 스레드 바인딩 세션 기능의 전역 기본값입니다. - `enabled`: 마스터 기본 스위치입니다(제공자가 재정의할 수 있으며, Discord는 `channels.discord.threadBindings.enabled`를 사용). - - `idleHours`: 기본 비활성 자동 언포커스 시간(시간 단위, `0`은 비활성화, 제공자가 재정의 가능). - - `maxAgeHours`: 기본 하드 최대 나이(시간 단위, `0`은 비활성화, 제공자가 재정의 가능). - - `spawnSessions`: `sessions_spawn` 및 ACP 스레드 스폰에서 스레드 바인딩 작업 세션 생성을 위한 기본 게이트입니다. 스레드 바인딩이 활성화되면 기본값은 `true`이며, 제공자/계정이 재정의할 수 있습니다. - - `defaultSpawnContext`: 스레드 바인딩 스폰을 위한 기본 네이티브 하위 에이전트 컨텍스트입니다(`"fork"` 또는 `"isolated"`). 기본값은 `"fork"`입니다. + - `idleHours`: 기본 비활성 자동 언포커스 시간(`0`은 비활성화, 제공자가 재정의 가능). + - `maxAgeHours`: 기본 하드 최대 수명 시간(`0`은 비활성화, 제공자가 재정의 가능). + - `spawnSessions`: `sessions_spawn` 및 ACP 스레드 스폰에서 스레드 바인딩 작업 세션 생성을 위한 기본 게이트입니다. 스레드 바인딩이 활성화되면 기본값은 `true`입니다. 제공자/계정이 재정의할 수 있습니다. + - `defaultSpawnContext`: 스레드 바인딩 스폰의 기본 네이티브 하위 에이전트 컨텍스트입니다(`"fork"` 또는 `"isolated"`). 기본값은 `"fork"`입니다. @@ -1255,36 +1258,36 @@ scripts/sandbox-browser-setup.sh # optional browser image ### 응답 접두사 -채널/계정별 재정의: `channels..responsePrefix`, `channels..accounts..responsePrefix`. +채널별/계정별 재정의: `channels..responsePrefix`, `channels..accounts..responsePrefix`. -해결 방식(가장 구체적인 설정이 우선): 계정 → 채널 → 전역. `""`는 비활성화하고 연쇄 적용을 중지합니다. `"auto"`는 `[{identity.name}]`에서 파생됩니다. +해결 방식(가장 구체적인 항목이 우선): 계정 → 채널 → 전역. `""`는 비활성화하고 cascade를 중단합니다. `"auto"`는 `[{identity.name}]`에서 파생됩니다. **템플릿 변수:** -| 변수 | 설명 | 예시 | -| ----------------- | ------------------ | --------------------------- | -| `{model}` | 짧은 모델 이름 | `claude-opus-4-6` | -| `{modelFull}` | 전체 모델 식별자 | `anthropic/claude-opus-4-6` | -| `{provider}` | 제공자 이름 | `anthropic` | -| `{thinkingLevel}` | 현재 사고 수준 | `high`, `low`, `off` | -| `{identity.name}` | 에이전트 ID 이름 | (`"auto"`와 동일) | +| 변수 | 설명 | 예시 | +| ----------------- | -------------------- | --------------------------- | +| `{model}` | 짧은 모델 이름 | `claude-opus-4-6` | +| `{modelFull}` | 전체 모델 식별자 | `anthropic/claude-opus-4-6` | +| `{provider}` | 제공자 이름 | `anthropic` | +| `{thinkingLevel}` | 현재 thinking 수준 | `high`, `low`, `off` | +| `{identity.name}` | 에이전트 identity 이름 | (`"auto"`와 동일) | 변수는 대소문자를 구분하지 않습니다. `{think}`는 `{thinkingLevel}`의 별칭입니다. ### 확인 반응 -- 기본값은 활성 에이전트의 `identity.emoji`이며, 없으면 `"👀"`입니다. 비활성화하려면 `""`로 설정합니다. +- 기본값은 활성 에이전트의 `identity.emoji`이고, 없으면 `"👀"`입니다. 비활성화하려면 `""`로 설정합니다. - 채널별 재정의: `channels..ackReaction`, `channels..accounts..ackReaction`. -- 해결 순서: 계정 → 채널 → `messages.ackReaction` → ID 대체값. +- 해결 순서: 계정 → 채널 → `messages.ackReaction` → identity fallback. - 범위: `group-mentions`(기본값), `group-all`, `direct`, `all`. - `removeAckAfterReply`: Slack, Discord, Telegram, WhatsApp, BlueBubbles처럼 반응을 지원하는 채널에서 답장 후 확인 반응을 제거합니다. - `messages.statusReactions.enabled`: Slack, Discord, Telegram에서 수명 주기 상태 반응을 활성화합니다. Slack과 Discord에서는 설정하지 않으면 확인 반응이 활성 상태일 때 상태 반응도 활성 상태로 유지됩니다. Telegram에서는 수명 주기 상태 반응을 활성화하려면 명시적으로 `true`로 설정합니다. -### 인바운드 디바운스 +### 수신 디바운스 -같은 발신자가 빠르게 보낸 텍스트 전용 메시지를 단일 에이전트 턴으로 묶습니다. 미디어/첨부 파일은 즉시 플러시됩니다. 제어 명령은 디바운스를 우회합니다. +같은 발신자가 빠르게 보낸 텍스트 전용 메시지를 단일 에이전트 턴으로 묶습니다. 미디어/첨부 파일은 즉시 flush합니다. 제어 명령은 디바운스를 우회합니다. ### TTS(텍스트 음성 변환) @@ -1334,12 +1337,12 @@ scripts/sandbox-browser-setup.sh # optional browser image } ``` -- `auto`는 기본 자동 TTS 모드를 제어합니다: `off`, `always`, `inbound`, 또는 `tagged`. `/tts on|off`는 로컬 환경설정을 재정의할 수 있으며, `/tts status`는 유효한 상태를 표시합니다. +- `auto`는 기본 자동 TTS 모드를 제어합니다: `off`, `always`, `inbound`, `tagged`. `/tts on|off`는 로컬 기본 설정을 재정의할 수 있고, `/tts status`는 적용 중인 상태를 표시합니다. - `summaryModel`은 자동 요약에 대해 `agents.defaults.model.primary`를 재정의합니다. -- `modelOverrides`는 기본적으로 활성화됩니다. `modelOverrides.allowProvider`의 기본값은 `false`입니다(옵트인). -- API 키는 `ELEVENLABS_API_KEY`/`XI_API_KEY` 및 `OPENAI_API_KEY`로 대체됩니다. -- 번들 음성 제공자는 Plugin 소유입니다. `plugins.allow`가 설정된 경우, 사용하려는 각 TTS 제공자 Plugin을 포함하세요. 예를 들어 Edge TTS에는 `microsoft`를 포함합니다. 기존 `edge` 제공자 ID는 `microsoft`의 별칭으로 허용됩니다. -- `providers.openai.baseUrl`은 OpenAI TTS 엔드포인트를 재정의합니다. 해결 순서는 설정, `OPENAI_TTS_BASE_URL`, `https://api.openai.com/v1`입니다. +- `modelOverrides`는 기본적으로 활성화됩니다. `modelOverrides.allowProvider`의 기본값은 `false`(명시적 선택)입니다. +- API 키는 `ELEVENLABS_API_KEY`/`XI_API_KEY` 및 `OPENAI_API_KEY`로 fallback합니다. +- 번들된 음성 제공자는 Plugin 소유입니다. `plugins.allow`가 설정되어 있으면 사용하려는 각 TTS 제공자 Plugin을 포함하세요. 예를 들어 Edge TTS에는 `microsoft`를 포함합니다. 기존 `edge` 제공자 id는 `microsoft`의 별칭으로 허용됩니다. +- `providers.openai.baseUrl`은 OpenAI TTS 엔드포인트를 재정의합니다. 해결 순서는 config, 그다음 `OPENAI_TTS_BASE_URL`, 그다음 `https://api.openai.com/v1`입니다. - `providers.openai.baseUrl`이 OpenAI가 아닌 엔드포인트를 가리키면 OpenClaw는 이를 OpenAI 호환 TTS 서버로 취급하고 모델/음성 검증을 완화합니다. --- @@ -1388,20 +1391,20 @@ Talk 모드(macOS/iOS/Android)의 기본값입니다. ``` - 여러 Talk 제공자가 구성된 경우 `talk.provider`는 `talk.providers`의 키와 일치해야 합니다. -- 기존 플랫 Talk 키(`talk.voiceId`, `talk.voiceAliases`, `talk.modelId`, `talk.outputFormat`, `talk.apiKey`)는 호환성 전용이며 `talk.providers.`로 자동 마이그레이션됩니다. -- 음성 ID는 `ELEVENLABS_VOICE_ID` 또는 `SAG_VOICE_ID`로 대체됩니다. +- 기존 평면 Talk 키(`talk.voiceId`, `talk.voiceAliases`, `talk.modelId`, `talk.outputFormat`, `talk.apiKey`)는 호환성 전용입니다. 유지된 config를 `talk.providers.`로 다시 작성하려면 `openclaw doctor --fix`를 실행합니다. +- 음성 ID는 `ELEVENLABS_VOICE_ID` 또는 `SAG_VOICE_ID`로 fallback합니다. - `providers.*.apiKey`는 일반 텍스트 문자열 또는 SecretRef 객체를 허용합니다. -- `ELEVENLABS_API_KEY` 대체값은 Talk API 키가 구성되지 않은 경우에만 적용됩니다. +- `ELEVENLABS_API_KEY` fallback은 Talk API 키가 구성되지 않은 경우에만 적용됩니다. - `providers.*.voiceAliases`를 사용하면 Talk 지시문에서 친숙한 이름을 사용할 수 있습니다. -- `providers.mlx.modelId`는 macOS 로컬 MLX 헬퍼가 사용하는 Hugging Face 저장소를 선택합니다. 생략하면 macOS는 `mlx-community/Soprano-80M-bf16`을 사용합니다. -- macOS MLX 재생은 번들 `openclaw-mlx-tts` 헬퍼가 있을 때 이를 통해 실행되며, 없으면 `PATH`의 실행 파일을 통해 실행됩니다. `OPENCLAW_MLX_TTS_BIN`은 개발용 헬퍼 경로를 재정의합니다. -- `speechLocale`은 iOS/macOS Talk 음성 인식에 사용되는 BCP 47 로케일 ID를 설정합니다. 설정하지 않으면 기기 기본값을 사용합니다. -- `silenceTimeoutMs`는 사용자 침묵 후 Talk 모드가 전사문을 보내기 전에 기다리는 시간을 제어합니다. 설정하지 않으면 플랫폼 기본 일시 중지 시간(`macOS 및 Android에서는 700 ms, iOS에서는 900 ms`)이 유지됩니다. +- `providers.mlx.modelId`는 macOS 로컬 MLX 헬퍼에서 사용하는 Hugging Face 저장소를 선택합니다. 생략하면 macOS는 `mlx-community/Soprano-80M-bf16`을 사용합니다. +- macOS MLX 재생은 존재하는 경우 번들된 `openclaw-mlx-tts` 헬퍼를 통해 실행되고, 없으면 `PATH`의 실행 파일을 통해 실행됩니다. `OPENCLAW_MLX_TTS_BIN`은 개발용 헬퍼 경로를 재정의합니다. +- `speechLocale`은 iOS/macOS Talk 음성 인식에서 사용하는 BCP 47 로케일 id를 설정합니다. 기기 기본값을 사용하려면 설정하지 않은 상태로 둡니다. +- `silenceTimeoutMs`는 사용자의 침묵 후 Talk 모드가 전사본을 보내기 전까지 기다리는 시간을 제어합니다. 설정하지 않으면 플랫폼 기본 일시 정지 창(`macOS 및 Android에서는 700 ms, iOS에서는 900 ms`)이 유지됩니다. --- -## 관련 문서 +## 관련 항목 -- [설정 참조](/ko/gateway/configuration-reference) — 기타 모든 설정 키 -- [설정](/ko/gateway/configuration) — 일반 작업 및 빠른 설정 -- [설정 예시](/ko/gateway/configuration-examples) +- [Configuration reference](/ko/gateway/configuration-reference) — 그 밖의 모든 config 키 +- [Configuration](/ko/gateway/configuration) — 일반 작업 및 빠른 설정 +- [Configuration examples](/ko/gateway/configuration-examples) diff --git a/docs/ko/gateway/config-channels.md b/docs/ko/gateway/config-channels.md index c191c91aa..eecba0969 100644 --- a/docs/ko/gateway/config-channels.md +++ b/docs/ko/gateway/config-channels.md @@ -1,15 +1,15 @@ --- read_when: - - 채널 Plugin 구성(인증, 접근 제어, 다중 계정) - - 채널별 구성 키 문제 해결 + - 채널 Plugin 구성하기(인증, 액세스 제어, 다중 계정) + - 채널별 설정 키 문제 해결 - DM 정책, 그룹 정책 또는 멘션 게이팅 감사 -summary: '채널 구성: Slack, Discord, Telegram, WhatsApp, Matrix, iMessage 등에서의 접근 제어, 페어링, 채널별 키' -title: 구성 — 채널 +summary: '채널 구성: Slack, Discord, Telegram, WhatsApp, Matrix, iMessage 등에서의 액세스 제어, 페어링, 채널별 키' +title: 설정 — 채널 x-i18n: - generated_at: "2026-05-04T02:24:05Z" + generated_at: "2026-05-06T17:55:33Z" model: gpt-5.5 provider: openai - source_hash: 57dcc0b5148324ea6fdee51b7b6e97ec7bd7dc3ca89518ab0816fe4172feefbc + source_hash: c9be70fd706bcf5acfd06b99632c97f4affb854c6aed02558f70c0403247c448 source_path: gateway/config-channels.md workflow: 16 --- @@ -23,34 +23,34 @@ Telegram, WhatsApp, Matrix, iMessage 및 기타 번들 채널 Plugin의 채널 ## 채널 -각 채널은 구성 섹션이 있으면 자동으로 시작됩니다(`enabled: false`가 아닌 경우). +각 채널은 해당 구성 섹션이 존재하면 자동으로 시작됩니다(`enabled: false`가 아닌 경우). ### DM 및 그룹 액세스 모든 채널은 DM 정책과 그룹 정책을 지원합니다. -| DM 정책 | 동작 | +| DM 정책 | 동작 | | ------------------- | --------------------------------------------------------------- | -| `pairing` (기본값) | 알 수 없는 발신자는 일회용 페어링 코드를 받으며, 소유자가 승인해야 함 | -| `allowlist` | `allowFrom`(또는 페어링된 허용 저장소)의 발신자만 허용 | -| `open` | 모든 인바운드 DM 허용(`allowFrom: ["*"]` 필요) | -| `disabled` | 모든 인바운드 DM 무시 | +| `pairing` (기본값) | 알 수 없는 발신자는 일회성 페어링 코드를 받으며, 소유자가 승인해야 함 | +| `allowlist` | `allowFrom`에 있는 발신자만 허용(또는 페어링된 허용 저장소) | +| `open` | 모든 수신 DM 허용(`allowFrom: ["*"]` 필요) | +| `disabled` | 모든 수신 DM 무시 | | 그룹 정책 | 동작 | | --------------------- | ------------------------------------------------------ | -| `allowlist` (기본값) | 구성된 허용 목록과 일치하는 그룹만 허용 | -| `open` | 그룹 허용 목록 우회(멘션 게이팅은 계속 적용됨) | -| `disabled` | 모든 그룹/방 메시지 차단 | +| `allowlist` (기본값) | 구성된 허용 목록과 일치하는 그룹만 허용 | +| `open` | 그룹 허용 목록 우회(멘션 게이팅은 계속 적용됨) | +| `disabled` | 모든 그룹/룸 메시지 차단 | `channels.defaults.groupPolicy`는 프로바이더의 `groupPolicy`가 설정되지 않았을 때 기본값을 설정합니다. 페어링 코드는 1시간 후 만료됩니다. 대기 중인 DM 페어링 요청은 **채널당 3개**로 제한됩니다. -프로바이더 블록이 완전히 누락된 경우(`channels.` 없음), 런타임 그룹 정책은 시작 경고와 함께 `allowlist`(실패 시 닫힘)로 대체됩니다. +프로바이더 블록이 완전히 누락된 경우(`channels.` 없음), 런타임 그룹 정책은 시작 경고와 함께 `allowlist`(실패 시 닫힘)로 폴백합니다. ### 채널 모델 재정의 -`channels.modelByChannel`을 사용해 특정 채널 ID를 모델에 고정합니다. 값은 `provider/model` 또는 구성된 모델 별칭을 허용합니다. 채널 매핑은 세션에 이미 모델 재정의가 없을 때 적용됩니다(예: `/model`로 설정된 경우). +`channels.modelByChannel`을 사용하여 특정 채널 ID를 모델에 고정합니다. 값은 `provider/model` 또는 구성된 모델 별칭을 허용합니다. 채널 매핑은 세션에 이미 모델 재정의가 없는 경우에 적용됩니다(예: `/model`로 설정한 경우). ```json5 { @@ -73,7 +73,7 @@ Telegram, WhatsApp, Matrix, iMessage 및 기타 번들 채널 Plugin의 채널 ### 채널 기본값 및 Heartbeat -프로바이더 전반의 공유 그룹 정책 및 Heartbeat 동작에는 `channels.defaults`를 사용합니다: +프로바이더 전반의 공유 그룹 정책 및 Heartbeat 동작에는 `channels.defaults`를 사용합니다. ```json5 { @@ -91,10 +91,10 @@ Telegram, WhatsApp, Matrix, iMessage 및 기타 번들 채널 Plugin의 채널 } ``` -- `channels.defaults.groupPolicy`: 프로바이더 수준 `groupPolicy`가 설정되지 않았을 때의 대체 그룹 정책입니다. -- `channels.defaults.contextVisibility`: 모든 채널의 기본 보조 컨텍스트 표시 모드입니다. 값: `all`(기본값, 인용/스레드/기록 컨텍스트 모두 포함), `allowlist`(허용 목록의 발신자 컨텍스트만 포함), `allowlist_quote`(allowlist와 동일하지만 명시적 인용/답장 컨텍스트 유지). 채널별 재정의: `channels..contextVisibility`. -- `channels.defaults.heartbeat.showOk`: 정상 채널 상태를 Heartbeat 출력에 포함합니다. -- `channels.defaults.heartbeat.showAlerts`: 성능 저하/오류 상태를 Heartbeat 출력에 포함합니다. +- `channels.defaults.groupPolicy`: 프로바이더 수준 `groupPolicy`가 설정되지 않았을 때의 폴백 그룹 정책입니다. +- `channels.defaults.contextVisibility`: 모든 채널의 기본 보조 컨텍스트 표시 모드입니다. 값: `all`(기본값, 인용/스레드/기록 컨텍스트 모두 포함), `allowlist`(허용 목록에 있는 발신자의 컨텍스트만 포함), `allowlist_quote`(allowlist와 같지만 명시적 인용/답장 컨텍스트 유지). 채널별 재정의: `channels..contextVisibility`. +- `channels.defaults.heartbeat.showOk`: Heartbeat 출력에 정상 채널 상태를 포함합니다. +- `channels.defaults.heartbeat.showAlerts`: Heartbeat 출력에 성능 저하/오류 상태를 포함합니다. - `channels.defaults.heartbeat.useIndicator`: 간결한 표시기 스타일의 Heartbeat 출력을 렌더링합니다. ### WhatsApp @@ -155,8 +155,8 @@ WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결 } ``` -- 아웃바운드 명령은 계정 `default`가 있으면 이를 기본으로 사용하고, 그렇지 않으면 첫 번째로 구성된 계정 ID(정렬 기준)를 사용합니다. -- 선택적 `channels.whatsapp.defaultAccount`는 구성된 계정 ID와 일치할 때 해당 대체 기본 계정 선택을 재정의합니다. +- 아웃바운드 명령은 존재하는 경우 기본적으로 `default` 계정을 사용하며, 그렇지 않으면 첫 번째 구성된 계정 ID(정렬됨)를 사용합니다. +- 선택 사항인 `channels.whatsapp.defaultAccount`는 구성된 계정 ID와 일치할 때 해당 폴백 기본 계정 선택을 재정의합니다. - 레거시 단일 계정 Baileys 인증 디렉터리는 `openclaw doctor`에 의해 `whatsapp/default`로 마이그레이션됩니다. - 계정별 재정의: `channels.whatsapp.accounts..sendReadReceipts`, `channels.whatsapp.accounts..dmPolicy`, `channels.whatsapp.accounts..allowFrom`. @@ -217,13 +217,13 @@ WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결 } ``` -- 봇 토큰: `channels.telegram.botToken` 또는 `channels.telegram.tokenFile`(일반 파일만 허용, 심볼릭 링크 거부), 기본 계정의 대체 값으로 `TELEGRAM_BOT_TOKEN` 사용. -- `apiRoot`는 Telegram Bot API 루트만 의미합니다. `https://api.telegram.org/bot`이 아니라 `https://api.telegram.org` 또는 자체 호스팅/프록시 루트를 사용하세요. `openclaw doctor --fix`는 실수로 붙은 후행 `/bot` 접미사를 제거합니다. -- 선택적 `channels.telegram.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. -- 다중 계정 설정(계정 ID 2개 이상)에서는 대체 라우팅을 피하려면 명시적 기본값(`channels.telegram.defaultAccount` 또는 `channels.telegram.accounts.default`)을 설정하세요. 이 값이 없거나 유효하지 않으면 `openclaw doctor`가 경고합니다. +- 봇 토큰: `channels.telegram.botToken` 또는 `channels.telegram.tokenFile`(일반 파일만 허용, 심볼릭 링크는 거부됨), 기본 계정의 폴백으로 `TELEGRAM_BOT_TOKEN`을 사용합니다. +- `apiRoot`는 Telegram Bot API 루트 전용입니다. `https://api.telegram.org/bot`이 아니라 `https://api.telegram.org` 또는 자체 호스팅/프록시 루트를 사용하세요. `openclaw doctor --fix`는 실수로 붙은 후행 `/bot` 접미사를 제거합니다. +- 선택 사항인 `channels.telegram.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. +- 다중 계정 설정(계정 ID 2개 이상)에서는 폴백 라우팅을 피하기 위해 명시적 기본값(`channels.telegram.defaultAccount` 또는 `channels.telegram.accounts.default`)을 설정하세요. 이것이 누락되었거나 유효하지 않으면 `openclaw doctor`가 경고합니다. - `configWrites: false`는 Telegram에서 시작된 구성 쓰기(슈퍼그룹 ID 마이그레이션, `/config set|unset`)를 차단합니다. -- `type: "acp"`가 있는 최상위 `bindings[]` 항목은 포럼 토픽의 영구 ACP 바인딩을 구성합니다(`match.peer.id`에서 정식 `chatId:topic:topicId` 사용). 필드 의미는 [ACP 에이전트](/ko/tools/acp-agents#persistent-channel-bindings)에서 공유됩니다. -- Telegram 스트림 미리보기는 `sendMessage` + `editMessageText`를 사용합니다(직접 및 그룹 채팅에서 동작). +- `type: "acp"`가 있는 최상위 `bindings[]` 항목은 포럼 주제의 영구 ACP 바인딩을 구성합니다(`match.peer.id`에는 표준 `chatId:topic:topicId` 사용). 필드 의미는 [ACP 에이전트](/ko/tools/acp-agents#persistent-channel-bindings)에서 공유됩니다. +- Telegram 스트림 미리보기는 `sendMessage` + `editMessageText`를 사용합니다(직접 채팅 및 그룹 채팅에서 작동). - 재시도 정책: [재시도 정책](/ko/concepts/retry)을 참조하세요. ### Discord @@ -329,38 +329,38 @@ WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결 } ``` -- 토큰: `channels.discord.token`, 기본 계정의 대체값으로 `DISCORD_BOT_TOKEN`을 사용합니다. -- 명시적인 Discord `token`을 제공하는 직접 아웃바운드 호출은 해당 토큰을 호출에 사용합니다. 계정 재시도/정책 설정은 여전히 활성 런타임 스냅샷에서 선택된 계정에서 가져옵니다. -- 선택적 `channels.discord.defaultAccount`는 구성된 계정 id와 일치할 때 기본 계정 선택을 재정의합니다. -- 전달 대상에는 `user:`(DM) 또는 `channel:`(길드 채널)를 사용합니다. 숫자 ID만 있는 값은 거부됩니다. -- 길드 슬러그는 소문자이며 공백은 `-`로 대체됩니다. 채널 키는 슬러그 처리된 이름을 사용합니다(`#` 없음). 길드 ID를 권장합니다. -- 봇이 작성한 메시지는 기본적으로 무시됩니다. `allowBots: true`는 이를 활성화합니다. 봇을 멘션한 봇 메시지만 허용하려면 `allowBots: "mentions"`를 사용하세요(자기 메시지는 계속 필터링됨). -- `channels.discord.guilds..ignoreOtherMentions`(및 채널 재정의)는 봇은 멘션하지 않고 다른 사용자나 역할을 멘션한 메시지를 삭제합니다(@everyone/@here 제외). -- `channels.discord.mentionAliases`는 전송 전에 안정적인 아웃바운드 `@handle` 텍스트를 Discord 사용자 ID에 매핑하므로, 임시 디렉터리 캐시가 비어 있어도 알려진 팀원을 결정적으로 멘션할 수 있습니다. 계정별 재정의는 `channels.discord.accounts..mentionAliases` 아래에 있습니다. -- `maxLinesPerMessage`(기본값 17)는 2000자 미만이어도 긴 메시지를 분할합니다. -- `channels.discord.threadBindings`는 Discord 스레드 바인딩 라우팅을 제어합니다. - - `enabled`: 스레드 바인딩 세션 기능(`/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age`, 바인딩된 전달/라우팅)에 대한 Discord 재정의 - - `idleHours`: 비활성 상태 자동 포커스 해제 시간(시간 단위)에 대한 Discord 재정의(`0`은 비활성화) - - `maxAgeHours`: 강제 최대 수명(시간 단위)에 대한 Discord 재정의(`0`은 비활성화) - - `spawnSessions`: `sessions_spawn({ thread: true })` 및 ACP 스레드 생성 자동 스레드 생성/바인딩을 위한 스위치(기본값: `true`) - - `defaultSpawnContext`: 스레드 바인딩 생성의 네이티브 하위 에이전트 컨텍스트(기본값 `"fork"`) -- `type: "acp"`인 최상위 `bindings[]` 항목은 채널과 스레드에 대한 영구 ACP 바인딩을 구성합니다(`match.peer.id`에 채널/스레드 id 사용). 필드 의미는 [ACP 에이전트](/ko/tools/acp-agents#persistent-channel-bindings)에서 공유됩니다. +- 토큰: `channels.discord.token`, 기본 계정의 대체값으로 `DISCORD_BOT_TOKEN` 사용. +- 명시적인 Discord `token`을 제공하는 직접 아웃바운드 호출은 호출에 해당 토큰을 사용합니다. 계정 재시도/정책 설정은 여전히 활성 런타임 스냅샷에서 선택된 계정에서 가져옵니다. +- 선택 사항인 `channels.discord.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. +- 전달 대상에는 `user:`(DM) 또는 `channel:`(길드 채널)를 사용하세요. 숫자 ID만 단독으로 쓰면 거부됩니다. +- 길드 슬러그는 소문자이며 공백은 `-`로 대체됩니다. 채널 키는 슬러그 처리된 이름을 사용합니다(`#` 없음). 길드 ID 사용을 권장합니다. +- 봇이 작성한 메시지는 기본적으로 무시됩니다. `allowBots: true`는 이를 활성화합니다. 봇을 멘션한 봇 메시지만 허용하려면 `allowBots: "mentions"`를 사용하세요. 단, 자체 메시지는 계속 필터링됩니다. +- `channels.discord.guilds..ignoreOtherMentions`(및 채널 재정의)는 봇은 멘션하지 않고 다른 사용자나 역할을 멘션한 메시지를 드롭합니다(@everyone/@here 제외). +- `channels.discord.mentionAliases`는 전송 전에 안정적인 아웃바운드 `@handle` 텍스트를 Discord 사용자 ID에 매핑하므로, 일시적 디렉터리 캐시가 비어 있어도 알려진 팀원을 결정적으로 멘션할 수 있습니다. 계정별 재정의는 `channels.discord.accounts..mentionAliases` 아래에 있습니다. +- `maxLinesPerMessage`(기본값 17)는 2000자 미만이어도 세로로 긴 메시지를 분할합니다. +- `channels.discord.threadBindings`는 Discord 스레드 바운드 라우팅을 제어합니다. + - `enabled`: 스레드 바운드 세션 기능(`/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age`, 바운드 전달/라우팅)에 대한 Discord 재정의 + - `idleHours`: 비활성 자동 언포커스 시간(시간 단위)에 대한 Discord 재정의(`0`은 비활성화) + - `maxAgeHours`: 하드 최대 수명(시간 단위)에 대한 Discord 재정의(`0`은 비활성화) + - `spawnSessions`: `sessions_spawn({ thread: true })` 및 ACP 스레드 스폰 자동 스레드 생성/바인딩을 위한 스위치(기본값: `true`) + - `defaultSpawnContext`: 스레드 바운드 스폰의 네이티브 서브에이전트 컨텍스트(기본값 `"fork"`) +- `type: "acp"`가 있는 최상위 `bindings[]` 항목은 채널과 스레드의 영구 ACP 바인딩을 구성합니다(`match.peer.id`에 채널/스레드 ID 사용). 필드 의미는 [ACP 에이전트](/ko/tools/acp-agents#persistent-channel-bindings)에서 공유됩니다. - `channels.discord.ui.components.accentColor`는 Discord 컴포넌트 v2 컨테이너의 강조 색상을 설정합니다. -- `channels.discord.voice`는 Discord 음성 채널 대화와 선택적 자동 참여 + LLM + TTS 재정의를 활성화합니다. 텍스트 전용 Discord 구성은 기본적으로 음성을 끕니다. 사용하려면 `channels.discord.voice.enabled=true`를 설정하세요. +- `channels.discord.voice`는 Discord 음성 채널 대화와 선택 사항인 자동 참여 + LLM + TTS 재정의를 활성화합니다. 텍스트 전용 Discord 구성은 기본적으로 음성이 꺼져 있습니다. 사용하려면 `channels.discord.voice.enabled=true`를 설정하세요. - `channels.discord.voice.model`은 Discord 음성 채널 응답에 사용되는 LLM 모델을 선택적으로 재정의합니다. - `channels.discord.voice.daveEncryption` 및 `channels.discord.voice.decryptionFailureTolerance`는 `@discordjs/voice` DAVE 옵션으로 전달됩니다(기본값은 `true` 및 `24`). -- `channels.discord.voice.connectTimeoutMs`는 `/vc join` 및 자동 참여 시도에 대한 초기 `@discordjs/voice` Ready 대기를 제어합니다(기본값 `30000`). -- `channels.discord.voice.reconnectGraceMs`는 연결이 끊긴 음성 세션이 OpenClaw에 의해 제거되기 전에 재연결 신호 상태에 진입할 수 있는 시간을 제어합니다(기본값 `15000`). -- OpenClaw는 반복된 복호화 실패 후 음성 세션을 나갔다가 다시 참여하여 음성 수신 복구도 시도합니다. -- `channels.discord.streaming`은 표준 스트림 모드 키입니다. 기존 `streamMode` 및 boolean `streaming` 값은 자동 마이그레이션됩니다. -- `channels.discord.autoPresence`는 런타임 가용성을 봇 프레즌스에 매핑하고(healthy => online, degraded => idle, exhausted => dnd), 선택적 상태 텍스트 재정의를 허용합니다. -- `channels.discord.dangerouslyAllowNameMatching`은 변경 가능한 이름/태그 매칭을 다시 활성화합니다(비상 호환성 모드). -- `channels.discord.execApprovals`: Discord 네이티브 exec 승인 전달 및 승인자 권한 부여. - - `enabled`: `true`, `false` 또는 `"auto"`(기본값). 자동 모드에서는 `approvers` 또는 `commands.ownerAllowFrom`에서 승인자를 확인할 수 있을 때 exec 승인이 활성화됩니다. +- `channels.discord.voice.connectTimeoutMs`는 `/vc join` 및 자동 참여 시도에 대한 초기 `@discordjs/voice` Ready 대기 시간을 제어합니다(기본값 `30000`). +- `channels.discord.voice.reconnectGraceMs`는 연결이 끊긴 음성 세션이 OpenClaw에 의해 삭제되기 전에 재연결 신호 상태로 들어갈 수 있는 시간을 제어합니다(기본값 `15000`). +- OpenClaw는 반복된 복호화 실패 후 음성 세션을 떠났다가 다시 참여하는 방식으로 음성 수신 복구를 추가로 시도합니다. +- `channels.discord.streaming`은 표준 스트림 모드 키입니다. 레거시 `streamMode` 및 불리언 `streaming` 값은 런타임 별칭으로 유지됩니다. 저장된 구성을 다시 쓰려면 `openclaw doctor --fix`를 실행하세요. +- `channels.discord.autoPresence`는 런타임 가용성을 봇 프레즌스에 매핑합니다(healthy => online, degraded => idle, exhausted => dnd). 선택적 상태 텍스트 재정의도 허용합니다. +- `channels.discord.dangerouslyAllowNameMatching`은 변경 가능한 이름/태그 매칭을 다시 활성화합니다(긴급 호환 모드). +- `channels.discord.execApprovals`: Discord 네이티브 exec 승인 전달 및 승인자 권한 부여입니다. + - `enabled`: `true`, `false`, 또는 `"auto"`(기본값). 자동 모드에서는 `approvers` 또는 `commands.ownerAllowFrom`에서 승인자를 확인할 수 있을 때 exec 승인이 활성화됩니다. - `approvers`: exec 요청을 승인할 수 있는 Discord 사용자 ID입니다. 생략하면 `commands.ownerAllowFrom`으로 대체됩니다. - - `agentFilter`: 선택적 에이전트 ID 허용 목록입니다. 생략하면 모든 에이전트의 승인이 전달됩니다. - - `sessionFilter`: 선택적 세션 키 패턴(부분 문자열 또는 정규식). - - `target`: 승인 프롬프트를 보낼 위치입니다. `"dm"`(기본값)은 승인자 DM으로 보내고, `"channel"`은 원본 채널로 보내며, `"both"`는 둘 다로 보냅니다. 대상에 `"channel"`이 포함되면 버튼은 확인된 승인자만 사용할 수 있습니다. + - `agentFilter`: 선택적 에이전트 ID 허용 목록입니다. 생략하면 모든 에이전트의 승인을 전달합니다. + - `sessionFilter`: 선택적 세션 키 패턴(부분 문자열 또는 정규식)입니다. + - `target`: 승인 프롬프트를 보낼 위치입니다. `"dm"`(기본값)은 승인자 DM으로 보내고, `"channel"`은 원본 채널로 보내며, `"both"`는 둘 다에 보냅니다. 대상에 `"channel"`이 포함되면 버튼은 확인된 승인자만 사용할 수 있습니다. - `cleanupAfterResolve`: `true`이면 승인, 거부 또는 시간 초과 후 승인 DM을 삭제합니다. **반응 알림 모드:** `off`(없음), `own`(봇의 메시지, 기본값), `all`(모든 메시지), `allowlist`(모든 메시지에서 `guilds..users` 기반). @@ -396,9 +396,9 @@ WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결 - 서비스 계정 JSON: 인라인(`serviceAccount`) 또는 파일 기반(`serviceAccountFile`). - 서비스 계정 SecretRef도 지원됩니다(`serviceAccountRef`). -- env 대체값: `GOOGLE_CHAT_SERVICE_ACCOUNT` 또는 `GOOGLE_CHAT_SERVICE_ACCOUNT_FILE`. -- 전달 대상에는 `spaces/` 또는 `users/`를 사용합니다. -- `channels.googlechat.dangerouslyAllowNameMatching`은 변경 가능한 이메일 주체 매칭을 다시 활성화합니다(비상 호환성 모드). +- 환경 대체값: `GOOGLE_CHAT_SERVICE_ACCOUNT` 또는 `GOOGLE_CHAT_SERVICE_ACCOUNT_FILE`. +- 전달 대상에는 `spaces/` 또는 `users/`를 사용하세요. +- `channels.googlechat.dangerouslyAllowNameMatching`은 변경 가능한 이메일 주체 매칭을 다시 활성화합니다(긴급 호환 모드). ### Slack @@ -470,43 +470,44 @@ WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결 } ``` -- **소켓 모드**에는 `botToken`과 `appToken`이 모두 필요합니다(기본 계정 env 대체값은 `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN`). +- **소켓 모드**에는 `botToken`과 `appToken`이 모두 필요합니다(기본 계정 환경 대체값은 `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN`). - **HTTP 모드**에는 `botToken`과 `signingSecret`이 필요합니다(루트 또는 계정별). -- `socketMode`는 Slack SDK Socket Mode 전송 튜닝을 공개 Bolt 수신기 API로 전달합니다. ping/pong 시간 초과 또는 오래된 websocket 동작을 조사할 때만 사용하세요. +- `socketMode`는 Slack SDK Socket Mode 전송 튜닝을 공개 Bolt 수신기 API로 전달합니다. ping/pong 시간 초과 또는 오래된 웹소켓 동작을 조사할 때만 사용하세요. - `botToken`, `appToken`, `signingSecret`, `userToken`은 평문 문자열 또는 SecretRef 객체를 허용합니다. -- Slack 계정 스냅샷은 `botTokenSource`, `botTokenStatus`, `appTokenStatus`와 같은 자격 증명별 소스/상태 필드 및 HTTP 모드의 - `signingSecretStatus`를 노출합니다. `configured_unavailable`은 계정이 - SecretRef를 통해 구성되었지만 현재 명령/런타임 경로가 - 시크릿 값을 확인할 수 없었음을 의미합니다. +- Slack 계정 스냅샷은 + `botTokenSource`, `botTokenStatus`, `appTokenStatus`, HTTP 모드의 + `signingSecretStatus` 같은 자격 증명별 소스/상태 필드를 노출합니다. `configured_unavailable`은 계정이 + SecretRef를 통해 구성되었지만 현재 명령/런타임 경로에서 + 비밀 값을 확인할 수 없었음을 의미합니다. - `configWrites: false`는 Slack에서 시작된 구성 쓰기를 차단합니다. -- 선택적 `channels.slack.defaultAccount`는 구성된 계정 id와 일치할 때 기본 계정 선택을 재정의합니다. -- `channels.slack.streaming.mode`는 표준 Slack 스트림 모드 키입니다. `channels.slack.streaming.nativeTransport`는 Slack의 네이티브 스트리밍 전송을 제어합니다. 기존 `streamMode`, boolean `streaming`, `nativeStreaming` 값은 자동 마이그레이션됩니다. -- 전달 대상에는 `user:`(DM) 또는 `channel:`를 사용합니다. +- 선택 사항인 `channels.slack.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. +- `channels.slack.streaming.mode`는 표준 Slack 스트림 모드 키입니다. `channels.slack.streaming.nativeTransport`는 Slack의 네이티브 스트리밍 전송을 제어합니다. 레거시 `streamMode`, 불리언 `streaming`, `nativeStreaming` 값은 런타임 별칭으로 유지됩니다. 저장된 구성을 다시 쓰려면 `openclaw doctor --fix`를 실행하세요. +- 전달 대상에는 `user:`(DM) 또는 `channel:`를 사용하세요. **반응 알림 모드:** `off`, `own`(기본값), `all`, `allowlist`(`reactionAllowlist` 기반). -**스레드 세션 격리:** `thread.historyScope`는 스레드별(기본값) 또는 채널 전체 공유입니다. `thread.inheritParent`는 상위 채널 대화 기록을 새 스레드로 복사합니다. +**스레드 세션 격리:** `thread.historyScope`는 스레드별(기본값) 또는 채널 전체 공유입니다. `thread.inheritParent`는 상위 채널 트랜스크립트를 새 스레드로 복사합니다. -- Slack 네이티브 스트리밍과 Slack 어시스턴트 스타일의 "입력 중..." 스레드 상태에는 답장 스레드 대상이 필요합니다. 최상위 DM은 기본적으로 스레드 밖에 유지되므로, 스레드 스타일의 네이티브 스트림/상태 미리보기를 표시하는 대신 Slack 초안 게시 및 편집 미리보기를 통해 계속 스트리밍할 수 있습니다. -- `typingReaction`은 답장이 실행되는 동안 인바운드 Slack 메시지에 임시 반응을 추가한 뒤 완료 시 제거합니다. `"hourglass_flowing_sand"`와 같은 Slack 이모지 shortcode를 사용하세요. -- `channels.slack.execApprovals`: Slack 네이티브 exec 승인 전달 및 승인자 권한 부여. Discord와 동일한 스키마입니다: `enabled`(`true`/`false`/`"auto"`), `approvers`(Slack 사용자 ID), `agentFilter`, `sessionFilter`, `target`(`"dm"`, `"channel"` 또는 `"both"`). +- Slack 네이티브 스트리밍과 Slack 어시스턴트 스타일의 "is typing..." 스레드 상태에는 응답 스레드 대상이 필요합니다. 최상위 DM은 기본적으로 스레드 외부에 있으므로, 스레드 스타일 네이티브 스트림/상태 미리보기를 표시하는 대신 Slack 초안 게시 후 편집 미리보기를 통해 계속 스트리밍할 수 있습니다. +- `typingReaction`은 응답이 실행되는 동안 인바운드 Slack 메시지에 임시 반응을 추가한 뒤 완료 시 제거합니다. `"hourglass_flowing_sand"` 같은 Slack 이모지 쇼트코드를 사용하세요. +- `channels.slack.execApprovals`: Slack 네이티브 exec 승인 전달 및 승인자 권한 부여입니다. Discord와 동일한 스키마입니다: `enabled`(`true`/`false`/`"auto"`), `approvers`(Slack 사용자 ID), `agentFilter`, `sessionFilter`, `target`(`"dm"`, `"channel"`, 또는 `"both"`). | 작업 그룹 | 기본값 | 참고 | | ------------ | ------- | ---------------------- | -| reactions | 활성화됨 | 반응 추가 + 반응 목록 | -| messages | 활성화됨 | 읽기/보내기/편집/삭제 | -| pins | 활성화됨 | 고정/고정 해제/목록 | -| memberInfo | 활성화됨 | 멤버 정보 | -| emojiList | 활성화됨 | 사용자 지정 이모지 목록 | +| reactions | 활성화 | 반응 추가 + 반응 목록 | +| messages | 활성화 | 읽기/보내기/수정/삭제 | +| pins | 활성화 | 고정/고정 해제/목록 | +| memberInfo | 활성화 | 멤버 정보 | +| emojiList | 활성화 | 커스텀 이모지 목록 | ### Mattermost -Mattermost는 현재 OpenClaw 릴리스에서 번들 Plugin으로 제공됩니다. 이전 또는 -사용자 지정 빌드는 다음 명령으로 현재 npm 패키지를 설치할 수 있습니다. -`openclaw plugins install @openclaw/mattermost`. 버전을 고정하기 전에 현재 dist-tag는 +Mattermost는 현재 OpenClaw 릴리스에서 번들 Plugin으로 제공됩니다. 이전 버전 또는 +커스텀 빌드는 다음 명령으로 최신 npm 패키지를 설치할 수 있습니다. +`openclaw plugins install @openclaw/mattermost`. 버전을 고정하기 전에 [npmjs.com/package/@openclaw/mattermost](https://www.npmjs.com/package/@openclaw/mattermost)에서 -확인하세요. +현재 dist-tag를 확인하세요. ```json5 { @@ -536,15 +537,15 @@ Mattermost는 현재 OpenClaw 릴리스에서 번들 Plugin으로 제공됩니 } ``` -채팅 모드: `oncall`(@멘션에 응답, 기본값), `onmessage`(모든 메시지), `onchar`(트리거 접두사로 시작하는 메시지). +채팅 모드: `oncall`(@-멘션에 응답, 기본값), `onmessage`(모든 메시지), `onchar`(트리거 접두사로 시작하는 메시지). Mattermost 네이티브 명령이 활성화된 경우: - `commands.callbackPath`는 전체 URL이 아니라 경로여야 합니다(예: `/api/channels/mattermost/command`). - `commands.callbackUrl`은 OpenClaw Gateway 엔드포인트로 확인되어야 하며 Mattermost 서버에서 접근 가능해야 합니다. -- 네이티브 슬래시 콜백은 슬래시 명령 등록 중 Mattermost가 반환한 명령별 토큰으로 인증됩니다. 등록에 실패하거나 활성화된 명령이 없으면 OpenClaw는 `Unauthorized: invalid command token.`으로 콜백을 거부합니다. +- 네이티브 슬래시 콜백은 슬래시 명령 등록 중 Mattermost가 반환한 명령별 토큰으로 인증됩니다. 등록에 실패하거나 활성화된 명령이 없으면 OpenClaw는 콜백을 `Unauthorized: invalid command token.`으로 거부합니다. - 비공개/tailnet/내부 콜백 호스트의 경우 Mattermost에서 `ServiceSettings.AllowedUntrustedInternalConnections`에 콜백 호스트/도메인을 포함해야 할 수 있습니다. 전체 URL이 아니라 호스트/도메인 값을 사용하세요. -- `channels.mattermost.configWrites`: Mattermost에서 시작한 구성 쓰기를 허용하거나 거부합니다. +- `channels.mattermost.configWrites`: Mattermost가 시작한 구성 쓰기를 허용하거나 거부합니다. - `channels.mattermost.requireMention`: 채널에서 답장하기 전에 `@mention`을 요구합니다. - `channels.mattermost.groups..requireMention`: 채널별 멘션 게이팅 재정의(기본값은 `"*"`). - 선택 사항인 `channels.mattermost.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. @@ -568,10 +569,10 @@ Mattermost 네이티브 명령이 활성화된 경우: } ``` -**반응 알림 모드:** `off`, `own`(기본값), `all`, `allowlist`(`reactionAllowlist`에서 가져옴). +**반응 알림 모드:** `off`, `own`(기본값), `all`, `allowlist`(`reactionAllowlist`에서). - `channels.signal.account`: 채널 시작을 특정 Signal 계정 ID에 고정합니다. -- `channels.signal.configWrites`: Signal에서 시작한 구성 쓰기를 허용하거나 거부합니다. +- `channels.signal.configWrites`: Signal이 시작한 구성 쓰기를 허용하거나 거부합니다. - 선택 사항인 `channels.signal.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. ### BlueBubbles @@ -593,12 +594,12 @@ BlueBubbles는 권장되는 iMessage 경로입니다(Plugin 기반, `channels.bl - 여기서 다루는 핵심 키 경로: `channels.bluebubbles`, `channels.bluebubbles.dmPolicy`. - 선택 사항인 `channels.bluebubbles.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. -- `type: "acp"`가 있는 최상위 `bindings[]` 항목은 BlueBubbles 대화를 지속 ACP 세션에 바인딩할 수 있습니다. `match.peer.id`에서 BlueBubbles 핸들 또는 대상 문자열(`chat_id:*`, `chat_guid:*`, `chat_identifier:*`)을 사용하세요. 공유 필드 의미 체계: [ACP 에이전트](/ko/tools/acp-agents#persistent-channel-bindings). +- 최상위 `bindings[]` 항목 중 `type: "acp"`인 항목은 BlueBubbles 대화를 영구 ACP 세션에 바인딩할 수 있습니다. `match.peer.id`에서 BlueBubbles 핸들 또는 대상 문자열(`chat_id:*`, `chat_guid:*`, `chat_identifier:*`)을 사용하세요. 공유 필드 의미 체계: [ACP 에이전트](/ko/tools/acp-agents#persistent-channel-bindings). - 전체 BlueBubbles 채널 구성은 [BlueBubbles](/ko/channels/bluebubbles)에 문서화되어 있습니다. ### iMessage -OpenClaw는 `imsg rpc`(표준 입출력을 통한 JSON-RPC)를 생성합니다. 데몬이나 포트는 필요하지 않습니다. +OpenClaw는 `imsg rpc`(stdio를 통한 JSON-RPC)를 생성합니다. 데몬이나 포트가 필요하지 않습니다. ```json5 { @@ -625,12 +626,12 @@ OpenClaw는 `imsg rpc`(표준 입출력을 통한 JSON-RPC)를 생성합니다. - 선택 사항인 `channels.imessage.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. - Messages DB에 대한 전체 디스크 접근 권한이 필요합니다. -- `chat_id:` 대상을 선호하세요. 채팅을 나열하려면 `imsg chats --limit 20`을 사용하세요. +- `chat_id:` 대상을 선호하세요. `imsg chats --limit 20`을 사용하여 채팅을 나열하세요. - `cliPath`는 SSH 래퍼를 가리킬 수 있습니다. SCP 첨부 파일 가져오기를 위해 `remoteHost`(`host` 또는 `user@host`)를 설정하세요. -- `attachmentRoots` 및 `remoteAttachmentRoots`는 수신 첨부 파일 경로를 제한합니다(기본값: `/Users/*/Library/Messages/Attachments`). +- `attachmentRoots` 및 `remoteAttachmentRoots`는 인바운드 첨부 파일 경로를 제한합니다(기본값: `/Users/*/Library/Messages/Attachments`). - SCP는 엄격한 호스트 키 검사를 사용하므로 릴레이 호스트 키가 이미 `~/.ssh/known_hosts`에 있는지 확인하세요. -- `channels.imessage.configWrites`: iMessage에서 시작한 구성 쓰기를 허용하거나 거부합니다. -- `type: "acp"`가 있는 최상위 `bindings[]` 항목은 iMessage 대화를 지속 ACP 세션에 바인딩할 수 있습니다. `match.peer.id`에서 정규화된 핸들 또는 명시적 채팅 대상(`chat_id:*`, `chat_guid:*`, `chat_identifier:*`)을 사용하세요. 공유 필드 의미 체계: [ACP 에이전트](/ko/tools/acp-agents#persistent-channel-bindings). +- `channels.imessage.configWrites`: iMessage가 시작한 구성 쓰기를 허용하거나 거부합니다. +- 최상위 `bindings[]` 항목 중 `type: "acp"`인 항목은 iMessage 대화를 영구 ACP 세션에 바인딩할 수 있습니다. `match.peer.id`에서 정규화된 핸들 또는 명시적 채팅 대상(`chat_id:*`, `chat_guid:*`, `chat_identifier:*`)을 사용하세요. 공유 필드 의미 체계: [ACP 에이전트](/ko/tools/acp-agents#persistent-channel-bindings). @@ -677,17 +678,17 @@ Matrix는 Plugin 기반이며 `channels.matrix` 아래에서 구성됩니다. - `channels.matrix.proxy`는 Matrix HTTP 트래픽을 명시적 HTTP(S) 프록시를 통해 라우팅합니다. 명명된 계정은 `channels.matrix.accounts..proxy`로 이를 재정의할 수 있습니다. - `channels.matrix.network.dangerouslyAllowPrivateNetwork`는 비공개/내부 홈서버를 허용합니다. `proxy`와 이 네트워크 옵트인은 독립적인 제어 항목입니다. - `channels.matrix.defaultAccount`는 다중 계정 설정에서 선호 계정을 선택합니다. -- `channels.matrix.autoJoin`의 기본값은 `off`이므로 `autoJoinAllowlist`와 함께 `autoJoin: "allowlist"`를 설정하거나 `autoJoin: "always"`를 설정할 때까지 초대된 방과 새 DM 스타일 초대는 무시됩니다. -- `channels.matrix.execApprovals`: Matrix 네이티브 실행 승인 전달 및 승인자 권한 부여입니다. - - `enabled`: `true`, `false` 또는 `"auto"`(기본값). 자동 모드에서는 `approvers` 또는 `commands.ownerAllowFrom`에서 승인자를 확인할 수 있을 때 실행 승인이 활성화됩니다. - - `approvers`: 실행 요청을 승인할 수 있는 Matrix 사용자 ID(예: `@owner:example.org`)입니다. - - `agentFilter`: 선택 사항인 에이전트 ID 허용 목록입니다. 모든 에이전트에 대한 승인을 전달하려면 생략하세요. - - `sessionFilter`: 선택 사항인 세션 키 패턴(부분 문자열 또는 정규식)입니다. - - `target`: 승인 프롬프트를 보낼 위치입니다. `"dm"`(기본값), `"channel"`(원본 방) 또는 `"both"`입니다. +- `channels.matrix.autoJoin`의 기본값은 `off`이므로 `autoJoin: "allowlist"`와 `autoJoinAllowlist`를 설정하거나 `autoJoin: "always"`를 설정할 때까지 초대된 방과 새로운 DM 스타일 초대가 무시됩니다. +- `channels.matrix.execApprovals`: Matrix 네이티브 exec 승인 전달 및 승인자 권한 부여. + - `enabled`: `true`, `false` 또는 `"auto"`(기본값). 자동 모드에서는 `approvers` 또는 `commands.ownerAllowFrom`에서 승인자를 확인할 수 있을 때 exec 승인이 활성화됩니다. + - `approvers`: exec 요청을 승인할 수 있는 Matrix 사용자 ID(예: `@owner:example.org`). + - `agentFilter`: 선택 사항인 에이전트 ID 허용 목록. 모든 에이전트의 승인을 전달하려면 생략하세요. + - `sessionFilter`: 선택 사항인 세션 키 패턴(부분 문자열 또는 정규식). + - `target`: 승인 프롬프트를 보낼 위치. `"dm"`(기본값), `"channel"`(원본 방) 또는 `"both"`. - 계정별 재정의: `channels.matrix.accounts..execApprovals`. - `channels.matrix.dm.sessionScope`는 Matrix DM이 세션으로 그룹화되는 방식을 제어합니다. `per-user`(기본값)는 라우팅된 피어별로 공유하고, `per-room`은 각 DM 방을 격리합니다. -- Matrix 상태 프로브와 실시간 디렉터리 조회는 런타임 트래픽과 동일한 프록시 정책을 사용합니다. -- 전체 Matrix 구성, 대상 지정 규칙 및 설정 예시는 [Matrix](/ko/channels/matrix)에 문서화되어 있습니다. +- Matrix 상태 프로브와 라이브 디렉터리 조회는 런타임 트래픽과 동일한 프록시 정책을 사용합니다. +- 전체 Matrix 구성, 대상 지정 규칙, 설정 예시는 [Matrix](/ko/channels/matrix)에 문서화되어 있습니다. ### Microsoft Teams @@ -738,7 +739,7 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성됩니다. ### 다중 계정(모든 채널) -채널별로 여러 계정을 실행합니다(각각 고유한 `accountId` 사용). +채널당 여러 계정을 실행합니다(각각 자체 `accountId` 보유). ```json5 { @@ -759,13 +760,13 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성됩니다. } ``` -- `accountId`가 생략되면 `default`가 사용됩니다(CLI + 라우팅). -- 환경 변수 토큰은 **기본** 계정에만 적용됩니다. +- `default`는 `accountId`가 생략될 때 사용됩니다(CLI + 라우팅). +- Env 토큰은 **기본** 계정에만 적용됩니다. - 기본 채널 설정은 계정별로 재정의하지 않는 한 모든 계정에 적용됩니다. -- 각 계정을 다른 에이전트로 라우팅하려면 `bindings[].match.accountId`를 사용하세요. -- 단일 계정 최상위 채널 구성 상태에서 `openclaw channels add`(또는 채널 온보딩)를 통해 기본이 아닌 계정을 추가하면, OpenClaw는 원래 계정이 계속 작동하도록 먼저 계정 범위의 최상위 단일 계정 값을 채널 계정 맵으로 승격합니다. 대부분의 채널은 이를 `channels..accounts.default`로 이동합니다. Matrix는 기존의 일치하는 명명된/기본 대상을 대신 보존할 수 있습니다. +- `bindings[].match.accountId`를 사용하여 각 계정을 다른 에이전트로 라우팅합니다. +- 단일 계정 최상위 채널 구성 상태에서 `openclaw channels add`(또는 채널 온보딩)를 통해 기본값이 아닌 계정을 추가하면, OpenClaw는 먼저 계정 범위 최상위 단일 계정 값을 채널 계정 맵으로 승격하여 원래 계정이 계속 작동하도록 합니다. 대부분의 채널은 이를 `channels..accounts.default`로 이동합니다. Matrix는 기존에 일치하는 명명된/기본 대상을 대신 보존할 수 있습니다. - 기존 채널 전용 바인딩(`accountId` 없음)은 기본 계정과 계속 일치합니다. 계정 범위 바인딩은 계속 선택 사항입니다. -- `openclaw doctor --fix`도 해당 채널에 대해 선택된 승격 계정으로 계정 범위의 최상위 단일 계정 값을 이동하여 혼합 형태를 복구합니다. 대부분의 채널은 `accounts.default`를 사용합니다. Matrix는 기존의 일치하는 명명된/기본 대상을 대신 보존할 수 있습니다. +- `openclaw doctor --fix`도 계정 범위 최상위 단일 계정 값을 해당 채널에 대해 선택된 승격 계정으로 이동하여 혼합 형태를 복구합니다. 대부분의 채널은 `accounts.default`를 사용합니다. Matrix는 기존에 일치하는 명명된/기본 대상을 대신 보존할 수 있습니다. ### 기타 Plugin 채널 @@ -774,15 +775,15 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성됩니다. ### 그룹 채팅 멘션 게이팅 -그룹 메시지는 기본적으로 **멘션 필요**입니다(메타데이터 멘션 또는 안전한 정규식 패턴). WhatsApp, Telegram, Discord, Google Chat 및 iMessage 그룹 채팅에 적용됩니다. +그룹 메시지는 기본적으로 **멘션 필요**(메타데이터 멘션 또는 안전한 정규식 패턴)입니다. WhatsApp, Telegram, Discord, Google Chat, iMessage 그룹 채팅에 적용됩니다. -보이는 답장은 별도로 제어됩니다. 그룹/채널 방의 기본값은 `messages.groupChat.visibleReplies: "message_tool"`입니다. OpenClaw는 여전히 턴을 처리하지만, 일반적인 최종 답장은 비공개로 유지되며 보이는 방 출력에는 `message(action=send)`가 필요합니다. 일반 답장이 방에 다시 게시되는 레거시 동작을 원할 때만 `"automatic"`으로 설정하세요. 동일한 도구 전용 보이는 답장 동작을 직접 채팅에도 적용하려면 `messages.visibleReplies: "message_tool"`을 설정하세요. Codex 하네스도 설정되지 않은 직접 채팅 기본값으로 이 도구 전용 동작을 사용합니다. +표시되는 답장은 별도로 제어됩니다. 그룹/채널 방의 기본값은 `messages.groupChat.visibleReplies: "message_tool"`입니다. OpenClaw는 여전히 턴을 처리하지만, 일반 최종 답장은 비공개로 유지되며 방에 표시되는 출력에는 `message(action=send)`가 필요합니다. 일반 답장이 방에 다시 게시되는 레거시 동작을 원할 때만 `"automatic"`을 설정하세요. 직접 채팅에도 동일한 도구 전용 표시 답장 동작을 적용하려면 `messages.visibleReplies: "message_tool"`을 설정하세요. Codex 하네스도 설정되지 않은 직접 채팅 기본값으로 해당 도구 전용 동작을 사용합니다. -도구 전용 보이는 답장에는 도구를 안정적으로 호출하는 모델/런타임이 필요합니다. 세션 로그에 `didSendViaMessagingTool: false`가 있는 어시스턴트 텍스트가 표시되면 모델이 메시지 도구를 호출하는 대신 비공개 최종 답변을 생성한 것입니다. 해당 채널에 더 강력한 도구 호출 모델로 전환하거나, 레거시 보이는 최종 답장을 복원하려면 `messages.groupChat.visibleReplies: "automatic"`을 설정하세요. +도구 전용 표시 답장에는 안정적으로 도구를 호출하는 모델/런타임이 필요합니다. 세션 로그에 `didSendViaMessagingTool: false`인 어시스턴트 텍스트가 표시되면, 모델이 메시지 도구를 호출하는 대신 비공개 최종 답변을 생성한 것입니다. 해당 채널에 대해 더 강력한 도구 호출 모델로 전환하거나, 레거시 표시 최종 답장을 복원하려면 `messages.groupChat.visibleReplies: "automatic"`을 설정하세요. -활성 도구 정책에서 메시지 도구를 사용할 수 없는 경우 OpenClaw는 응답을 조용히 억제하는 대신 자동 보이는 답장으로 대체합니다. `openclaw doctor`는 이 불일치에 대해 경고합니다. +활성 도구 정책에서 메시지 도구를 사용할 수 없는 경우, OpenClaw는 응답을 조용히 억제하는 대신 자동 표시 답장으로 폴백합니다. `openclaw doctor`는 이 불일치에 대해 경고합니다. -파일이 저장된 후 Gateway는 `messages` 구성을 핫 리로드합니다. 배포에서 파일 감시 또는 구성 리로드가 비활성화된 경우에만 다시 시작하세요. +Gateway는 파일이 저장된 후 `messages` 구성을 핫 리로드합니다. 배포에서 파일 감시 또는 구성 리로드가 비활성화된 경우에만 다시 시작하세요. **멘션 유형:** @@ -807,7 +808,7 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성됩니다. `messages.groupChat.historyLimit`는 전역 기본값을 설정합니다. 채널은 `channels..historyLimit`(또는 계정별 설정)로 재정의할 수 있습니다. 비활성화하려면 `0`으로 설정하세요. -`messages.visibleReplies`는 전역 소스 턴 기본값입니다. `messages.groupChat.visibleReplies`는 그룹/채널 소스 턴에서 이를 재정의합니다. `messages.visibleReplies`가 설정되지 않은 경우, 하네스는 자체 direct/source 기본값을 제공할 수 있습니다. Codex 하네스는 기본값으로 `message_tool`을 사용합니다. 채널 허용 목록과 멘션 게이팅은 여전히 턴을 처리할지 결정합니다. +`messages.visibleReplies`는 전역 소스 턴 기본값입니다. `messages.groupChat.visibleReplies`는 그룹/채널 소스 턴에 대해 이를 재정의합니다. `messages.visibleReplies`가 설정되지 않은 경우, 하네스가 자체 direct/source 기본값을 제공할 수 있습니다. Codex 하네스의 기본값은 `message_tool`입니다. 채널 허용 목록과 멘션 게이팅은 여전히 턴을 처리할지 여부를 결정합니다. #### DM 기록 제한 @@ -824,13 +825,13 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성됩니다. } ``` -해결 순서: DM별 재정의 → 제공자 기본값 → 제한 없음(모두 보존). +해결 순서: DM별 재정의 → 제공자 기본값 → 제한 없음(모두 유지). -지원됨: `telegram`, `whatsapp`, `discord`, `slack`, `signal`, `imessage`, `msteams`. +지원: `telegram`, `whatsapp`, `discord`, `slack`, `signal`, `imessage`, `msteams`. #### 셀프 채팅 모드 -셀프 채팅 모드를 활성화하려면 `allowFrom`에 자신의 번호를 포함하세요(네이티브 @-멘션을 무시하고 텍스트 패턴에만 응답함). +셀프 채팅 모드를 활성화하려면 `allowFrom`에 자신의 번호를 포함하세요(네이티브 @-멘션은 무시하고 텍스트 패턴에만 응답). ```json5 { @@ -880,27 +881,27 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성됩니다. -- 이 블록은 명령 표면을 구성합니다. 현재 내장 및 번들 명령 카탈로그는 [슬래시 명령](/ko/tools/slash-commands)을 참조하세요. -- 이 페이지는 전체 명령 카탈로그가 아니라 **구성 키 참조**입니다. QQ Bot `/bot-ping` `/bot-help` `/bot-logs`, LINE `/card`, 기기 페어링 `/pair`, 메모리 `/dreaming`, 전화 제어 `/phone`, Talk `/voice`처럼 채널/Plugin이 소유한 명령은 해당 채널/Plugin 페이지와 [슬래시 명령](/ko/tools/slash-commands)에 문서화되어 있습니다. -- 텍스트 명령은 선행 `/`가 있는 **독립형** 메시지여야 합니다. -- `native: "auto"`는 Discord/Telegram에서 네이티브 명령을 켜고 Slack은 꺼진 상태로 둡니다. -- `nativeSkills: "auto"`는 Discord/Telegram에서 네이티브 Skills 명령을 켜고 Slack은 꺼진 상태로 둡니다. -- 채널별로 재정의하려면 `channels.discord.commands.native`(불리언 또는 `"auto"`)를 사용하세요. Discord의 경우 `false`는 시작 중 네이티브 명령 등록과 정리를 건너뜁니다. -- `channels..commands.nativeSkills`로 채널별 네이티브 Skills 등록을 재정의합니다. +- 이 블록은 명령 표면을 구성합니다. 현재 기본 제공 및 번들 명령 카탈로그는 [슬래시 명령](/ko/tools/slash-commands)을 참조하세요. +- 이 페이지는 전체 명령 카탈로그가 아니라 **구성 키 참조**입니다. QQ Bot `/bot-ping` `/bot-help` `/bot-logs`, LINE `/card`, 기기 페어링 `/pair`, 메모리 `/dreaming`, 전화 제어 `/phone`, Talk `/voice`처럼 채널/Plugin 소유 명령은 해당 채널/Plugin 페이지와 [슬래시 명령](/ko/tools/slash-commands)에 문서화되어 있습니다. +- 텍스트 명령은 앞에 `/`가 붙은 **독립 실행형** 메시지여야 합니다. +- `native: "auto"`는 Discord/Telegram의 네이티브 명령을 켜고 Slack은 꺼진 상태로 둡니다. +- `nativeSkills: "auto"`는 Discord/Telegram의 네이티브 skill 명령을 켜고 Slack은 꺼진 상태로 둡니다. +- 채널별 재정의: `channels.discord.commands.native`(불리언 또는 `"auto"`). Discord의 경우 `false`는 시작 중 네이티브 명령 등록과 정리를 건너뜁니다. +- `channels..commands.nativeSkills`로 채널별 네이티브 skill 등록을 재정의하세요. - `channels.telegram.customCommands`는 추가 Telegram 봇 메뉴 항목을 추가합니다. -- `bash: true`는 호스트 셸에 대해 `! `를 활성화합니다. `tools.elevated.enabled`가 필요하며 발신자가 `tools.elevated.allowFrom.`에 있어야 합니다. -- `config: true`는 `/config`(`openclaw.json` 읽기/쓰기)를 활성화합니다. Gateway `chat.send` 클라이언트의 경우, 영구 `/config set|unset` 쓰기에는 `operator.admin`도 필요합니다. 읽기 전용 `/config show`는 일반 쓰기 범위 operator 클라이언트에서도 계속 사용할 수 있습니다. -- `mcp: true`는 `mcp.servers` 아래의 OpenClaw 관리 MCP 서버 구성에 대해 `/mcp`를 활성화합니다. +- `bash: true`는 호스트 셸에 대해 `! `를 활성화합니다. `tools.elevated.enabled`와 `tools.elevated.allowFrom.`에 포함된 발신자가 필요합니다. +- `config: true`는 `/config`(`openclaw.json` 읽기/쓰기)를 활성화합니다. Gateway `chat.send` 클라이언트의 경우 영구 `/config set|unset` 쓰기에는 `operator.admin`도 필요합니다. 읽기 전용 `/config show`는 일반 쓰기 범위 operator 클라이언트에도 계속 제공됩니다. +- `mcp: true`는 `mcp.servers` 아래 OpenClaw 관리 MCP 서버 구성에 대한 `/mcp`를 활성화합니다. - `plugins: true`는 Plugin 검색, 설치, 활성화/비활성화 제어를 위한 `/plugins`를 활성화합니다. -- `channels..configWrites`는 채널별 구성 변경을 제어합니다(기본값: true). -- 다중 계정 채널의 경우 `channels..accounts..configWrites`도 해당 계정을 대상으로 하는 쓰기를 제어합니다(예: `/allowlist --config --account ` 또는 `/config set channels..accounts....`). -- `restart: false`는 `/restart`와 Gateway 재시작 도구 동작을 비활성화합니다. 기본값: `true`. -- `ownerAllowFrom`은 소유자 전용 명령/도구를 위한 명시적 소유자 허용 목록입니다. `allowFrom`과 별개입니다. +- `channels..configWrites`는 채널별 구성 변경을 게이트합니다(기본값: true). +- 다중 계정 채널의 경우 `channels..accounts..configWrites`도 해당 계정을 대상으로 하는 쓰기를 게이트합니다(예: `/allowlist --config --account ` 또는 `/config set channels..accounts....`). +- `restart: false`는 `/restart`와 Gateway 재시작 도구 작업을 비활성화합니다. 기본값: `true`. +- `ownerAllowFrom`은 소유자 전용 명령/도구에 대한 명시적 소유자 허용 목록입니다. `allowFrom`과는 별개입니다. - `ownerDisplay: "hash"`는 시스템 프롬프트에서 소유자 ID를 해시합니다. 해싱을 제어하려면 `ownerDisplaySecret`을 설정하세요. -- `allowFrom`은 제공자별입니다. 설정하면 이것이 **유일한** 인증 소스가 됩니다(채널 허용 목록/페어링 및 `useAccessGroups`는 무시됨). -- `useAccessGroups: false`는 `allowFrom`이 설정되지 않은 경우 명령이 액세스 그룹 정책을 우회할 수 있게 합니다. +- `allowFrom`은 제공자별입니다. 설정된 경우 이것이 **유일한** 인증 소스입니다(채널 허용 목록/페어링 및 `useAccessGroups`는 무시됨). +- `useAccessGroups: false`는 `allowFrom`이 설정되지 않은 경우 명령이 액세스 그룹 정책을 우회하도록 허용합니다. - 명령 문서 맵: - - 내장 및 번들 카탈로그: [슬래시 명령](/ko/tools/slash-commands) + - 기본 제공 및 번들 카탈로그: [슬래시 명령](/ko/tools/slash-commands) - 채널별 명령 표면: [채널](/ko/channels) - QQ Bot 명령: [QQ Bot](/ko/channels/qqbot) - 페어링 명령: [페어링](/ko/channels/pairing) diff --git a/docs/ko/gateway/configuration-examples.md b/docs/ko/gateway/configuration-examples.md index f975969dc..f63b73d8c 100644 --- a/docs/ko/gateway/configuration-examples.md +++ b/docs/ko/gateway/configuration-examples.md @@ -1,24 +1,24 @@ --- read_when: - OpenClaw 구성 방법 알아보기 - - 설정 예시 찾기 - - 처음으로 OpenClaw 설정하기 -summary: 일반적인 OpenClaw 설정을 위한 스키마와 일치하는 구성 예제 + - 구성 예제를 찾는 중 + - OpenClaw를 처음 설정하기 +summary: 일반적인 OpenClaw 설정을 위한 스키마에 정확히 맞는 구성 예시 title: 구성 예시 x-i18n: - generated_at: "2026-05-04T02:24:09Z" + generated_at: "2026-05-06T17:55:28Z" model: gpt-5.5 provider: openai - source_hash: 60c8c2d731f8dce93c4d14657041d72043bc36e3d71ab6cb13c02993ba90dbe3 + source_hash: 01dd16c73f1156c4012fd3956083062141825b502722b6aa34f1f90462a6823a source_path: gateway/configuration-examples.md workflow: 16 --- -아래 예시는 현재 구성 스키마와 일치합니다. 전체 참조와 필드별 참고 사항은 [구성](/ko/gateway/configuration)을 참조하세요. +아래 예시는 현재 구성 스키마에 맞춰져 있습니다. 전체 참조와 필드별 참고 사항은 [구성](/ko/gateway/configuration)을 참조하세요. ## 빠른 시작 -### 최소 필수 구성 +### 최소 구성 ```json5 { @@ -59,7 +59,7 @@ x-i18n: ## 확장 예시(주요 옵션) -> JSON5에서는 주석과 후행 쉼표를 사용할 수 있습니다. 일반 JSON도 작동합니다. +> JSON5에서는 주석과 후행 쉼표를 사용할 수 있습니다. 일반 JSON도 사용할 수 있습니다. ```json5 { @@ -473,7 +473,7 @@ x-i18n: ## 일반적인 패턴 -### 하나의 재정의가 있는 공유 Skills 기준선 +### 하나의 재정의가 있는 공유 스킬 기준선 ```json5 { @@ -492,7 +492,7 @@ x-i18n: - `agents.defaults.skills`는 공유 기준값입니다. - `agents.list[].skills`는 한 에이전트에 대해 해당 기준값을 대체합니다. -- 에이전트가 어떤 Skills도 보지 않아야 할 때는 `skills: []`를 사용하세요. +- 에이전트가 Skills를 보지 않아야 하면 `skills: []`를 사용하세요. ### 멀티 플랫폼 설정 @@ -518,8 +518,8 @@ x-i18n: ### 신뢰할 수 있는 Node 네트워크 자동 승인 네트워크 경로를 제어하지 않는 한 기기 페어링은 수동으로 유지하세요. 전용 -랩이나 tailnet 서브넷의 경우, 정확한 CIDR 또는 IP를 사용해 최초 Node 기기 -자동 승인을 선택적으로 활성화할 수 있습니다. +실험실 또는 tailnet 서브넷의 경우, 정확한 CIDR 또는 IP로 최초 Node 기기 자동 승인을 +선택적으로 활성화할 수 있습니다. ```json5 { @@ -533,13 +533,13 @@ x-i18n: } ``` -설정하지 않으면 이 기능은 꺼진 상태로 유지됩니다. 요청된 범위가 없는 -새 `role: node` 페어링에만 적용됩니다. 운영자/브라우저 클라이언트와 역할, -범위, 메타데이터 또는 공개 키 업그레이드는 여전히 수동 승인이 필요합니다. +설정하지 않으면 이 기능은 꺼진 상태로 유지됩니다. 요청된 범위가 없는 새로운 `role: node` +페어링에만 적용됩니다. 운영자/브라우저 클라이언트와 역할, 범위, 메타데이터 또는 +공개 키 업그레이드는 여전히 수동 승인이 필요합니다. ### 보안 DM 모드(공유 받은 편지함 / 다중 사용자 DM) -두 명 이상이 봇에 DM을 보낼 수 있는 경우(`allowFrom`에 여러 항목이 있거나, 여러 사람에 대한 페어링 승인 또는 `dmPolicy: "open"`), **보안 DM 모드**를 활성화하여 서로 다른 발신자의 DM이 기본적으로 하나의 컨텍스트를 공유하지 않도록 하세요. +둘 이상의 사람이 봇에 DM을 보낼 수 있는 경우(`allowFrom`에 여러 항목이 있거나, 여러 사람에 대한 페어링 승인이 있거나, `dmPolicy: "open"`인 경우) **보안 DM 모드**를 활성화하여 서로 다른 발신자의 DM이 기본적으로 하나의 컨텍스트를 공유하지 않도록 하세요. ```json5 { @@ -563,10 +563,10 @@ x-i18n: } ``` -Discord/Slack/Google Chat/Microsoft Teams/Mattermost/IRC의 경우, 발신자 승인은 기본적으로 ID 우선입니다. +Discord/Slack/Google Chat/Microsoft Teams/Mattermost/IRC의 경우 발신자 권한 부여는 기본적으로 ID 우선입니다. 해당 위험을 명시적으로 수락하는 경우에만 각 채널의 `dangerouslyAllowNameMatching: true`로 직접 변경 가능한 이름/이메일/닉네임 매칭을 활성화하세요. -### Anthropic API 키 + MiniMax 대체 수단 +### Anthropic API 키 + MiniMax 대체 ```json5 { @@ -659,7 +659,7 @@ Discord/Slack/Google Chat/Microsoft Teams/Mattermost/IRC의 경우, 발신자 ## 팁 -- `dmPolicy: "open"`을 설정하면, 일치하는 `allowFrom` 목록에 `"*"`가 포함되어야 합니다. +- `dmPolicy: "open"`을 설정하면 대응하는 `allowFrom` 목록에 `"*"`가 포함되어야 합니다. - 제공자 ID는 서로 다릅니다(전화번호, 사용자 ID, 채널 ID). 형식을 확인하려면 제공자 문서를 사용하세요. - 나중에 추가할 수 있는 선택 섹션: `web`, `browser`, `ui`, `discovery`, `canvasHost`, `talk`, `signal`, `imessage`. - 더 자세한 설정 참고 사항은 [제공자](/ko/providers) 및 [문제 해결](/ko/gateway/troubleshooting)을 참조하세요. diff --git a/docs/ko/gateway/configuration-reference.md b/docs/ko/gateway/configuration-reference.md index 6135d7e00..069851d72 100644 --- a/docs/ko/gateway/configuration-reference.md +++ b/docs/ko/gateway/configuration-reference.md @@ -1,63 +1,63 @@ --- read_when: - - 정확한 필드 수준 설정 의미 체계 또는 기본값이 필요한 경우 + - 정확한 필드 수준의 구성 의미 체계 또는 기본값이 필요합니다 - 채널, 모델, Gateway 또는 도구 구성 블록을 검증하고 있습니다 -summary: 핵심 OpenClaw 키, 기본값 및 전용 하위 시스템 참조 링크에 대한 Gateway 구성 참조 +summary: 핵심 OpenClaw 키, 기본값 및 전용 하위 시스템 참조 링크를 위한 Gateway 구성 참조 title: 설정 참조 x-i18n: - generated_at: "2026-05-06T06:24:47Z" + generated_at: "2026-05-06T17:55:34Z" model: gpt-5.5 provider: openai - source_hash: 119194a7e041a7ca35b9dd1575c4f4c4d5c67f412cd3002e65bf5b706b210a90 + source_hash: 5e5f7c2246b28f801d527437ae6242686998f1e8b75fd3977723d240a760d859 source_path: gateway/configuration-reference.md workflow: 16 --- -`~/.openclaw/openclaw.json`의 핵심 구성 참조입니다. 작업 중심 개요는 [구성](/ko/gateway/configuration)을 참조하세요. +Core config reference for `~/.openclaw/openclaw.json`의 핵심 config 참조입니다. 작업 중심 개요는 [Configuration](/ko/gateway/configuration)을 참조하세요. -주요 OpenClaw 구성 표면을 다루며, 하위 시스템에 자체적인 더 자세한 참조가 있는 경우 링크로 안내합니다. 채널 및 Plugin 소유 명령 카탈로그와 심층 메모리/QMD 조정 항목은 이 페이지가 아니라 각자의 페이지에 있습니다. +주요 OpenClaw config 표면을 다루며, 하위 시스템에 더 자세한 자체 참조가 있는 경우 해당 문서로 연결합니다. 채널 및 Plugin 소유 명령 카탈로그와 심층 메모리/QMD 조정값은 이 페이지가 아니라 각자의 페이지에 있습니다. 코드 기준: -- `openclaw config schema`는 검증 및 Control UI에 사용되는 실제 JSON Schema를 출력하며, 사용 가능할 때 번들/Plugin/채널 메타데이터를 병합합니다. -- `config.schema.lookup`은 드릴다운 도구를 위한 경로 범위 스키마 노드 하나를 반환합니다. -- `pnpm config:docs:check` / `pnpm config:docs:gen`은 현재 스키마 표면을 기준으로 구성 문서 기준 해시를 검증합니다. +- `openclaw config schema`는 검증 및 Control UI에 사용되는 실시간 JSON Schema를 출력하며, 사용 가능한 경우 번들/Plugin/채널 메타데이터가 병합됩니다 +- `config.schema.lookup`은 드릴다운 도구를 위해 경로 범위 schema 노드 하나를 반환합니다 +- `pnpm config:docs:check` / `pnpm config:docs:gen`은 현재 schema 표면에 대해 config 문서 기준 해시를 검증합니다 -에이전트 조회 경로: 수정하기 전에 정확한 필드 수준 문서와 제약 조건은 `gateway` 도구 작업 `config.schema.lookup`을 사용하세요. 작업 중심 안내는 [구성](/ko/gateway/configuration)을 사용하고, 더 넓은 필드 맵, 기본값, 하위 시스템 참조 링크는 이 페이지를 사용하세요. +Agent 조회 경로: 편집 전에 정확한 필드 수준 문서와 제약 조건을 확인하려면 `gateway` 도구 작업 `config.schema.lookup`을 사용하세요. 작업 중심 안내는 [Configuration](/ko/gateway/configuration)을 사용하고, 더 넓은 필드 맵, 기본값, 하위 시스템 참조 링크는 이 페이지를 사용하세요. 전용 심층 참조: -- `agents.defaults.memorySearch.*`, `memory.qmd.*`, `memory.citations`, 그리고 `plugins.entries.memory-core.config.dreaming` 아래의 dreaming 구성은 [메모리 구성 참조](/ko/reference/memory-config) -- 현재 내장 + 번들 명령 카탈로그는 [슬래시 명령](/ko/tools/slash-commands) +- `agents.defaults.memorySearch.*`, `memory.qmd.*`, `memory.citations`, 그리고 `plugins.entries.memory-core.config.dreaming` 아래의 dreaming config는 [Memory configuration reference](/ko/reference/memory-config) +- 현재 내장 + 번들 명령 카탈로그는 [Slash commands](/ko/tools/slash-commands) - 채널별 명령 표면은 소유 채널/Plugin 페이지 -구성 형식은 **JSON5**입니다(주석 + 후행 쉼표 허용). 모든 필드는 선택 사항입니다. 생략되면 OpenClaw는 안전한 기본값을 사용합니다. +Config 형식은 **JSON5**입니다(주석 + 후행 쉼표 허용). 모든 필드는 선택 사항입니다 - 생략하면 OpenClaw는 안전한 기본값을 사용합니다. --- ## 채널 -채널별 구성 키는 전용 페이지로 이동했습니다. Slack, Discord, Telegram, WhatsApp, Matrix, iMessage 및 기타 번들 채널(인증, 접근 제어, 다중 계정, 멘션 게이팅)을 포함한 `channels.*`는 [구성 - 채널](/ko/gateway/config-channels)을 참조하세요. +채널별 config 키는 전용 페이지로 이동했습니다 - Slack, Discord, Telegram, WhatsApp, Matrix, iMessage 및 기타 번들 채널(auth, 접근 제어, 다중 계정, 멘션 게이팅)을 포함한 `channels.*`는 [Configuration - channels](/ko/gateway/config-channels)를 참조하세요. -## 에이전트 기본값, 다중 에이전트, 세션, 메시지 +## Agent 기본값, multi-agent, 세션 및 메시지 -전용 페이지로 이동했습니다. 다음 항목은 [구성 - 에이전트](/ko/gateway/config-agents)를 참조하세요. +전용 페이지로 이동했습니다 - 다음 항목은 [Configuration - agents](/ko/gateway/config-agents)를 참조하세요: -- `agents.defaults.*`(작업공간, 모델, thinking, heartbeat, 메모리, 미디어, Skills, 샌드박스) -- `multiAgent.*`(다중 에이전트 라우팅 및 바인딩) -- `session.*`(세션 수명 주기, Compaction, 가지치기) -- `messages.*`(메시지 전달, TTS, 마크다운 렌더링) +- `agents.defaults.*`(workspace, model, thinking, heartbeat, memory, media, skills, sandbox) +- `multiAgent.*`(multi-agent 라우팅 및 바인딩) +- `session.*`(세션 수명 주기, Compaction, pruning) +- `messages.*`(메시지 전달, TTS, markdown 렌더링) - `talk.*`(Talk 모드) - - `talk.speechLocale`: iOS/macOS의 Talk 음성 인식을 위한 선택적 BCP 47 로캘 ID - - `talk.silenceTimeoutMs`: 설정하지 않으면 Talk는 대본을 보내기 전에 플랫폼 기본 일시 중지 창을 유지합니다(`macOS 및 Android에서는 700 ms, iOS에서는 900 ms`). + - `talk.speechLocale`: iOS/macOS의 Talk 음성 인식을 위한 선택적 BCP 47 locale id + - `talk.silenceTimeoutMs`: 설정하지 않으면 Talk는 transcript를 보내기 전 플랫폼 기본 일시 중지 창을 유지합니다(`macOS 및 Android에서는 700 ms, iOS에서는 900 ms`) -## 도구 및 사용자 지정 제공자 +## 도구 및 사용자 지정 provider -도구 정책, 실험적 토글, 제공자 기반 도구 구성, 사용자 지정 제공자 / 기본 URL 설정은 전용 페이지로 이동했습니다. [구성 - 도구 및 사용자 지정 제공자](/ko/gateway/config-tools)를 참조하세요. +도구 정책, 실험적 토글, provider 기반 도구 config, 사용자 지정 provider / base-URL 설정은 전용 페이지로 이동했습니다 - [Configuration - tools and custom providers](/ko/gateway/config-tools)를 참조하세요. ## 모델 -제공자 정의, 모델 허용 목록, 사용자 지정 제공자 설정은 [구성 - 도구 및 사용자 지정 제공자](/ko/gateway/config-tools#custom-providers-and-base-urls)에 있습니다. `models` 루트도 전역 모델 카탈로그 동작을 소유합니다. +Provider 정의, 모델 allowlist, 사용자 지정 provider 설정은 [Configuration - tools and custom providers](/ko/gateway/config-tools#custom-providers-and-base-urls)에 있습니다. `models` root는 전역 모델 카탈로그 동작도 소유합니다. ```json5 { @@ -68,13 +68,13 @@ x-i18n: } ``` -- `models.mode`: 제공자 카탈로그 동작(`merge` 또는 `replace`). -- `models.providers`: 제공자 ID를 키로 사용하는 사용자 지정 제공자 맵. -- `models.pricing.enabled`: sidecar와 채널이 Gateway 준비 경로에 도달한 후 시작되는 백그라운드 가격 부트스트랩을 제어합니다. `false`이면 Gateway는 OpenRouter와 LiteLLM 가격 카탈로그 가져오기를 건너뜁니다. 구성된 `models.providers.*.models[].cost` 값은 로컬 비용 추정에 계속 작동합니다. +- `models.mode`: provider 카탈로그 동작(`merge` 또는 `replace`). +- `models.providers`: provider id로 키가 지정된 사용자 지정 provider 맵. +- `models.pricing.enabled`: sidecar와 채널이 Gateway ready 경로에 도달한 후 시작되는 백그라운드 pricing bootstrap을 제어합니다. `false`이면 Gateway는 OpenRouter 및 LiteLLM pricing-catalog 가져오기를 건너뛰며, 구성된 `models.providers.*.models[].cost` 값은 로컬 비용 추정에 계속 작동합니다. ## MCP -OpenClaw가 관리하는 MCP 서버 정의는 `mcp.servers` 아래에 있으며, 임베디드 Pi 및 기타 런타임 어댑터가 사용합니다. `openclaw mcp list`, `show`, `set`, `unset` 명령은 구성 수정 중 대상 서버에 연결하지 않고 이 블록을 관리합니다. +OpenClaw가 관리하는 MCP 서버 정의는 `mcp.servers` 아래에 있으며 embedded Pi와 기타 런타임 어댑터에서 사용됩니다. `openclaw mcp list`, `show`, `set`, `unset` 명령은 config 편집 중 대상 서버에 연결하지 않고 이 블록을 관리합니다. ```json5 { @@ -98,11 +98,15 @@ OpenClaw가 관리하는 MCP 서버 정의는 `mcp.servers` 아래에 있으며, } ``` -- `mcp.servers`: 구성된 MCP 도구를 노출하는 런타임을 위한 이름 있는 stdio 또는 원격 MCP 서버 정의입니다. 원격 항목은 `transport: "streamable-http"` 또는 `transport: "sse"`를 사용합니다. `type: "http"`는 `openclaw mcp set`과 `openclaw doctor --fix`가 표준 `transport` 필드로 정규화하는 CLI 네이티브 별칭입니다. -- `mcp.sessionIdleTtlMs`: 세션 범위 번들 MCP 런타임의 유휴 TTL입니다. 일회성 임베디드 실행은 실행 종료 정리를 요청합니다. 이 TTL은 장기 실행 세션과 향후 호출자를 위한 대비책입니다. -- `mcp.*` 아래 변경 사항은 캐시된 세션 MCP 런타임을 폐기하여 즉시 적용됩니다. 다음 도구 검색/사용이 새 구성에서 런타임을 다시 생성하므로, 제거된 `mcp.servers` 항목은 유휴 TTL을 기다리지 않고 즉시 회수됩니다. +- `mcp.servers`: 구성된 MCP 도구를 노출하는 런타임을 위한 이름 있는 stdio 또는 원격 MCP 서버 정의. + 원격 항목은 `transport: "streamable-http"` 또는 `transport: "sse"`를 사용합니다. + `type: "http"`는 `openclaw mcp set` 및 `openclaw doctor --fix`가 표준 `transport` 필드로 정규화하는 CLI 네이티브 별칭입니다. +- `mcp.sessionIdleTtlMs`: 세션 범위 번들 MCP 런타임의 idle TTL. + 일회성 embedded 실행은 실행 종료 정리를 요청합니다. 이 TTL은 장기 세션과 향후 호출자를 위한 백스톱입니다. +- `mcp.*` 아래 변경 사항은 캐시된 세션 MCP 런타임을 폐기하여 hot-apply됩니다. + 다음 도구 검색/사용 시 새 config에서 다시 생성하므로 제거된 `mcp.servers` 항목은 idle TTL을 기다리지 않고 즉시 정리됩니다. -런타임 동작은 [MCP](/ko/cli/mcp#openclaw-as-an-mcp-client-registry) 및 [CLI 백엔드](/ko/gateway/cli-backends#bundle-mcp-overlays)를 참조하세요. +런타임 동작은 [MCP](/ko/cli/mcp#openclaw-as-an-mcp-client-registry) 및 [CLI backends](/ko/gateway/cli-backends#bundle-mcp-overlays)를 참조하세요. ## Skills @@ -129,16 +133,16 @@ OpenClaw가 관리하는 MCP 서버 정의는 `mcp.servers` 아래에 있으며, } ``` -- `allowBundled`: 번들 Skills 전용 선택적 허용 목록입니다(관리형/작업공간 Skills에는 영향 없음). -- `load.extraDirs`: 추가 공유 skill 루트(가장 낮은 우선순위). -- `install.preferBrew`: true이면 `brew`를 사용할 수 있을 때 다른 설치 프로그램 종류로 대체하기 전에 Homebrew 설치 프로그램을 우선합니다. -- `install.nodeManager`: `metadata.openclaw.install` 사양에 대한 node 설치 프로그램 선호도(`npm` | `pnpm` | `yarn` | `bun`). +- `allowBundled`: 번들 Skills에만 적용되는 선택적 allowlist(관리형/workspace Skills에는 영향 없음). +- `load.extraDirs`: 추가 공유 skill root(가장 낮은 우선순위). +- `install.preferBrew`: true이면 `brew`를 사용할 수 있을 때 다른 installer 종류로 fallback하기 전에 Homebrew installer를 우선합니다. +- `install.nodeManager`: `metadata.openclaw.install` 사양에 대한 node installer 선호도(`npm` | `pnpm` | `yarn` | `bun`). - `entries..enabled: false`는 번들/설치되어 있더라도 skill을 비활성화합니다. -- `entries..apiKey`: 기본 환경 변수를 선언하는 Skills를 위한 편의 기능입니다(일반 텍스트 문자열 또는 SecretRef 객체). +- `entries..apiKey`: 기본 env var를 선언하는 Skills를 위한 편의 기능(plaintext string 또는 SecretRef object). --- -## Plugin +## Plugins ```json5 { @@ -163,59 +167,59 @@ OpenClaw가 관리하는 MCP 서버 정의는 `mcp.servers` 아래에 있으며, } ``` -- `~/.openclaw/extensions`, `/.openclaw/extensions`, 그리고 `plugins.load.paths`에서 로드됩니다. -- 검색은 네이티브 OpenClaw plugins와 호환되는 Codex 번들 및 Claude 번들을 허용하며, 매니페스트가 없는 Claude 기본 레이아웃 번들도 포함합니다. -- **구성 변경에는 gateway 재시작이 필요합니다.** -- `allow`: 선택적 허용 목록(나열된 plugins만 로드). `deny`가 우선합니다. -- `bundledDiscovery`: 새 구성에서는 기본값이 `"allowlist"`이므로, 비어 있지 않은 `plugins.allow`는 web-search 런타임 제공자를 포함한 번들 제공자 plugins도 게이트합니다. Doctor는 기존 번들 제공자 동작을 사용자가 옵트인할 때까지 보존하기 위해 마이그레이션된 레거시 허용 목록 구성에 `"compat"`을 씁니다. -- `plugins.entries..apiKey`: Plugin 수준 API 키 편의 필드입니다(Plugin에서 지원하는 경우). -- `plugins.entries..env`: Plugin 범위 환경 변수 맵. -- `plugins.entries..hooks.allowPromptInjection`: `false`이면 core가 `before_prompt_build`를 차단하고 레거시 `before_agent_start`의 프롬프트 변경 필드를 무시하면서, 레거시 `modelOverride`와 `providerOverride`는 보존합니다. 네이티브 Plugin hooks와 지원되는 번들 제공 hook 디렉터리에 적용됩니다. -- `plugins.entries..hooks.allowConversationAccess`: `true`이면 신뢰할 수 있는 비번들 plugins가 `llm_input`, `llm_output`, `before_agent_finalize`, `agent_end` 같은 typed hooks에서 원시 대화 내용을 읽을 수 있습니다. -- `plugins.entries..subagent.allowModelOverride`: 이 Plugin이 백그라운드 하위 에이전트 실행에 대해 실행별 `provider` 및 `model` override를 요청할 수 있도록 명시적으로 신뢰합니다. -- `plugins.entries..subagent.allowedModels`: 신뢰할 수 있는 하위 에이전트 override를 위한 표준 `provider/model` 대상의 선택적 허용 목록입니다. 어떤 모델이든 허용하려는 의도가 있을 때만 `"*"`를 사용하세요. -- `plugins.entries..config`: Plugin 정의 구성 객체입니다(사용 가능한 경우 네이티브 OpenClaw Plugin 스키마로 검증). -- 채널 Plugin 계정/런타임 설정은 `channels.` 아래에 있으며, 중앙 OpenClaw 옵션 레지스트리가 아니라 소유 Plugin의 매니페스트 `channelConfigs` 메타데이터로 설명되어야 합니다. -- `plugins.entries.firecrawl.config.webFetch`: Firecrawl web-fetch 제공자 설정. - - `apiKey`: Firecrawl API 키(SecretRef 허용). `plugins.entries.firecrawl.config.webSearch.apiKey`, 레거시 `tools.web.fetch.firecrawl.apiKey`, 또는 `FIRECRAWL_API_KEY` 환경 변수로 대체됩니다. - - `baseUrl`: Firecrawl API 기본 URL(기본값: `https://api.firecrawl.dev`; 자체 호스팅 override는 private/internal 엔드포인트를 대상으로 해야 함). - - `onlyMainContent`: 페이지에서 주요 콘텐츠만 추출합니다(기본값: `true`). - - `maxAgeMs`: 최대 캐시 수명(밀리초)(기본값: `172800000` / 2일). - - `timeoutSeconds`: 스크레이프 요청 제한 시간(초)(기본값: `60`). -- `plugins.entries.xai.config.xSearch`: xAI X Search(Grok 웹 검색) 설정. - - `enabled`: X Search 제공자를 활성화합니다. +- `~/.openclaw/extensions`, `/.openclaw/extensions` 및 `plugins.load.paths`에서 로드됩니다. +- Discovery는 네이티브 OpenClaw Plugins와 호환되는 Codex 번들 및 Claude 번들을 허용하며, manifest가 없는 Claude 기본 레이아웃 번들도 포함합니다. +- **Config 변경에는 gateway 재시작이 필요합니다.** +- `allow`: 선택적 allowlist(나열된 Plugins만 로드). `deny`가 우선합니다. +- `bundledDiscovery`: 새 config의 기본값은 `"allowlist"`이므로 비어 있지 않은 `plugins.allow`는 web-search 런타임 provider를 포함한 번들 provider Plugins도 gate합니다. Doctor는 기존 번들 provider 동작을 opt in할 때까지 보존하기 위해 마이그레이션된 legacy allowlist config에 `"compat"`를 씁니다. +- `plugins.entries..apiKey`: Plugin 수준 API key 편의 필드(Plugin에서 지원하는 경우). +- `plugins.entries..env`: Plugin 범위 env var 맵. +- `plugins.entries..hooks.allowPromptInjection`: `false`이면 core가 `before_prompt_build`를 차단하고 legacy `before_agent_start`의 prompt 변경 필드를 무시하며, legacy `modelOverride`와 `providerOverride`는 보존합니다. 네이티브 Plugin hook 및 지원되는 bundle 제공 hook 디렉터리에 적용됩니다. +- `plugins.entries..hooks.allowConversationAccess`: `true`이면 신뢰할 수 있는 비번들 Plugins가 `llm_input`, `llm_output`, `before_model_resolve`, `before_agent_reply`, `before_agent_run`, `before_agent_finalize`, `agent_end` 같은 typed hooks에서 원시 conversation content를 읽을 수 있습니다. +- `plugins.entries..subagent.allowModelOverride`: 이 Plugin이 background subagent 실행마다 `provider` 및 `model` override를 요청하도록 명시적으로 신뢰합니다. +- `plugins.entries..subagent.allowedModels`: 신뢰할 수 있는 subagent override를 위한 표준 `provider/model` 대상의 선택적 allowlist. 어떤 모델이든 허용하려는 의도가 있을 때만 `"*"`를 사용하세요. +- `plugins.entries..config`: Plugin 정의 config object(사용 가능한 경우 네이티브 OpenClaw Plugin schema로 검증됨). +- 채널 Plugin 계정/런타임 설정은 `channels.` 아래에 있으며, 중앙 OpenClaw option registry가 아니라 소유 Plugin의 manifest `channelConfigs` 메타데이터로 설명되어야 합니다. +- `plugins.entries.firecrawl.config.webFetch`: Firecrawl web-fetch provider 설정. + - `apiKey`: Firecrawl API key(SecretRef 허용). `plugins.entries.firecrawl.config.webSearch.apiKey`, legacy `tools.web.fetch.firecrawl.apiKey` 또는 `FIRECRAWL_API_KEY` env var로 fallback합니다. + - `baseUrl`: Firecrawl API base URL(기본값: `https://api.firecrawl.dev`; self-hosted override는 private/internal endpoint를 대상으로 해야 함). + - `onlyMainContent`: 페이지에서 main content만 추출합니다(기본값: `true`). + - `maxAgeMs`: 밀리초 단위 최대 cache age(기본값: `172800000` / 2일). + - `timeoutSeconds`: 초 단위 scrape request timeout(기본값: `60`). +- `plugins.entries.xai.config.xSearch`: xAI X Search(Grok web search) 설정. + - `enabled`: X Search provider를 활성화합니다. - `model`: 검색에 사용할 Grok 모델(예: `"grok-4-1-fast"`). -- `plugins.entries.memory-core.config.dreaming`: 메모리 dreaming 설정. 단계와 임곗값은 [Dreaming](/ko/concepts/dreaming)을 참조하세요. - - `enabled`: 마스터 dreaming 스위치(기본값 `false`). - - `frequency`: 각 전체 dreaming 스윕의 cron 주기(기본값 `"0 3 * * *"`). - - `model`: 선택적 Dream Diary 하위 에이전트 모델 override. `plugins.entries.memory-core.subagent.allowModelOverride: true`가 필요합니다. 대상을 제한하려면 `allowedModels`와 함께 사용하세요. 모델 사용 불가 오류는 세션 기본 모델로 한 번 재시도합니다. 신뢰 또는 허용 목록 실패는 조용히 대체되지 않습니다. - - 단계 정책과 임곗값은 구현 세부 사항입니다(사용자 노출 구성 키가 아님). -- 전체 메모리 구성은 [메모리 구성 참조](/ko/reference/memory-config)에 있습니다. +- `plugins.entries.memory-core.config.dreaming`: 메모리 dreaming 설정. 단계와 threshold는 [Dreaming](/ko/concepts/dreaming)을 참조하세요. + - `enabled`: master dreaming switch(기본값 `false`). + - `frequency`: 각 전체 dreaming sweep의 cron cadence(기본값 `"0 3 * * *"`). + - `model`: 선택적 Dream Diary subagent 모델 override. `plugins.entries.memory-core.subagent.allowModelOverride: true`가 필요하며, 대상을 제한하려면 `allowedModels`와 함께 사용하세요. 모델을 사용할 수 없음 오류는 세션 기본 모델로 한 번 retry합니다. trust 또는 allowlist 실패는 조용히 fallback하지 않습니다. + - phase policy와 threshold는 구현 세부 사항입니다(사용자에게 노출되는 config key가 아님). +- 전체 메모리 config는 [Memory configuration reference](/ko/reference/memory-config)에 있습니다: - `agents.defaults.memorySearch.*` - `memory.backend` - `memory.citations` - `memory.qmd.*` - `plugins.entries.memory-core.config.dreaming` -- 활성화된 Claude 번들 plugins도 `settings.json`에서 임베디드 Pi 기본값을 제공할 수 있습니다. OpenClaw는 이를 원시 OpenClaw 구성 패치가 아니라 정리된 에이전트 설정으로 적용합니다. -- `plugins.slots.memory`: 활성 메모리 Plugin ID를 선택하거나, 메모리 plugins를 비활성화하려면 `"none"`을 선택합니다. -- `plugins.slots.contextEngine`: 활성 컨텍스트 엔진 Plugin ID를 선택합니다. 다른 엔진을 설치하고 선택하지 않는 한 기본값은 `"legacy"`입니다. +- 활성화된 Claude bundle Plugins는 `settings.json`에서 embedded Pi 기본값도 제공할 수 있습니다. OpenClaw는 이를 원시 OpenClaw config patch가 아니라 sanitized agent settings로 적용합니다. +- `plugins.slots.memory`: 활성 memory Plugin id를 선택하거나, memory Plugins를 비활성화하려면 `"none"`을 선택합니다. +- `plugins.slots.contextEngine`: 활성 context engine Plugin id를 선택합니다. 다른 engine을 설치하고 선택하지 않는 한 기본값은 `"legacy"`입니다. -[Plugin](/ko/tools/plugin)을 참조하세요. +[Plugins](/ko/tools/plugin)를 참조하세요. --- -## 약속 +## Commitments -`commitments`는 추론된 후속 메모리를 제어합니다. OpenClaw는 대화 턴에서 check-in을 감지하고 Heartbeat 실행을 통해 전달할 수 있습니다. +`commitments`는 추론된 follow-up memory를 제어합니다. OpenClaw는 conversation turn에서 check-in을 감지하고 heartbeat 실행을 통해 전달할 수 있습니다. -- `commitments.enabled`: 추론된 후속 약속에 대한 숨겨진 LLM 추출, 저장, Heartbeat 전달을 활성화합니다. 기본값: `false`. -- `commitments.maxPerDay`: rolling day 동안 에이전트 세션당 전달되는 추론된 후속 약속의 최대 수입니다. 기본값: `3`. +- `commitments.enabled`: 추론된 follow-up commitments에 대한 숨겨진 LLM extraction, storage, heartbeat delivery를 활성화합니다. 기본값: `false`. +- `commitments.maxPerDay`: rolling day 동안 agent session마다 전달되는 추론된 follow-up commitments의 최대 수. 기본값: `3`. -[추론된 약속](/ko/concepts/commitments)을 참조하세요. +[Inferred commitments](/ko/concepts/commitments)을 참조하세요. --- -## 브라우저 +## Browser ```json5 { @@ -262,26 +266,26 @@ OpenClaw가 관리하는 MCP 서버 정의는 `mcp.servers` 아래에 있으며, ``` - `evaluateEnabled: false`는 `act:evaluate`와 `wait --fn`을 비활성화합니다. -- `tabCleanup`은 유휴 시간 이후 또는 세션이 한도를 초과할 때 추적 중인 기본 에이전트 탭을 회수합니다. `idleMinutes: 0` 또는 `maxTabsPerSession: 0`을 설정하면 해당 개별 정리 모드를 비활성화할 수 있습니다. +- `tabCleanup`은 유휴 시간이 지난 뒤 또는 세션이 한도를 초과할 때 추적 중인 기본 에이전트 탭을 회수합니다. 해당 개별 정리 모드를 비활성화하려면 `idleMinutes: 0` 또는 `maxTabsPerSession: 0`을 설정하세요. - `ssrfPolicy.dangerouslyAllowPrivateNetwork`는 설정하지 않으면 비활성화되므로, 브라우저 탐색은 기본적으로 엄격하게 유지됩니다. -- private-network 브라우저 탐색을 의도적으로 신뢰하는 경우에만 `ssrfPolicy.dangerouslyAllowPrivateNetwork: true`를 설정하세요. -- 엄격 모드에서는 원격 CDP 프로필 엔드포인트(`profiles.*.cdpUrl`)가 도달 가능성/검색 확인 중 동일한 private-network 차단의 적용을 받습니다. -- `ssrfPolicy.allowPrivateNetwork`는 기존 별칭으로 계속 지원됩니다. +- 비공개 네트워크 브라우저 탐색을 의도적으로 신뢰하는 경우에만 `ssrfPolicy.dangerouslyAllowPrivateNetwork: true`를 설정하세요. +- 엄격 모드에서는 원격 CDP 프로필 엔드포인트(`profiles.*.cdpUrl`)도 도달 가능성/검색 검사 중 동일한 비공개 네트워크 차단의 적용을 받습니다. +- `ssrfPolicy.allowPrivateNetwork`는 레거시 별칭으로 계속 지원됩니다. - 엄격 모드에서는 명시적 예외에 `ssrfPolicy.hostnameAllowlist`와 `ssrfPolicy.allowedHostnames`를 사용하세요. -- 원격 프로필은 연결 전용입니다(시작/중지/재설정 비활성화). +- 원격 프로필은 attach-only입니다(시작/중지/재설정 비활성화). - `profiles.*.cdpUrl`은 `http://`, `https://`, `ws://`, `wss://`를 허용합니다. - OpenClaw가 `/json/version`을 검색하도록 하려면 HTTP(S)를 사용하고, 공급자가 직접 DevTools WebSocket URL을 제공하는 경우 WS(S)를 사용하세요. + OpenClaw가 `/json/version`을 검색하도록 하려면 HTTP(S)를 사용하고, 공급자가 직접 DevTools WebSocket URL을 제공하는 경우에는 WS(S)를 사용하세요. - `remoteCdpTimeoutMs`와 `remoteCdpHandshakeTimeoutMs`는 원격 및 `attachOnly` CDP 도달 가능성과 탭 열기 요청에 적용됩니다. 관리형 loopback 프로필은 로컬 CDP 기본값을 유지합니다. -- 외부에서 관리되는 CDP 서비스가 loopback을 통해 도달 가능한 경우 해당 프로필의 `attachOnly: true`를 설정하세요. 그렇지 않으면 OpenClaw는 loopback 포트를 로컬 관리형 브라우저 프로필로 취급하며 로컬 포트 소유권 오류를 보고할 수 있습니다. +- 외부에서 관리되는 CDP 서비스가 loopback을 통해 도달 가능한 경우 해당 프로필의 `attachOnly: true`를 설정하세요. 그렇지 않으면 OpenClaw는 loopback 포트를 로컬 관리형 브라우저 프로필로 취급하여 로컬 포트 소유권 오류를 보고할 수 있습니다. - `existing-session` 프로필은 CDP 대신 Chrome MCP를 사용하며, 선택한 호스트 또는 연결된 브라우저 노드를 통해 연결할 수 있습니다. -- `existing-session` 프로필은 Brave나 Edge 같은 특정 Chromium 기반 브라우저 프로필을 대상으로 `userDataDir`를 설정할 수 있습니다. -- `existing-session` 프로필은 현재 Chrome MCP 라우트 제한을 유지합니다: - CSS 선택자 대상 지정 대신 스냅샷/ref 기반 작업, 단일 파일 업로드 hook, 대화 상자 시간 제한 재정의 없음, `wait --load networkidle` 없음, `responsebody`, PDF 내보내기, 다운로드 가로채기 또는 배치 작업 없음. -- 로컬 관리형 `openclaw` 프로필은 `cdpPort`와 `cdpUrl`을 자동 할당합니다. 원격 CDP에 대해서만 `cdpUrl`을 명시적으로 설정하세요. -- 로컬 관리형 프로필은 해당 프로필의 전역 `browser.executablePath`를 재정의하도록 `executablePath`를 설정할 수 있습니다. 이를 사용해 한 프로필은 Chrome에서, 다른 프로필은 Brave에서 실행하세요. -- 로컬 관리형 프로필은 프로세스 시작 후 Chrome CDP HTTP 검색에 `browser.localLaunchTimeoutMs`를 사용하고, 실행 후 CDP websocket 준비 상태에 `browser.localCdpReadyTimeoutMs`를 사용합니다. Chrome은 성공적으로 시작되지만 준비 상태 확인이 시작과 경합하는 느린 호스트에서는 이 값을 높이세요. 두 값 모두 `120000` ms 이하의 양의 정수여야 하며, 유효하지 않은 구성 값은 거부됩니다. -- 자동 감지 순서: 기본 브라우저가 Chromium 기반인 경우 → Chrome → Brave → Edge → Chromium → Chrome Canary. -- `browser.executablePath`와 `browser.profiles..executablePath`는 모두 Chromium 실행 전에 OS 홈 디렉터리에 대해 `~`와 `~/...`를 허용합니다. +- `existing-session` 프로필은 Brave나 Edge 같은 특정 Chromium 기반 브라우저 프로필을 대상으로 지정하기 위해 `userDataDir`을 설정할 수 있습니다. +- `existing-session` 프로필은 현재 Chrome MCP 경로 제한을 유지합니다. + CSS 선택자 대상 지정 대신 snapshot/ref 기반 작업, 단일 파일 업로드 훅, 대화 상자 시간 제한 재정의 없음, `wait --load networkidle` 없음, 그리고 `responsebody`, PDF 내보내기, 다운로드 가로채기, 배치 작업 없음. +- 로컬 관리형 `openclaw` 프로필은 `cdpPort`와 `cdpUrl`을 자동으로 할당합니다. 원격 CDP에 대해서만 `cdpUrl`을 명시적으로 설정하세요. +- 로컬 관리형 프로필은 해당 프로필에 대해 전역 `browser.executablePath`를 재정의하도록 `executablePath`를 설정할 수 있습니다. 이를 사용해 한 프로필은 Chrome에서, 다른 프로필은 Brave에서 실행할 수 있습니다. +- 로컬 관리형 프로필은 프로세스 시작 후 Chrome CDP HTTP 검색에 `browser.localLaunchTimeoutMs`를 사용하고, 실행 후 CDP websocket 준비 상태에는 `browser.localCdpReadyTimeoutMs`를 사용합니다. Chrome은 정상적으로 시작되지만 준비 상태 검사가 시작과 경합하는 느린 호스트에서는 이 값을 늘리세요. 두 값은 모두 `120000`ms 이하의 양의 정수여야 하며, 잘못된 구성 값은 거부됩니다. +- 자동 감지 순서: Chromium 기반인 경우 기본 브라우저 → Chrome → Brave → Edge → Chromium → Chrome Canary. +- `browser.executablePath`와 `browser.profiles..executablePath`는 모두 Chromium 실행 전에 OS 홈 디렉터리로 `~`와 `~/...`를 허용합니다. `existing-session` 프로필의 프로필별 `userDataDir`도 틸드 확장이 적용됩니다. - 제어 서비스: loopback 전용(`gateway.port`에서 파생된 포트, 기본값 `18791`). - `extraArgs`는 로컬 Chromium 시작에 추가 실행 플래그를 덧붙입니다(예: `--disable-gpu`, 창 크기 지정 또는 디버그 플래그). @@ -302,8 +306,8 @@ OpenClaw가 관리하는 MCP 서버 정의는 `mcp.servers` 아래에 있으며, } ``` -- `seamColor`: 네이티브 앱 UI chrome의 강조 색상(Talk Mode 버블 색조 등). -- `assistant`: Control UI ID 재정의. 활성 에이전트 ID로 대체됩니다. +- `seamColor`: 네이티브 앱 UI 크롬의 강조 색상(Talk Mode 말풍선 색조 등). +- `assistant`: Control UI ID 재정의입니다. 활성 에이전트 ID로 대체됩니다. --- @@ -379,55 +383,54 @@ OpenClaw가 관리하는 MCP 서버 정의는 `mcp.servers` 아래에 있으며, } ``` - + -- `mode`: `local`(gateway 실행) 또는 `remote`(원격 gateway에 연결). Gateway는 `local`이 아니면 시작을 거부합니다. -- `port`: WS + HTTP용 단일 멀티플렉스 포트. 우선순위: `--port` > `OPENCLAW_GATEWAY_PORT` > `gateway.port` > `18789`. -- `bind`: `auto`, `loopback`(기본값), `lan`(`0.0.0.0`), `tailnet`(Tailscale IP만), 또는 `custom`. -- **레거시 bind 별칭**: 호스트 별칭(`0.0.0.0`, `127.0.0.1`, `localhost`, `::`, `::1`)이 아니라 `gateway.bind`의 bind 모드 값(`auto`, `loopback`, `lan`, `tailnet`, `custom`)을 사용하세요. -- **Docker 참고**: 기본 `loopback` bind는 컨테이너 내부의 `127.0.0.1`에서 수신 대기합니다. Docker 브리지 네트워킹(`-p 18789:18789`)에서는 트래픽이 `eth0`로 들어오므로 gateway에 도달할 수 없습니다. 모든 인터페이스에서 수신 대기하려면 `--network host`를 사용하거나 `bind: "lan"`(또는 `customBindHost: "0.0.0.0"`와 함께 `bind: "custom"`)을 설정하세요. -- **인증**: 기본적으로 필요합니다. 비루프백 bind에는 gateway 인증이 필요합니다. 실제로는 공유 토큰/비밀번호 또는 `gateway.auth.mode: "trusted-proxy"`를 사용하는 ID 인식 리버스 프록시를 의미합니다. 온보딩 마법사는 기본적으로 토큰을 생성합니다. -- `gateway.auth.token`과 `gateway.auth.password`가 모두 구성된 경우(SecretRef 포함) `gateway.auth.mode`를 명시적으로 `token` 또는 `password`로 설정하세요. 둘 다 구성되어 있고 mode가 설정되지 않은 경우 시작 및 서비스 설치/복구 흐름이 실패합니다. -- `gateway.auth.mode: "none"`: 명시적 무인증 모드입니다. 신뢰할 수 있는 local loopback 설정에서만 사용하세요. 이는 의도적으로 온보딩 프롬프트에서 제공되지 않습니다. -- `gateway.auth.mode: "trusted-proxy"`: 브라우저/사용자 인증을 ID 인식 리버스 프록시에 위임하고 `gateway.trustedProxies`의 ID 헤더를 신뢰합니다([신뢰할 수 있는 프록시 인증](/ko/gateway/trusted-proxy-auth) 참조). 이 모드는 기본적으로 **비루프백** 프록시 소스를 기대합니다. 동일 호스트 루프백 리버스 프록시에는 명시적 `gateway.auth.trustedProxy.allowLoopback = true`가 필요합니다. 내부 동일 호스트 호출자는 로컬 직접 폴백으로 `gateway.auth.password`를 사용할 수 있습니다. `gateway.auth.token`은 trusted-proxy 모드와 계속 상호 배타적입니다. -- `gateway.auth.allowTailscale`: `true`이면 Tailscale Serve ID 헤더가 Control UI/WebSocket 인증을 충족할 수 있습니다(`tailscale whois`로 확인). HTTP API 엔드포인트는 해당 Tailscale 헤더 인증을 사용하지 **않으며**, 대신 gateway의 일반 HTTP 인증 모드를 따릅니다. 이 무토큰 흐름은 gateway 호스트가 신뢰된다고 가정합니다. `tailscale.mode = "serve"`이면 기본값은 `true`입니다. -- `gateway.auth.rateLimit`: 선택적 인증 실패 제한기입니다. 클라이언트 IP별, 인증 범위별로 적용됩니다(공유 비밀과 디바이스 토큰은 독립적으로 추적됨). 차단된 시도는 `429` + `Retry-After`를 반환합니다. - - 비동기 Tailscale Serve Control UI 경로에서는 동일한 `{scope, clientIp}`에 대한 실패 시도가 실패 쓰기 전에 직렬화됩니다. 따라서 동일 클라이언트의 동시 잘못된 시도는 둘 다 단순 불일치로 경합하며 통과하는 대신 두 번째 요청에서 제한기를 트리거할 수 있습니다. - - `gateway.auth.rateLimit.exemptLoopback`의 기본값은 `true`입니다. localhost 트래픽도 의도적으로 속도 제한하려면(테스트 설정 또는 엄격한 프록시 배포의 경우) `false`로 설정하세요. -- 브라우저 출처 WS 인증 시도는 항상 루프백 예외가 비활성화된 상태로 스로틀링됩니다(브라우저 기반 localhost 무차별 대입에 대한 심층 방어). +- `mode`: `local`(Gateway 실행) 또는 `remote`(원격 Gateway에 연결). `local`이 아니면 Gateway가 시작을 거부합니다. +- `port`: WS + HTTP용 단일 다중화 포트. 우선순위: `--port` > `OPENCLAW_GATEWAY_PORT` > `gateway.port` > `18789`. +- `bind`: `auto`, `loopback`(기본값), `lan`(`0.0.0.0`), `tailnet`(Tailscale IP만) 또는 `custom`. +- **레거시 바인드 별칭**: `gateway.bind`에는 호스트 별칭(`0.0.0.0`, `127.0.0.1`, `localhost`, `::`, `::1`)이 아니라 바인드 모드 값(`auto`, `loopback`, `lan`, `tailnet`, `custom`)을 사용하세요. +- **Docker 참고**: 기본 `loopback` 바인드는 컨테이너 내부의 `127.0.0.1`에서 수신 대기합니다. Docker 브리지 네트워킹(`-p 18789:18789`)에서는 트래픽이 `eth0`로 도착하므로 Gateway에 접근할 수 없습니다. 모든 인터페이스에서 수신 대기하려면 `--network host`를 사용하거나 `bind: "lan"`(또는 `customBindHost: "0.0.0.0"`와 함께 `bind: "custom"`)을 설정하세요. +- **인증**: 기본적으로 필요합니다. 비루프백 바인드에는 Gateway 인증이 필요합니다. 실제로는 공유 토큰/비밀번호 또는 `gateway.auth.mode: "trusted-proxy"`를 사용하는 ID 인식 리버스 프록시를 의미합니다. 온보딩 마법사는 기본적으로 토큰을 생성합니다. +- `gateway.auth.token`과 `gateway.auth.password`가 모두 구성된 경우(SecretRefs 포함), `gateway.auth.mode`를 `token` 또는 `password`로 명시적으로 설정하세요. 둘 다 구성되어 있고 모드가 설정되지 않으면 시작 및 서비스 설치/복구 흐름이 실패합니다. +- `gateway.auth.mode: "none"`: 명시적 무인증 모드입니다. 신뢰할 수 있는 local loopback 설정에만 사용하세요. 이 모드는 의도적으로 온보딩 프롬프트에서 제공되지 않습니다. +- `gateway.auth.mode: "trusted-proxy"`: 브라우저/사용자 인증을 ID 인식 리버스 프록시에 위임하고 `gateway.trustedProxies`의 ID 헤더를 신뢰합니다([신뢰할 수 있는 프록시 인증](/ko/gateway/trusted-proxy-auth) 참조). 이 모드는 기본적으로 **비루프백** 프록시 소스를 기대합니다. 동일 호스트 루프백 리버스 프록시는 명시적으로 `gateway.auth.trustedProxy.allowLoopback = true`가 필요합니다. 내부 동일 호스트 호출자는 로컬 직접 폴백으로 `gateway.auth.password`를 사용할 수 있습니다. `gateway.auth.token`은 trusted-proxy 모드와 계속 상호 배타적입니다. +- `gateway.auth.allowTailscale`: `true`이면 Tailscale Serve ID 헤더가 Control UI/WebSocket 인증을 충족할 수 있습니다(`tailscale whois`로 확인). HTTP API 엔드포인트는 해당 Tailscale 헤더 인증을 **사용하지 않고**, 대신 Gateway의 일반 HTTP 인증 모드를 따릅니다. 이 토큰 없는 흐름은 Gateway 호스트가 신뢰된다고 가정합니다. `tailscale.mode = "serve"`이면 기본값은 `true`입니다. +- `gateway.auth.rateLimit`: 선택적 인증 실패 제한기입니다. 클라이언트 IP별 및 인증 범위별로 적용됩니다(shared-secret과 device-token은 독립적으로 추적됨). 차단된 시도는 `429` + `Retry-After`를 반환합니다. + - 비동기 Tailscale Serve Control UI 경로에서는 동일한 `{scope, clientIp}`에 대한 실패 시도가 실패 쓰기 전에 직렬화됩니다. 따라서 동일한 클라이언트의 동시 잘못된 시도는 둘 다 일반 불일치로 통과하는 대신 두 번째 요청에서 제한기에 걸릴 수 있습니다. + - `gateway.auth.rateLimit.exemptLoopback`의 기본값은 `true`입니다. localhost 트래픽도 의도적으로 속도 제한하려는 경우(테스트 설정 또는 엄격한 프록시 배포) `false`로 설정하세요. +- 브라우저 출처 WS 인증 시도는 항상 루프백 예외가 비활성화된 상태로 제한됩니다(브라우저 기반 localhost 무차별 대입에 대한 심층 방어). - 루프백에서는 이러한 브라우저 출처 잠금이 정규화된 `Origin` - 값별로 격리되므로, 한 localhost 출처의 반복 실패가 다른 출처를 자동으로 - 잠그지는 않습니다. -- `tailscale.mode`: `serve`(tailnet만, 루프백 bind) 또는 `funnel`(공개, 인증 필요). -- `controlUi.allowedOrigins`: Gateway WebSocket 연결에 대한 명시적 브라우저 출처 허용 목록입니다. 브라우저 클라이언트가 비루프백 출처에서 예상되는 경우 필요합니다. + 값별로 격리되므로, 한 localhost 출처에서 반복 실패해도 다른 출처가 + 자동으로 잠기지 않습니다. +- `tailscale.mode`: `serve`(tailnet 전용, 루프백 바인드) 또는 `funnel`(공개, 인증 필요). +- `controlUi.allowedOrigins`: Gateway WebSocket 연결을 위한 명시적 브라우저 출처 허용 목록입니다. 비루프백 출처의 브라우저 클라이언트가 예상되는 경우 필요합니다. - `controlUi.chatMessageMaxWidth`: 그룹화된 Control UI 채팅 메시지의 선택적 최대 너비입니다. `960px`, `82%`, `min(1280px, 82%)`, `calc(100% - 2rem)` 같은 제한된 CSS 너비 값을 허용합니다. -- `controlUi.dangerouslyAllowHostHeaderOriginFallback`: 의도적으로 Host 헤더 출처 정책에 의존하는 배포를 위해 Host 헤더 출처 폴백을 활성화하는 위험한 모드입니다. +- `controlUi.dangerouslyAllowHostHeaderOriginFallback`: Host 헤더 출처 정책에 의도적으로 의존하는 배포에서 Host 헤더 출처 폴백을 활성화하는 위험한 모드입니다. - `remote.transport`: `ssh`(기본값) 또는 `direct`(ws/wss). `direct`의 경우 `remote.url`은 `ws://` 또는 `wss://`여야 합니다. - `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`: 신뢰할 수 있는 사설 네트워크 - IP에 대한 평문 `ws://`를 허용하는 클라이언트 측 프로세스 환경 - 비상 오버라이드입니다. 평문 기본값은 여전히 루프백 전용입니다. 이에 대응하는 `openclaw.json` - 설정은 없으며, - `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` 같은 브라우저 사설 네트워크 구성은 Gateway - WebSocket 클라이언트에 영향을 주지 않습니다. -- `gateway.remote.token` / `.password`는 원격 클라이언트 자격 증명 필드입니다. 이 필드만으로 gateway 인증을 구성하지는 않습니다. -- `gateway.push.apns.relay.baseUrl`: 공식/TestFlight iOS 빌드가 릴레이 기반 등록을 gateway에 게시한 뒤 사용하는 외부 APNs 릴레이의 기본 HTTPS URL입니다. 이 URL은 iOS 빌드에 컴파일된 릴레이 URL과 일치해야 합니다. -- `gateway.push.apns.relay.timeoutMs`: gateway에서 릴레이로 전송할 때의 제한 시간(밀리초)입니다. 기본값은 `10000`입니다. -- 릴레이 기반 등록은 특정 gateway ID에 위임됩니다. 페어링된 iOS 앱은 `gateway.identity.get`을 가져와 해당 ID를 릴레이 등록에 포함하고, 등록 범위 전송 권한을 gateway로 전달합니다. 다른 gateway는 저장된 해당 등록을 재사용할 수 없습니다. -- `OPENCLAW_APNS_RELAY_BASE_URL` / `OPENCLAW_APNS_RELAY_TIMEOUT_MS`: 위 릴레이 구성에 대한 임시 env 오버라이드입니다. + IP에 대해 평문 `ws://`를 허용하는 클라이언트 측 프로세스 환경 + 비상 우회 설정입니다. 평문 기본값은 계속 루프백 전용입니다. 이에 해당하는 `openclaw.json` + 설정은 없으며, `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` 같은 + 브라우저 사설 네트워크 구성은 Gateway WebSocket 클라이언트에 영향을 주지 않습니다. +- `gateway.remote.token` / `.password`는 원격 클라이언트 자격 증명 필드입니다. 이 필드들만으로 Gateway 인증을 구성하지 않습니다. +- `gateway.push.apns.relay.baseUrl`: 공식/TestFlight iOS 빌드가 릴레이 기반 등록을 Gateway에 게시한 뒤 사용하는 외부 APNs 릴레이의 기본 HTTPS URL입니다. 이 URL은 iOS 빌드에 컴파일된 릴레이 URL과 일치해야 합니다. +- `gateway.push.apns.relay.timeoutMs`: Gateway에서 릴레이로 보내는 전송 제한 시간(밀리초)입니다. 기본값은 `10000`입니다. +- 릴레이 기반 등록은 특정 Gateway ID에 위임됩니다. 페어링된 iOS 앱은 `gateway.identity.get`을 가져오고, 해당 ID를 릴레이 등록에 포함하며, 등록 범위 전송 권한을 Gateway로 전달합니다. 다른 Gateway는 저장된 등록을 재사용할 수 없습니다. +- `OPENCLAW_APNS_RELAY_BASE_URL` / `OPENCLAW_APNS_RELAY_TIMEOUT_MS`: 위 릴레이 구성에 대한 임시 환경 재정의입니다. - `OPENCLAW_APNS_RELAY_ALLOW_HTTP=true`: 루프백 HTTP 릴레이 URL을 위한 개발 전용 탈출구입니다. 프로덕션 릴레이 URL은 HTTPS를 유지해야 합니다. -- `gateway.handshakeTimeoutMs`: 인증 전 Gateway WebSocket 핸드셰이크 제한 시간(밀리초)입니다. 기본값: `15000`. `OPENCLAW_HANDSHAKE_TIMEOUT_MS`가 설정되면 우선합니다. 시작 워밍업이 아직 안정화되는 동안 로컬 클라이언트가 연결될 수 있는, 부하가 있거나 저전력인 호스트에서는 이 값을 늘리세요. +- `gateway.handshakeTimeoutMs`: 인증 전 Gateway WebSocket 핸드셰이크 제한 시간(밀리초)입니다. 기본값: `15000`. 설정된 경우 `OPENCLAW_HANDSHAKE_TIMEOUT_MS`가 우선합니다. 시작 워밍업이 아직 안정화 중인 동안 로컬 클라이언트가 연결할 수 있는 부하가 있거나 저전력인 호스트에서는 이 값을 늘리세요. - `gateway.channelHealthCheckMinutes`: 채널 상태 모니터 간격(분)입니다. 상태 모니터 재시작을 전역적으로 비활성화하려면 `0`으로 설정하세요. 기본값: `5`. - `gateway.channelStaleEventThresholdMinutes`: 오래된 소켓 임계값(분)입니다. 이 값은 `gateway.channelHealthCheckMinutes`보다 크거나 같게 유지하세요. 기본값: `30`. - `gateway.channelMaxRestartsPerHour`: 롤링 1시간 동안 채널/계정별 최대 상태 모니터 재시작 횟수입니다. 기본값: `10`. -- `channels..healthMonitor.enabled`: 전역 모니터는 활성화한 채 상태 모니터 재시작에서 채널별로 제외하는 설정입니다. -- `channels..accounts..healthMonitor.enabled`: 다중 계정 채널에 대한 계정별 오버라이드입니다. 설정되면 채널 수준 오버라이드보다 우선합니다. -- 로컬 gateway 호출 경로는 `gateway.auth.*`가 설정되지 않은 경우에만 `gateway.remote.*`를 폴백으로 사용할 수 있습니다. -- `gateway.auth.token` / `gateway.auth.password`가 SecretRef를 통해 명시적으로 구성되었고 해결되지 않은 경우, 해결은 닫힌 상태로 실패합니다(원격 폴백으로 가려지지 않음). -- `trustedProxies`: TLS를 종료하거나 전달된 클라이언트 헤더를 주입하는 리버스 프록시 IP입니다. 제어하는 프록시만 나열하세요. 루프백 항목은 동일 호스트 프록시/로컬 감지 설정(예: Tailscale Serve 또는 로컬 리버스 프록시)에도 유효하지만, 루프백 요청이 `gateway.auth.mode: "trusted-proxy"`에 적합해지도록 만들지는 **않습니다**. -- `allowRealIpFallback`: `true`이면 `X-Forwarded-For`가 없을 때 gateway가 `X-Real-IP`를 허용합니다. 닫힌 상태로 실패하는 동작을 위해 기본값은 `false`입니다. -- `gateway.nodes.pairing.autoApproveCidrs`: 요청된 범위가 없는 최초 node 디바이스 페어링을 자동 승인하기 위한 선택적 CIDR/IP 허용 목록입니다. 설정하지 않으면 비활성화됩니다. operator/browser/Control UI/WebChat 페어링은 자동 승인하지 않으며, 역할, 범위, 메타데이터 또는 공개 키 업그레이드도 자동 승인하지 않습니다. -- `gateway.nodes.allowCommands` / `gateway.nodes.denyCommands`: 페어링 및 플랫폼 허용 목록 평가 후 선언된 node 명령에 대한 전역 허용/거부 조정입니다. `camera.snap`, `camera.clip`, `screen.record` 같은 위험한 node 명령을 선택적으로 허용하려면 `allowCommands`를 사용하세요. `denyCommands`는 플랫폼 기본값이나 명시적 허용에 포함될 명령이라도 제거합니다. node가 선언한 명령 목록을 변경한 뒤에는 해당 디바이스 페어링을 거부하고 다시 승인하여 gateway가 업데이트된 명령 스냅샷을 저장하도록 하세요. -- `gateway.tools.deny`: HTTP `POST /tools/invoke`에 대해 차단되는 추가 도구 이름입니다(기본 거부 목록 확장). +- `channels..healthMonitor.enabled`: 전역 모니터는 활성화한 채로 상태 모니터 재시작을 채널별로 제외합니다. +- `channels..accounts..healthMonitor.enabled`: 다중 계정 채널의 계정별 재정의입니다. 설정하면 채널 수준 재정보다 우선합니다. +- 로컬 Gateway 호출 경로는 `gateway.auth.*`가 설정되지 않은 경우에만 `gateway.remote.*`를 폴백으로 사용할 수 있습니다. +- `gateway.auth.token` / `gateway.auth.password`가 SecretRef를 통해 명시적으로 구성되어 있고 해석되지 않으면, 해석은 실패 폐쇄됩니다(원격 폴백으로 가려지지 않음). +- `trustedProxies`: TLS를 종료하거나 전달된 클라이언트 헤더를 삽입하는 리버스 프록시 IP입니다. 제어하는 프록시만 나열하세요. 루프백 항목은 동일 호스트 프록시/로컬 감지 설정(예: Tailscale Serve 또는 로컬 리버스 프록시)에도 여전히 유효하지만, 루프백 요청이 `gateway.auth.mode: "trusted-proxy"`에 적격하게 만들지는 **않습니다**. +- `allowRealIpFallback`: `true`이면 `X-Forwarded-For`가 없을 때 Gateway가 `X-Real-IP`를 허용합니다. 실패 폐쇄 동작을 위해 기본값은 `false`입니다. +- `gateway.nodes.pairing.autoApproveCidrs`: 요청된 범위가 없는 최초 노드 장치 페어링을 자동 승인하기 위한 선택적 CIDR/IP 허용 목록입니다. 설정되지 않으면 비활성화됩니다. 이는 운영자/브라우저/Control UI/WebChat 페어링을 자동 승인하지 않으며, 역할, 범위, 메타데이터 또는 공개 키 업그레이드도 자동 승인하지 않습니다. +- `gateway.nodes.allowCommands` / `gateway.nodes.denyCommands`: 페어링 및 플랫폼 허용 목록 평가 후 선언된 노드 명령에 대한 전역 허용/거부 제어입니다. `camera.snap`, `camera.clip`, `screen.record` 같은 위험한 노드 명령을 선택적으로 허용하려면 `allowCommands`를 사용하세요. `denyCommands`는 플랫폼 기본값 또는 명시적 허용에 포함되더라도 명령을 제거합니다. 노드가 선언된 명령 목록을 변경한 후에는 해당 장치 페어링을 거부하고 다시 승인하여 Gateway가 업데이트된 명령 스냅샷을 저장하게 하세요. +- `gateway.tools.deny`: HTTP `POST /tools/invoke`에서 차단되는 추가 도구 이름입니다(기본 거부 목록 확장). - `gateway.tools.allow`: 기본 HTTP 거부 목록에서 도구 이름을 제거합니다. @@ -447,7 +450,7 @@ OpenClaw가 관리하는 MCP 서버 정의는 `mcp.servers` 아래에 있으며, ### 다중 인스턴스 격리 -고유한 포트와 상태 디렉터리로 한 호스트에서 여러 gateway를 실행합니다. +고유한 포트와 상태 디렉터리로 한 호스트에서 여러 Gateway를 실행합니다. ```bash OPENCLAW_CONFIG_PATH=~/.openclaw/a.json \ @@ -475,11 +478,11 @@ openclaw gateway --port 19001 } ``` -- `enabled`: gateway 리스너에서 TLS 종료(HTTPS/WSS)를 활성화합니다(기본값: `false`). -- `autoGenerate`: 명시적 파일이 구성되지 않은 경우 로컬 자체 서명 인증서/키 쌍을 자동 생성합니다. 로컬/개발 용도로만 사용하세요. +- `enabled`: Gateway 리스너(HTTPS/WSS)에서 TLS 종료를 활성화합니다(기본값: `false`). +- `autoGenerate`: 명시적 파일이 구성되지 않은 경우 로컬 자체 서명 인증서/키 쌍을 자동 생성합니다. 로컬/개발용으로만 사용하세요. - `certPath`: TLS 인증서 파일의 파일 시스템 경로입니다. -- `keyPath`: TLS 개인 키 파일의 파일 시스템 경로입니다. 권한을 제한하세요. -- `caPath`: 클라이언트 확인 또는 사용자 지정 신뢰 체인을 위한 선택적 CA 번들 경로입니다. +- `keyPath`: TLS 개인 키 파일의 파일 시스템 경로입니다. 권한을 제한해 유지하세요. +- `caPath`: 클라이언트 검증 또는 사용자 지정 신뢰 체인을 위한 선택적 CA 번들 경로입니다. ### `gateway.reload` @@ -496,16 +499,16 @@ openclaw gateway --port 19001 ``` - `mode`: 런타임에 구성 편집을 적용하는 방식을 제어합니다. - - `"off"`: 실시간 편집을 무시합니다. 변경 사항에는 명시적 재시작이 필요합니다. - - `"restart"`: 구성 변경 시 항상 gateway 프로세스를 재시작합니다. - - `"hot"`: 재시작 없이 프로세스 내에서 변경 사항을 적용합니다. - - `"hybrid"`(기본값): 먼저 핫 리로드를 시도하고, 필요하면 재시작으로 폴백합니다. -- `debounceMs`: 구성 변경이 적용되기 전 디바운스 창(ms)입니다(음이 아닌 정수). -- `deferralTimeoutMs`: 재시작을 강제하기 전에 진행 중인 작업을 기다리는 선택적 최대 시간(ms)입니다. 기본 제한 대기(`300000`)를 사용하려면 생략하세요. 무기한 대기하고 주기적으로 아직 대기 중이라는 경고를 기록하려면 `0`으로 설정하세요. + - `"off"`: 실시간 편집을 무시합니다. 변경에는 명시적 재시작이 필요합니다. + - `"restart"`: 구성 변경 시 항상 Gateway 프로세스를 재시작합니다. + - `"hot"`: 재시작 없이 프로세스 내에서 변경을 적용합니다. + - `"hybrid"`(기본값): 먼저 핫 리로드를 시도하고, 필요한 경우 재시작으로 폴백합니다. +- `debounceMs`: 구성 변경이 적용되기 전의 디바운스 창(ms, 음수가 아닌 정수)입니다. +- `deferralTimeoutMs`: 재시작을 강제하기 전에 진행 중인 작업을 기다릴 선택적 최대 시간(ms)입니다. 기본 제한 대기(`300000`)를 사용하려면 생략하세요. 무기한 대기하고 주기적인 아직 대기 중 경고를 기록하려면 `0`으로 설정하세요. --- -## 훅 +## Hooks ```json5 { @@ -539,47 +542,47 @@ openclaw gateway --port 19001 ``` 인증: `Authorization: Bearer ` 또는 `x-openclaw-token: `. -쿼리 문자열 훅 토큰은 거부됩니다. +쿼리 문자열 hook token은 거부됩니다. 검증 및 안전 참고 사항: - `hooks.enabled=true`에는 비어 있지 않은 `hooks.token`이 필요합니다. -- `hooks.token`은 `gateway.auth.token`과 **달라야** 합니다. Gateway 토큰을 재사용하면 거부됩니다. +- `hooks.token`은 `gateway.auth.token`과 **달라야** 합니다. Gateway token을 재사용하면 거부됩니다. - `hooks.path`는 `/`일 수 없습니다. `/hooks` 같은 전용 하위 경로를 사용하세요. -- `hooks.allowRequestSessionKey=true`이면 `hooks.allowedSessionKeyPrefixes`를 제한하세요(예: `["hook:"]`). -- 매핑 또는 프리셋이 템플릿 기반 `sessionKey`를 사용하는 경우 `hooks.allowedSessionKeyPrefixes`를 설정하고 `hooks.allowRequestSessionKey=true`로 설정하세요. 정적 매핑 키에는 해당 명시적 동의가 필요하지 않습니다. +- `hooks.allowRequestSessionKey=true`인 경우 `hooks.allowedSessionKeyPrefixes`를 제한하세요(예: `["hook:"]`). +- 매핑 또는 프리셋이 템플릿화된 `sessionKey`를 사용하는 경우 `hooks.allowedSessionKeyPrefixes`를 설정하고 `hooks.allowRequestSessionKey=true`로 설정하세요. 정적 매핑 키에는 이 옵트인이 필요하지 않습니다. **엔드포인트:** - `POST /hooks/wake` → `{ text, mode?: "now"|"next-heartbeat" }` - `POST /hooks/agent` → `{ message, name?, agentId?, sessionKey?, wakeMode?, deliver?, channel?, to?, model?, thinking?, timeoutSeconds? }` - - 요청 페이로드의 `sessionKey`는 `hooks.allowRequestSessionKey=true`일 때만 허용됩니다(기본값: `false`). -- `POST /hooks/` → `hooks.mappings`를 통해 확인됩니다. - - 템플릿으로 렌더링된 매핑 `sessionKey` 값은 외부에서 제공된 것으로 처리되며, 역시 `hooks.allowRequestSessionKey=true`가 필요합니다. + - 요청 페이로드의 `sessionKey`는 `hooks.allowRequestSessionKey=true`인 경우에만 허용됩니다(기본값: `false`). +- `POST /hooks/` → `hooks.mappings`를 통해 해석됨 + - 템플릿으로 렌더링된 매핑 `sessionKey` 값은 외부에서 제공된 것으로 처리되며, 이 역시 `hooks.allowRequestSessionKey=true`가 필요합니다. - + - `match.path`는 `/hooks` 뒤의 하위 경로와 일치합니다(예: `/hooks/gmail` → `gmail`). - `match.source`는 일반 경로의 페이로드 필드와 일치합니다. - `{{messages[0].subject}}` 같은 템플릿은 페이로드에서 읽습니다. -- `transform`은 훅 작업을 반환하는 JS/TS 모듈을 가리킬 수 있습니다. - - `transform.module`은 상대 경로여야 하며 `hooks.transformsDir` 내부에 있어야 합니다(절대 경로와 경로 순회는 거부됩니다). - - `hooks.transformsDir`는 `~/.openclaw/hooks/transforms` 아래에 두세요. 워크스페이스 Skills 디렉터리는 거부됩니다. `openclaw doctor`가 이 경로를 유효하지 않다고 보고하면 변환 모듈을 훅 변환 디렉터리로 이동하거나 `hooks.transformsDir`를 제거하세요. -- `agentId`는 특정 에이전트로 라우팅합니다. 알 수 없는 ID는 기본값으로 폴백됩니다. +- `transform`은 hook 작업을 반환하는 JS/TS 모듈을 가리킬 수 있습니다. + - `transform.module`은 상대 경로여야 하며 `hooks.transformsDir` 내부에 머물러야 합니다(절대 경로와 경로 순회는 거부됨). + - `hooks.transformsDir`는 `~/.openclaw/hooks/transforms` 아래에 두세요. 작업 영역 skill 디렉터리는 거부됩니다. `openclaw doctor`가 이 경로를 유효하지 않다고 보고하면 transform 모듈을 hooks transforms 디렉터리로 옮기거나 `hooks.transformsDir`를 제거하세요. +- `agentId`는 특정 agent로 라우팅합니다. 알 수 없는 ID는 기본값으로 폴백합니다. - `allowedAgentIds`: 명시적 라우팅을 제한합니다(`*` 또는 생략 = 모두 허용, `[]` = 모두 거부). -- `defaultSessionKey`: 명시적 `sessionKey` 없이 훅 에이전트를 실행할 때 사용할 선택적 고정 세션 키입니다. -- `allowRequestSessionKey`: `/hooks/agent` 호출자와 템플릿 기반 매핑 세션 키가 `sessionKey`를 설정하도록 허용합니다(기본값: `false`). -- `allowedSessionKeyPrefixes`: 명시적 `sessionKey` 값(요청 + 매핑)에 대한 선택적 접두사 허용 목록입니다(예: `["hook:"]`). 매핑 또는 프리셋이 템플릿 기반 `sessionKey`를 사용하는 경우 필수입니다. -- `deliver: true`는 최종 답장을 채널로 보냅니다. `channel`의 기본값은 `last`입니다. -- `model`은 이 훅 실행의 LLM을 재정의합니다(모델 카탈로그가 설정된 경우 허용되어야 함). +- `defaultSessionKey`: 명시적 `sessionKey` 없이 hook agent 실행에 사용할 선택적 고정 session key입니다. +- `allowRequestSessionKey`: `/hooks/agent` 호출자와 템플릿 기반 매핑 session key가 `sessionKey`를 설정하도록 허용합니다(기본값: `false`). +- `allowedSessionKeyPrefixes`: 명시적 `sessionKey` 값(요청 + 매핑)에 대한 선택적 prefix 허용 목록입니다(예: `["hook:"]`). 매핑 또는 프리셋이 템플릿화된 `sessionKey`를 사용하면 필수입니다. +- `deliver: true`는 최종 응답을 채널로 보냅니다. `channel`의 기본값은 `last`입니다. +- `model`은 이 hook 실행의 LLM을 재정의합니다(model catalog가 설정된 경우 허용되어야 함). ### Gmail 통합 -- 기본 제공 Gmail 프리셋은 `sessionKey: "hook:gmail:{{messages[0].id}}"`를 사용합니다. -- 해당 메시지별 라우팅을 유지하는 경우 `hooks.allowRequestSessionKey: true`를 설정하고 `hooks.allowedSessionKeyPrefixes`를 Gmail 네임스페이스와 일치하도록 제한하세요. 예: `["hook:", "hook:gmail:"]`. -- `hooks.allowRequestSessionKey: false`가 필요한 경우 템플릿 기본값 대신 정적 `sessionKey`로 프리셋을 재정의하세요. +- 내장 Gmail 프리셋은 `sessionKey: "hook:gmail:{{messages[0].id}}"`를 사용합니다. +- 메시지별 라우팅을 유지하려면 `hooks.allowRequestSessionKey: true`를 설정하고 `hooks.allowedSessionKeyPrefixes`를 Gmail 네임스페이스와 일치하도록 제한하세요. 예: `["hook:", "hook:gmail:"]`. +- `hooks.allowRequestSessionKey: false`가 필요한 경우 템플릿화된 기본값 대신 정적 `sessionKey`로 프리셋을 재정의하세요. ```json5 { @@ -602,12 +605,12 @@ openclaw gateway --port 19001 } ``` -- 설정된 경우 Gateway는 부팅 시 `gog gmail watch serve`를 자동 시작합니다. 비활성화하려면 `OPENCLAW_SKIP_GMAIL_WATCHER=1`을 설정하세요. +- 구성된 경우 Gateway는 부팅 시 `gog gmail watch serve`를 자동으로 시작합니다. 비활성화하려면 `OPENCLAW_SKIP_GMAIL_WATCHER=1`을 설정하세요. - Gateway와 함께 별도의 `gog gmail watch serve`를 실행하지 마세요. --- -## 캔버스 호스트 +## Canvas host ```json5 { @@ -619,18 +622,18 @@ openclaw gateway --port 19001 } ``` -- 에이전트가 편집할 수 있는 HTML/CSS/JS와 A2UI를 Gateway 포트 아래에서 HTTP로 제공합니다. +- agent가 편집할 수 있는 HTML/CSS/JS 및 A2UI를 Gateway 포트 아래에서 HTTP로 제공합니다. - `http://:/__openclaw__/canvas/` - `http://:/__openclaw__/a2ui/` -- 로컬 전용: `gateway.bind: "loopback"`(기본값)을 유지하세요. -- local loopback이 아닌 바인드: 캔버스 경로에는 다른 Gateway HTTP 표면과 동일하게 Gateway 인증(토큰/비밀번호/신뢰할 수 있는 프록시)이 필요합니다. -- Node WebView는 일반적으로 인증 헤더를 보내지 않습니다. 노드가 페어링되고 연결된 후 Gateway는 캔버스/A2UI 접근을 위한 노드 범위 기능 URL을 알립니다. -- 기능 URL은 활성 노드 WS 세션에 바인딩되며 빠르게 만료됩니다. IP 기반 폴백은 사용되지 않습니다. -- 제공되는 HTML에 실시간 새로고침 클라이언트를 삽입합니다. -- 비어 있을 때 시작용 `index.html`을 자동 생성합니다. +- 로컬 전용: `gateway.bind: "loopback"`을 유지하세요(기본값). +- local loopback이 아닌 바인드: canvas 경로에는 다른 Gateway HTTP 표면과 동일하게 Gateway 인증(token/password/trusted-proxy)이 필요합니다. +- Node WebViews는 일반적으로 인증 헤더를 보내지 않습니다. Node가 페어링되고 연결되면 Gateway는 canvas/A2UI 접근을 위한 Node 범위 capability URL을 알립니다. +- Capability URL은 활성 Node WS 세션에 바인딩되며 빠르게 만료됩니다. IP 기반 폴백은 사용되지 않습니다. +- 제공되는 HTML에 live-reload 클라이언트를 주입합니다. +- 비어 있으면 시작용 `index.html`을 자동 생성합니다. - A2UI도 `/__openclaw__/a2ui/`에서 제공합니다. - 변경 사항에는 Gateway 재시작이 필요합니다. -- 큰 디렉터리 또는 `EMFILE` 오류가 있는 경우 실시간 새로고침을 비활성화하세요. +- 큰 디렉터리 또는 `EMFILE` 오류에서는 live reload를 비활성화하세요. --- @@ -648,11 +651,11 @@ openclaw gateway --port 19001 } ``` -- `minimal`(번들된 `bonjour` Plugin이 활성화된 경우 기본값): TXT 레코드에서 `cliPath` + `sshPort`를 생략합니다. -- `full`: `cliPath` + `sshPort`를 포함합니다. LAN 멀티캐스트 광고에는 여전히 번들된 `bonjour` Plugin이 활성화되어 있어야 합니다. -- `off`: Plugin 활성화를 변경하지 않고 LAN 멀티캐스트 광고를 억제합니다. -- 번들된 `bonjour` Plugin은 macOS 호스트에서 자동 시작되며 Linux, Windows 및 컨테이너화된 Gateway 배포에서는 명시적으로 선택해야 합니다. -- 호스트 이름은 유효한 DNS 레이블인 경우 시스템 호스트 이름이 기본값이며, 그렇지 않으면 `openclaw`로 폴백됩니다. `OPENCLAW_MDNS_HOSTNAME`으로 재정의하세요. +- `minimal`(번들 `bonjour` Plugin이 활성화된 경우 기본값): TXT 레코드에서 `cliPath` + `sshPort`를 생략합니다. +- `full`: `cliPath` + `sshPort`를 포함합니다. LAN 멀티캐스트 광고에는 여전히 번들 `bonjour` Plugin이 활성화되어 있어야 합니다. +- `off`: Plugin 활성화 상태를 변경하지 않고 LAN 멀티캐스트 광고를 억제합니다. +- 번들 `bonjour` Plugin은 macOS 호스트에서 자동으로 시작되며 Linux, Windows, 컨테이너화된 Gateway 배포에서는 옵트인입니다. +- 호스트 이름은 유효한 DNS 레이블인 경우 시스템 호스트 이름이 기본값이며, 그렇지 않으면 `openclaw`로 폴백합니다. `OPENCLAW_MDNS_HOSTNAME`으로 재정의하세요. ### 광역 (DNS-SD) @@ -664,7 +667,7 @@ openclaw gateway --port 19001 } ``` -`~/.openclaw/dns/` 아래에 유니캐스트 DNS-SD 영역을 작성합니다. 네트워크 간 검색에는 DNS 서버(CoreDNS 권장) + Tailscale 분할 DNS를 함께 사용하세요. +`~/.openclaw/dns/` 아래에 unicast DNS-SD zone을 씁니다. 네트워크 간 검색의 경우 DNS 서버(CoreDNS 권장) + Tailscale split DNS와 함께 사용하세요. 설정: `openclaw dns setup --apply`. @@ -691,12 +694,12 @@ openclaw gateway --port 19001 - 인라인 환경 변수는 프로세스 환경에 해당 키가 없을 때만 적용됩니다. - `.env` 파일: CWD `.env` + `~/.openclaw/.env`(둘 다 기존 변수를 덮어쓰지 않음). -- `shellEnv`: 로그인 셸 프로필에서 누락된 예상 키를 가져옵니다. -- 전체 우선순위는 [환경](/ko/help/environment)을 참고하세요. +- `shellEnv`: 누락된 예상 키를 로그인 셸 프로필에서 가져옵니다. +- 전체 우선순위는 [환경](/ko/help/environment)을 참조하세요. ### 환경 변수 치환 -모든 구성 문자열에서 `${VAR_NAME}`으로 환경 변수를 참조합니다. +`${VAR_NAME}`을 사용해 모든 구성 문자열에서 환경 변수를 참조합니다. ```json5 { @@ -713,13 +716,13 @@ openclaw gateway --port 19001 --- -## 비밀 정보 +## 비밀 -비밀 정보 참조는 추가적입니다. 일반 텍스트 값도 계속 작동합니다. +비밀 참조는 추가 방식입니다. 일반 텍스트 값도 계속 작동합니다. ### `SecretRef` -다음 객체 형태 하나를 사용합니다. +하나의 객체 형태를 사용합니다. ```json5 { source: "env" | "file" | "exec", provider: "default", id: "..." } @@ -731,15 +734,15 @@ openclaw gateway --port 19001 - `source: "env"` id 패턴: `^[A-Z][A-Z0-9_]{0,127}$` - `source: "file"` id: 절대 JSON 포인터(예: `"/providers/openai/apiKey"`) - `source: "exec"` id 패턴: `^[A-Za-z0-9][A-Za-z0-9._:/-]{0,255}$` -- `source: "exec"` id에는 슬래시로 구분된 경로 세그먼트 `.` 또는 `..`가 포함되면 안 됩니다(예: `a/../b`는 거부됨). +- `source: "exec"` id에는 슬래시로 구분된 경로 세그먼트 `.` 또는 `..`이 포함되면 안 됩니다(예: `a/../b`는 거부됨). -### 지원되는 자격 증명 범위 +### 지원되는 자격 증명 표면 -- 정식 매트릭스: [SecretRef 자격 증명 범위](/ko/reference/secretref-credential-surface) +- 표준 매트릭스: [SecretRef 자격 증명 표면](/ko/reference/secretref-credential-surface) - `secrets apply`는 지원되는 `openclaw.json` 자격 증명 경로를 대상으로 합니다. - `auth-profiles.json` 참조는 런타임 해석 및 감사 범위에 포함됩니다. -### 비밀 정보 제공자 구성 +### 비밀 공급자 구성 ```json5 { @@ -769,14 +772,14 @@ openclaw gateway --port 19001 참고: -- `file` 제공자는 `mode: "json"` 및 `mode: "singleValue"`를 지원합니다(`singleValue` 모드에서는 `id`가 `"value"`여야 함). -- Windows ACL 검증을 사용할 수 없으면 파일 및 exec 제공자 경로는 안전하게 실패합니다. 검증할 수 없는 신뢰된 경로에만 `allowInsecurePath: true`를 설정하세요. -- `exec` 제공자는 절대 `command` 경로가 필요하며 stdin/stdout에서 프로토콜 페이로드를 사용합니다. -- 기본적으로 symlink 명령 경로는 거부됩니다. 해석된 대상 경로를 검증하면서 symlink 경로를 허용하려면 `allowSymlinkCommand: true`를 설정하세요. -- `trustedDirs`가 구성된 경우 신뢰된 디렉터리 검사는 해석된 대상 경로에 적용됩니다. -- `exec` 자식 환경은 기본적으로 최소화됩니다. 필요한 변수는 `passEnv`로 명시적으로 전달하세요. -- 비밀 정보 참조는 활성화 시점에 메모리 내 스냅샷으로 해석되며, 이후 요청 경로는 스냅샷만 읽습니다. -- 활성 표면 필터링은 활성화 중 적용됩니다. 활성화된 표면의 해석되지 않은 참조는 시작/다시 로드를 실패시키며, 비활성 표면은 진단과 함께 건너뜁니다. +- `file` 공급자는 `mode: "json"` 및 `mode: "singleValue"`를 지원합니다(`singleValue` 모드에서는 `id`가 `"value"`여야 함). +- Windows ACL 검증을 사용할 수 없으면 file 및 exec 공급자 경로는 안전하게 실패합니다. 검증할 수 없는 신뢰할 수 있는 경로에만 `allowInsecurePath: true`를 설정하세요. +- `exec` 공급자에는 절대 `command` 경로가 필요하며 stdin/stdout에서 프로토콜 페이로드를 사용합니다. +- 기본적으로 심볼릭 링크 명령 경로는 거부됩니다. 해석된 대상 경로를 검증하면서 심볼릭 링크 경로를 허용하려면 `allowSymlinkCommand: true`를 설정하세요. +- `trustedDirs`가 구성된 경우 신뢰할 수 있는 디렉터리 검사는 해석된 대상 경로에 적용됩니다. +- `exec` 자식 환경은 기본적으로 최소화되어 있습니다. 필요한 변수는 `passEnv`로 명시적으로 전달하세요. +- 비밀 참조는 활성화 시점에 인메모리 스냅샷으로 해석되며, 이후 요청 경로는 스냅샷만 읽습니다. +- 활성 표면 필터링은 활성화 중에 적용됩니다. 활성화된 표면의 해석되지 않은 참조는 시작/다시 로드를 실패하게 하며, 비활성 표면은 진단과 함께 건너뜁니다. --- @@ -800,12 +803,12 @@ openclaw gateway --port 19001 - 에이전트별 프로필은 `/auth-profiles.json`에 저장됩니다. - `auth-profiles.json`은 정적 자격 증명 모드에 대해 값 수준 참조(`api_key`의 경우 `keyRef`, `token`의 경우 `tokenRef`)를 지원합니다. -- `{ "provider": { "apiKey": "..." } }`와 같은 레거시 플랫 `auth-profiles.json` 맵은 런타임 형식이 아닙니다. `openclaw doctor --fix`는 이를 `.legacy-flat.*.bak` 백업과 함께 정식 `provider:default` API 키 프로필로 다시 작성합니다. +- `{ "provider": { "apiKey": "..." } }` 같은 레거시 플랫 `auth-profiles.json` 맵은 런타임 형식이 아닙니다. `openclaw doctor --fix`는 이를 `.legacy-flat.*.bak` 백업과 함께 표준 `provider:default` API 키 프로필로 다시 작성합니다. - OAuth 모드 프로필(`auth.profiles..mode = "oauth"`)은 SecretRef 기반 인증 프로필 자격 증명을 지원하지 않습니다. -- 정적 런타임 자격 증명은 메모리 내 해석된 스냅샷에서 가져옵니다. 레거시 정적 `auth.json` 항목은 발견되면 정리됩니다. -- 레거시 OAuth는 `~/.openclaw/credentials/oauth.json`에서 가져옵니다. -- [OAuth](/ko/concepts/oauth)를 참고하세요. -- 비밀 정보 런타임 동작 및 `audit/configure/apply` 도구: [비밀 정보 관리](/ko/gateway/secrets). +- 정적 런타임 자격 증명은 인메모리 해석 스냅샷에서 가져옵니다. 레거시 정적 `auth.json` 항목은 발견되면 제거됩니다. +- 레거시 OAuth 가져오기는 `~/.openclaw/credentials/oauth.json`에서 수행됩니다. +- [OAuth](/ko/concepts/oauth)를 참조하세요. +- 비밀 런타임 동작 및 `audit/configure/apply` 도구: [비밀 관리](/ko/gateway/secrets). ### `auth.cooldowns` @@ -827,15 +830,15 @@ openclaw gateway --port 19001 } ``` -- `billingBackoffHours`: 프로필이 실제 청구/크레딧 부족 오류로 실패할 때 시간 단위의 기본 백오프입니다(기본값: `5`). 명시적인 청구 텍스트는 `401`/`403` 응답에서도 여기에 들어올 수 있지만, 공급자별 텍스트 매처는 이를 소유한 공급자로 범위가 제한됩니다(예: OpenRouter `Key limit exceeded`). 재시도 가능한 HTTP `402` 사용량 기간 또는 조직/워크스페이스 지출 한도 메시지는 대신 `rate_limit` 경로에 남습니다. -- `billingBackoffHoursByProvider`: 공급자별 청구 백오프 시간 재정의를 위한 선택적 설정입니다. -- `billingMaxHours`: 청구 백오프 지수 증가의 시간 단위 상한입니다(기본값: `24`). -- `authPermanentBackoffMinutes`: 신뢰도 높은 `auth_permanent` 실패에 대한 분 단위 기본 백오프입니다(기본값: `10`). -- `authPermanentMaxMinutes`: `auth_permanent` 백오프 증가의 분 단위 상한입니다(기본값: `60`). -- `failureWindowHours`: 백오프 카운터에 사용하는 시간 단위 롤링 기간입니다(기본값: `24`). -- `overloadedProfileRotations`: 모델 fallback으로 전환하기 전 과부하 오류에 대해 허용되는 동일 공급자 인증 프로필 로테이션의 최대 횟수입니다(기본값: `1`). `ModelNotReadyException` 같은 공급자 사용 중 형식은 여기에 들어옵니다. -- `overloadedBackoffMs`: 과부하된 공급자/프로필 로테이션을 재시도하기 전 고정 지연입니다(기본값: `0`). -- `rateLimitedProfileRotations`: 모델 fallback으로 전환하기 전 속도 제한 오류에 대해 허용되는 동일 공급자 인증 프로필 로테이션의 최대 횟수입니다(기본값: `1`). 이 속도 제한 버킷에는 `Too many concurrent requests`, `ThrottlingException`, `concurrency limit reached`, `workers_ai ... quota limit exceeded`, `resource exhausted` 같은 공급자 형식의 텍스트가 포함됩니다. +- `billingBackoffHours`: 실제 billing/insufficient-credit 오류로 프로필이 실패할 때 적용되는 기본 백오프 시간(기본값: `5`). 명시적인 청구 관련 문구는 `401`/`403` 응답에서도 여기에 도달할 수 있지만, 공급자별 텍스트 매처는 이를 소유한 공급자 범위로 유지됩니다(예: OpenRouter `Key limit exceeded`). 재시도 가능한 HTTP `402` 사용량 창 또는 조직/워크스페이스 지출 한도 메시지는 대신 `rate_limit` 경로에 유지됩니다. +- `billingBackoffHoursByProvider`: 청구 백오프 시간에 대한 선택적 공급자별 재정의입니다. +- `billingMaxHours`: 청구 백오프 지수 증가의 시간 단위 상한(기본값: `24`)입니다. +- `authPermanentBackoffMinutes`: 신뢰도 높은 `auth_permanent` 실패에 대한 기본 백오프 분 단위 시간(기본값: `10`)입니다. +- `authPermanentMaxMinutes`: `auth_permanent` 백오프 증가의 분 단위 상한(기본값: `60`)입니다. +- `failureWindowHours`: 백오프 카운터에 사용되는 시간 단위 롤링 윈도우(기본값: `24`)입니다. +- `overloadedProfileRotations`: 모델 폴백으로 전환하기 전에 과부하 오류에 대해 허용되는 동일 공급자 인증 프로필 최대 순환 횟수(기본값: `1`)입니다. `ModelNotReadyException` 같은 공급자 사용 중 형태가 여기에 도달합니다. +- `overloadedBackoffMs`: 과부하된 공급자/프로필 순환을 재시도하기 전 고정 지연 시간(기본값: `0`)입니다. +- `rateLimitedProfileRotations`: 모델 폴백으로 전환하기 전에 rate-limit 오류에 대해 허용되는 동일 공급자 인증 프로필 최대 순환 횟수(기본값: `1`)입니다. 해당 rate-limit 버킷에는 `Too many concurrent requests`, `ThrottlingException`, `concurrency limit reached`, `workers_ai ... quota limit exceeded`, `resource exhausted` 같은 공급자 형태의 텍스트가 포함됩니다. --- @@ -855,10 +858,10 @@ openclaw gateway --port 19001 ``` - 기본 로그 파일: `/tmp/openclaw/openclaw-YYYY-MM-DD.log`. -- 안정적인 경로가 필요하면 `logging.file`을 설정하세요. +- 안정적인 경로를 사용하려면 `logging.file`을 설정하세요. - `--verbose`일 때 `consoleLevel`이 `debug`로 올라갑니다. -- `maxFileBytes`: 로테이션 전 활성 로그 파일의 최대 크기(바이트)입니다(양의 정수, 기본값: `104857600` = 100MB). OpenClaw는 활성 파일 옆에 번호가 붙은 아카이브를 최대 5개까지 유지합니다. -- `redactSensitive` / `redactPatterns`: 콘솔 출력, 파일 로그, OTLP 로그 레코드, 저장된 세션 트랜스크립트 텍스트에 대한 최선 노력 마스킹입니다. `redactSensitive: "off"`는 이 일반 로그/트랜스크립트 정책만 비활성화합니다. UI/도구/진단 안전 표면은 내보내기 전에 여전히 비밀 값을 마스킹합니다. +- `maxFileBytes`: 순환 전 활성 로그 파일의 최대 크기(바이트)입니다(양의 정수, 기본값: `104857600` = 100 MB). OpenClaw는 활성 파일 옆에 번호가 붙은 아카이브를 최대 5개까지 유지합니다. +- `redactSensitive` / `redactPatterns`: 콘솔 출력, 파일 로그, OTLP 로그 레코드, 저장된 세션 트랜스크립트 텍스트에 대한 최선 노력 마스킹입니다. `redactSensitive: "off"`는 이 일반 로그/트랜스크립트 정책만 비활성화하며, UI/도구/진단 안전 표면은 여전히 내보내기 전에 비밀 값을 마스킹합니다. --- @@ -909,24 +912,24 @@ openclaw gateway --port 19001 - `enabled`: 계측 출력의 마스터 토글입니다(기본값: `true`). - `flags`: 대상 로그 출력을 활성화하는 플래그 문자열 배열입니다(`"telegram.*"` 또는 `"*"` 같은 와일드카드 지원). -- `stuckSessionWarnMs`: 장기 실행 처리 세션을 `session.long_running`, `session.stalled`, 또는 `session.stuck`으로 분류하기 위한 진행 없음 경과 시간 임계값(ms)입니다. 답장, 도구, 상태, 블록, ACP 진행은 타이머를 재설정합니다. 반복되는 `session.stuck` 진단은 변경 사항이 없으면 백오프됩니다. -- `stuckSessionAbortMs`: 복구를 위해 자격이 있는 정체된 활성 작업을 중단-배출할 수 있기 전 진행 없음 경과 시간 임계값(ms)입니다. 설정하지 않으면 OpenClaw는 최소 10분 및 `stuckSessionWarnMs`의 5배인 더 안전한 확장 임베디드 실행 기간을 사용합니다. +- `stuckSessionWarnMs`: 진행 없음 기간을 ms 단위로 계산하여 장기 실행 처리 세션을 `session.long_running`, `session.stalled`, `session.stuck`으로 분류하는 임계값입니다. 응답, 도구, 상태, 블록, ACP 진행은 타이머를 재설정하며, 반복되는 `session.stuck` 진단은 변경 사항이 없으면 백오프됩니다. +- `stuckSessionAbortMs`: 복구를 위해 적격한 정체 활성 작업을 abort-drain할 수 있기 전의 진행 없음 기간 임계값(ms)입니다. 설정하지 않으면 OpenClaw는 최소 10분 및 `stuckSessionWarnMs`의 5배인 더 안전한 확장 임베디드 실행 윈도우를 사용합니다. - `otel.enabled`: OpenTelemetry 내보내기 파이프라인을 활성화합니다(기본값: `false`). 전체 구성, 신호 카탈로그, 개인정보 보호 모델은 [OpenTelemetry 내보내기](/ko/gateway/opentelemetry)를 참조하세요. -- `otel.endpoint`: OTel 내보내기용 수집기 URL입니다. -- `otel.tracesEndpoint` / `otel.metricsEndpoint` / `otel.logsEndpoint`: 선택적 신호별 OTLP 엔드포인트입니다. 설정하면 해당 신호에 대해서만 `otel.endpoint`를 재정의합니다. -- `otel.protocol`: `"http/protobuf"`(기본값) 또는 `"grpc"`. +- `otel.endpoint`: OTel 내보내기용 컬렉터 URL입니다. +- `otel.tracesEndpoint` / `otel.metricsEndpoint` / `otel.logsEndpoint`: 선택적 신호별 OTLP 엔드포인트입니다. 설정되면 해당 신호에 대해서만 `otel.endpoint`를 재정의합니다. +- `otel.protocol`: `"http/protobuf"`(기본값) 또는 `"grpc"`입니다. - `otel.headers`: OTel 내보내기 요청과 함께 전송되는 추가 HTTP/gRPC 메타데이터 헤더입니다. -- `otel.serviceName`: 리소스 속성의 서비스 이름입니다. +- `otel.serviceName`: 리소스 속성에 사용할 서비스 이름입니다. - `otel.traces` / `otel.metrics` / `otel.logs`: 트레이스, 메트릭 또는 로그 내보내기를 활성화합니다. - `otel.sampleRate`: 트레이스 샘플링 비율 `0`-`1`입니다. - `otel.flushIntervalMs`: 주기적 텔레메트리 플러시 간격(ms)입니다. -- `otel.captureContent`: OTEL 스팬 속성을 위한 원시 콘텐츠 캡처 옵트인입니다. 기본값은 꺼짐입니다. 불리언 `true`는 시스템이 아닌 메시지/도구 콘텐츠를 캡처합니다. 객체 형식을 사용하면 `inputMessages`, `outputMessages`, `toolInputs`, `toolOutputs`, `systemPrompt`를 명시적으로 활성화할 수 있습니다. -- `OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental`: 최신 실험적 GenAI 스팬 공급자 속성을 위한 환경 토글입니다. 기본적으로 스팬은 호환성을 위해 기존 `gen_ai.system` 속성을 유지합니다. GenAI 메트릭은 제한된 의미론적 속성을 사용합니다. +- `otel.captureContent`: OTEL span 속성에 대한 원시 콘텐츠 캡처를 옵트인합니다. 기본값은 꺼짐입니다. Boolean `true`는 시스템이 아닌 메시지/도구 콘텐츠를 캡처하며, 객체 형식에서는 `inputMessages`, `outputMessages`, `toolInputs`, `toolOutputs`, `systemPrompt`를 명시적으로 활성화할 수 있습니다. +- `OTEL_SEMCONV_STABILITY_OPT_IN=gen_ai_latest_experimental`: 최신 실험적 GenAI span 공급자 속성을 위한 환경 토글입니다. 기본적으로 span은 호환성을 위해 기존 `gen_ai.system` 속성을 유지하며, GenAI 메트릭은 제한된 시맨틱 속성을 사용합니다. - `OPENCLAW_OTEL_PRELOADED=1`: 전역 OpenTelemetry SDK를 이미 등록한 호스트를 위한 환경 토글입니다. 그러면 OpenClaw는 진단 리스너를 활성 상태로 유지하면서 Plugin 소유 SDK 시작/종료를 건너뜁니다. -- `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`, `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`, `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT`: 일치하는 구성 키가 설정되지 않았을 때 사용되는 신호별 엔드포인트 환경 변수입니다. -- `cacheTrace.enabled`: 임베디드 실행의 캐시 트레이스 스냅샷을 기록합니다(기본값: `false`). +- `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT`, `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT`, `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT`: 일치하는 구성 키가 설정되지 않은 경우 사용되는 신호별 엔드포인트 환경 변수입니다. +- `cacheTrace.enabled`: 임베디드 실행에 대한 캐시 트레이스 스냅샷을 기록합니다(기본값: `false`). - `cacheTrace.filePath`: 캐시 트레이스 JSONL의 출력 경로입니다(기본값: `$OPENCLAW_STATE_DIR/logs/cache-trace.jsonl`). -- `cacheTrace.includeMessages` / `includePrompt` / `includeSystem`: 캐시 트레이스 출력에 포함할 항목을 제어합니다(모두 기본값: `true`). +- `cacheTrace.includeMessages` / `includePrompt` / `includeSystem`: 캐시 트레이스 출력에 포함할 내용을 제어합니다(모두 기본값: `true`). --- @@ -948,12 +951,12 @@ openclaw gateway --port 19001 } ``` -- `channel`: npm/git 설치의 릴리스 채널입니다 - `"stable"`, `"beta"`, 또는 `"dev"`. -- `checkOnStart`: gateway가 시작될 때 npm 업데이트를 확인합니다(기본값: `true`). +- `channel`: npm/git 설치의 릴리스 채널입니다. `"stable"`, `"beta"` 또는 `"dev"`입니다. +- `checkOnStart`: Gateway가 시작될 때 npm 업데이트를 확인합니다(기본값: `true`). - `auto.enabled`: 패키지 설치에 대한 백그라운드 자동 업데이트를 활성화합니다(기본값: `false`). -- `auto.stableDelayHours`: stable 채널 자동 적용 전 최소 지연 시간(시간)입니다(기본값: `6`, 최대: `168`). -- `auto.stableJitterHours`: 추가 stable 채널 롤아웃 분산 기간(시간)입니다(기본값: `12`, 최대: `168`). -- `auto.betaCheckIntervalHours`: beta 채널 확인 실행 빈도(시간)입니다(기본값: `1`, 최대: `24`). +- `auto.stableDelayHours`: stable 채널 자동 적용 전 최소 지연 시간(시간 단위)입니다(기본값: `6`, 최대: `168`). +- `auto.stableJitterHours`: stable 채널 롤아웃 분산을 위한 추가 시간 창(시간 단위)입니다(기본값: `12`, 최대: `168`). +- `auto.betaCheckIntervalHours`: beta 채널 확인 실행 주기(시간 단위)입니다(기본값: `1`, 최대: `24`). --- @@ -986,21 +989,21 @@ openclaw gateway --port 19001 } ``` -- `enabled`: 전역 ACP 기능 게이트입니다(기본값: `true`, ACP 디스패치와 생성 기능을 숨기려면 `false`로 설정). -- `dispatch.enabled`: ACP 세션 턴 디스패치의 독립 게이트입니다(기본값: `true`). ACP 명령을 사용할 수 있게 유지하면서 실행을 차단하려면 `false`로 설정하세요. +- `enabled`: 전역 ACP 기능 게이트입니다(기본값: `true`, ACP 디스패치 및 스폰 어포던스를 숨기려면 `false`로 설정). +- `dispatch.enabled`: ACP 세션 턴 디스패치에 대한 독립 게이트입니다(기본값: `true`). ACP 명령은 사용할 수 있게 유지하면서 실행을 차단하려면 `false`로 설정하세요. - `backend`: 기본 ACP 런타임 백엔드 ID입니다(등록된 ACP 런타임 Plugin과 일치해야 함). - 먼저 백엔드 Plugin을 설치하고, `plugins.allow`가 설정된 경우 백엔드 Plugin ID(예: `acpx`)를 포함하세요. 그렇지 않으면 ACP 백엔드가 로드되지 않습니다. -- `defaultAgent`: 생성 시 명시적 대상이 지정되지 않은 경우 fallback ACP 대상 에이전트 ID입니다. -- `allowedAgents`: ACP 런타임 세션에 허용된 에이전트 ID 허용 목록입니다. 비어 있으면 추가 제한이 없음을 의미합니다. -- `maxConcurrentSessions`: 동시에 활성화될 수 있는 ACP 세션의 최대 수입니다. -- `stream.coalesceIdleMs`: 스트리밍 텍스트의 유휴 플러시 기간(ms)입니다. -- `stream.maxChunkChars`: 스트리밍된 블록 프로젝션을 분할하기 전 최대 청크 크기입니다. + 먼저 백엔드 Plugin을 설치하고, `plugins.allow`가 설정되어 있으면 백엔드 Plugin ID(예: `acpx`)를 포함하세요. 그렇지 않으면 ACP 백엔드가 로드되지 않습니다. +- `defaultAgent`: 스폰이 명시적 대상을 지정하지 않을 때 사용할 폴백 ACP 대상 에이전트 ID입니다. +- `allowedAgents`: ACP 런타임 세션에 허용되는 에이전트 ID의 허용 목록입니다. 비어 있으면 추가 제한이 없음을 의미합니다. +- `maxConcurrentSessions`: 동시에 활성 상태일 수 있는 ACP 세션의 최대 수입니다. +- `stream.coalesceIdleMs`: 스트리밍 텍스트의 유휴 플러시 윈도우(ms)입니다. +- `stream.maxChunkChars`: 스트리밍된 블록 투영을 분할하기 전 최대 청크 크기입니다. - `stream.repeatSuppression`: 턴마다 반복되는 상태/도구 줄을 억제합니다(기본값: `true`). - `stream.deliveryMode`: `"live"`는 증분 스트리밍하고, `"final_only"`는 턴 종료 이벤트까지 버퍼링합니다. -- `stream.hiddenBoundarySeparator`: 숨겨진 도구 이벤트 뒤의 표시 텍스트 앞에 넣는 구분자입니다(기본값: `"paragraph"`). -- `stream.maxOutputChars`: ACP 턴마다 투영되는 어시스턴트 출력 문자의 최대 수입니다. +- `stream.hiddenBoundarySeparator`: 숨겨진 도구 이벤트 뒤의 표시 텍스트 앞에 넣을 구분자입니다(기본값: `"paragraph"`). +- `stream.maxOutputChars`: ACP 턴당 투영되는 최대 어시스턴트 출력 문자 수입니다. - `stream.maxSessionUpdateChars`: 투영된 ACP 상태/업데이트 줄의 최대 문자 수입니다. -- `stream.tagVisibility`: 스트리밍된 이벤트에 대한 태그 이름별 불리언 표시 여부 재정의 레코드입니다. +- `stream.tagVisibility`: 스트리밍 이벤트의 태그 이름별 boolean 표시 여부 재정의 레코드입니다. - `runtime.ttlMinutes`: ACP 세션 워커가 정리 대상이 되기 전 유휴 TTL(분)입니다. - `runtime.installCommand`: ACP 런타임 환경을 부트스트랩할 때 실행할 선택적 설치 명령입니다. @@ -1019,16 +1022,16 @@ openclaw gateway --port 19001 ``` - `cli.banner.taglineMode`는 배너 태그라인 스타일을 제어합니다. - - `"random"`(기본값): 순환되는 유머/시즌별 태그라인입니다. + - `"random"`(기본값): 순환되는 재미/계절 태그라인입니다. - `"default"`: 고정된 중립 태그라인(`All your chats, one OpenClaw.`)입니다. - - `"off"`: 태그라인 텍스트 없음(배너 제목/버전은 계속 표시됨). -- 전체 배너(태그라인만이 아님)를 숨기려면 환경 변수 `OPENCLAW_HIDE_BANNER=1`을 설정하세요. + - `"off"`: 태그라인 텍스트가 없습니다(배너 제목/버전은 계속 표시됨). +- 전체 배너를 숨기려면(태그라인만이 아님) 환경 변수 `OPENCLAW_HIDE_BANNER=1`을 설정하세요. --- ## 마법사 -CLI 안내 설정 흐름(`onboard`, `configure`, `doctor`)에서 작성하는 메타데이터: +CLI 안내 설정 플로우(`onboard`, `configure`, `doctor`)가 기록하는 메타데이터: ```json5 { @@ -1044,17 +1047,17 @@ CLI 안내 설정 흐름(`onboard`, `configure`, `doctor`)에서 작성하는 --- -## 식별 정보 +## ID -[에이전트 기본값](/ko/gateway/config-agents#agent-defaults)의 `agents.list` 식별 정보 필드를 참조하세요. +[에이전트 기본값](/ko/gateway/config-agents#agent-defaults) 아래의 `agents.list` ID 필드를 참조하세요. --- ## 브리지(레거시, 제거됨) -현재 빌드에는 더 이상 TCP 브리지가 포함되지 않습니다. Node는 Gateway WebSocket을 통해 연결됩니다. `bridge.*` 키는 더 이상 구성 스키마의 일부가 아닙니다(제거될 때까지 검증이 실패합니다. `openclaw doctor --fix`로 알 수 없는 키를 제거할 수 있습니다). +현재 빌드에는 더 이상 TCP 브리지가 포함되지 않습니다. Node는 Gateway WebSocket을 통해 연결됩니다. `bridge.*` 키는 더 이상 구성 스키마의 일부가 아닙니다(제거할 때까지 검증이 실패하며, `openclaw doctor --fix`로 알 수 없는 키를 제거할 수 있음). - + ```json { @@ -1092,11 +1095,11 @@ CLI 안내 설정 흐름(`onboard`, `configure`, `doctor`)에서 작성하는 } ``` -- `sessionRetention`: 완료된 격리된 Cron 실행 세션을 `sessions.json`에서 정리하기 전에 보관할 기간입니다. 보관된 삭제 Cron transcript의 정리도 제어합니다. 기본값: `24h`; 비활성화하려면 `false`로 설정하세요. -- `runLog.maxBytes`: 정리 전에 실행 로그 파일(`cron/runs/.jsonl`)당 최대 크기입니다. 기본값: `2_000_000`바이트. -- `runLog.keepLines`: 실행 로그 정리가 트리거될 때 보존할 최신 줄 수입니다. 기본값: `2000`. -- `webhookToken`: Cron Webhook POST 전달(`delivery.mode = "webhook"`)에 사용되는 bearer token입니다. 생략하면 인증 헤더가 전송되지 않습니다. -- `webhook`: `notify: true`가 아직 있는 저장된 작업에만 사용되는 더 이상 권장되지 않는 레거시 대체 Webhook URL(http/https)입니다. +- `sessionRetention`: 완료된 격리된 Cron 실행 세션을 `sessions.json`에서 정리하기 전에 보관할 기간입니다. 보관된 삭제 Cron transcript의 정리도 제어합니다. 기본값: `24h`; 비활성화하려면 `false`로 설정합니다. +- `runLog.maxBytes`: 정리하기 전 실행 로그 파일(`cron/runs/.jsonl`)당 최대 크기입니다. 기본값: `2_000_000`바이트. +- `runLog.keepLines`: 실행 로그 정리가 트리거될 때 유지할 최신 줄 수입니다. 기본값: `2000`. +- `webhookToken`: Cron Webhook POST 전달(`delivery.mode = "webhook"`)에 사용되는 bearer token입니다. 생략하면 auth header가 전송되지 않습니다. +- `webhook`: 아직 `notify: true`가 있는 저장된 작업에만 사용되는 더 이상 사용되지 않는 legacy fallback Webhook URL(http/https)입니다. ### `cron.retry` @@ -1112,8 +1115,8 @@ CLI 안내 설정 흐름(`onboard`, `configure`, `doctor`)에서 작성하는 } ``` -- `maxAttempts`: 일시적 오류 발생 시 일회성 작업의 최대 재시도 횟수입니다(기본값: `3`; 범위: `0`-`10`). -- `backoffMs`: 각 재시도 시도에 대한 ms 단위 백오프 지연 배열입니다(기본값: `[30000, 60000, 300000]`; 항목 1-10개). +- `maxAttempts`: 일회성 작업의 일시적 오류에 대한 최대 재시도 횟수입니다(기본값: `3`; 범위: `0`-`10`). +- `backoffMs`: 각 재시도 시도에 대한 ms 단위 backoff 지연 배열입니다(기본값: `[30000, 60000, 300000]`; 1-10개 항목). - `retryOn`: 재시도를 트리거하는 오류 유형입니다 - `"rate_limit"`, `"overloaded"`, `"network"`, `"timeout"`, `"server_error"`. 생략하면 모든 일시적 유형을 재시도합니다. 일회성 Cron 작업에만 적용됩니다. 반복 작업은 별도의 실패 처리를 사용합니다. @@ -1135,11 +1138,11 @@ CLI 안내 설정 흐름(`onboard`, `configure`, `doctor`)에서 작성하는 } ``` -- `enabled`: Cron 작업의 실패 알림을 활성화합니다(기본값: `false`). -- `after`: 알림이 발생하기 전까지의 연속 실패 횟수입니다(양의 정수, 최솟값: `1`). -- `cooldownMs`: 같은 작업에 대해 반복 알림 사이의 최소 밀리초입니다(음수가 아닌 정수). -- `includeSkipped`: 연속으로 건너뛴 실행을 알림 임계값에 포함합니다(기본값: `false`). 건너뛴 실행은 별도로 추적되며 실행 오류 백오프에 영향을 주지 않습니다. -- `mode`: 전달 모드입니다 - `"announce"`는 채널 메시지로 전송하고, `"webhook"`은 구성된 Webhook에 게시합니다. +- `enabled`: Cron 작업에 대한 실패 알림을 활성화합니다(기본값: `false`). +- `after`: 알림이 발생하기 전의 연속 실패 횟수입니다(양의 정수, 최솟값: `1`). +- `cooldownMs`: 같은 작업에 대한 반복 알림 사이의 최소 밀리초입니다(음수가 아닌 정수). +- `includeSkipped`: 연속으로 건너뛴 실행을 알림 임계값에 포함합니다(기본값: `false`). 건너뛴 실행은 별도로 추적되며 실행 오류 backoff에 영향을 주지 않습니다. +- `mode`: 전달 모드입니다 - `"announce"`는 채널 메시지를 통해 전송하고, `"webhook"`은 구성된 Webhook으로 게시합니다. - `accountId`: 알림 전달 범위를 지정할 선택적 계정 또는 채널 id입니다. ### `cron.failureDestination` @@ -1157,16 +1160,16 @@ CLI 안내 설정 흐름(`onboard`, `configure`, `doctor`)에서 작성하는 } ``` -- 모든 작업에 대한 Cron 실패 알림의 기본 대상입니다. +- 모든 작업의 Cron 실패 알림에 대한 기본 대상입니다. - `mode`: `"announce"` 또는 `"webhook"`입니다. 충분한 대상 데이터가 있으면 기본값은 `"announce"`입니다. -- `channel`: announce 전달을 위한 채널 재정의입니다. `"last"`는 마지막으로 알려진 전달 채널을 재사용합니다. +- `channel`: announce 전달에 대한 채널 override입니다. `"last"`는 마지막으로 알려진 전달 채널을 재사용합니다. - `to`: 명시적 announce 대상 또는 Webhook URL입니다. Webhook 모드에 필요합니다. -- `accountId`: 전달을 위한 선택적 계정 재정의입니다. -- 작업별 `delivery.failureDestination`은 이 전역 기본값을 재정의합니다. -- 전역 실패 대상도 작업별 실패 대상도 설정되지 않은 경우, 이미 `announce`로 전달하는 작업은 실패 시 해당 기본 announce 대상으로 대체됩니다. +- `accountId`: 전달에 대한 선택적 계정 override입니다. +- 작업별 `delivery.failureDestination`은 이 전역 기본값을 override합니다. +- 전역 또는 작업별 실패 대상이 설정되지 않은 경우, 이미 `announce`로 전달되는 작업은 실패 시 해당 기본 announce 대상으로 fallback됩니다. - `delivery.failureDestination`은 작업의 기본 `delivery.mode`가 `"webhook"`인 경우를 제외하고 `sessionTarget="isolated"` 작업에만 지원됩니다. -[Cron 작업](/ko/automation/cron-jobs)을 참조하세요. 격리된 Cron 실행은 [백그라운드 작업](/ko/automation/tasks)으로 추적됩니다. +[Cron 작업](/ko/automation/cron-jobs)을 참고하세요. 격리된 Cron 실행은 [background tasks](/ko/automation/tasks)로 추적됩니다. --- @@ -1176,32 +1179,32 @@ CLI 안내 설정 흐름(`onboard`, `configure`, `doctor`)에서 작성하는 | 변수 | 설명 | | ------------------ | ------------------------------------------------- | -| `{{Body}}` | 전체 인바운드 메시지 본문 | -| `{{RawBody}}` | 원시 본문(기록/발신자 래퍼 없음) | +| `{{Body}}` | 전체 수신 메시지 본문 | +| `{{RawBody}}` | 원시 본문(history/sender wrapper 없음) | | `{{BodyStripped}}` | 그룹 멘션이 제거된 본문 | | `{{From}}` | 발신자 식별자 | | `{{To}}` | 대상 식별자 | | `{{MessageSid}}` | 채널 메시지 id | | `{{SessionId}}` | 현재 세션 UUID | -| `{{IsNewSession}}` | 새 세션이 생성되면 `"true"` | -| `{{MediaUrl}}` | 인바운드 미디어 pseudo-URL | +| `{{IsNewSession}}` | 새 세션이 생성되었을 때 `"true"` | +| `{{MediaUrl}}` | 수신 미디어 pseudo-URL | | `{{MediaPath}}` | 로컬 미디어 경로 | | `{{MediaType}}` | 미디어 유형(image/audio/document/…) | | `{{Transcript}}` | 오디오 transcript | -| `{{Prompt}}` | CLI 항목에 대해 확인된 미디어 프롬프트 | -| `{{MaxChars}}` | CLI 항목에 대해 확인된 최대 출력 문자 수 | +| `{{Prompt}}` | CLI 항목에 대해 해석된 미디어 prompt | +| `{{MaxChars}}` | CLI 항목에 대해 해석된 최대 출력 문자 수 | | `{{ChatType}}` | `"direct"` 또는 `"group"` | | `{{GroupSubject}}` | 그룹 제목(최선의 노력) | -| `{{GroupMembers}}` | 그룹 구성원 미리보기(최선의 노력) | +| `{{GroupMembers}}` | 그룹 멤버 미리보기(최선의 노력) | | `{{SenderName}}` | 발신자 표시 이름(최선의 노력) | | `{{SenderE164}}` | 발신자 전화번호(최선의 노력) | -| `{{Provider}}` | provider 힌트(whatsapp, telegram, discord 등) | +| `{{Provider}}` | 제공자 힌트(WhatsApp, Telegram, Discord 등) | --- ## 구성 include(`$include`) -구성을 여러 파일로 분할합니다: +구성을 여러 파일로 분할합니다. ```json5 // ~/.openclaw/openclaw.json @@ -1217,13 +1220,13 @@ CLI 안내 설정 흐름(`onboard`, `configure`, `doctor`)에서 작성하는 **병합 동작:** - 단일 파일: 포함하는 객체를 대체합니다. -- 파일 배열: 순서대로 deep-merge됩니다(나중 항목이 이전 항목을 재정의). -- 형제 키: include 후에 병합됩니다(포함된 값을 재정의). -- 중첩 include: 최대 10단계 깊이까지 지원합니다. -- 경로: 포함하는 파일을 기준으로 확인되지만, 최상위 구성 디렉터리(`openclaw.json`의 `dirname`) 안에 있어야 합니다. 절대 경로/`../` 형식은 해당 경계 안으로 확인되는 경우에만 허용됩니다. -- 최상위 섹션 하나만 변경하고 단일 파일 include가 뒷받침하는 OpenClaw 소유 쓰기는 해당 포함 파일에 바로 기록됩니다. 예를 들어 `plugins install`은 `plugins.json5`의 `plugins: { $include: "./plugins.json5" }`를 업데이트하고 `openclaw.json`은 그대로 둡니다. -- 루트 include, include 배열, 형제 재정의가 있는 include는 OpenClaw 소유 쓰기에 대해 읽기 전용입니다. 이러한 쓰기는 구성을 평탄화하는 대신 fail closed됩니다. -- 오류: 누락된 파일, 파싱 오류, 순환 include에 대해 명확한 메시지를 제공합니다. +- 파일 배열: 순서대로 deep-merge됩니다(나중 항목이 이전 항목을 override). +- 형제 키: include 후 병합됩니다(포함된 값을 override). +- 중첩 include: 최대 10단계 깊이까지 허용됩니다. +- 경로: 포함하는 파일을 기준으로 해석되지만 최상위 구성 디렉터리(`openclaw.json`의 `dirname`) 안에 있어야 합니다. 절대 경로/`../` 형식은 여전히 해당 경계 안으로 해석되는 경우에만 허용됩니다. +- 단일 파일 include가 뒷받침하는 하나의 최상위 섹션만 변경하는 OpenClaw 소유 쓰기는 해당 include 파일로 전달되어 기록됩니다. 예를 들어, `plugins install`은 `plugins.json5`의 `plugins: { $include: "./plugins.json5" }`를 업데이트하고 `openclaw.json`은 그대로 둡니다. +- 루트 include, include 배열, 형제 override가 있는 include는 OpenClaw 소유 쓰기에 대해 읽기 전용입니다. 이러한 쓰기는 구성을 flatten하는 대신 fail-closed됩니다. +- 오류: 누락된 파일, parse 오류, 순환 include에 대해 명확한 메시지를 제공합니다. --- diff --git a/docs/ko/gateway/doctor.md b/docs/ko/gateway/doctor.md index 1d751a5cc..c5238494b 100644 --- a/docs/ko/gateway/doctor.md +++ b/docs/ko/gateway/doctor.md @@ -1,15 +1,15 @@ --- read_when: - - doctor 마이그레이션 추가 또는 수정 - - 호환성을 깨는 구성 변경 사항 도입 + - 진단 마이그레이션 추가 또는 수정 + - 호환성을 깨는 설정 변경 도입 sidebarTitle: Doctor -summary: '진단 명령: 상태 검사, 구성 마이그레이션 및 복구 단계' +summary: '진단 명령어: 상태 점검, 설정 마이그레이션 및 복구 단계' title: 진단 x-i18n: - generated_at: "2026-05-06T06:25:08Z" + generated_at: "2026-05-06T17:55:52Z" model: gpt-5.5 provider: openai - source_hash: 5cee2793b1a0665a3a816586fcb597de1fd3133819d34480aa420346f4d7a78d + source_hash: 1e8a1e280717b7a523ba092dec2e2f7d1c13e67a5ede30d0b4bb5a3100dc0e44 source_path: gateway/doctor.md workflow: 16 --- @@ -30,7 +30,7 @@ openclaw doctor openclaw doctor --yes ``` - 프롬프트 없이 기본값을 수락합니다(해당되는 경우 재시작/서비스/샌드박스 복구 단계 포함). + 프롬프트 없이 기본값을 수락합니다(해당하는 경우 restart/service/sandbox 복구 단계 포함). @@ -54,7 +54,7 @@ openclaw doctor openclaw doctor --non-interactive ``` - 프롬프트 없이 실행하고 안전한 마이그레이션만 적용합니다(config 정규화 + 디스크상 state 이동). 사람의 확인이 필요한 재시작/서비스/샌드박스 작업은 건너뜁니다. 레거시 state 마이그레이션은 감지되면 자동으로 실행됩니다. + 프롬프트 없이 실행하고 안전한 마이그레이션만 적용합니다(config 정규화 + 디스크 내 state 이동). 사람의 확인이 필요한 restart/service/sandbox 작업은 건너뜁니다. 레거시 state 마이그레이션은 감지되면 자동으로 실행됩니다. @@ -77,64 +77,64 @@ cat ~/.openclaw/openclaw.json - - git 설치의 선택적 사전 업데이트(대화형 전용). - - UI 프로토콜 최신 상태 검사(프로토콜 스키마가 더 최신이면 Control UI를 다시 빌드). + - git 설치에 대한 선택적 사전 업데이트(대화형 전용). + - UI 프로토콜 최신성 검사(프로토콜 스키마가 더 최신이면 Control UI를 다시 빌드). - 상태 검사 + 재시작 프롬프트. - Skills 상태 요약(적격/누락/차단) 및 Plugin 상태. - + - 레거시 값에 대한 config 정규화. - - 레거시 플랫 `talk.*` 필드에서 `talk.provider` + `talk.providers.`로 Talk config 마이그레이션. - - 레거시 Chrome extension config 및 Chrome MCP 준비 상태에 대한 Browser 마이그레이션 검사. + - 레거시 평면 `talk.*` 필드에서 `talk.provider` + `talk.providers.`로 Talk config 마이그레이션. + - 레거시 Chrome 확장 config 및 Chrome MCP 준비 상태에 대한 브라우저 마이그레이션 검사. - OpenCode provider override 경고(`models.providers.opencode` / `models.providers.opencode-go`). - Codex OAuth shadowing 경고(`models.providers.openai-codex`). - - OpenAI Codex OAuth 프로필의 OAuth TLS 필수 조건 검사. - - `plugins.allow`가 제한적이지만 tool policy가 여전히 wildcard 또는 Plugin 소유 도구를 요구할 때 Plugin/tool allowlist 경고. - - 레거시 디스크상 state 마이그레이션(sessions/agent dir/WhatsApp auth). - - 레거시 Plugin manifest contract key 마이그레이션(`speechProviders`, `realtimeTranscriptionProviders`, `realtimeVoiceProviders`, `mediaUnderstandingProviders`, `imageGenerationProviders`, `videoGenerationProviders`, `webFetchProviders`, `webSearchProviders` → `contracts`). - - 레거시 cron store 마이그레이션(`jobId`, `schedule.cron`, 최상위 delivery/payload 필드, payload `provider`, 단순 `notify: true` webhook fallback jobs). + - OpenAI Codex OAuth 프로필에 대한 OAuth TLS 필수 조건 검사. + - `plugins.allow`가 제한적이지만 도구 정책이 여전히 와일드카드 또는 Plugin 소유 도구를 요청할 때 Plugin/tool allowlist 경고. + - 레거시 디스크 내 state 마이그레이션(sessions/agent dir/WhatsApp auth). + - 레거시 Plugin manifest contract 키 마이그레이션(`speechProviders`, `realtimeTranscriptionProviders`, `realtimeVoiceProviders`, `mediaUnderstandingProviders`, `imageGenerationProviders`, `videoGenerationProviders`, `webFetchProviders`, `webSearchProviders` → `contracts`). + - 레거시 Cron 저장소 마이그레이션(`jobId`, `schedule.cron`, 최상위 delivery/payload 필드, payload `provider`, 단순 `notify: true` Webhook fallback jobs). - 레거시 agent runtime-policy를 `agents.defaults.agentRuntime` 및 `agents.list[].agentRuntime`로 마이그레이션. - - Plugin이 활성화되어 있을 때 오래된 Plugin config 정리. `plugins.enabled=false`이면 오래된 Plugin 참조는 비활성 containment config로 처리되어 보존됩니다. + - Plugin이 활성화된 경우 오래된 Plugin config 정리. `plugins.enabled=false`인 경우 오래된 Plugin 참조는 비활성 containment config로 취급되어 보존됩니다. - - Session lock file 검사 및 오래된 lock 정리. - - 영향을 받은 2026.4.24 빌드가 생성한 중복 prompt-rewrite branch에 대한 session transcript 복구. - - 멈춘 subagent restart-recovery tombstone 감지. 시작 시 child를 계속 restart-aborted로 처리하지 않도록 오래된 aborted recovery flag를 지우는 `--fix` 지원 포함. + - 세션 lock file 검사 및 오래된 lock 정리. + - 영향을 받은 2026.4.24 빌드에서 생성된 중복 prompt-rewrite branch에 대한 세션 transcript 복구. + - wedged subagent restart-recovery tombstone 감지. `--fix` 지원을 통해 오래된 aborted recovery flag를 지워 startup이 child를 restart-aborted로 계속 취급하지 않도록 합니다. - State 무결성 및 권한 검사(sessions, transcripts, state dir). - 로컬에서 실행할 때 config 파일 권한 검사(chmod 600). - - Model auth 상태: OAuth 만료를 확인하고, 만료 예정 token을 갱신할 수 있으며, auth-profile cooldown/disabled state를 보고합니다. + - Model auth 상태: OAuth 만료를 검사하고, 만료 임박 토큰을 새로 고칠 수 있으며, auth-profile cooldown/disabled 상태를 보고합니다. - 추가 workspace dir 감지(`~/openclaw`). - - 샌드박싱이 활성화된 경우 샌드박스 이미지 복구. + - sandboxing이 활성화된 경우 sandbox 이미지 복구. - 레거시 서비스 마이그레이션 및 추가 Gateway 감지. - - Matrix channel 레거시 state 마이그레이션(`--fix` / `--repair` 모드에서). - - Gateway runtime 검사(서비스가 설치되어 있지만 실행 중이 아님, 캐시된 launchd label). - - Channel 상태 경고(실행 중인 Gateway에서 probe). - - local TUI client가 아직 실행 중일 때 Gateway event-loop 상태 저하에 대한 WhatsApp 응답성 검사. `--fix`는 검증된 local TUI client만 중지합니다. - - primary model, fallback, heartbeat/subagent/compaction override, hook, channel model override, session route pin의 레거시 `openai-codex/*` model ref에 대한 Codex route 복구. `--fix`는 이를 `openai/*`로 다시 쓰고, Codex Plugin이 설치 및 활성화되어 있고 `codex` harness를 제공하며 사용 가능한 OAuth가 있는 경우에만 `agentRuntime.id: "codex"`를 선택합니다. 그렇지 않으면 `agentRuntime.id: "pi"`를 선택합니다. - - 선택적 복구가 포함된 supervisor config 감사(launchd/systemd/schtasks). - - 설치 또는 업데이트 중 shell `HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY` 값을 캡처한 Gateway service의 embedded proxy environment 정리. - - Gateway runtime 모범 사례 검사(Node vs Bun, version-manager path). - - Gateway port 충돌 진단(기본값 `18789`). + - Matrix 채널 레거시 state 마이그레이션(`--fix` / `--repair` 모드). + - Gateway runtime 검사(서비스가 설치되었지만 실행 중이 아님, 캐시된 launchd label). + - 채널 상태 경고(실행 중인 Gateway에서 probe). + - local TUI 클라이언트가 계속 실행 중인 상태에서 Gateway event-loop 상태가 저하된 경우 WhatsApp 응답성 검사. `--fix`는 검증된 local TUI 클라이언트만 중지합니다. + - primary models, fallbacks, heartbeat/subagent/compaction overrides, hooks, channel model overrides, session route pins의 레거시 `openai-codex/*` model ref에 대한 Codex route 복구. `--fix`는 이를 `openai/*`로 다시 쓰고, Codex Plugin이 설치 및 활성화되어 있고 `codex` harness를 제공하며 사용 가능한 OAuth가 있는 경우에만 `agentRuntime.id: "codex"`를 선택합니다. 그렇지 않으면 `agentRuntime.id: "pi"`를 선택합니다. + - 선택적 복구가 포함된 supervisor config audit(launchd/systemd/schtasks). + - 설치 또는 업데이트 중 shell `HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY` 값을 캡처한 Gateway 서비스에 대한 embedded proxy 환경 정리. + - Gateway runtime 모범 사례 검사(Node vs Bun, version-manager paths). + - Gateway 포트 충돌 진단(기본값 `18789`). - - - 열린 DM policy에 대한 보안 경고. - - local token mode에 대한 Gateway auth 검사(token source가 없으면 token generation을 제안하며, token SecretRef config를 덮어쓰지 않음). - - Device pairing 문제 감지(대기 중인 최초 pair request, 대기 중인 role/scope upgrade, 오래된 local device-token cache drift, paired-record auth drift). + + - open DM 정책에 대한 보안 경고. + - local token mode에 대한 Gateway auth 검사(토큰 소스가 없으면 토큰 생성을 제안하며 token SecretRef config를 덮어쓰지 않음). + - 디바이스 페어링 문제 감지(대기 중인 최초 pair 요청, 대기 중인 role/scope upgrade, 오래된 local device-token cache drift, paired-record auth drift). - - Linux에서 systemd linger 검사. - - Workspace bootstrap file size 검사(context file의 잘림/한계 근접 경고). - - default agent에 대한 Skills 준비 상태 검사. 누락된 bin, env, config 또는 OS 요구 사항이 있는 허용된 Skills를 보고하며, `--fix`는 `skills.entries`에서 사용할 수 없는 Skills를 비활성화할 수 있습니다. + - Linux의 systemd linger 검사. + - Workspace bootstrap 파일 크기 검사(context 파일에 대한 truncation/near-limit 경고). + - 기본 agent에 대한 Skills 준비 상태 검사. 누락된 bins, env, config 또는 OS 요구 사항이 있는 허용된 skills를 보고하며, `--fix`는 `skills.entries`에서 사용할 수 없는 skills를 비활성화할 수 있습니다. - Shell completion 상태 검사 및 자동 설치/업그레이드. - Memory search embedding provider 준비 상태 검사(local model, remote API key 또는 QMD binary). - - Source install 검사(pnpm workspace mismatch, 누락된 UI asset, 누락된 tsx binary). + - 소스 설치 검사(pnpm workspace 불일치, 누락된 UI assets, 누락된 tsx binary). - 업데이트된 config + wizard metadata를 씁니다. @@ -142,27 +142,27 @@ cat ~/.openclaw/openclaw.json ## Dreams UI backfill 및 reset -Control UI Dreams scene에는 grounded dreaming workflow를 위한 **Backfill**, **Reset**, **Clear Grounded** 작업이 포함됩니다. 이러한 작업은 gateway doctor 스타일 RPC method를 사용하지만, `openclaw doctor` CLI 복구/마이그레이션의 일부는 **아닙니다**. +Control UI Dreams scene에는 grounded Dreaming 워크플로를 위한 **Backfill**, **Reset**, **Clear Grounded** 작업이 포함되어 있습니다. 이러한 작업은 Gateway doctor 스타일 RPC 메서드를 사용하지만, `openclaw doctor` CLI repair/migration의 일부는 **아닙니다**. -수행 작업: +수행하는 작업: -- **Backfill**은 active workspace의 과거 `memory/YYYY-MM-DD.md` 파일을 스캔하고, grounded REM diary pass를 실행하며, 되돌릴 수 있는 backfill entry를 `DREAMS.md`에 씁니다. +- **Backfill**은 활성 workspace의 과거 `memory/YYYY-MM-DD.md` 파일을 스캔하고, grounded REM diary pass를 실행하며, 되돌릴 수 있는 backfill entry를 `DREAMS.md`에 씁니다. - **Reset**은 `DREAMS.md`에서 표시된 backfill diary entry만 제거합니다. - **Clear Grounded**는 과거 replay에서 왔고 아직 live recall 또는 daily support가 누적되지 않은 staged grounded-only short-term entry만 제거합니다. -자체적으로 수행하지 **않는** 작업: +그 자체로 수행하지 **않는** 작업: - `MEMORY.md`를 편집하지 않습니다 - 전체 doctor 마이그레이션을 실행하지 않습니다 -- staged CLI path를 명시적으로 먼저 실행하지 않는 한, grounded candidate를 live short-term promotion store에 자동으로 stage하지 않습니다 +- staged CLI path를 먼저 명시적으로 실행하지 않는 한 grounded candidate를 live short-term promotion store에 자동으로 stage하지 않습니다 -grounded historical replay가 일반 deep promotion lane에 영향을 주게 하려면 대신 CLI flow를 사용하세요. +grounded historical replay가 일반 deep promotion lane에 영향을 주도록 하려면 대신 CLI 흐름을 사용하세요. ```bash openclaw memory rem-backfill --path ./memory --stage-short-term ``` -이렇게 하면 `DREAMS.md`를 review surface로 유지하면서 grounded durable candidate를 short-term dreaming store에 stage합니다. +이는 `DREAMS.md`를 review surface로 유지하면서 grounded durable candidate를 short-term Dreaming store에 stage합니다. ## 상세 동작 및 근거 @@ -171,27 +171,27 @@ openclaw memory rem-backfill --path ./memory --stage-short-term 이것이 git checkout이고 doctor가 대화형으로 실행 중이면 doctor 실행 전에 업데이트(fetch/rebase/build)를 제안합니다. - config에 레거시 값 형태(예: channel-specific override가 없는 `messages.ackReaction`)가 포함되어 있으면 doctor가 이를 현재 스키마로 정규화합니다. + config에 레거시 값 형태(예: 채널별 override가 없는 `messages.ackReaction`)가 포함되어 있으면 doctor는 이를 현재 스키마로 정규화합니다. - 여기에는 레거시 Talk flat field가 포함됩니다. 현재 public Talk speech config는 `talk.provider` + `talk.providers.`이고, realtime voice config는 `talk.realtime.*`입니다. Doctor는 이전 `talk.voiceId` / `talk.voiceAliases` / `talk.modelId` / `talk.outputFormat` / `talk.apiKey` 형태를 provider map으로 다시 쓰고, 레거시 최상위 realtime selector(`talk.mode`, `talk.transport`, `talk.brain`, `talk.model`, `talk.voice`)를 `talk.realtime`로 다시 씁니다. + 여기에는 레거시 Talk 평면 필드가 포함됩니다. 현재 공개 Talk speech config는 `talk.provider` + `talk.providers.`이고, realtime voice config는 `talk.realtime.*`입니다. Doctor는 이전 `talk.voiceId` / `talk.voiceAliases` / `talk.modelId` / `talk.outputFormat` / `talk.apiKey` 형태를 provider map으로 다시 쓰고, 레거시 최상위 realtime selector(`talk.mode`, `talk.transport`, `talk.brain`, `talk.model`, `talk.voice`)를 `talk.realtime`로 다시 씁니다. - Doctor는 또한 `plugins.allow`가 비어 있지 않고 tool policy가 - wildcard 또는 Plugin 소유 tool entry를 사용할 때 경고합니다. `tools.allow: ["*"]`는 실제로 로드되는 Plugin의 tool에만 일치합니다. - 배타적 Plugin allowlist를 우회하지 않습니다. Doctor는 마이그레이션된 + Doctor는 또한 `plugins.allow`가 비어 있지 않고 도구 정책이 + wildcard 또는 Plugin 소유 도구 entry를 사용할 때 경고합니다. `tools.allow: ["*"]`는 실제로 로드되는 Plugin의 도구에만 일치하며, + exclusive Plugin allowlist를 우회하지 않습니다. Doctor는 마이그레이션된 레거시 allowlist config에 대해 기존 bundled provider 동작을 보존하기 위해 `plugins.bundledDiscovery: "compat"`를 쓰고, - 그다음 더 엄격한 `"allowlist"` 설정을 가리킵니다. + 그런 다음 더 엄격한 `"allowlist"` 설정을 안내합니다. - - config에 deprecated key가 포함되어 있으면 다른 command는 실행을 거부하고 `openclaw doctor`를 실행하라고 요청합니다. + + config에 deprecated key가 포함되어 있으면 다른 명령은 실행을 거부하고 `openclaw doctor`를 실행하라고 요청합니다. Doctor는 다음을 수행합니다. - - 어떤 레거시 key가 발견되었는지 설명합니다. - - 적용한 마이그레이션을 표시합니다. - - 업데이트된 스키마로 `~/.openclaw/openclaw.json`를 다시 씁니다. + - 발견된 레거시 키를 설명합니다. + - 적용한 마이그레이션을 보여줍니다. + - 업데이트된 스키마로 `~/.openclaw/openclaw.json`을 다시 씁니다. - Gateway도 시작 시 레거시 config format을 감지하면 doctor 마이그레이션을 자동 실행하므로, 오래된 config는 수동 개입 없이 복구됩니다. Cron job store 마이그레이션은 `openclaw doctor --fix`가 처리합니다. + Gateway startup은 레거시 config 형식을 거부하고 `openclaw doctor --fix`를 실행하라고 요청합니다. startup에서 `openclaw.json`을 다시 쓰지는 않습니다. Cron job store 마이그레이션도 `openclaw doctor --fix`에서 처리됩니다. 현재 마이그레이션: @@ -200,12 +200,12 @@ openclaw memory rem-backfill --path ./memory --stage-short-term - `routing.groupChat.historyLimit` → `messages.groupChat.historyLimit` - `routing.groupChat.mentionPatterns` → `messages.groupChat.mentionPatterns` - `channels.telegram.requireMention` → `channels.telegram.groups."*".requireMention` - - 표시되는 답장 정책이 없는 구성된 채널 설정 → `messages.groupChat.visibleReplies: "message_tool"` + - visible reply policy가 누락된 configured-channel 설정 → `messages.groupChat.visibleReplies: "message_tool"` - `routing.queue` → `messages.queue` - `routing.bindings` → 최상위 `bindings` - `routing.agents`/`routing.defaultAgentId` → `agents.list` + `agents.list[].default` - 레거시 `talk.voiceId`/`talk.voiceAliases`/`talk.modelId`/`talk.outputFormat`/`talk.apiKey` → `talk.provider` + `talk.providers.` - - 레거시 최상위 실시간 Talk 선택자(`talk.mode`/`talk.transport`/`talk.brain`/`talk.model`/`talk.voice`) + `talk.provider`/`talk.providers` → `talk.realtime` + - 레거시 최상위 실시간 Talk selector(`talk.mode`/`talk.transport`/`talk.brain`/`talk.model`/`talk.voice`) + `talk.provider`/`talk.providers` → `talk.realtime` - `routing.agentToAgent` → `tools.agentToAgent` - `routing.transcribeAudio` → `tools.media.audio.models` - `messages.tts.`(`openai`/`elevenlabs`/`microsoft`/`edge`) → `messages.tts.providers.` @@ -219,215 +219,215 @@ openclaw memory rem-backfill --path ./memory --stage-short-term - `plugins.entries.voice-call.config.streaming.sttProvider` → `plugins.entries.voice-call.config.streaming.provider` - `plugins.entries.voice-call.config.streaming.openaiApiKey|sttModel|silenceDurationMs|vadThreshold` → `plugins.entries.voice-call.config.streaming.providers.openai.*` - `bindings[].match.accountID` → `bindings[].match.accountId` - - 이름 있는 `accounts`가 있지만 단일 계정용 최상위 채널 값이 남아 있는 채널의 경우, 해당 계정 범위 값을 그 채널에 선택된 승격 계정으로 이동합니다(대부분의 채널은 `accounts.default`, Matrix는 기존의 일치하는 이름 있는/기본 대상을 보존할 수 있음). + - 이름 있는 `accounts`가 있지만 단일 계정용 최상위 channel 값이 남아 있는 channel의 경우, 해당 계정 범위 값을 해당 channel에 대해 선택된 승격 계정으로 이동합니다(대부분의 channel은 `accounts.default`; Matrix는 기존의 일치하는 named/default 대상을 보존할 수 있음) - `identity` → `agents.list[].identity` - `agent.*` → `agents.defaults` + `tools.*`(tools/elevated/exec/sandbox/subagents) - `agent.model`/`allowedModels`/`modelAliases`/`modelFallbacks`/`imageModelFallbacks` → `agents.defaults.models` + `agents.defaults.model.primary/fallbacks` + `agents.defaults.imageModel.primary/fallbacks` - - `agents.defaults.llm` 제거; 느린 provider/model 시간 제한에는 `models.providers..timeoutSeconds` 사용 + - `agents.defaults.llm` 제거; 느린 provider/model timeout에는 `models.providers..timeoutSeconds` 사용 - `browser.ssrfPolicy.allowPrivateNetwork` → `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork` - `browser.profiles.*.driver: "extension"` → `"existing-session"` - - `browser.relayBindHost` 제거(레거시 extension 릴레이 설정) - - 레거시 `models.providers.*.api: "openai"` → `"openai-completions"`(Gateway 시작 시 `api`가 미래 또는 알 수 없는 enum 값으로 설정된 provider도 실패로 닫는 대신 건너뜁니다) + - `browser.relayBindHost` 제거(레거시 extension relay 설정) + - 레거시 `models.providers.*.api: "openai"` → `"openai-completions"`(Gateway 시작 시 `api`가 미래 또는 알 수 없는 enum 값으로 설정된 provider도 fail closed하지 않고 건너뜀) - Doctor 경고에는 다중 계정 채널에 대한 계정 기본값 안내도 포함됩니다. + Doctor 경고에는 multi-account channel을 위한 account-default 지침도 포함됩니다. - - 둘 이상의 `channels..accounts` 항목이 `channels..defaultAccount` 또는 `accounts.default` 없이 구성되어 있으면, Doctor는 fallback 라우팅이 예상치 못한 계정을 선택할 수 있다고 경고합니다. - - `channels..defaultAccount`가 알 수 없는 계정 ID로 설정되어 있으면, Doctor는 경고하고 구성된 계정 ID를 나열합니다. + - 두 개 이상의 `channels..accounts` 항목이 `channels..defaultAccount` 또는 `accounts.default` 없이 설정된 경우, doctor는 fallback routing이 예상치 못한 계정을 선택할 수 있다고 경고합니다. + - `channels..defaultAccount`가 알 수 없는 account ID로 설정된 경우, doctor는 경고하고 설정된 account ID를 나열합니다. - `models.providers.opencode`, `opencode-zen` 또는 `opencode-go`를 수동으로 추가했다면, `@mariozechner/pi-ai`의 기본 제공 OpenCode 카탈로그를 재정의합니다. 이로 인해 모델이 잘못된 API로 강제되거나 비용이 0으로 설정될 수 있습니다. Doctor는 이 재정의를 제거하고 모델별 API 라우팅 및 비용을 복원할 수 있도록 경고합니다. + `models.providers.opencode`, `opencode-zen` 또는 `opencode-go`를 수동으로 추가한 경우, `@mariozechner/pi-ai`의 기본 제공 OpenCode 카탈로그를 재정의합니다. 이로 인해 model이 잘못된 API로 강제되거나 비용이 0이 될 수 있습니다. Doctor는 해당 재정의를 제거하고 model별 API routing 및 비용을 복원할 수 있도록 경고합니다. - 브라우저 설정이 여전히 제거된 Chrome extension 경로를 가리키는 경우, Doctor는 이를 현재의 호스트 로컬 Chrome MCP 연결 모델로 정규화합니다. + browser 설정이 제거된 Chrome extension 경로를 계속 가리키는 경우, doctor는 이를 현재 host-local Chrome MCP attach model로 정규화합니다. - - `browser.profiles.*.driver: "extension"`는 `"existing-session"`이 됩니다 + - `browser.profiles.*.driver: "extension"`은 `"existing-session"`이 됩니다 - `browser.relayBindHost`가 제거됩니다 - Doctor는 `defaultProfile: "user"` 또는 구성된 `existing-session` 프로필을 사용할 때 호스트 로컬 Chrome MCP 경로도 감사합니다. + Doctor는 `defaultProfile: "user"` 또는 설정된 `existing-session` profile을 사용할 때 host-local Chrome MCP 경로도 감사합니다. - - 기본 자동 연결 프로필의 경우 같은 호스트에 Google Chrome이 설치되어 있는지 확인합니다 - - 감지된 Chrome 버전을 확인하고 Chrome 144 미만이면 경고합니다 - - 브라우저 검사 페이지에서 원격 디버깅을 활성화하라고 알립니다(예: `chrome://inspect/#remote-debugging`, `brave://inspect/#remote-debugging` 또는 `edge://inspect/#remote-debugging`) + - 기본 auto-connect profile을 위해 같은 host에 Google Chrome이 설치되어 있는지 확인합니다 + - 감지된 Chrome version을 확인하고 Chrome 144 미만이면 경고합니다 + - browser inspect page에서 remote debugging을 활성화하라고 알려 줍니다(예: `chrome://inspect/#remote-debugging`, `brave://inspect/#remote-debugging` 또는 `edge://inspect/#remote-debugging`) - Doctor는 사용자를 대신해 Chrome 쪽 설정을 활성화할 수 없습니다. 호스트 로컬 Chrome MCP에는 여전히 다음이 필요합니다. + Doctor는 Chrome 쪽 설정을 대신 활성화할 수 없습니다. Host-local Chrome MCP에는 여전히 다음이 필요합니다. - - Gateway/Node 호스트의 Chromium 기반 브라우저 144+ - - 로컬에서 실행 중인 브라우저 - - 해당 브라우저에서 활성화된 원격 디버깅 - - 브라우저의 첫 연결 동의 프롬프트 승인 + - gateway/node host의 Chromium 기반 browser 144+ + - 로컬에서 실행 중인 browser + - 해당 browser에서 remote debugging 활성화 + - browser에서 첫 attach consent prompt 승인 - 여기서의 준비 상태는 로컬 연결 전제 조건에만 관한 것입니다. 기존 세션은 현재 Chrome MCP 라우트 제한을 유지합니다. `responsebody`, PDF 내보내기, 다운로드 가로채기, 일괄 작업 같은 고급 라우트에는 여전히 관리형 브라우저 또는 원시 CDP 프로필이 필요합니다. + 여기서 readiness는 local attach prerequisites에만 관한 것입니다. Existing-session은 현재 Chrome MCP route limit을 유지합니다. `responsebody`, PDF export, download interception, batch action 같은 advanced route에는 여전히 managed browser 또는 raw CDP profile이 필요합니다. - 이 검사는 Docker, sandbox, 원격 브라우저 또는 기타 headless 흐름에는 적용되지 않습니다. 이러한 흐름은 계속 원시 CDP를 사용합니다. + 이 검사는 Docker, sandbox, remote-browser 또는 기타 headless flow에는 적용되지 **않습니다**. 이러한 flow는 계속 raw CDP를 사용합니다. - OpenAI Codex OAuth 프로필이 구성되어 있으면, Doctor는 OpenAI 인증 엔드포인트를 조사하여 로컬 Node/OpenSSL TLS 스택이 인증서 체인을 검증할 수 있는지 확인합니다. 조사가 인증서 오류(예: `UNABLE_TO_GET_ISSUER_CERT_LOCALLY`, 만료된 인증서 또는 자체 서명 인증서)로 실패하면, Doctor는 플랫폼별 수정 안내를 출력합니다. Homebrew Node를 사용하는 macOS에서는 일반적으로 `brew postinstall ca-certificates`가 수정 방법입니다. `--deep`을 사용하면 Gateway가 정상이어도 조사가 실행됩니다. + OpenAI Codex OAuth profile이 설정된 경우, doctor는 OpenAI authorization endpoint를 probe하여 local Node/OpenSSL TLS stack이 certificate chain을 검증할 수 있는지 확인합니다. probe가 certificate error(예: `UNABLE_TO_GET_ISSUER_CERT_LOCALLY`, 만료된 cert 또는 self-signed cert)로 실패하면 doctor는 platform별 수정 지침을 출력합니다. Homebrew Node를 사용하는 macOS에서는 일반적으로 `brew postinstall ca-certificates`로 수정할 수 있습니다. `--deep`에서는 Gateway가 정상이어도 probe가 실행됩니다. - 이전에 `models.providers.openai-codex` 아래에 레거시 OpenAI 전송 설정을 추가했다면, 최신 릴리스가 자동으로 사용하는 기본 제공 Codex OAuth provider 경로를 가릴 수 있습니다. Doctor는 Codex OAuth와 함께 이러한 오래된 전송 설정을 발견하면 경고하므로, 오래된 전송 재정의를 제거하거나 다시 작성해 기본 제공 라우팅/fallback 동작을 되돌릴 수 있습니다. 사용자 지정 프록시와 헤더 전용 재정의는 계속 지원되며 이 경고를 트리거하지 않습니다. + 이전에 `models.providers.openai-codex` 아래에 레거시 OpenAI transport 설정을 추가했다면, 최신 release가 자동으로 사용하는 기본 제공 Codex OAuth provider path를 가릴 수 있습니다. Doctor는 Codex OAuth와 함께 이러한 오래된 transport 설정이 보이면 경고하므로, stale transport override를 제거하거나 다시 작성해 기본 제공 routing/fallback 동작을 복원할 수 있습니다. Custom proxy와 header-only override는 계속 지원되며 이 경고를 트리거하지 않습니다. - Doctor는 레거시 `openai-codex/*` 모델 참조를 확인합니다. 네이티브 Codex 하네스 라우팅은 표준 `openai/*` 모델 참조와 `agentRuntime.id: "codex"`를 사용하므로, 턴이 OpenClaw PI OpenAI 경로 대신 Codex app-server 하네스를 통과합니다. + Doctor는 레거시 `openai-codex/*` model ref를 확인합니다. Native Codex harness routing은 canonical `openai/*` model ref와 `agentRuntime.id: "codex"`를 사용하므로 turn이 OpenClaw PI OpenAI path 대신 Codex app-server harness를 거칩니다. - `--fix` / `--repair` 모드에서 Doctor는 primary 모델, fallback, Heartbeat/subagent/Compaction 재정의, 훅, 채널 모델 재정의, 오래된 저장 세션 라우트 상태를 포함해 영향을 받는 기본 에이전트 및 에이전트별 참조를 다시 작성합니다. + `--fix` / `--repair` mode에서 doctor는 primary model, fallback, heartbeat/subagent/compaction override, hook, channel model override, stale persisted session route state를 포함하여 영향을 받는 default-agent 및 per-agent ref를 다시 작성합니다. - `openai-codex/gpt-*`는 `openai/gpt-*`가 됩니다. - - 일치하는 에이전트 런타임은 Codex가 설치되어 있고, 활성화되어 있으며, `codex` 하네스를 제공하고, 사용 가능한 OAuth가 있을 때만 `agentRuntime.id: "codex"`가 됩니다. - - 그렇지 않으면 일치하는 에이전트 런타임은 `agentRuntime.id: "pi"`가 됩니다. - - 기존 모델 fallback 목록은 레거시 항목이 다시 작성된 채로 보존됩니다. 복사된 모델별 설정은 레거시 키에서 표준 `openai/*` 키로 이동합니다. - - 저장된 세션 `modelProvider`/`providerOverride`, `model`/`modelOverride`, fallback 알림, 인증 프로필 고정, Codex 하네스 고정이 발견된 모든 에이전트 세션 저장소에서 복구됩니다. - - `/codex ...`는 "채팅에서 네이티브 Codex 대화를 제어하거나 바인딩"을 의미합니다. - - `/acp ...` 또는 `runtime: "acp"`는 "외부 ACP/acpx 어댑터 사용"을 의미합니다. + - 일치하는 agent runtime은 Codex가 설치되어 있고, 활성화되어 있으며, `codex` harness를 제공하고, 사용할 수 있는 OAuth가 있는 경우에만 `agentRuntime.id: "codex"`가 됩니다. + - 그렇지 않으면 일치하는 agent runtime은 `agentRuntime.id: "pi"`가 됩니다. + - 기존 model fallback list는 레거시 항목이 다시 작성된 상태로 보존됩니다. 복사된 per-model 설정은 레거시 key에서 canonical `openai/*` key로 이동합니다. + - Persisted session의 `modelProvider`/`providerOverride`, `model`/`modelOverride`, fallback notice, auth-profile pin, Codex harness pin은 발견된 모든 agent session store에서 복구됩니다. + - `/codex ...`는 “채팅에서 native Codex conversation을 제어하거나 bind한다”는 뜻입니다. + - `/acp ...` 또는 `runtime: "acp"`는 “external ACP/acpx adapter를 사용한다”는 뜻입니다. - Doctor는 Codex와 같은 Plugin 소유 라우트에서 구성된 모델 또는 런타임을 옮긴 뒤 남은 오래된 자동 생성 라우트 상태가 있는지 발견된 에이전트 세션 저장소도 검사합니다. + Doctor는 설정된 model 또는 runtime을 Codex 같은 plugin-owned route에서 다른 곳으로 옮긴 뒤 stale auto-created route state가 있는지도 발견된 agent session store에서 스캔합니다. - `openclaw doctor --fix`는 소유 라우트가 더 이상 구성되어 있지 않을 때 `modelOverrideSource: "auto"` 모델 고정, 런타임 모델 메타데이터, 고정된 하네스 ID, CLI 세션 바인딩, 자동 인증 프로필 재정의와 같은 자동 생성된 오래된 상태를 정리할 수 있습니다. 명시적인 사용자 또는 레거시 세션 모델 선택은 수동 검토 대상으로 보고되고 그대로 둡니다. 해당 라우트가 더 이상 의도되지 않는 경우 `/model ...`, `/new`로 전환하거나 세션을 재설정하세요. + `openclaw doctor --fix`는 소유 route가 더 이상 설정되지 않았을 때 `modelOverrideSource: "auto"` model pin, runtime model metadata, pinned harness id, CLI session binding, auto auth-profile override 같은 auto-created stale state를 지울 수 있습니다. 명시적인 사용자 또는 레거시 session model 선택은 수동 검토 대상으로 보고되고 그대로 둡니다. 해당 route가 더 이상 의도된 것이 아니라면 `/model ...`, `/new`로 전환하거나 session을 reset하세요. - Doctor는 오래된 온디스크 레이아웃을 현재 구조로 마이그레이션할 수 있습니다. + Doctor는 오래된 on-disk layout을 현재 구조로 migration할 수 있습니다. - - 세션 저장소 + transcript: + - Session store + transcript: - `~/.openclaw/sessions/`에서 `~/.openclaw/agents//sessions/`로 - - 에이전트 디렉터리: + - Agent dir: - `~/.openclaw/agent/`에서 `~/.openclaw/agents//agent/`로 - - WhatsApp 인증 상태(Baileys): + - WhatsApp auth state(Baileys): - 레거시 `~/.openclaw/credentials/*.json`에서(`oauth.json` 제외) - - `~/.openclaw/credentials/whatsapp//...`로(기본 계정 ID: `default`) + - `~/.openclaw/credentials/whatsapp//...`로(기본 account id: `default`) - 이러한 마이그레이션은 최선 노력 방식이며 멱등적입니다. Doctor가 레거시 폴더를 백업으로 남겨둘 때 경고를 출력합니다. Gateway/CLI도 시작 시 레거시 세션 + 에이전트 디렉터리를 자동 마이그레이션하므로, 수동으로 Doctor를 실행하지 않아도 기록/인증/모델이 에이전트별 경로에 위치합니다. WhatsApp 인증은 의도적으로 `openclaw doctor`를 통해서만 마이그레이션됩니다. Talk provider/provider-map 정규화는 이제 구조적 동등성으로 비교하므로, 키 순서만 다른 diff는 더 이상 반복적인 no-op `doctor --fix` 변경을 트리거하지 않습니다. + 이러한 migration은 best-effort이며 idempotent합니다. doctor는 legacy folder를 backup으로 남겨 두는 경우 경고를 표시합니다. Gateway/CLI도 시작 시 레거시 session + agent dir을 자동 migration하므로 history/auth/model이 수동 doctor 실행 없이 per-agent path에 저장됩니다. WhatsApp auth는 의도적으로 `openclaw doctor`를 통해서만 migration됩니다. Talk provider/provider-map normalization은 이제 structural equality로 비교하므로, key order만 다른 diff는 더 이상 반복적인 no-op `doctor --fix` 변경을 트리거하지 않습니다. - Doctor는 설치된 모든 Plugin 매니페스트를 스캔하여 사용 중단된 최상위 capability 키(`speechProviders`, `realtimeTranscriptionProviders`, `realtimeVoiceProviders`, `mediaUnderstandingProviders`, `imageGenerationProviders`, `videoGenerationProviders`, `webFetchProviders`, `webSearchProviders`)를 찾습니다. 발견되면 이를 `contracts` 객체로 이동하고 매니페스트 파일을 제자리에서 다시 작성하도록 제안합니다. 이 마이그레이션은 멱등적입니다. `contracts` 키에 이미 동일한 값이 있으면 데이터를 중복하지 않고 레거시 키가 제거됩니다. + Doctor는 설치된 모든 plugin manifest에서 deprecated top-level capability key(`speechProviders`, `realtimeTranscriptionProviders`, `realtimeVoiceProviders`, `mediaUnderstandingProviders`, `imageGenerationProviders`, `videoGenerationProviders`, `webFetchProviders`, `webSearchProviders`)를 스캔합니다. 발견되면 이를 `contracts` object로 이동하고 manifest file을 in-place로 다시 쓰도록 제안합니다. 이 migration은 idempotent합니다. `contracts` key에 이미 같은 값이 있으면 data를 중복하지 않고 legacy key가 제거됩니다. - Doctor는 cron 작업 저장소(기본값은 `~/.openclaw/cron/jobs.json`, 재정의된 경우 `cron.store`)에서 스케줄러가 호환성을 위해 여전히 허용하는 오래된 작업 형태도 확인합니다. + Doctor는 cron job store(기본값 `~/.openclaw/cron/jobs.json`, override된 경우 `cron.store`)에서도 scheduler가 compatibility를 위해 여전히 허용하는 오래된 job shape가 있는지 확인합니다. - 현재 cron 정리에는 다음이 포함됩니다. + 현재 cron cleanup에는 다음이 포함됩니다. - `jobId` → `id` - `schedule.cron` → `schedule.expr` - - 최상위 payload 필드(`message`, `model`, `thinking`, ...) → `payload` - - 최상위 delivery 필드(`deliver`, `channel`, `to`, `provider`, ...) → `delivery` - - payload `provider` delivery 별칭 → 명시적 `delivery.channel` - - 단순 레거시 `notify: true` webhook fallback 작업 → `delivery.to=cron.webhook`이 포함된 명시적 `delivery.mode="webhook"` + - 최상위 payload field(`message`, `model`, `thinking`, ...) → `payload` + - 최상위 delivery field(`deliver`, `channel`, `to`, `provider`, ...) → `delivery` + - payload `provider` delivery alias → 명시적 `delivery.channel` + - 단순 레거시 `notify: true` webhook fallback job → `delivery.to=cron.webhook`가 있는 명시적 `delivery.mode="webhook"` - Doctor는 동작을 변경하지 않고 수행할 수 있을 때만 `notify: true` 작업을 자동 마이그레이션합니다. 작업이 레거시 notify 폴백과 기존 비-Webhook 전달 모드를 함께 사용하는 경우, doctor는 경고를 표시하고 해당 작업을 수동 검토 대상으로 남겨 둡니다. + Doctor는 동작을 변경하지 않고 처리할 수 있을 때만 `notify: true` 작업을 자동 마이그레이션합니다. 작업이 기존 notify 대체 동작과 기존 비 Webhook 전달 모드를 함께 사용하는 경우 doctor는 경고하고 해당 작업을 수동 검토 대상으로 남겨 둡니다. - Linux에서는 사용자의 crontab이 여전히 레거시 `~/.openclaw/bin/ensure-whatsapp.sh`를 호출하는 경우에도 doctor가 경고합니다. 이 호스트 로컬 스크립트는 현재 OpenClaw에서 유지 관리되지 않으며, cron이 systemd 사용자 버스에 접근할 수 없을 때 `~/.openclaw/logs/whatsapp-health.log`에 잘못된 `Gateway inactive` 메시지를 쓸 수 있습니다. `crontab -e`로 오래된 crontab 항목을 제거하세요. 현재 상태 확인에는 `openclaw channels status --probe`, `openclaw doctor`, `openclaw gateway status`를 사용하세요. + Linux에서는 사용자의 crontab이 여전히 레거시 `~/.openclaw/bin/ensure-whatsapp.sh`를 호출하는 경우에도 doctor가 경고합니다. 이 호스트 로컬 스크립트는 현재 OpenClaw에서 유지 관리되지 않으며, cron이 systemd 사용자 버스에 연결할 수 없을 때 `~/.openclaw/logs/whatsapp-health.log`에 잘못된 `Gateway inactive` 메시지를 쓸 수 있습니다. `crontab -e`로 오래된 crontab 항목을 제거하세요. 현재 상태 점검에는 `openclaw channels status --probe`, `openclaw doctor`, `openclaw gateway status`를 사용하세요. - Doctor는 모든 에이전트 세션 디렉터리에서 오래된 쓰기 잠금 파일, 즉 세션이 비정상적으로 종료될 때 남겨진 파일을 검사합니다. 발견된 각 잠금 파일에 대해 경로, PID, PID가 아직 살아 있는지 여부, 잠금 기간, 오래된 것으로 간주되는지 여부(죽은 PID 또는 30분 초과)를 보고합니다. `--fix` / `--repair` 모드에서는 오래된 잠금 파일을 자동으로 제거합니다. 그렇지 않으면 참고 메시지를 출력하고 `--fix`로 다시 실행하라고 안내합니다. + Doctor는 모든 에이전트 세션 디렉터리에서 오래된 쓰기 잠금 파일, 즉 세션이 비정상 종료되었을 때 남은 파일을 스캔합니다. 발견된 각 잠금 파일에 대해 경로, PID, PID가 아직 살아 있는지 여부, 잠금 경과 시간, 오래된 것으로 간주되는지 여부(죽은 PID 또는 30분 초과)를 보고합니다. `--fix` / `--repair` 모드에서는 오래된 잠금 파일을 자동으로 제거합니다. 그렇지 않으면 참고 메시지를 출력하고 `--fix`로 다시 실행하라고 안내합니다. - - Doctor는 2026.4.24 프롬프트 트랜스크립트 재작성 버그로 생성된 중복 브랜치 형태를 찾기 위해 에이전트 세션 JSONL 파일을 검사합니다. 이 형태는 OpenClaw 내부 런타임 컨텍스트가 있는 버려진 사용자 턴과, 동일한 표시용 사용자 프롬프트를 포함하는 활성 형제 브랜치로 구성됩니다. `--fix` / `--repair` 모드에서 doctor는 영향을 받은 각 파일을 원본 옆에 백업하고 트랜스크립트를 활성 브랜치로 다시 작성하여 Gateway 기록과 메모리 리더가 더 이상 중복 턴을 보지 않게 합니다. + + Doctor는 2026.4.24 프롬프트 transcript 재작성 버그로 생성된 중복 브랜치 형태를 찾기 위해 에이전트 세션 JSONL 파일을 스캔합니다. 이는 OpenClaw 내부 런타임 컨텍스트가 있는 버려진 사용자 턴과 동일한 표시 사용자 프롬프트를 포함하는 활성 형제 항목이 함께 있는 형태입니다. `--fix` / `--repair` 모드에서 doctor는 영향을 받은 각 파일을 원본 옆에 백업하고 transcript를 활성 브랜치로 다시 작성하여 Gateway 기록 및 메모리 리더가 더 이상 중복 턴을 보지 않게 합니다. - - 상태 디렉터리는 운영상의 중추입니다. 이 디렉터리가 사라지면 다른 곳에 백업이 없는 한 세션, 자격 증명, 로그, 설정을 잃게 됩니다. + + 상태 디렉터리는 운영상의 중추입니다. 이것이 사라지면 다른 곳에 백업이 없는 한 세션, 자격 증명, 로그, 구성을 잃게 됩니다. - Doctor는 다음을 확인합니다. + Doctor가 검사하는 항목: - - **상태 디렉터리 없음**: 치명적인 상태 손실을 경고하고, 디렉터리를 다시 만들지 묻고, 누락된 데이터는 복구할 수 없다고 알립니다. - - **상태 디렉터리 권한**: 쓰기 가능 여부를 확인합니다. 권한 복구를 제안하고, 소유자/그룹 불일치가 감지되면 `chown` 힌트를 출력합니다. - - **macOS 클라우드 동기화 상태 디렉터리**: 상태가 iCloud Drive(`~/Library/Mobile Documents/com~apple~CloudDocs/...`) 또는 `~/Library/CloudStorage/...` 아래로 해석되면, 동기화 기반 경로가 더 느린 I/O와 잠금/동기화 경합을 유발할 수 있으므로 경고합니다. - - **Linux SD 또는 eMMC 상태 디렉터리**: 상태가 `mmcblk*` 마운트 소스로 해석되면, SD 또는 eMMC 기반 랜덤 I/O가 세션 및 자격 증명 쓰기 중 더 느리고 더 빨리 마모될 수 있으므로 경고합니다. - - **세션 디렉터리 없음**: 기록을 지속하고 `ENOENT` 크래시를 피하려면 `sessions/`와 세션 저장소 디렉터리가 필요합니다. - - **트랜스크립트 불일치**: 최근 세션 항목에 트랜스크립트 파일이 없으면 경고합니다. - - **메인 세션 "1-line JSONL"**: 메인 트랜스크립트가 한 줄뿐인 경우(기록이 누적되지 않음) 표시합니다. - - **여러 상태 디렉터리**: 홈 디렉터리 전반에 여러 `~/.openclaw` 폴더가 있거나 `OPENCLAW_STATE_DIR`이 다른 곳을 가리키면 경고합니다(설치 간 기록이 나뉠 수 있음). - - **원격 모드 알림**: `gateway.mode=remote`이면 doctor는 원격 호스트에서 실행하라고 알립니다(상태가 그곳에 있음). - - **설정 파일 권한**: `~/.openclaw/openclaw.json`이 그룹/전역 읽기 가능이면 경고하고 `600`으로 강화하도록 제안합니다. + - **상태 디렉터리 없음**: 치명적인 상태 손실을 경고하고, 디렉터리를 다시 만들지 묻고, 누락된 데이터는 복구할 수 없음을 알려 줍니다. + - **상태 디렉터리 권한**: 쓰기 가능 여부를 확인합니다. 권한 복구를 제안하고 소유자/그룹 불일치가 감지되면 `chown` 힌트를 출력합니다. + - **macOS 클라우드 동기화 상태 디렉터리**: 상태가 iCloud Drive(`~/Library/Mobile Documents/com~apple~CloudDocs/...`) 또는 `~/Library/CloudStorage/...` 아래로 해석될 때 경고합니다. 동기화 기반 경로는 I/O를 느리게 만들고 잠금/동기화 경합을 일으킬 수 있기 때문입니다. + - **Linux SD 또는 eMMC 상태 디렉터리**: 상태가 `mmcblk*` 마운트 소스로 해석될 때 경고합니다. SD 또는 eMMC 기반 랜덤 I/O는 세션 및 자격 증명 쓰기에서 더 느리고 더 빨리 마모될 수 있기 때문입니다. + - **세션 디렉터리 없음**: `sessions/` 및 세션 저장소 디렉터리는 기록을 유지하고 `ENOENT` 크래시를 방지하는 데 필요합니다. + - **Transcript 불일치**: 최근 세션 항목에 transcript 파일이 없을 때 경고합니다. + - **메인 세션 "1줄 JSONL"**: 메인 transcript가 한 줄뿐인 경우 표시합니다(기록이 누적되지 않음). + - **여러 상태 디렉터리**: 홈 디렉터리 전반에 여러 `~/.openclaw` 폴더가 있거나 `OPENCLAW_STATE_DIR`이 다른 위치를 가리킬 때 경고합니다(설치 간 기록이 분리될 수 있음). + - **원격 모드 알림**: `gateway.mode=remote`인 경우 doctor는 원격 호스트에서 실행하라고 알려 줍니다(상태가 그곳에 있음). + - **구성 파일 권한**: `~/.openclaw/openclaw.json`이 그룹/전체 사용자에게 읽기 가능하면 경고하고 `600`으로 강화할 것을 제안합니다. - Doctor는 인증 저장소의 OAuth 프로필을 검사하고, 토큰이 곧 만료되거나 만료되었을 때 경고하며, 안전할 경우 새로 고칠 수 있습니다. Anthropic OAuth/토큰 프로필이 오래되었으면 Anthropic API 키 또는 Anthropic 설정 토큰 경로를 제안합니다. 새로 고침 프롬프트는 대화형(TTY)으로 실행할 때만 나타납니다. `--non-interactive`는 새로 고침 시도를 건너뜁니다. + Doctor는 인증 저장소의 OAuth 프로필을 검사하고, 토큰이 곧 만료되거나 만료된 경우 경고하며, 안전할 때 갱신할 수 있습니다. Anthropic OAuth/토큰 프로필이 오래된 경우 Anthropic API 키 또는 Anthropic setup-token 경로를 제안합니다. 갱신 프롬프트는 대화형(TTY)으로 실행할 때만 표시됩니다. `--non-interactive`는 갱신 시도를 건너뜁니다. - OAuth 새로 고침이 영구적으로 실패하면(예: `refresh_token_reused`, `invalid_grant`, 또는 제공자가 다시 로그인하라고 알리는 경우) doctor는 재인증이 필요하다고 보고하고 실행할 정확한 `openclaw models auth login --provider ...` 명령을 출력합니다. + OAuth 갱신이 영구적으로 실패하면(예: `refresh_token_reused`, `invalid_grant` 또는 제공자가 다시 로그인하라고 알리는 경우) doctor는 재인증이 필요하다고 보고하고 실행할 정확한 `openclaw models auth login --provider ...` 명령을 출력합니다. Doctor는 다음으로 인해 일시적으로 사용할 수 없는 인증 프로필도 보고합니다. - - 짧은 쿨다운(속도 제한/시간 초과/인증 실패) - - 더 긴 비활성화(결제/크레딧 실패) + - 짧은 cooldown(rate limit/timeout/auth failure) + - 더 긴 비활성화(billing/credit failure) - - `hooks.gmail.model`이 설정되어 있으면 doctor는 카탈로그와 허용 목록에 대해 모델 참조를 검증하고, 해석되지 않거나 허용되지 않으면 경고합니다. + + `hooks.gmail.model`이 설정된 경우 doctor는 카탈로그 및 허용 목록을 기준으로 모델 참조를 검증하고, 확인할 수 없거나 허용되지 않는 경우 경고합니다. - 샌드박싱이 활성화되어 있으면 doctor는 Docker 이미지를 확인하고, 현재 이미지가 없을 경우 빌드하거나 레거시 이름으로 전환하도록 제안합니다. + 샌드박스가 활성화된 경우 doctor는 Docker 이미지를 검사하고 현재 이미지가 없으면 빌드하거나 레거시 이름으로 전환할 것을 제안합니다. - Doctor는 `openclaw doctor --fix` / `openclaw doctor --repair` 모드에서 레거시 OpenClaw 생성 Plugin 의존성 스테이징 상태를 제거합니다. 여기에는 오래된 생성 의존성 루트, 이전 설치 스테이지 디렉터리, 예전 번들 Plugin 의존성 복구 코드에서 남은 패키지 로컬 잔해, 현재 번들 매니페스트를 가릴 수 있는 고아 상태이거나 복구된 관리형 npm 번들 `@openclaw/*` Plugin 복사본이 포함됩니다. + Doctor는 `openclaw doctor --fix` / `openclaw doctor --repair` 모드에서 레거시 OpenClaw 생성 Plugin 의존성 스테이징 상태를 제거합니다. 여기에는 오래된 생성 의존성 루트, 이전 install-stage 디렉터리, 예전 번들 Plugin 의존성 복구 코드에서 남은 패키지 로컬 잔해, 현재 번들 매니페스트를 가릴 수 있는 번들 `@openclaw/*` Plugin의 고아 상태 또는 복구된 관리형 npm 사본이 포함됩니다. - 설정에서 참조하지만 로컬 Plugin 레지스트리가 찾을 수 없는 다운로드 가능 Plugin이 누락된 경우 doctor가 다시 설치할 수도 있습니다. 예로는 실제 `plugins.entries`, 설정된 채널/제공자/검색 설정, 설정된 에이전트 런타임이 있습니다. 패키지 업데이트 중에는 코어 패키지가 교체되는 동안 doctor가 패키지 관리자 Plugin 복구를 실행하지 않습니다. 설정된 Plugin에 여전히 복구가 필요하면 업데이트 후 `openclaw doctor --fix`를 다시 실행하세요. Gateway 시작과 설정 다시 로드는 패키지 관리자를 실행하지 않습니다. Plugin 설치는 명시적인 doctor/install/update 작업으로 남습니다. + Doctor는 구성에서 다운로드 가능한 Plugin을 참조하지만 로컬 Plugin 레지스트리에서 찾을 수 없는 경우 누락된 Plugin을 다시 설치할 수도 있습니다. 예로는 실제 `plugins.entries`, 구성된 채널/제공자/검색 설정, 구성된 에이전트 런타임이 있습니다. 패키지 업데이트 중에는 core 패키지가 교체되는 동안 doctor가 패키지 관리자 Plugin 복구를 실행하지 않습니다. 구성된 Plugin에 여전히 복구가 필요하면 업데이트 후 `openclaw doctor --fix`를 다시 실행하세요. Gateway 시작 및 구성 다시 로드는 패키지 관리자를 실행하지 않습니다. Plugin 설치는 명시적인 doctor/install/update 작업으로 남아 있습니다. - Doctor는 레거시 Gateway 서비스(launchd/systemd/schtasks)를 감지하고, 현재 Gateway 포트를 사용하여 이를 제거하고 OpenClaw 서비스를 설치하도록 제안합니다. 또한 추가 Gateway 유사 서비스를 검색하고 정리 힌트를 출력할 수 있습니다. 프로필 이름이 지정된 OpenClaw Gateway 서비스는 일급 대상으로 간주되며 "추가"로 표시되지 않습니다. + Doctor는 레거시 Gateway 서비스(launchd/systemd/schtasks)를 감지하고 이를 제거한 뒤 현재 Gateway 포트를 사용하여 OpenClaw 서비스를 설치할 것을 제안합니다. 또한 추가 Gateway 유사 서비스를 스캔하고 정리 힌트를 출력할 수 있습니다. 프로필 이름이 지정된 OpenClaw Gateway 서비스는 일급 대상으로 간주되며 "extra"로 표시되지 않습니다. - Linux에서 사용자 수준 Gateway 서비스가 없지만 시스템 수준 OpenClaw Gateway 서비스가 있는 경우, doctor는 두 번째 사용자 수준 서비스를 자동으로 설치하지 않습니다. `openclaw gateway status --deep` 또는 `openclaw doctor --deep`으로 검사한 다음, 중복 항목을 제거하거나 시스템 감독자가 Gateway 수명 주기를 소유할 때 `OPENCLAW_SERVICE_REPAIR_POLICY=external`을 설정하세요. + Linux에서 사용자 수준 Gateway 서비스가 없지만 시스템 수준 OpenClaw Gateway 서비스가 있는 경우 doctor는 두 번째 사용자 수준 서비스를 자동으로 설치하지 않습니다. `openclaw gateway status --deep` 또는 `openclaw doctor --deep`로 검사한 다음, 중복 서비스를 제거하거나 시스템 supervisor가 Gateway 수명 주기를 소유하는 경우 `OPENCLAW_SERVICE_REPAIR_POLICY=external`을 설정하세요. - - Matrix 채널 계정에 보류 중이거나 실행 가능한 레거시 상태 마이그레이션이 있으면 doctor는 (`--fix` / `--repair` 모드에서) 마이그레이션 전 스냅샷을 만든 다음 최선의 마이그레이션 단계인 레거시 Matrix 상태 마이그레이션과 레거시 암호화 상태 준비를 실행합니다. 두 단계 모두 치명적이지 않습니다. 오류는 기록되고 시작은 계속됩니다. 읽기 전용 모드(`--fix` 없이 `openclaw doctor`)에서는 이 검사를 완전히 건너뜁니다. + + Matrix 채널 계정에 보류 중이거나 조치 가능한 레거시 상태 마이그레이션이 있는 경우 doctor는 (`--fix` / `--repair` 모드에서) 마이그레이션 전 스냅샷을 만든 다음 최선의 마이그레이션 단계를 실행합니다. 레거시 Matrix 상태 마이그레이션 및 레거시 암호화 상태 준비가 이에 해당합니다. 두 단계 모두 치명적이지 않습니다. 오류는 로그에 기록되고 시작은 계속됩니다. 읽기 전용 모드(`--fix` 없이 `openclaw doctor`)에서는 이 검사를 완전히 건너뜁니다. - Doctor는 이제 일반 상태 검사 과정의 일부로 기기 페어링 상태를 검사합니다. + 이제 Doctor는 일반 상태 점검의 일부로 기기 페어링 상태를 검사합니다. 보고하는 항목: - 보류 중인 최초 페어링 요청 - 이미 페어링된 기기의 보류 중인 역할 업그레이드 - 이미 페어링된 기기의 보류 중인 범위 업그레이드 - - 기기 ID는 여전히 일치하지만 기기 ID 정보가 승인된 레코드와 더 이상 일치하지 않는 공개 키 불일치 복구 - - 승인된 역할에 대한 활성 토큰이 없는 페어링 레코드 - - 범위가 승인된 페어링 기준선 밖으로 드리프트한 페어링 토큰 - - Gateway 측 토큰 회전보다 오래되었거나 오래된 범위 메타데이터를 가진 현재 머신의 로컬 캐시 기기 토큰 항목 + - 기기 id는 여전히 일치하지만 기기 identity가 더 이상 승인된 레코드와 일치하지 않는 공개 키 불일치 복구 + - 승인된 역할에 대한 활성 토큰이 없는 페어링된 레코드 + - 범위가 승인된 페어링 기준선 밖으로 드리프트된 페어링 토큰 + - Gateway 측 토큰 rotation보다 오래되었거나 오래된 범위 메타데이터를 포함하는 현재 머신의 로컬 캐시 기기 토큰 항목 - Doctor는 페어링 요청을 자동 승인하거나 기기 토큰을 자동 회전하지 않습니다. 대신 정확한 다음 단계를 출력합니다. + Doctor는 페어링 요청을 자동 승인하거나 기기 토큰을 자동 rotation하지 않습니다. 대신 정확한 다음 단계를 출력합니다. - `openclaw devices list`로 보류 중인 요청 검사 - `openclaw devices approve `로 정확한 요청 승인 - - `openclaw devices rotate --device --role `로 새 토큰 회전 - - `openclaw devices remove `로 오래된 레코드 제거 및 재승인 + - `openclaw devices rotate --device --role `로 새 토큰 rotation + - `openclaw devices remove `로 오래된 레코드 제거 후 다시 승인 - 이것은 흔한 "이미 페어링되었지만 여전히 페어링 필요가 표시됨" 허점을 닫습니다. doctor는 이제 최초 페어링, 보류 중인 역할/범위 업그레이드, 오래된 토큰/기기 ID 정보 드리프트를 구분합니다. + 이는 흔한 "이미 페어링되었지만 여전히 페어링 필요 메시지가 표시되는" 문제를 해결합니다. 이제 doctor는 최초 페어링, 보류 중인 역할/범위 업그레이드, 오래된 토큰/기기 identity 드리프트를 구분합니다. - Doctor는 제공자가 허용 목록 없이 DM에 열려 있거나 정책이 위험한 방식으로 설정된 경우 경고를 출력합니다. + Doctor는 제공자가 허용 목록 없이 DM에 열려 있거나 정책이 위험한 방식으로 구성된 경우 경고를 출력합니다. - systemd 사용자 서비스로 실행 중이면 doctor는 로그아웃 후에도 Gateway가 계속 살아 있도록 lingering이 활성화되어 있는지 확인합니다. + systemd 사용자 서비스로 실행 중인 경우 doctor는 Gateway가 로그아웃 후에도 살아 있도록 lingering이 활성화되어 있는지 확인합니다. - - Doctor는 기본 에이전트에 대한 워크스페이스 상태 요약을 출력합니다. + + Doctor는 기본 에이전트의 Workspace 상태 요약을 출력합니다. - **Skills 상태**: 적격, 요구 사항 누락, 허용 목록 차단 Skills 수를 셉니다. - - **레거시 워크스페이스 디렉터리**: 현재 워크스페이스와 함께 `~/openclaw` 또는 기타 레거시 워크스페이스 디렉터리가 있으면 경고합니다. - - **Plugin 상태**: 활성화/비활성화/오류 Plugin 수를 셉니다. 오류가 있는 경우 Plugin ID를 나열합니다. 번들 Plugin 기능을 보고합니다. + - **레거시 Workspace 디렉터리**: `~/openclaw` 또는 기타 레거시 Workspace 디렉터리가 현재 Workspace와 함께 존재할 때 경고합니다. + - **Plugin 상태**: 활성화/비활성화/오류 Plugin 수를 셉니다. 오류가 있는 경우 Plugin ID를 나열하고 번들 Plugin 기능을 보고합니다. - **Plugin 호환성 경고**: 현재 런타임과 호환성 문제가 있는 Plugin을 표시합니다. - **Plugin 진단**: Plugin 레지스트리가 로드 시 출력한 경고 또는 오류를 표시합니다. - - Doctor는 워크스페이스 부트스트랩 파일(예: `AGENTS.md`, `CLAUDE.md` 또는 기타 삽입된 컨텍스트 파일)이 설정된 문자 예산에 가깝거나 초과했는지 확인합니다. 파일별 원시 문자 수와 삽입된 문자 수, 잘림 비율, 잘림 원인(`max/file` 또는 `max/total`), 총 예산 대비 총 삽입 문자 수를 보고합니다. 파일이 잘렸거나 한도에 가까우면 doctor는 `agents.defaults.bootstrapMaxChars`와 `agents.defaults.bootstrapTotalMaxChars` 조정 팁을 출력합니다. + + Doctor는 Workspace Bootstrap 파일(예: `AGENTS.md`, `CLAUDE.md` 또는 기타 주입된 컨텍스트 파일)이 구성된 문자 예산에 가깝거나 초과하는지 확인합니다. 파일별 원시 문자 수와 주입된 문자 수, 잘림 비율, 잘림 원인(`max/file` 또는 `max/total`), 전체 예산 대비 총 주입 문자 비율을 보고합니다. 파일이 잘렸거나 한도에 가까우면 doctor는 `agents.defaults.bootstrapMaxChars` 및 `agents.defaults.bootstrapTotalMaxChars` 조정 팁을 출력합니다. - `openclaw doctor --fix`가 누락된 채널 Plugin을 제거할 때, 해당 Plugin을 참조하던 매달린 채널 범위 설정도 제거합니다. 여기에는 `channels.` 항목, 채널 이름을 지정한 Heartbeat 대상, `agents.*.models["/*"]` 재정의가 포함됩니다. 이렇게 하면 채널 런타임은 사라졌지만 설정이 여전히 Gateway에 바인딩을 요청하는 Gateway 부팅 루프를 방지합니다. + `openclaw doctor --fix`가 누락된 채널 Plugin을 제거할 때 해당 Plugin을 참조하던 dangling 채널 범위 구성도 함께 제거합니다. 여기에는 `channels.` 항목, 해당 채널 이름을 지정한 Heartbeat 대상, `agents.*.models["/*"]` override가 포함됩니다. 이렇게 하면 채널 런타임은 사라졌지만 구성에서 여전히 Gateway에 바인딩을 요청하는 Gateway 부팅 루프를 방지합니다. - - Doctor는 현재 셸(zsh, bash, fish 또는 PowerShell)에 탭 완성이 설치되어 있는지 확인합니다. + + Doctor는 현재 셸(zsh, bash, fish 또는 PowerShell)에 탭 completion이 설치되어 있는지 확인합니다. - - 셸 프로필이 느린 동적 완성 패턴(`source <(openclaw completion ...)`)을 사용하면 doctor는 이를 더 빠른 캐시 파일 방식으로 업그레이드합니다. - - 완성이 프로필에 설정되어 있지만 캐시 파일이 없으면 doctor가 캐시를 자동으로 다시 생성합니다. - - 완성이 전혀 설정되어 있지 않으면 doctor가 설치를 묻습니다(대화형 모드에서만, `--non-interactive`에서는 건너뜀). + - 셸 프로필이 느린 동적 completion 패턴(`source <(openclaw completion ...)`)을 사용하는 경우 doctor는 이를 더 빠른 캐시 파일 방식으로 업그레이드합니다. + - 프로필에 completion이 구성되어 있지만 캐시 파일이 없으면 doctor가 캐시를 자동으로 다시 생성합니다. + - completion이 전혀 구성되어 있지 않으면 doctor가 설치 여부를 묻습니다(대화형 모드만 해당. `--non-interactive`에서는 건너뜀). 캐시를 수동으로 다시 생성하려면 `openclaw completion --write-state`를 실행하세요. @@ -435,80 +435,80 @@ openclaw memory rem-backfill --path ./memory --stage-short-term Doctor는 로컬 Gateway 토큰 인증 준비 상태를 확인합니다. - - 토큰 모드에 토큰이 필요하지만 토큰 소스가 없으면 doctor는 생성을 제안합니다. - - `gateway.auth.token`이 SecretRef로 관리되지만 사용할 수 없으면 doctor는 경고하고 이를 평문으로 덮어쓰지 않습니다. - - `openclaw doctor --generate-gateway-token`은 토큰 SecretRef가 설정되지 않은 경우에만 생성을 강제합니다. + - 토큰 모드에 토큰이 필요하지만 토큰 소스가 없으면 doctor가 생성을 제안합니다. + - `gateway.auth.token`이 SecretRef로 관리되지만 사용할 수 없는 경우 doctor가 경고하고 이를 평문으로 덮어쓰지 않습니다. + - `openclaw doctor --generate-gateway-token`은 토큰 SecretRef가 구성되지 않은 경우에만 생성을 강제합니다. - - 일부 복구 흐름은 런타임의 빠른 실패 동작을 약화하지 않고 구성된 자격 증명을 검사해야 합니다. + + 일부 복구 흐름은 런타임 빠른 실패 동작을 약화하지 않고 구성된 자격 증명을 검사해야 합니다. - - `openclaw doctor --fix`는 이제 대상 지정 구성 복구에 상태 계열 명령과 동일한 읽기 전용 SecretRef 요약 모델을 사용합니다. + - `openclaw doctor --fix`는 이제 대상 config 복구에 status 계열 명령과 동일한 읽기 전용 SecretRef 요약 모델을 사용합니다. - 예: Telegram `allowFrom` / `groupAllowFrom` `@username` 복구는 사용 가능한 경우 구성된 봇 자격 증명을 사용하려고 시도합니다. - - Telegram 봇 토큰이 SecretRef로 구성되었지만 현재 명령 경로에서 사용할 수 없는 경우, doctor는 토큰이 누락되었다고 잘못 보고하거나 충돌하는 대신 자격 증명이 구성되었지만 사용할 수 없다고 보고하고 자동 확인을 건너뜁니다. + - Telegram 봇 토큰이 SecretRef로 구성되어 있지만 현재 명령 경로에서 사용할 수 없는 경우, doctor는 자격 증명이 구성되었지만 사용할 수 없다고 보고하고, 토큰이 누락된 것으로 잘못 보고하거나 충돌하는 대신 자동 확인을 건너뜁니다. - 진단 도구는 상태 확인을 실행하고 Gateway가 비정상으로 보이면 재시작을 제안합니다. + Doctor는 상태 확인을 실행하고 Gateway가 비정상으로 보이면 재시작을 제안합니다. - 진단 도구는 구성된 메모리 검색 임베딩 제공자가 기본 에이전트에 대해 준비되었는지 확인합니다. 동작은 구성된 백엔드와 제공자에 따라 달라집니다. + Doctor는 구성된 메모리 검색 임베딩 provider가 기본 에이전트에 대해 준비되었는지 확인합니다. 동작은 구성된 백엔드와 provider에 따라 달라집니다. - **QMD 백엔드**: `qmd` 바이너리를 사용할 수 있고 시작할 수 있는지 검사합니다. 그렇지 않으면 npm 패키지와 수동 바이너리 경로 옵션을 포함한 수정 안내를 출력합니다. - - **명시적 로컬 제공자**: 로컬 모델 파일 또는 인식된 원격/다운로드 가능한 모델 URL이 있는지 확인합니다. 누락된 경우 원격 제공자로 전환하라고 제안합니다. - - **명시적 원격 제공자**(`openai`, `voyage` 등): API 키가 환경 또는 인증 저장소에 있는지 확인합니다. 누락된 경우 실행 가능한 수정 힌트를 출력합니다. - - **자동 제공자**: 먼저 로컬 모델 가용성을 확인한 다음 자동 선택 순서대로 각 원격 제공자를 시도합니다. + - **명시적 로컬 provider**: 로컬 모델 파일 또는 인식된 원격/다운로드 가능한 모델 URL을 확인합니다. 없으면 원격 provider로 전환할 것을 제안합니다. + - **명시적 원격 provider**(`openai`, `voyage` 등): API 키가 환경 또는 인증 저장소에 있는지 확인합니다. 없으면 실행 가능한 수정 힌트를 출력합니다. + - **자동 provider**: 먼저 로컬 모델 가용성을 확인한 다음, 자동 선택 순서에 따라 각 원격 provider를 시도합니다. - 캐시된 Gateway 검사 결과를 사용할 수 있는 경우(확인 시점에 Gateway가 정상 상태였던 경우), 진단 도구는 그 결과를 CLI에서 볼 수 있는 구성과 대조하고 불일치를 기록합니다. 진단 도구는 기본 경로에서 새 임베딩 ping을 시작하지 않습니다. 실시간 제공자 확인이 필요하면 심층 메모리 상태 명령을 사용하세요. + 캐시된 Gateway 검사 결과를 사용할 수 있으면(확인 당시 Gateway가 정상 상태였음), doctor는 그 결과를 CLI에서 볼 수 있는 config와 상호 참조하고 불일치를 알립니다. Doctor는 기본 경로에서 새 임베딩 ping을 시작하지 않습니다. 실시간 provider 확인이 필요하면 심층 메모리 상태 명령을 사용하세요. - 런타임에서 임베딩 준비 상태를 확인하려면 `openclaw memory status --deep`를 사용하세요. + 런타임에서 임베딩 준비 상태를 확인하려면 `openclaw memory status --deep`을 사용하세요. - Gateway가 정상 상태이면 진단 도구는 채널 상태 검사를 실행하고 제안된 수정과 함께 경고를 보고합니다. + Gateway가 정상 상태이면 doctor는 채널 상태 검사를 실행하고 제안된 수정과 함께 경고를 보고합니다. - - 진단 도구는 설치된 감독자 구성(launchd/systemd/schtasks)에 누락되었거나 오래된 기본값(예: systemd network-online 의존성 및 재시작 지연)이 있는지 확인합니다. 불일치를 발견하면 업데이트를 권장하고 서비스 파일/작업을 현재 기본값으로 다시 쓸 수 있습니다. + + Doctor는 설치된 supervisor config(launchd/systemd/schtasks)에 누락되었거나 오래된 기본값(예: systemd network-online 종속성 및 재시작 지연)이 있는지 확인합니다. 불일치가 발견되면 업데이트를 권장하고 service 파일/task를 현재 기본값으로 다시 작성할 수 있습니다. 참고: - - `openclaw doctor`는 감독자 구성을 다시 쓰기 전에 확인을 요청합니다. + - `openclaw doctor`는 supervisor config를 다시 작성하기 전에 확인을 요청합니다. - `openclaw doctor --yes`는 기본 복구 프롬프트를 수락합니다. - - `openclaw doctor --repair`는 확인 없이 권장 수정을 적용합니다. - - `openclaw doctor --repair --force`는 사용자 지정 감독자 구성을 덮어씁니다. - - `OPENCLAW_SERVICE_REPAIR_POLICY=external`은 Gateway 서비스 수명 주기에 대해 doctor를 읽기 전용으로 유지합니다. 서비스 상태를 계속 보고하고 서비스 외 복구를 실행하지만, 외부 감독자가 해당 수명 주기를 소유하므로 서비스 설치/시작/재시작/부트스트랩, 감독자 구성 재작성, 레거시 서비스 정리를 건너뜁니다. - - Linux에서는 일치하는 systemd Gateway 유닛이 활성 상태일 때 doctor가 명령/엔트리포인트 메타데이터를 다시 쓰지 않습니다. 또한 중복 서비스 검사 중 비활성 비레거시 추가 Gateway 유사 유닛을 무시하여 보조 서비스 파일이 정리 잡음을 만들지 않도록 합니다. - - 토큰 인증에 토큰이 필요하고 `gateway.auth.token`이 SecretRef로 관리되는 경우, doctor 서비스 설치/복구는 SecretRef를 검증하지만 확인된 평문 토큰 값을 감독자 서비스 환경 메타데이터에 유지하지 않습니다. - - doctor는 이전 LaunchAgent, systemd 또는 Windows 예약 작업 설치가 인라인으로 포함한 관리형 `.env`/SecretRef 기반 서비스 환경 값을 감지하고, 해당 값이 감독자 정의 대신 런타임 소스에서 로드되도록 서비스 메타데이터를 다시 씁니다. - - doctor는 `gateway.port` 변경 후에도 서비스 명령이 이전 `--port`를 고정하고 있는 경우를 감지하고 서비스 메타데이터를 현재 포트로 다시 씁니다. - - 토큰 인증에 토큰이 필요하지만 구성된 토큰 SecretRef가 확인되지 않은 경우, doctor는 실행 가능한 안내와 함께 설치/복구 경로를 차단합니다. - - `gateway.auth.token`과 `gateway.auth.password`가 모두 구성되어 있고 `gateway.auth.mode`가 설정되지 않은 경우, doctor는 모드가 명시적으로 설정될 때까지 설치/복구를 차단합니다. - - Linux 사용자 systemd 유닛의 경우, doctor 토큰 드리프트 검사는 이제 서비스 인증 메타데이터를 비교할 때 `Environment=` 및 `EnvironmentFile=` 소스를 모두 포함합니다. - - doctor 서비스 복구는 구성이 더 최신 버전에서 마지막으로 작성된 경우, 더 오래된 OpenClaw 바이너리의 Gateway 서비스를 다시 쓰거나 중지하거나 재시작하지 않습니다. [Gateway 문제 해결](/ko/gateway/troubleshooting#split-brain-installs-and-newer-config-guard)을 참조하세요. - - 언제든지 `openclaw gateway install --force`를 통해 전체 재작성을 강제할 수 있습니다. + - `openclaw doctor --repair`는 확인 없이 권장 수정 사항을 적용합니다. + - `openclaw doctor --repair --force`는 사용자 지정 supervisor config를 덮어씁니다. + - `OPENCLAW_SERVICE_REPAIR_POLICY=external`은 Gateway service 수명 주기에 대해 doctor를 읽기 전용으로 유지합니다. service 상태를 계속 보고하고 비 service 복구를 실행하지만, 외부 supervisor가 해당 수명 주기를 소유하므로 service 설치/시작/재시작/bootstrap, supervisor config 재작성, 레거시 service 정리를 건너뜁니다. + - Linux에서 doctor는 일치하는 systemd Gateway unit이 활성 상태인 동안 command/entrypoint 메타데이터를 다시 작성하지 않습니다. 또한 duplicate-service 검사 중 비활성 비 레거시 추가 Gateway 유사 unit을 무시하므로 동반 service 파일이 정리 잡음을 만들지 않습니다. + - 토큰 auth에 토큰이 필요하고 `gateway.auth.token`이 SecretRef로 관리되는 경우, doctor service 설치/복구는 SecretRef를 검증하지만 확인된 일반 텍스트 토큰 값을 supervisor service 환경 메타데이터에 유지하지 않습니다. + - Doctor는 이전 LaunchAgent, systemd 또는 Windows Scheduled Task 설치가 인라인으로 포함한 관리형 `.env`/SecretRef 기반 service 환경 값을 감지하고, 해당 값이 supervisor 정의 대신 런타임 소스에서 로드되도록 service 메타데이터를 다시 작성합니다. + - Doctor는 `gateway.port` 변경 후에도 service command가 여전히 이전 `--port`를 고정하고 있는 경우를 감지하고 service 메타데이터를 현재 포트로 다시 작성합니다. + - 토큰 auth에 토큰이 필요하고 구성된 토큰 SecretRef가 확인되지 않은 경우, doctor는 실행 가능한 안내와 함께 설치/복구 경로를 차단합니다. + - `gateway.auth.token`과 `gateway.auth.password`가 모두 구성되어 있고 `gateway.auth.mode`가 설정되지 않은 경우, doctor는 mode가 명시적으로 설정될 때까지 설치/복구를 차단합니다. + - Linux user-systemd unit의 경우, doctor 토큰 드리프트 검사는 이제 service auth 메타데이터를 비교할 때 `Environment=`와 `EnvironmentFile=` 소스를 모두 포함합니다. + - Doctor service 복구는 config가 더 새 버전에서 마지막으로 작성된 경우 이전 OpenClaw 바이너리의 Gateway service를 다시 작성, 중지 또는 재시작하는 것을 거부합니다. [Gateway 문제 해결](/ko/gateway/troubleshooting#split-brain-installs-and-newer-config-guard)을 참조하세요. + - `openclaw gateway install --force`를 통해 언제든지 전체 재작성을 강제할 수 있습니다. - 진단 도구는 서비스 런타임(PID, 마지막 종료 상태)을 검사하고 서비스가 설치되어 있지만 실제로 실행 중이 아닐 때 경고합니다. 또한 Gateway 포트(기본값 `18789`)에서 포트 충돌을 확인하고 가능한 원인(Gateway가 이미 실행 중, SSH 터널)을 보고합니다. + Doctor는 service 런타임(PID, 마지막 종료 상태)을 검사하고, service가 설치되어 있지만 실제로 실행 중이 아닐 때 경고합니다. 또한 Gateway 포트(기본값 `18789`)의 포트 충돌을 확인하고 가능한 원인(Gateway가 이미 실행 중, SSH 터널)을 보고합니다. - 진단 도구는 Gateway 서비스가 Bun 또는 버전 관리 Node 경로(`nvm`, `fnm`, `volta`, `asdf` 등)에서 실행될 때 경고합니다. WhatsApp + Telegram 채널에는 Node가 필요하며, 서비스가 셸 초기화를 로드하지 않기 때문에 버전 관리자 경로는 업그레이드 후 중단될 수 있습니다. 진단 도구는 사용할 수 있는 경우 시스템 Node 설치(Homebrew/apt/choco)로 마이그레이션할 것을 제안합니다. + Doctor는 Gateway service가 Bun 또는 버전 관리 Node 경로(`nvm`, `fnm`, `volta`, `asdf` 등)에서 실행될 때 경고합니다. WhatsApp + Telegram 채널에는 Node가 필요하며, 버전 관리자 경로는 service가 셸 초기화를 로드하지 않기 때문에 업그레이드 후 깨질 수 있습니다. Doctor는 사용 가능한 경우 시스템 Node 설치(Homebrew/apt/choco)로 마이그레이션할 것을 제안합니다. - 새로 설치되거나 복구된 macOS LaunchAgent는 대화형 셸 PATH를 복사하는 대신 표준 시스템 PATH(`/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin`)를 사용하므로 Volta, asdf, fnm, pnpm 및 기타 버전 관리자 디렉터리가 Node 자식 프로세스가 확인되는 방식을 변경하지 않습니다. Linux 서비스는 여전히 명시적 환경 루트(`NVM_DIR`, `FNM_DIR`, `VOLTA_HOME`, `ASDF_DATA_DIR`, `BUN_INSTALL`, `PNPM_HOME`)와 안정적인 사용자 바이너리 디렉터리를 유지하지만, 추정된 버전 관리자 대체 디렉터리는 해당 디렉터리가 디스크에 존재할 때만 서비스 PATH에 기록됩니다. + 새로 설치되거나 복구된 macOS LaunchAgent는 대화형 셸 PATH를 복사하는 대신 표준 시스템 PATH(`/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin`)를 사용하므로 Volta, asdf, fnm, pnpm 및 기타 버전 관리자 디렉터리가 Node 자식 프로세스 확인 방식을 변경하지 않습니다. Linux service는 여전히 명시적 환경 루트(`NVM_DIR`, `FNM_DIR`, `VOLTA_HOME`, `ASDF_DATA_DIR`, `BUN_INSTALL`, `PNPM_HOME`)와 안정적인 user-bin 디렉터리를 유지하지만, 추측된 버전 관리자 fallback 디렉터리는 해당 디렉터리가 디스크에 존재할 때만 service PATH에 기록됩니다. - - 진단 도구는 모든 구성 변경 사항을 유지하고 doctor 실행을 기록하기 위해 마법사 메타데이터를 표시합니다. + + Doctor는 config 변경 사항을 유지하고 doctor 실행을 기록하기 위해 wizard 메타데이터를 표시합니다. - - 진단 도구는 작업 공간 메모리 시스템이 없을 때 이를 제안하고, 작업 공간이 아직 git으로 관리되지 않는 경우 백업 팁을 출력합니다. + + Doctor는 누락된 경우 workspace 메모리 시스템을 제안하고, workspace가 아직 git 아래에 있지 않으면 백업 팁을 출력합니다. - 작업 공간 구조와 git 백업(비공개 GitHub 또는 GitLab 권장)에 대한 전체 가이드는 [/concepts/agent-workspace](/ko/concepts/agent-workspace)를 참조하세요. + workspace 구조 및 git 백업(비공개 GitHub 또는 GitLab 권장)에 대한 전체 가이드는 [/concepts/agent-workspace](/ko/concepts/agent-workspace)를 참조하세요. ## 관련 항목 -- [Gateway 실행 가이드](/ko/gateway) +- [Gateway runbook](/ko/gateway) - [Gateway 문제 해결](/ko/gateway/troubleshooting) diff --git a/docs/ko/gateway/logging.md b/docs/ko/gateway/logging.md index a0df9aeff..d3e463b4c 100644 --- a/docs/ko/gateway/logging.md +++ b/docs/ko/gateway/logging.md @@ -2,13 +2,13 @@ read_when: - 로깅 출력 또는 형식 변경 - CLI 또는 Gateway 출력 디버깅 -summary: 로깅 영역, 파일 로그, WS 로그 스타일 및 콘솔 포맷팅 +summary: 로깅 표면, 파일 로그, WS 로그 스타일 및 콘솔 형식 지정 title: Gateway 로깅 x-i18n: - generated_at: "2026-05-06T06:25:57Z" + generated_at: "2026-05-06T17:56:05Z" model: gpt-5.5 provider: openai - source_hash: 078b4196ef1c5af5f7f0a4253f704d90d474a3ff668ec555559cab56cbcb15c6 + source_hash: 16bce5763754d13f855a46777b4c3cc7a7c966e35e0cd08a15f359fd22623bcb source_path: gateway/logging.md workflow: 16 --- @@ -20,9 +20,9 @@ x-i18n: OpenClaw에는 두 가지 로그 "표면"이 있습니다. - **콘솔 출력**(터미널 / 디버그 UI에서 보이는 내용). -- Gateway 로거가 작성하는 **파일 로그**(JSON lines). +- **파일 로그**(JSON 줄)는 gateway 로거가 작성합니다. -시작 시 Gateway는 새 세션에 영향을 주는 모드 기본값과 함께 해석된 기본 에이전트 모델을 기록합니다. 예: +시작 시 Gateway는 새 세션에 영향을 주는 모드 기본값과 함께 확인된 기본 에이전트 모델을 기록합니다. 예를 들면 다음과 같습니다. ```text agent model: openai-codex/gpt-5.5 (thinking=medium, fast=on) @@ -34,54 +34,55 @@ agent model: openai-codex/gpt-5.5 (thinking=medium, fast=on) - 기본 롤링 로그 파일은 `/tmp/openclaw/` 아래에 있습니다(하루에 파일 하나): `openclaw-YYYY-MM-DD.log` - 날짜는 Gateway 호스트의 로컬 시간대를 사용합니다. -- 활성 로그 파일은 `logging.maxFileBytes`에서 로테이션됩니다(기본값: 100 MB). 번호가 붙은 아카이브를 최대 5개까지 유지하고 새 활성 파일에 계속 씁니다. -- 로그 파일 경로와 레벨은 `~/.openclaw/openclaw.json`에서 구성할 수 있습니다. +- 활성 로그 파일은 `logging.maxFileBytes`에서 순환됩니다(기본값: 100 MB). 번호가 매겨진 아카이브를 최대 5개까지 유지하고 새 활성 파일에 계속 기록합니다. +- 로그 파일 경로와 수준은 `~/.openclaw/openclaw.json`을 통해 구성할 수 있습니다. - `logging.file` - `logging.level` -파일 형식은 한 줄에 JSON 객체 하나입니다. +파일 형식은 줄마다 JSON 객체 하나입니다. + +대화, 실시간 음성, 관리형 룸 코드 경로는 제한된 수명 주기 기록에 공유 파일 로거를 사용합니다. 이러한 기록은 운영 디버깅과 OTLP 로그 내보내기를 위한 것입니다. 대화 기록 텍스트, 오디오 페이로드, 턴 ID, 호출 ID, 공급자 항목 ID는 로그 기록에 복사되지 않습니다. 제어 UI 로그 탭은 Gateway(`logs.tail`)를 통해 이 파일을 tail합니다. -CLI도 동일하게 수행할 수 있습니다. +CLI도 동일하게 할 수 있습니다. ```bash openclaw logs --follow ``` -**상세 출력과 로그 레벨** +**상세 출력과 로그 수준** -- **파일 로그**는 `logging.level`로만 제어됩니다. -- `--verbose`는 **콘솔 상세도**(및 WS 로그 스타일)에만 영향을 주며, 파일 로그 레벨을 높이지 **않습니다**. +- **파일 로그**는 전적으로 `logging.level`로 제어됩니다. +- `--verbose`는 **콘솔 상세도**(및 WS 로그 스타일)에만 영향을 주며, 파일 로그 수준을 높이지 **않습니다**. - 상세 출력 전용 세부 정보를 파일 로그에 캡처하려면 `logging.level`을 `debug` 또는 `trace`로 설정하세요. -- Trace 로깅에는 Plugin 도구 팩토리 준비와 같은 선택된 핫 경로에 대한 진단 타이밍 요약도 포함됩니다. [/tools/plugin#slow-plugin-tool-setup](/ko/tools/plugin#slow-plugin-tool-setup)을 참조하세요. +- 추적 로깅에는 Plugin 도구 팩토리 준비와 같은 선택된 핫 경로에 대한 진단 타이밍 요약도 포함됩니다. [/tools/plugin#slow-plugin-tool-setup](/ko/tools/plugin#slow-plugin-tool-setup)을 참조하세요. ## 콘솔 캡처 -CLI는 `console.log/info/warn/error/debug/trace`를 캡처해 파일 로그에 쓰면서도 stdout/stderr에는 계속 출력합니다. +CLI는 `console.log/info/warn/error/debug/trace`를 캡처해 파일 로그에 쓰면서, stdout/stderr에도 계속 출력합니다. 콘솔 상세도는 다음으로 독립적으로 조정할 수 있습니다. - `logging.consoleLevel`(기본값 `info`) - `logging.consoleStyle`(`pretty` | `compact` | `json`) -## 수정 +## 마스킹 -OpenClaw는 로그 또는 트랜스크립트 출력이 프로세스를 떠나기 전에 민감한 토큰을 마스킹할 수 있습니다. 이 로깅 수정 정책은 콘솔, 파일 로그, OTLP 로그 레코드, 세션 트랜스크립트 텍스트 싱크에 적용되므로 일치하는 비밀 값은 JSONL 줄이나 메시지가 디스크에 기록되기 전에 마스킹됩니다. +OpenClaw는 로그 또는 대화 기록 출력이 프로세스를 떠나기 전에 민감한 토큰을 마스킹할 수 있습니다. 이 로깅 마스킹 정책은 콘솔, 파일 로그, OTLP 로그 기록, 세션 대화 기록 텍스트 싱크에 적용되므로, 일치하는 비밀 값은 JSONL 줄이나 메시지가 디스크에 기록되기 전에 마스킹됩니다. - `logging.redactSensitive`: `off` | `tools`(기본값: `tools`) - `logging.redactPatterns`: 정규식 문자열 배열(기본값 재정의) - 원시 정규식 문자열(자동 `gi`)을 사용하거나, 사용자 지정 플래그가 필요하면 `/pattern/flags`를 사용하세요. - - 일치 항목은 처음 6자 + 마지막 4자를 유지해 마스킹합니다(길이 >= 18). 그렇지 않으면 `***`입니다. - - 기본값은 일반적인 키 할당, CLI 플래그, JSON 필드, bearer 헤더, PEM 블록, 널리 쓰이는 토큰 접두사, 카드 번호, CVC/CVV, 공유 결제 토큰, 결제 자격 증명 같은 결제 자격 증명 필드 이름을 포함합니다. + - 일치 항목은 처음 6자 + 마지막 4자를 유지해 마스킹됩니다(길이 >= 18). 그렇지 않으면 `***`입니다. + - 기본값은 일반적인 키 할당, CLI 플래그, JSON 필드, bearer 헤더, PEM 블록, 널리 쓰이는 토큰 접두사, 카드 번호, CVC/CVV, 공유 결제 토큰, 결제 자격 증명 같은 결제 자격 증명 필드 이름을 포괄합니다. -일부 안전 경계는 `logging.redactSensitive`와 관계없이 항상 수정합니다. -여기에는 제어 UI 도구 호출 이벤트, `sessions_history` 도구 출력, 진단 지원 내보내기, 공급자 오류 관찰, 실행 승인 명령 표시, Gateway WebSocket 프로토콜 로그가 포함됩니다. 이러한 표면은 여전히 `logging.redactPatterns`를 추가 패턴으로 사용할 수 있지만, `redactSensitive: "off"`로 설정해도 원시 비밀 값을 내보내지는 않습니다. +일부 안전 경계는 `logging.redactSensitive`와 관계없이 항상 마스킹합니다. 여기에는 제어 UI 도구 호출 이벤트, `sessions_history` 도구 출력, 진단 지원 내보내기, 공급자 오류 관찰, exec 승인 명령 표시, Gateway WebSocket 프로토콜 로그가 포함됩니다. 이러한 표면은 여전히 추가 패턴으로 `logging.redactPatterns`를 사용할 수 있지만, `redactSensitive: "off"`가 원시 비밀을 내보내게 하지는 않습니다. ## Gateway WebSocket 로그 Gateway는 WebSocket 프로토콜 로그를 두 가지 모드로 출력합니다. -- **일반 모드(`--verbose` 없음)**: "흥미로운" RPC 결과만 출력됩니다. +- **일반 모드(`--verbose` 없음)**: "흥미로운" RPC 결과만 출력합니다. - 오류(`ok=false`) - 느린 호출(기본 임계값: `>= 50ms`) - 파싱 오류 @@ -91,12 +92,12 @@ Gateway는 WebSocket 프로토콜 로그를 두 가지 모드로 출력합니다 `openclaw gateway`는 Gateway별 스타일 스위치를 지원합니다. -- `--ws-log auto`(기본값): 일반 모드는 최적화되고, 상세 모드는 압축 출력을 사용합니다 -- `--ws-log compact`: 상세 모드에서 압축 출력(쌍으로 묶인 요청/응답) +- `--ws-log auto`(기본값): 일반 모드는 최적화되고, 상세 모드는 compact 출력을 사용합니다. +- `--ws-log compact`: 상세 모드에서 compact 출력(쌍을 이룬 요청/응답) - `--ws-log full`: 상세 모드에서 프레임별 전체 출력 - `--compact`: `--ws-log compact`의 별칭 -예: +예시: ```bash # optimized (only errors/slow) @@ -109,24 +110,24 @@ openclaw gateway --verbose --ws-log compact openclaw gateway --verbose --ws-log full ``` -## 콘솔 포맷팅(하위 시스템 로깅) +## 콘솔 형식 지정(하위 시스템 로깅) 콘솔 포매터는 **TTY 인식** 방식이며 일관된 접두사가 붙은 줄을 출력합니다. 하위 시스템 로거는 출력을 그룹화하고 훑어보기 쉽게 유지합니다. 동작: -- 모든 줄에 **하위 시스템 접두사**(예: `[gateway]`, `[canvas]`, `[tailscale]`) -- **하위 시스템 색상**(하위 시스템별로 안정적) 및 레벨 색상 -- **출력이 TTY이거나 환경이 리치 터미널처럼 보일 때 색상 사용**(`TERM`/`COLORTERM`/`TERM_PROGRAM`), `NO_COLOR` 준수 -- **축약된 하위 시스템 접두사**: 앞의 `gateway/` + `channels/`를 제거하고 마지막 2개 세그먼트를 유지합니다(예: `whatsapp/outbound`) +- 모든 줄의 **하위 시스템 접두사**(예: `[gateway]`, `[canvas]`, `[tailscale]`) +- **하위 시스템 색상**(하위 시스템별로 안정적)과 수준 색상 +- **출력이 TTY이거나 환경이 풍부한 터미널처럼 보일 때 색상 사용**(`TERM`/`COLORTERM`/`TERM_PROGRAM`), `NO_COLOR` 준수 +- **축약된 하위 시스템 접두사**: 앞의 `gateway/` + `channels/`를 제거하고 마지막 2개 세그먼트를 유지합니다(예: `whatsapp/outbound`). - **하위 시스템별 하위 로거**(자동 접두사 + 구조화 필드 `{ subsystem }`) -- QR/UX 출력용 **`logRaw()`**(접두사 없음, 포맷팅 없음) +- QR/UX 출력용 **`logRaw()`**(접두사 없음, 형식 지정 없음) - **콘솔 스타일**(예: `pretty | compact | json`) -- 파일 로그 레벨과 별도인 **콘솔 로그 레벨**(`logging.level`이 `debug`/`trace`로 설정되면 파일은 전체 세부 정보를 유지) -- **WhatsApp 메시지 본문**은 `debug`로 기록됩니다(보려면 `--verbose` 사용) +- 파일 로그 수준과 별도인 **콘솔 로그 수준**(`logging.level`이 `debug`/`trace`로 설정되면 파일은 전체 세부 정보를 유지) +- **WhatsApp 메시지 본문**은 `debug`로 기록됩니다(보려면 `--verbose` 사용). -이렇게 하면 기존 파일 로그는 안정적으로 유지하면서 대화형 출력은 훑어보기 쉬워집니다. +이렇게 하면 기존 파일 로그를 안정적으로 유지하면서 대화형 출력을 훑어보기 쉽게 만들 수 있습니다. ## 관련 항목 diff --git a/docs/ko/gateway/opentelemetry.md b/docs/ko/gateway/opentelemetry.md index d11addd98..b38d4ba91 100644 --- a/docs/ko/gateway/opentelemetry.md +++ b/docs/ko/gateway/opentelemetry.md @@ -1,31 +1,31 @@ --- read_when: - OpenClaw 모델 사용량, 메시지 흐름 또는 세션 메트릭을 OpenTelemetry 수집기로 보내려는 경우 - - 트레이스, 메트릭 또는 로그를 Grafana, Datadog, Honeycomb, New Relic, Tempo 또는 다른 OTLP 백엔드에 연결하는 경우 - - 대시보드나 알림을 구축하려면 정확한 메트릭 이름, 스팬 이름 또는 속성 구조가 필요합니다. + - Grafana, Datadog, Honeycomb, New Relic, Tempo 또는 다른 OTLP 백엔드에 트레이스, 메트릭 또는 로그를 연결하는 경우 + - 대시보드 또는 알림을 구축하려면 정확한 메트릭 이름, 스팬 이름 또는 속성 형태가 필요합니다 summary: diagnostics-otel Plugin(OTLP/HTTP)을 통해 OpenClaw 진단 정보를 모든 OpenTelemetry 수집기로 내보내기 title: OpenTelemetry 내보내기 x-i18n: - generated_at: "2026-05-06T06:26:44Z" + generated_at: "2026-05-06T17:56:17Z" model: gpt-5.5 provider: openai - source_hash: 2d52e5072fcdb097a3dce36a13d9470cea8c169d2af49998cd727814013c411e + source_hash: b09453a4a1592d2698de6340e5f006ef16edfd8e86132285c48865d468d20ab6 source_path: gateway/opentelemetry.md workflow: 16 --- -OpenClaw는 공식 `diagnostics-otel` Plugin을 통해 **OTLP/HTTP (protobuf)**로 진단 정보를 내보냅니다. OTLP/HTTP를 수락하는 모든 컬렉터나 백엔드는 코드 변경 없이 작동합니다. 로컬 파일 로그와 읽는 방법은 [로깅](/ko/logging)을 참조하세요. +OpenClaw는 공식 `diagnostics-otel` Plugin을 통해 **OTLP/HTTP (protobuf)**로 진단 정보를 내보냅니다. OTLP/HTTP를 수신하는 모든 컬렉터나 백엔드는 코드 변경 없이 작동합니다. 로컬 파일 로그와 읽는 방법은 [로깅](/ko/logging)을 참조하세요. -## 작동 방식 +## 전체 구성 방식 -- **진단 이벤트**는 모델 실행, 메시지 흐름, 세션, 큐, exec에 대해 Gateway와 번들 Plugin이 내보내는 구조화된 인프로세스 레코드입니다. -- **`diagnostics-otel` Plugin**은 해당 이벤트를 구독하고 OTLP/HTTP를 통해 OpenTelemetry **메트릭**, **트레이스**, **로그**로 내보냅니다. -- **제공자 호출**은 제공자 전송 계층이 사용자 지정 헤더를 허용할 때 OpenClaw의 신뢰된 모델 호출 span 컨텍스트에서 W3C `traceparent` 헤더를 받습니다. Plugin에서 내보낸 트레이스 컨텍스트는 전파되지 않습니다. -- 내보내기는 진단 표면과 Plugin이 모두 활성화된 경우에만 연결되므로 기본적으로 인프로세스 비용은 거의 0에 가깝게 유지됩니다. +- **진단 이벤트**는 Gateway와 번들 Plugin이 모델 실행, 메시지 흐름, 세션, 큐, exec에 대해 내보내는 구조화된 인프로세스 레코드입니다. +- **`diagnostics-otel` Plugin**은 이러한 이벤트를 구독하고 OTLP/HTTP를 통해 OpenTelemetry **메트릭**, **트레이스**, **로그**로 내보냅니다. +- **Provider 호출**은 provider 전송 계층이 사용자 지정 헤더를 허용할 때 OpenClaw의 신뢰된 모델 호출 span 컨텍스트에서 W3C `traceparent` 헤더를 받습니다. Plugin에서 내보낸 trace 컨텍스트는 전파되지 않습니다. +- 내보내기는 진단 표면과 Plugin이 모두 활성화된 경우에만 연결되므로, 기본적으로 인프로세스 비용은 거의 0에 가깝게 유지됩니다. ## 빠른 시작 -패키지 설치의 경우 먼저 Plugin을 설치합니다. +패키지 설치에서는 먼저 Plugin을 설치하세요. ```bash openclaw plugins install clawhub:@openclaw/diagnostics-otel @@ -56,7 +56,7 @@ openclaw plugins install clawhub:@openclaw/diagnostics-otel } ``` -CLI에서도 Plugin을 활성화할 수 있습니다. +CLI에서 Plugin을 활성화할 수도 있습니다. ```bash openclaw plugins enable diagnostics-otel @@ -68,11 +68,11 @@ openclaw plugins enable diagnostics-otel ## 내보내는 신호 -| 신호 | 포함되는 내용 | -| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -| **메트릭** | 토큰 사용량, 비용, 실행 기간, 메시지 흐름, 큐 레인, 세션 상태, exec, 메모리 압박에 대한 카운터와 히스토그램입니다. | -| **트레이스** | 모델 사용량, 모델 호출, 하네스 수명 주기, 도구 실행, exec, Webhook/메시지 처리, 컨텍스트 조립, 도구 루프에 대한 span입니다. | -| **로그** | `diagnostics.otel.logs`가 활성화되었을 때 OTLP로 내보내는 구조화된 `logging.file` 레코드입니다. | +| 신호 | 포함되는 내용 | +| ----------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **메트릭** | 토큰 사용량, 비용, 실행 시간, 메시지 흐름, Talk 이벤트, 큐 lane, 세션 상태/복구, exec, 메모리 압박에 대한 카운터와 히스토그램입니다. | +| **트레이스** | 모델 사용량, 모델 호출, harness 수명 주기, 도구 실행, exec, webhook/메시지 처리, 컨텍스트 조립, 도구 루프에 대한 span입니다. | +| **로그** | `diagnostics.otel.logs`가 활성화된 경우 OTLP를 통해 내보내는 구조화된 `logging.file` 레코드입니다. | `traces`, `metrics`, `logs`를 독립적으로 전환할 수 있습니다. `diagnostics.otel.enabled`가 true이면 세 가지 모두 기본적으로 켜집니다. @@ -113,134 +113,129 @@ openclaw plugins enable diagnostics-otel | 변수 | 목적 | | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `OTEL_EXPORTER_OTLP_ENDPOINT` | `diagnostics.otel.endpoint`를 재정의합니다. 값에 이미 `/v1/traces`, `/v1/metrics`, `/v1/logs`가 포함되어 있으면 그대로 사용됩니다. | -| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` / `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` / `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` | 일치하는 `diagnostics.otel.*Endpoint` 구성 키가 설정되지 않았을 때 사용하는 신호별 엔드포인트 재정의입니다. 신호별 구성은 신호별 환경 변수보다 우선하며, 신호별 환경 변수는 공유 엔드포인트보다 우선합니다. | +| `OTEL_EXPORTER_OTLP_ENDPOINT` | `diagnostics.otel.endpoint`를 재정의합니다. 값에 이미 `/v1/traces`, `/v1/metrics`, 또는 `/v1/logs`가 포함되어 있으면 그대로 사용됩니다. | +| `OTEL_EXPORTER_OTLP_TRACES_ENDPOINT` / `OTEL_EXPORTER_OTLP_METRICS_ENDPOINT` / `OTEL_EXPORTER_OTLP_LOGS_ENDPOINT` | 일치하는 `diagnostics.otel.*Endpoint` 구성 키가 설정되지 않았을 때 사용되는 신호별 엔드포인트 재정의입니다. 신호별 구성이 신호별 환경 변수보다 우선하고, 신호별 환경 변수가 공유 엔드포인트보다 우선합니다. | | `OTEL_SERVICE_NAME` | `diagnostics.otel.serviceName`을 재정의합니다. | -| `OTEL_EXPORTER_OTLP_PROTOCOL` | 유선 프로토콜을 재정의합니다(현재는 `http/protobuf`만 적용됩니다). | -| `OTEL_SEMCONV_STABILITY_OPT_IN` | 레거시 `gen_ai.system` 대신 최신 실험적 GenAI span 속성(`gen_ai.provider.name`)을 내보내려면 `gen_ai_latest_experimental`로 설정합니다. GenAI 메트릭은 관계없이 항상 제한된 저카디널리티 의미 속성을 사용합니다. | -| `OPENCLAW_OTEL_PRELOADED` | 다른 프리로드 또는 호스트 프로세스가 전역 OpenTelemetry SDK를 이미 등록한 경우 `1`로 설정합니다. 그러면 Plugin은 자체 NodeSDK 수명 주기를 건너뛰지만 진단 리스너를 계속 연결하고 `traces`/`metrics`/`logs`를 준수합니다. | +| `OTEL_EXPORTER_OTLP_PROTOCOL` | wire 프로토콜을 재정의합니다. 현재는 `http/protobuf`만 적용됩니다. | +| `OTEL_SEMCONV_STABILITY_OPT_IN` | 레거시 `gen_ai.system` 대신 최신 실험적 GenAI span 속성(`gen_ai.provider.name`)을 내보내려면 `gen_ai_latest_experimental`로 설정합니다. GenAI 메트릭은 항상 제한된 낮은 카디널리티의 의미론적 속성을 사용합니다. | +| `OPENCLAW_OTEL_PRELOADED` | 다른 preload 또는 호스트 프로세스가 이미 전역 OpenTelemetry SDK를 등록한 경우 `1`로 설정합니다. 그러면 Plugin은 자체 NodeSDK 수명 주기를 건너뛰지만 진단 listener를 계속 연결하고 `traces`/`metrics`/`logs`를 적용합니다. | ## 개인정보 보호 및 콘텐츠 캡처 -원시 모델/도구 콘텐츠는 기본적으로 내보내지 **않습니다**. Span은 제한된 식별자(채널, 제공자, 모델, 오류 범주, 해시 전용 요청 ID)를 포함하며 프롬프트 텍스트, 응답 텍스트, 도구 입력, 도구 출력 또는 세션 키는 절대 포함하지 않습니다. +원시 모델/도구 콘텐츠는 기본적으로 내보내지 **않습니다**. Span은 제한된 식별자(channel, provider, model, 오류 범주, 해시 전용 요청 ID)를 포함하며, 프롬프트 텍스트, 응답 텍스트, 도구 입력, 도구 출력 또는 세션 키를 절대 포함하지 않습니다. +Talk 메트릭은 mode, transport, provider, event type 같은 제한된 이벤트 메타데이터만 내보냅니다. transcript, 오디오 페이로드, 세션 ID, turn ID, call ID, room ID 또는 handoff token은 포함하지 않습니다. -아웃바운드 모델 요청에는 W3C `traceparent` 헤더가 포함될 수 있습니다. 이 헤더는 활성 모델 호출에 대한 OpenClaw 소유 진단 트레이스 컨텍스트에서만 생성됩니다. 기존 호출자가 제공한 `traceparent` 헤더는 교체되므로 Plugin이나 사용자 지정 제공자 옵션이 서비스 간 트레이스 계보를 위조할 수 없습니다. +아웃바운드 모델 요청에는 W3C `traceparent` 헤더가 포함될 수 있습니다. 이 헤더는 활성 모델 호출에 대해 OpenClaw가 소유한 진단 trace 컨텍스트에서만 생성됩니다. 기존 호출자 제공 `traceparent` 헤더는 교체되므로 Plugin이나 사용자 지정 provider 옵션이 서비스 간 trace 조상을 스푸핑할 수 없습니다. -컬렉터와 보존 정책이 프롬프트, 응답, 도구 또는 시스템 프롬프트 텍스트에 대해 승인된 경우에만 `diagnostics.otel.captureContent.*`를 `true`로 설정하세요. 각 하위 키는 독립적으로 옵트인합니다. +컬렉터와 보존 정책이 프롬프트, 응답, 도구 또는 system-prompt 텍스트에 대해 승인된 경우에만 `diagnostics.otel.captureContent.*`를 `true`로 설정하세요. 각 하위 키는 독립적으로 opt-in입니다. - `inputMessages` - 사용자 프롬프트 콘텐츠. - `outputMessages` - 모델 응답 콘텐츠. -- `toolInputs` - 도구 인수 페이로드. +- `toolInputs` - 도구 인자 페이로드. - `toolOutputs` - 도구 결과 페이로드. -- `systemPrompt` - 조립된 시스템/개발자 프롬프트. +- `systemPrompt` - 조립된 system/developer 프롬프트. -하위 키가 하나라도 활성화되면 모델 및 도구 span은 해당 클래스에 대해서만 제한되고 수정된 `openclaw.content.*` 속성을 받습니다. +하위 키가 하나라도 활성화되면 모델 및 도구 span에는 해당 클래스에 대해서만 제한되고 수정된 `openclaw.content.*` 속성이 추가됩니다. ## 샘플링 및 플러시 -- **트레이스:** `diagnostics.otel.sampleRate`(루트 span만 해당, `0.0`은 모두 버리고 `1.0`은 모두 유지). +- **트레이스:** `diagnostics.otel.sampleRate`(root-span만 해당, `0.0`은 모두 버리고 `1.0`은 모두 유지). - **메트릭:** `diagnostics.otel.flushIntervalMs`(최소 `1000`). -- **로그:** OTLP 로그는 `logging.level`(파일 로그 레벨)을 따릅니다. 콘솔 포맷팅이 아니라 진단 로그 레코드 수정 경로를 사용합니다. 대용량 설치에서는 로컬 샘플링보다 OTLP 컬렉터 샘플링/필터링을 선호해야 합니다. -- **파일 로그 상관관계:** JSONL 파일 로그는 로그 호출에 유효한 진단 트레이스 컨텍스트가 포함된 경우 최상위 `traceId`, `spanId`, `parentSpanId`, `traceFlags`를 포함하므로 로그 프로세서가 로컬 로그 줄을 내보낸 span과 결합할 수 있습니다. -- **요청 상관관계:** Gateway HTTP 요청과 WebSocket 프레임은 내부 요청 트레이스 범위를 생성합니다. 해당 범위 안의 로그와 진단 이벤트는 기본적으로 요청 트레이스를 상속하며, 에이전트 실행과 모델 호출 span은 자식으로 생성되어 제공자 `traceparent` 헤더가 같은 트레이스에 유지됩니다. +- **로그:** OTLP 로그는 `logging.level`(파일 로그 수준)을 따릅니다. 콘솔 형식 지정이 아니라 진단 로그 레코드 수정 경로를 사용합니다. 대용량 설치에서는 로컬 샘플링보다 OTLP 컬렉터 샘플링/필터링을 선호해야 합니다. +- **파일 로그 상관관계:** JSONL 파일 로그는 로그 호출에 유효한 진단 trace 컨텍스트가 있을 때 최상위 `traceId`, `spanId`, `parentSpanId`, `traceFlags`를 포함하므로, 로그 프로세서가 로컬 로그 줄을 내보낸 span과 결합할 수 있습니다. +- **요청 상관관계:** Gateway HTTP 요청과 WebSocket 프레임은 내부 요청 trace 범위를 생성합니다. 해당 범위 안의 로그와 진단 이벤트는 기본적으로 요청 trace를 상속하고, agent 실행 및 모델 호출 span은 자식으로 생성되어 provider `traceparent` 헤더가 동일한 trace에 유지됩니다. -## 내보낸 메트릭 +## 내보내는 메트릭 ### 모델 사용량 -- `openclaw.tokens`(카운터, 속성: `openclaw.token`, `openclaw.channel`, `openclaw.provider`, `openclaw.model`, `openclaw.agent`) -- `openclaw.cost.usd`(카운터, 속성: `openclaw.channel`, `openclaw.provider`, `openclaw.model`) -- `openclaw.run.duration_ms`(히스토그램, 속성: `openclaw.channel`, `openclaw.provider`, `openclaw.model`) -- `openclaw.context.tokens`(히스토그램, 속성: `openclaw.context`, `openclaw.channel`, `openclaw.provider`, `openclaw.model`) -- `gen_ai.client.token.usage`(히스토그램, GenAI 의미 규칙 메트릭, 속성: `gen_ai.token.type` = `input`/`output`, `gen_ai.provider.name`, `gen_ai.operation.name`, `gen_ai.request.model`) -- `gen_ai.client.operation.duration`(히스토그램, 초, GenAI 의미 규칙 메트릭, 속성: `gen_ai.provider.name`, `gen_ai.operation.name`, `gen_ai.request.model`, 선택적 `error.type`) -- `openclaw.model_call.duration_ms`(히스토그램, 속성: `openclaw.provider`, `openclaw.model`, `openclaw.api`, `openclaw.transport`, 그리고 분류된 오류의 경우 `openclaw.errorCategory` 및 `openclaw.failureKind`) -- `openclaw.model_call.request_bytes`(히스토그램, 최종 모델 요청 페이로드의 UTF-8 바이트 크기, 원시 페이로드 콘텐츠 없음) -- `openclaw.model_call.response_bytes`(히스토그램, 스트리밍된 모델 응답 이벤트의 UTF-8 바이트 크기, 원시 응답 콘텐츠 없음) -- `openclaw.model_call.time_to_first_byte_ms`(히스토그램, 첫 번째 스트리밍 응답 이벤트 전까지 경과한 시간) +- `openclaw.tokens` (counter, attrs: `openclaw.token`, `openclaw.channel`, `openclaw.provider`, `openclaw.model`, `openclaw.agent`) +- `openclaw.cost.usd` (counter, attrs: `openclaw.channel`, `openclaw.provider`, `openclaw.model`) +- `openclaw.run.duration_ms` (histogram, attrs: `openclaw.channel`, `openclaw.provider`, `openclaw.model`) +- `openclaw.context.tokens` (histogram, attrs: `openclaw.context`, `openclaw.channel`, `openclaw.provider`, `openclaw.model`) +- `gen_ai.client.token.usage` (histogram, GenAI semantic-conventions metric, attrs: `gen_ai.token.type` = `input`/`output`, `gen_ai.provider.name`, `gen_ai.operation.name`, `gen_ai.request.model`) +- `gen_ai.client.operation.duration` (histogram, seconds, GenAI semantic-conventions metric, attrs: `gen_ai.provider.name`, `gen_ai.operation.name`, `gen_ai.request.model`, optional `error.type`) +- `openclaw.model_call.duration_ms` (histogram, attrs: `openclaw.provider`, `openclaw.model`, `openclaw.api`, `openclaw.transport`, plus `openclaw.errorCategory` and `openclaw.failureKind` on classified errors) +- `openclaw.model_call.request_bytes` (histogram, 최종 모델 요청 페이로드의 UTF-8 바이트 크기; 원시 페이로드 콘텐츠 없음) +- `openclaw.model_call.response_bytes` (histogram, 스트리밍된 모델 응답 이벤트의 UTF-8 바이트 크기; 원시 응답 콘텐츠 없음) +- `openclaw.model_call.time_to_first_byte_ms` (histogram, 첫 번째 스트리밍 응답 이벤트 전까지의 경과 시간) ### 메시지 흐름 -- `openclaw.webhook.received`(카운터, 속성: `openclaw.channel`, `openclaw.webhook`) -- `openclaw.webhook.error`(카운터, 속성: `openclaw.channel`, `openclaw.webhook`) -- `openclaw.webhook.duration_ms`(히스토그램, 속성: `openclaw.channel`, `openclaw.webhook`) -- `openclaw.message.queued`(카운터, 속성: `openclaw.channel`, `openclaw.source`) -- `openclaw.message.processed`(카운터, 속성: `openclaw.channel`, `openclaw.outcome`) -- `openclaw.message.duration_ms`(히스토그램, 속성: `openclaw.channel`, `openclaw.outcome`) -- `openclaw.message.delivery.started`(카운터, 속성: `openclaw.channel`, `openclaw.delivery.kind`) -- `openclaw.message.delivery.duration_ms`(히스토그램, 속성: `openclaw.channel`, `openclaw.delivery.kind`, `openclaw.outcome`, `openclaw.errorCategory`) +- `openclaw.webhook.received` (counter, attrs: `openclaw.channel`, `openclaw.webhook`) +- `openclaw.webhook.error` (counter, attrs: `openclaw.channel`, `openclaw.webhook`) +- `openclaw.webhook.duration_ms` (histogram, attrs: `openclaw.channel`, `openclaw.webhook`) +- `openclaw.message.queued` (counter, attrs: `openclaw.channel`, `openclaw.source`) +- `openclaw.message.processed` (counter, attrs: `openclaw.channel`, `openclaw.outcome`) +- `openclaw.message.duration_ms` (histogram, attrs: `openclaw.channel`, `openclaw.outcome`) +- `openclaw.message.delivery.started` (counter, attrs: `openclaw.channel`, `openclaw.delivery.kind`) +- `openclaw.message.delivery.duration_ms` (histogram, attrs: `openclaw.channel`, `openclaw.delivery.kind`, `openclaw.outcome`, `openclaw.errorCategory`) -### 큐 및 세션 +### Talk + +- `openclaw.talk.event` (counter, attrs: `openclaw.talk.event_type`, `openclaw.talk.mode`, `openclaw.talk.transport`, `openclaw.talk.brain`, `openclaw.talk.provider`) +- `openclaw.talk.event.duration_ms` (histogram, attrs: `openclaw.talk.event`와 동일; Talk 이벤트가 duration을 보고할 때 내보냄) +- `openclaw.talk.audio.bytes` (histogram, attrs: `openclaw.talk.event`와 동일; 바이트 길이를 보고하는 Talk 오디오 프레임 이벤트에 대해 내보냄) + +### 큐와 세션 - `openclaw.queue.lane.enqueue`(카운터, 속성: `openclaw.lane`) - `openclaw.queue.lane.dequeue`(카운터, 속성: `openclaw.lane`) - `openclaw.queue.depth`(히스토그램, 속성: `openclaw.lane` 또는 `openclaw.channel=heartbeat`) - `openclaw.queue.wait_ms`(히스토그램, 속성: `openclaw.lane`) - `openclaw.session.state`(카운터, 속성: `openclaw.state`, `openclaw.reason`) -- `openclaw.session.stuck`(카운터, 속성: `openclaw.state`; 활성 작업이 없는 오래된 세션 장부 처리에 대해서만 내보냄) -- `openclaw.session.stuck_age_ms`(히스토그램, 속성: `openclaw.state`; 활성 작업이 없는 오래된 세션 장부 처리에 대해서만 내보냄) +- `openclaw.session.stuck`(카운터, 속성: `openclaw.state`; 활성 작업이 없는 오래된 세션 기록 관리에만 내보냄) +- `openclaw.session.stuck_age_ms`(히스토그램, 속성: `openclaw.state`; 활성 작업이 없는 오래된 세션 기록 관리에만 내보냄) +- `openclaw.session.recovery.requested`(카운터, 속성: `openclaw.state`, `openclaw.action`, `openclaw.active_work_kind`, `openclaw.reason`) +- `openclaw.session.recovery.completed`(카운터, 속성: `openclaw.state`, `openclaw.action`, `openclaw.status`, `openclaw.active_work_kind`, `openclaw.reason`) +- `openclaw.session.recovery.age_ms`(히스토그램, 속성: 일치하는 복구 카운터와 동일) - `openclaw.run.attempt`(카운터, 속성: `openclaw.attempt`) ### 세션 활성 상태 텔레메트리 -`diagnostics.stuckSessionWarnMs`는 세션 활성 상태 진단을 위한 진행 없음 경과 시간 임계값입니다. OpenClaw가 reply, tool, status, block 또는 ACP 런타임 진행을 관찰하는 동안 `processing` 세션은 이 임계값을 향해 오래된 것으로 간주되지 않습니다. 입력 상태 keepalive는 진행으로 계산되지 않으므로 조용한 모델이나 하네스도 여전히 감지될 수 있습니다. +`diagnostics.stuckSessionWarnMs`는 세션 활성 상태 진단을 위한 진행 없음 경과 시간 임계값입니다. OpenClaw가 응답, 도구, 상태, 블록 또는 ACP 런타임 진행을 관찰하는 동안 `processing` 세션은 이 임계값을 향해 경과 시간이 누적되지 않습니다. 입력 keepalive는 진행으로 계산되지 않으므로, 조용한 모델이나 하네스도 여전히 감지될 수 있습니다. -OpenClaw는 여전히 관찰할 수 있는 작업을 기준으로 세션을 분류합니다: +OpenClaw는 아직 관찰할 수 있는 작업을 기준으로 세션을 분류합니다. -- `session.long_running`: 활성 임베디드 작업, 모델 호출 또는 도구 호출이 - 아직 진행 중입니다. -- `session.stalled`: 활성 작업은 있지만, 활성 실행이 최근 진행 상황을 - 보고하지 않았습니다. 정체된 임베디드 실행은 처음에는 관찰 전용으로 유지된 뒤, - 진행 상황이 없으면 `diagnostics.stuckSessionAbortMs` 이후 abort-drain되어 해당 - 레인 뒤에 대기 중인 턴이 재개될 수 있습니다. 설정하지 않으면 abort 임계값은 - 최소 10분 및 `diagnostics.stuckSessionWarnMs`의 5배인 더 안전한 확장 창으로 - 기본 설정됩니다. -- `session.stuck`: 활성 작업이 없는 오래된 세션 장부 상태입니다. 이는 영향을 - 받은 세션 레인을 즉시 해제합니다. +- `session.long_running`: 활성 내장 작업, 모델 호출 또는 도구 호출이 여전히 진행 중입니다. +- `session.stalled`: 활성 작업이 있지만 활성 실행이 최근 진행 상황을 보고하지 않았습니다. 중단된 내장 실행은 처음에는 observe-only 상태로 유지된 다음, 진행이 없으면 `diagnostics.stuckSessionAbortMs` 이후 abort-drain되어 해당 레인 뒤에 대기 중인 턴이 재개될 수 있습니다. 설정되지 않은 경우 중단 임계값은 최소 10분 및 `diagnostics.stuckSessionWarnMs`의 5배인 더 안전한 확장 기간으로 기본 설정됩니다. +- `session.stuck`: 활성 작업이 없는 오래된 세션 기록 관리입니다. 이는 영향을 받는 세션 레인을 즉시 해제합니다. -복구는 구조화된 `session.recovery.requested` 및 -`session.recovery.completed` 이벤트를 내보냅니다. 진단 세션 상태는 변경을 -수반하는 복구 결과(`aborted` 또는 `released`) 이후에만, 그리고 동일한 처리 -세대가 여전히 현재 상태일 때에만 유휴로 표시됩니다. +복구는 구조화된 `session.recovery.requested` 및 `session.recovery.completed` 이벤트를 내보냅니다. 진단 세션 상태는 변경을 일으키는 복구 결과(`aborted` 또는 `released`) 이후에만, 그리고 동일한 처리 세대가 아직 현재 상태인 경우에만 유휴로 표시됩니다. -`session.stuck`만 `openclaw.session.stuck` 카운터, -`openclaw.session.stuck_age_ms` 히스토그램 및 `openclaw.session.stuck` -span을 내보냅니다. 반복되는 `session.stuck` 진단은 세션이 변경되지 않은 동안 -백오프되므로, 대시보드는 모든 Heartbeat 틱이 아니라 지속적인 증가에 대해 -경고해야 합니다. 구성 노브와 기본값은 -[구성 참조](/ko/gateway/configuration-reference#diagnostics)를 참조하세요. +`session.stuck`만 `openclaw.session.stuck` 카운터, `openclaw.session.stuck_age_ms` 히스토그램, `openclaw.session.stuck` span을 내보냅니다. 반복되는 `session.stuck` 진단은 세션이 변경되지 않은 동안 백오프되므로, 대시보드는 모든 Heartbeat 틱이 아니라 지속적인 증가에 대해 경고해야 합니다. 구성 노브와 기본값은 [구성 참조](/ko/gateway/configuration-reference#diagnostics)를 참조하세요. ### 하네스 수명 주기 -- `openclaw.harness.duration_ms` (히스토그램, attrs: `openclaw.harness.id`, `openclaw.harness.plugin`, `openclaw.outcome`, `openclaw.harness.phase` 오류 시) +- `openclaw.harness.duration_ms`(히스토그램, 속성: `openclaw.harness.id`, `openclaw.harness.plugin`, `openclaw.outcome`, 오류 시 `openclaw.harness.phase`) ### 실행 -- `openclaw.exec.duration_ms` (히스토그램, attrs: `openclaw.exec.target`, `openclaw.exec.mode`, `openclaw.outcome`, `openclaw.failureKind`) +- `openclaw.exec.duration_ms`(히스토그램, 속성: `openclaw.exec.target`, `openclaw.exec.mode`, `openclaw.outcome`, `openclaw.failureKind`) -### 진단 내부 구조(메모리 및 도구 루프) +### 진단 내부 요소(메모리 및 도구 루프) -- `openclaw.memory.heap_used_bytes` (히스토그램, attrs: `openclaw.memory.kind`) -- `openclaw.memory.rss_bytes` (히스토그램) -- `openclaw.memory.pressure` (카운터, attrs: `openclaw.memory.level`) -- `openclaw.tool.loop.iterations` (카운터, attrs: `openclaw.toolName`, `openclaw.outcome`) -- `openclaw.tool.loop.duration_ms` (히스토그램, attrs: `openclaw.toolName`, `openclaw.outcome`) +- `openclaw.memory.heap_used_bytes`(히스토그램, 속성: `openclaw.memory.kind`) +- `openclaw.memory.rss_bytes`(히스토그램) +- `openclaw.memory.pressure`(카운터, 속성: `openclaw.memory.level`) +- `openclaw.tool.loop.iterations`(카운터, 속성: `openclaw.toolName`, `openclaw.outcome`) +- `openclaw.tool.loop.duration_ms`(히스토그램, 속성: `openclaw.toolName`, `openclaw.outcome`) -## 내보내는 span +## 내보낸 span - `openclaw.model.usage` - `openclaw.channel`, `openclaw.provider`, `openclaw.model` - - `openclaw.tokens.*` (input/output/cache_read/cache_write/total) - - 기본적으로 `gen_ai.system`, 또는 최신 GenAI 의미 체계 규칙을 선택한 경우 `gen_ai.provider.name` + - `openclaw.tokens.*`(입력/출력/캐시 읽기/캐시 쓰기/합계) + - 기본적으로 `gen_ai.system`, 또는 최신 GenAI 의미론적 규칙을 선택한 경우 `gen_ai.provider.name` - `gen_ai.request.model`, `gen_ai.operation.name`, `gen_ai.usage.*` - `openclaw.run` - `openclaw.outcome`, `openclaw.channel`, `openclaw.provider`, `openclaw.model`, `openclaw.errorCategory` - `openclaw.model.call` - - 기본적으로 `gen_ai.system`, 또는 최신 GenAI 의미 체계 규칙을 선택한 경우 `gen_ai.provider.name` + - 기본적으로 `gen_ai.system`, 또는 최신 GenAI 의미론적 규칙을 선택한 경우 `gen_ai.provider.name` - `gen_ai.request.model`, `gen_ai.operation.name`, `openclaw.provider`, `openclaw.model`, `openclaw.api`, `openclaw.transport` - 오류 시 `openclaw.errorCategory` 및 선택적 `openclaw.failureKind` - `openclaw.model_call.request_bytes`, `openclaw.model_call.response_bytes`, `openclaw.model_call.time_to_first_byte_ms` - - `openclaw.provider.request_id_hash` (업스트림 제공자 요청 id의 제한된 SHA 기반 해시; 원시 id는 내보내지 않음) + - `openclaw.provider.request_id_hash`(업스트림 제공자 요청 ID의 경계가 있는 SHA 기반 해시; 원시 ID는 내보내지 않음) - `openclaw.harness.run` - `openclaw.harness.id`, `openclaw.harness.plugin`, `openclaw.outcome`, `openclaw.provider`, `openclaw.model`, `openclaw.channel` - 완료 시: `openclaw.harness.result_classification`, `openclaw.harness.yield_detected`, `openclaw.harness.items.started`, `openclaw.harness.items.completed`, `openclaw.harness.items.active` @@ -260,27 +255,21 @@ span을 내보냅니다. 반복되는 `session.stuck` 진단은 세션이 변경 - `openclaw.session.stuck` - `openclaw.state`, `openclaw.ageMs`, `openclaw.queueDepth` - `openclaw.context.assembled` - - `openclaw.prompt.size`, `openclaw.history.size`, `openclaw.context.tokens`, `openclaw.errorCategory` (프롬프트, 기록, 응답 또는 세션 키 콘텐츠 없음) + - `openclaw.prompt.size`, `openclaw.history.size`, `openclaw.context.tokens`, `openclaw.errorCategory`(프롬프트, 기록, 응답 또는 세션 키 콘텐츠 없음) - `openclaw.tool.loop` - - `openclaw.toolName`, `openclaw.outcome`, `openclaw.iterations`, `openclaw.errorCategory` (루프 메시지, params 또는 도구 출력 없음) + - `openclaw.toolName`, `openclaw.outcome`, `openclaw.iterations`, `openclaw.errorCategory`(루프 메시지, 매개변수 또는 도구 출력 없음) - `openclaw.memory.pressure` - `openclaw.memory.level`, `openclaw.memory.heap_used_bytes`, `openclaw.memory.rss_bytes` -콘텐츠 캡처를 명시적으로 활성화하면 모델 및 도구 span에는 선택한 특정 -콘텐츠 클래스에 대해 제한되고 수정된 `openclaw.content.*` 속성도 포함될 수 -있습니다. +콘텐츠 캡처가 명시적으로 활성화된 경우, 모델 및 도구 span에는 선택한 특정 콘텐츠 클래스에 대해 경계가 있고 수정된 `openclaw.content.*` 속성도 포함될 수 있습니다. ## 진단 이벤트 카탈로그 -아래 이벤트는 위의 메트릭과 span을 뒷받침합니다. Plugins도 OTLP 내보내기 없이 -직접 구독할 수 있습니다. +아래 이벤트는 위의 메트릭과 span을 뒷받침합니다. Plugin은 OTLP 내보내기 없이도 이를 직접 구독할 수 있습니다. **모델 사용량** -- `model.usage` - 토큰, 비용, 기간, 컨텍스트, 제공자/모델/채널, - 세션 id. `usage`는 비용 및 원격 측정을 위한 제공자/턴 회계입니다. - `context.used`는 현재 프롬프트/컨텍스트 스냅샷이며, 캐시된 입력 또는 - 도구 루프 호출이 관련된 경우 제공자 `usage.total`보다 낮을 수 있습니다. +- `model.usage` - 토큰, 비용, 기간, 컨텍스트, 제공자/모델/채널, 세션 ID. `usage`는 비용 및 텔레메트리를 위한 제공자/턴 회계입니다. `context.used`는 현재 프롬프트/컨텍스트 스냅샷이며 캐시된 입력 또는 도구 루프 호출이 관련된 경우 제공자 `usage.total`보다 낮을 수 있습니다. **메시지 흐름** @@ -293,28 +282,19 @@ span을 내보냅니다. 반복되는 `session.stuck` 진단은 세션이 변경 - `queue.lane.enqueue` / `queue.lane.dequeue` - `session.state` / `session.long_running` / `session.stalled` / `session.stuck` - `run.attempt` / `run.progress` -- `diagnostic.heartbeat` (집계 카운터: Webhook/큐/세션) +- `diagnostic.heartbeat`(집계 카운터: Webhook/큐/세션) **하네스 수명 주기** -- `harness.run.started` / `harness.run.completed` / `harness.run.error` - - 에이전트 하네스의 실행별 수명 주기입니다. `harnessId`, 선택적 - `pluginId`, 제공자/모델/채널 및 실행 id를 포함합니다. 완료 시 - `durationMs`, `outcome`, 선택적 `resultClassification`, `yieldDetected`, - 및 `itemLifecycle` 카운트가 추가됩니다. 오류 시 `phase` - (`prepare`/`start`/`send`/`resolve`/`cleanup`), `errorCategory` 및 - 선택적 `cleanupFailed`가 추가됩니다. +- `harness.run.started` / `harness.run.completed` / `harness.run.error` - 에이전트 하네스의 실행별 수명 주기입니다. `harnessId`, 선택적 `pluginId`, 제공자/모델/채널, 실행 ID를 포함합니다. 완료 시 `durationMs`, `outcome`, 선택적 `resultClassification`, `yieldDetected`, `itemLifecycle` 카운트가 추가됩니다. 오류 시 `phase`(`prepare`/`start`/`send`/`resolve`/`cleanup`), `errorCategory`, 선택적 `cleanupFailed`가 추가됩니다. **실행** -- `exec.process.completed` - 터미널 결과, 기간, 대상, 모드, 종료 - 코드 및 실패 종류입니다. 명령 텍스트와 작업 디렉터리는 포함되지 - 않습니다. +- `exec.process.completed` - 터미널 결과, 기간, 대상, 모드, 종료 코드, 실패 종류입니다. 명령 텍스트와 작업 디렉터리는 포함되지 않습니다. ## exporter 없이 사용 -`diagnostics-otel`을 실행하지 않고도 진단 이벤트를 Plugins 또는 사용자 지정 싱크에서 -사용할 수 있게 유지할 수 있습니다. +`diagnostics-otel`을 실행하지 않고도 진단 이벤트를 Plugin이나 사용자 지정 싱크에서 사용할 수 있게 유지할 수 있습니다. ```json5 { @@ -322,9 +302,7 @@ span을 내보냅니다. 반복되는 `session.stuck` 진단은 세션이 변경 } ``` -`logging.level`을 올리지 않고 대상 지정 디버그 출력을 사용하려면 진단 -플래그를 사용하세요. 플래그는 대소문자를 구분하지 않으며 와일드카드를 -지원합니다(예: `telegram.*` 또는 `*`). +`logging.level`을 올리지 않고 대상 지정 디버그 출력을 사용하려면 진단 플래그를 사용하세요. 플래그는 대소문자를 구분하지 않으며 와일드카드를 지원합니다(예: `telegram.*` 또는 `*`). ```json5 { @@ -332,15 +310,13 @@ span을 내보냅니다. 반복되는 `session.stuck` 진단은 세션이 변경 } ``` -또는 일회성 env 재정의로 사용할 수 있습니다. +또는 일회성 환경 변수 재정의로 사용할 수 있습니다. ```bash OPENCLAW_DIAGNOSTICS=telegram.http,telegram.payload openclaw gateway ``` -플래그 출력은 표준 로그 파일(`logging.file`)로 이동하며, 여전히 -`logging.redactSensitive`에 의해 수정됩니다. 전체 가이드: -[진단 플래그](/ko/diagnostics/flags). +플래그 출력은 표준 로그 파일(`logging.file`)로 이동하며, 여전히 `logging.redactSensitive`에 의해 수정됩니다. 전체 가이드: [진단 플래그](/ko/diagnostics/flags). ## 비활성화 @@ -350,13 +326,12 @@ OPENCLAW_DIAGNOSTICS=telegram.http,telegram.payload openclaw gateway } ``` -`plugins.allow`에서 `diagnostics-otel`을 제외하거나 -`openclaw plugins disable diagnostics-otel`을 실행할 수도 있습니다. +`plugins.allow`에서 `diagnostics-otel`을 제외하거나 `openclaw plugins disable diagnostics-otel`을 실행할 수도 있습니다. ## 관련 항목 -- [로깅](/ko/logging) - 파일 로그, 콘솔 출력, CLI tailing 및 Control UI 로그 탭 -- [Gateway 로깅 내부 구조](/ko/gateway/logging) - WS 로그 스타일, 서브시스템 접두사 및 콘솔 캡처 +- [로깅](/ko/logging) - 파일 로그, 콘솔 출력, CLI tailing, Control UI 로그 탭 +- [Gateway 로깅 내부 요소](/ko/gateway/logging) - WS 로그 스타일, 하위 시스템 접두사, 콘솔 캡처 - [진단 플래그](/ko/diagnostics/flags) - 대상 지정 디버그 로그 플래그 - [진단 내보내기](/ko/gateway/diagnostics) - 운영자 지원 번들 도구(OTEL 내보내기와 별도) - [구성 참조](/ko/gateway/configuration-reference#diagnostics) - 전체 `diagnostics.*` 필드 참조 diff --git a/docs/ko/gateway/prometheus.md b/docs/ko/gateway/prometheus.md index 1a4d150fe..94927e4e0 100644 --- a/docs/ko/gateway/prometheus.md +++ b/docs/ko/gateway/prometheus.md @@ -1,21 +1,21 @@ --- read_when: - - Prometheus, Grafana, VictoriaMetrics 또는 다른 스크레이퍼가 OpenClaw Gateway 메트릭을 수집하도록 하려고 합니다 - - 대시보드 또는 알림을 위해 Prometheus 메트릭 이름과 레이블 정책이 필요합니다. - - OpenTelemetry collector를 실행하지 않고 메트릭을 사용하려는 경우 + - Prometheus, Grafana, VictoriaMetrics 또는 다른 스크레이퍼가 OpenClaw Gateway 메트릭을 수집하도록 하려는 경우 + - 대시보드 또는 알림에 사용할 Prometheus 메트릭 이름과 레이블 정책이 필요합니다 + - OpenTelemetry 수집기를 실행하지 않고 메트릭을 사용하려는 경우 sidebarTitle: Prometheus -summary: diagnostics-prometheus Plugin을 통해 OpenClaw 진단을 Prometheus 텍스트 메트릭으로 노출 +summary: diagnostics-prometheus Plugin을 통해 OpenClaw 진단 정보를 Prometheus 텍스트 메트릭으로 노출 title: Prometheus 메트릭 x-i18n: - generated_at: "2026-05-02T20:52:23Z" + generated_at: "2026-05-06T17:56:29Z" model: gpt-5.5 provider: openai - source_hash: 49df17348c5b63c4b5f3c05f3378d43764e5de985135ad30c1e74ef607e0dd37 + source_hash: 864e2a343266d84baaaaca9d8e494359198a3b43e8663ec8dcfcd4e2e4c6c004 source_path: gateway/prometheus.md workflow: 16 --- -OpenClaw는 공식 `diagnostics-prometheus` Plugin을 통해 진단 메트릭을 노출할 수 있습니다. 이 Plugin은 신뢰할 수 있는 내부 진단을 수신하고 다음 위치에 Prometheus 텍스트 엔드포인트를 렌더링합니다. +OpenClaw은 공식 `diagnostics-prometheus` Plugin을 통해 진단 메트릭을 노출할 수 있습니다. 신뢰할 수 있는 내부 진단을 수신하고 다음 위치에 Prometheus 텍스트 엔드포인트를 렌더링합니다: ```text GET /api/diagnostics/prometheus @@ -24,10 +24,10 @@ GET /api/diagnostics/prometheus 콘텐츠 유형은 표준 Prometheus 노출 형식인 `text/plain; version=0.0.4; charset=utf-8`입니다. -이 경로는 Gateway 인증(운영자 범위)을 사용합니다. 공개 미인증 `/metrics` 엔드포인트로 노출하지 마세요. 다른 운영자 API에 사용하는 것과 동일한 인증 경로를 통해 스크레이프하세요. +이 라우트는 Gateway 인증(운영자 범위)을 사용합니다. 공개 무인증 `/metrics` 엔드포인트로 노출하지 마세요. 다른 운영자 API에 사용하는 것과 동일한 인증 경로를 통해 스크레이프하세요. -트레이스, 로그, OTLP 푸시, OpenTelemetry GenAI 의미론적 속성은 [OpenTelemetry 내보내기](/ko/gateway/opentelemetry)를 참조하세요. +트레이스, 로그, OTLP 푸시, OpenTelemetry GenAI 시맨틱 속성은 [OpenTelemetry 내보내기](/ko/gateway/opentelemetry)를 참고하세요. ## 빠른 시작 @@ -39,7 +39,7 @@ GET /api/diagnostics/prometheus - + ```json5 { plugins: { @@ -62,10 +62,10 @@ GET /api/diagnostics/prometheus - HTTP 경로는 Plugin 시작 시 등록되므로, 활성화한 뒤 다시 로드하세요. + HTTP 라우트는 Plugin 시작 시 등록되므로 활성화한 뒤 다시 로드하세요. - - 운영자 클라이언트가 사용하는 것과 동일한 Gateway 인증을 보내세요. + + 운영자 클라이언트가 사용하는 것과 동일한 Gateway 인증을 보내세요: ```bash curl -H "Authorization: Bearer $OPENCLAW_GATEWAY_TOKEN" \ @@ -89,7 +89,7 @@ GET /api/diagnostics/prometheus -`diagnostics.enabled: true`가 필요합니다. 이 값이 없으면 Plugin은 여전히 HTTP 경로를 등록하지만 진단 이벤트가 내보내기 도구로 유입되지 않으므로 응답이 비어 있습니다. +`diagnostics.enabled: true`가 필요합니다. 이 값이 없으면 Plugin은 여전히 HTTP 라우트를 등록하지만 내보내기로 진단 이벤트가 흐르지 않으므로 응답이 비어 있습니다. ## 내보내는 메트릭 @@ -109,12 +109,18 @@ GET /api/diagnostics/prometheus | `openclaw_harness_run_duration_seconds` | 히스토그램 | `channel`, `error_category`, `harness`, `model`, `outcome`, `phase`, `plugin`, `provider` | | `openclaw_message_processed_total` | 카운터 | `channel`, `outcome`, `reason` | | `openclaw_message_processed_duration_seconds` | 히스토그램 | `channel`, `outcome`, `reason` | +| `openclaw_message_delivery_started_total` | 카운터 | `channel`, `delivery_kind` | | `openclaw_message_delivery_total` | 카운터 | `channel`, `delivery_kind`, `error_category`, `outcome` | | `openclaw_message_delivery_duration_seconds` | 히스토그램 | `channel`, `delivery_kind`, `error_category`, `outcome` | +| `openclaw_talk_event_total` | 카운터 | `brain`, `event_type`, `mode`, `provider`, `transport` | +| `openclaw_talk_event_duration_seconds` | 히스토그램 | `brain`, `event_type`, `mode`, `provider`, `transport` | +| `openclaw_talk_audio_bytes` | 히스토그램 | `brain`, `event_type`, `mode`, `provider`, `transport` | | `openclaw_queue_lane_size` | 게이지 | `lane` | | `openclaw_queue_lane_wait_seconds` | 히스토그램 | `lane` | | `openclaw_session_state_total` | 카운터 | `reason`, `state` | | `openclaw_session_queue_depth` | 게이지 | `state` | +| `openclaw_session_recovery_total` | 카운터 | `action`, `active_work_kind`, `state`, `status` | +| `openclaw_session_recovery_age_seconds` | 히스토그램 | `action`, `active_work_kind`, `state`, `status` | | `openclaw_memory_bytes` | 게이지 | `kind` | | `openclaw_memory_rss_bytes` | 히스토그램 | 없음 | | `openclaw_memory_pressure_total` | 카운터 | `level`, `reason` | @@ -125,20 +131,21 @@ GET /api/diagnostics/prometheus - Prometheus 레이블은 제한되며 저카디널리티를 유지합니다. 내보내기 도구는 `runId`, `sessionKey`, `sessionId`, `callId`, `toolCallId`, 메시지 ID, 채팅 ID 또는 공급자 요청 ID 같은 원시 진단 식별자를 내보내지 않습니다. + Prometheus 레이블은 제한되고 저카디널리티를 유지합니다. 내보내기는 `runId`, `sessionKey`, `sessionId`, `callId`, `toolCallId`, 메시지 ID, 채팅 ID 또는 제공자 요청 ID 같은 원시 진단 식별자를 내보내지 않습니다. - 레이블 값은 수정 처리되며 OpenClaw의 저카디널리티 문자 정책과 일치해야 합니다. 정책을 통과하지 못하는 값은 메트릭에 따라 `unknown`, `other` 또는 `none`으로 대체됩니다. + 레이블 값은 수정되어 표시되며 OpenClaw의 저카디널리티 문자 정책과 일치해야 합니다. 정책을 통과하지 못하는 값은 메트릭에 따라 `unknown`, `other` 또는 `none`으로 대체됩니다. - - 내보내기 도구는 카운터, 게이지, 히스토그램을 합쳐 메모리에 보관하는 시계열을 **2048**개로 제한합니다. 이 한도를 넘는 새 시리즈는 삭제되며, 그때마다 `openclaw_prometheus_series_dropped_total`이 1씩 증가합니다. + + exporter는 메모리에 보존되는 시계열을 카운터, 게이지, 히스토그램을 합쳐 **2048**개 시리즈로 제한합니다. 이 한도를 넘는 새 시리즈는 삭제되며, 그때마다 `openclaw_prometheus_series_dropped_total`이 1씩 증가합니다. - 이 카운터는 상위 속성이 고카디널리티 값을 누출하고 있음을 나타내는 강한 신호로 관찰하세요. 내보내기 도구는 한도를 자동으로 올리지 않습니다. 값이 증가하면 한도를 비활성화하지 말고 원인을 수정하세요. + 이 카운터를 상위 속성에서 높은 카디널리티 값이 누출되고 있다는 강한 신호로 관찰하세요. exporter는 한도를 자동으로 올리지 않습니다. 값이 증가하면 한도를 비활성화하지 말고 원인을 수정하세요. - 프롬프트 텍스트, 응답 텍스트, 도구 입력, 도구 출력, 시스템 프롬프트 - - 원시 공급자 요청 ID(해당하는 경우 span에는 제한된 해시만 포함되며, 메트릭에는 절대 포함되지 않음) + - Talk 대화 기록, 오디오 페이로드, 호출 ID, 방 ID, 핸드오프 토큰, 턴 ID, 원시 세션 ID + - 원시 제공자 요청 ID(해당하는 경우 span에는 제한된 해시만 포함되며, 메트릭에는 절대 포함되지 않음) - 세션 키와 세션 ID - 호스트 이름, 파일 경로, 비밀 값 @@ -172,26 +179,26 @@ increase(openclaw_prometheus_series_dropped_total[15m]) > 0 ``` -교차 공급자 대시보드에는 `gen_ai_client_token_usage`를 선호하세요. 이 메트릭은 OpenTelemetry GenAI 의미론적 규칙을 따르며 OpenClaw가 아닌 GenAI 서비스의 메트릭과도 일관됩니다. +교차 제공자 대시보드에는 `gen_ai_client_token_usage`를 선호하세요. 이는 OpenTelemetry GenAI 의미 체계 규칙을 따르며 OpenClaw가 아닌 GenAI 서비스의 메트릭과도 일관됩니다. -## Prometheus와 OpenTelemetry 내보내기 중 선택하기 +## Prometheus와 OpenTelemetry 내보내기 중 선택 -OpenClaw는 두 표면을 독립적으로 모두 지원합니다. 둘 중 하나만 실행하거나, 둘 다 실행하거나, 둘 다 실행하지 않을 수 있습니다. +OpenClaw는 두 인터페이스를 독립적으로 모두 지원합니다. 둘 중 하나를 실행하거나, 둘 다 실행하거나, 둘 다 실행하지 않을 수 있습니다. - **Pull** 모델: Prometheus가 `/api/diagnostics/prometheus`를 스크레이프합니다. - - 외부 수집기가 필요 없습니다. + - 외부 collector가 필요하지 않습니다. - 일반 Gateway 인증을 통해 인증됩니다. - - 표면은 메트릭 전용입니다(트레이스 또는 로그 없음). - - 이미 Prometheus + Grafana로 표준화된 스택에 가장 적합합니다. + - 인터페이스는 메트릭 전용입니다(트레이스나 로그 없음). + - Prometheus + Grafana로 이미 표준화된 스택에 가장 적합합니다. - - **Push** 모델: OpenClaw가 OTLP/HTTP를 수집기 또는 OTLP 호환 백엔드로 보냅니다. - - 표면에는 메트릭, 트레이스, 로그가 포함됩니다. - - 둘 다 필요할 때 OpenTelemetry Collector(`prometheus` 또는 `prometheusremotewrite` 내보내기 도구)를 통해 Prometheus로 연결합니다. + - **Push** 모델: OpenClaw가 OTLP/HTTP를 collector 또는 OTLP 호환 백엔드로 전송합니다. + - 인터페이스에는 메트릭, 트레이스, 로그가 포함됩니다. + - 둘 다 필요할 때 OpenTelemetry Collector(`prometheus` 또는 `prometheusremotewrite` exporter)를 통해 Prometheus로 연결합니다. - 전체 카탈로그는 [OpenTelemetry 내보내기](/ko/gateway/opentelemetry)를 참조하세요. @@ -200,26 +207,26 @@ OpenClaw는 두 표면을 독립적으로 모두 지원합니다. 둘 중 하나 ## 문제 해결 - - - 구성에서 `diagnostics.enabled: true`를 확인하세요. - - `openclaw plugins list --enabled`로 Plugin이 활성화되고 로드되었는지 확인하세요. - - 일부 트래픽을 생성하세요. 카운터와 히스토그램은 이벤트가 하나 이상 발생한 뒤에만 줄을 내보냅니다. + + - config에서 `diagnostics.enabled: true`를 확인하세요. + - Plugin이 활성화되어 있고 `openclaw plugins list --enabled`로 로드되었는지 확인하세요. + - 트래픽을 생성하세요. 카운터와 히스토그램은 이벤트가 하나 이상 발생한 뒤에만 줄을 내보냅니다. - 엔드포인트에는 Gateway 운영자 범위(`auth: "gateway"`와 `gatewayRuntimeScopeSurface: "trusted-operator"`)가 필요합니다. Prometheus가 다른 Gateway 운영자 경로에 사용하는 것과 동일한 토큰 또는 비밀번호를 사용하세요. 공개 미인증 모드는 없습니다. + 엔드포인트에는 Gateway operator 범위(`auth: "gateway"` 및 `gatewayRuntimeScopeSurface: "trusted-operator"`)가 필요합니다. Prometheus가 다른 Gateway operator 경로에 사용하는 것과 동일한 토큰 또는 비밀번호를 사용하세요. 공개 미인증 모드는 없습니다. - - 새 속성이 **2048**개 시리즈 한도를 초과하고 있습니다. 최근 메트릭에서 예기치 않게 카디널리티가 높은 레이블을 검사하고 원인을 수정하세요. 내보내기 도구는 레이블을 조용히 다시 쓰는 대신 의도적으로 새 시리즈를 삭제합니다. + + 새 속성이 **2048**개 시리즈 한도를 초과하고 있습니다. 최근 메트릭에서 예상치 못하게 카디널리티가 높은 label을 점검하고 원인에서 수정하세요. exporter는 label을 조용히 다시 쓰는 대신 의도적으로 새 시리즈를 삭제합니다. - - Plugin은 상태를 메모리에만 보관합니다. Gateway를 다시 시작하면 카운터는 0으로 재설정되고 게이지는 다음에 보고된 값에서 다시 시작합니다. 재설정을 깔끔하게 처리하려면 PromQL `rate()`와 `increase()`를 사용하세요. + + Plugin은 상태를 메모리에만 보관합니다. Gateway를 재시작하면 카운터는 0으로 재설정되고 게이지는 다음에 보고되는 값에서 다시 시작합니다. 재설정을 깔끔하게 처리하려면 PromQL `rate()`와 `increase()`를 사용하세요. -## 관련 항목 +## 관련 -- [진단 내보내기](/ko/gateway/diagnostics) — 지원 번들을 위한 로컬 진단 zip +- [진단 내보내기](/ko/gateway/diagnostics) — 지원 번들용 로컬 진단 ZIP - [상태 및 준비 상태](/ko/gateway/health) — `/healthz` 및 `/readyz` 프로브 - [로깅](/ko/logging) — 파일 기반 로깅 -- [OpenTelemetry 내보내기](/ko/gateway/opentelemetry) — 트레이스, 메트릭, 로그용 OTLP 푸시 +- [OpenTelemetry 내보내기](/ko/gateway/opentelemetry) — 추적, 메트릭 및 로그를 위한 OTLP 푸시 diff --git a/docs/ko/gateway/tailscale.md b/docs/ko/gateway/tailscale.md index 738d500d3..7604d4ffe 100644 --- a/docs/ko/gateway/tailscale.md +++ b/docs/ko/gateway/tailscale.md @@ -1,46 +1,46 @@ --- read_when: - - 로컬호스트 외부에 Gateway 제어 UI 노출하기 + - Gateway 제어 UI를 localhost 외부에 노출하기 - 테일넷 또는 공개 대시보드 액세스 자동화 summary: Gateway 대시보드용 통합 Tailscale Serve/Funnel title: Tailscale x-i18n: - generated_at: "2026-04-30T06:33:43Z" + generated_at: "2026-05-06T17:56:37Z" model: gpt-5.5 provider: openai - source_hash: e5bc0a90ce8105017f5f52bad4a40609711f4bd4538437916c020680d3e9eda4 + source_hash: 89a2094dc5d9250b3af2dcc991e83099bdf6fc4039c86358ca57f7e58899196d source_path: gateway/tailscale.md workflow: 16 --- -OpenClaw는 Gateway 대시보드와 WebSocket 포트에 대해 Tailscale **Serve**(tailnet) 또는 **Funnel**(공개)을 자동 구성할 수 있습니다. 이렇게 하면 Gateway는 loopback에 바인딩된 상태를 유지하고, Tailscale이 HTTPS, 라우팅 및 (Serve의 경우) ID 헤더를 제공합니다. +OpenClaw은 Gateway 대시보드와 WebSocket 포트에 대해 Tailscale **Serve**(테일넷) 또는 **Funnel**(공개)을 자동 구성할 수 있습니다. 이렇게 하면 Gateway는 루프백에 바인딩된 상태로 유지되고, Tailscale이 HTTPS, 라우팅, 그리고 Serve의 경우 ID 헤더를 제공합니다. ## 모드 -- `serve`: `tailscale serve`를 통한 tailnet 전용 Serve입니다. gateway는 `127.0.0.1`에 유지됩니다. +- `serve`: `tailscale serve`를 통한 테일넷 전용 Serve입니다. Gateway는 `127.0.0.1`에 유지됩니다. - `funnel`: `tailscale funnel`을 통한 공개 HTTPS입니다. OpenClaw에는 공유 암호가 필요합니다. -- `off`: 기본값(Tailscale 자동화 없음)입니다. +- `off`: 기본값입니다(Tailscale 자동화 없음). -상태 및 감사 출력은 이 OpenClaw Serve/Funnel 모드에 대해 **Tailscale 노출**을 사용합니다. `off`는 OpenClaw가 Serve 또는 Funnel을 관리하지 않는다는 뜻입니다. local Tailscale 데몬이 중지되었거나 로그아웃되었다는 뜻은 아닙니다. +상태 및 감사 출력은 이 OpenClaw Serve/Funnel 모드에 대해 **Tailscale 노출**을 사용합니다. `off`는 OpenClaw이 Serve 또는 Funnel을 관리하지 않는다는 뜻입니다. 로컬 Tailscale 데몬이 중지되었거나 로그아웃되었다는 뜻은 아닙니다. ## 인증 핸드셰이크를 제어하려면 `gateway.auth.mode`를 설정하세요. -- `none`(비공개 인그레스만) +- `none`(비공개 인그레스 전용) - `token`(`OPENCLAW_GATEWAY_TOKEN`이 설정된 경우 기본값) - `password`(`OPENCLAW_GATEWAY_PASSWORD` 또는 구성을 통한 공유 비밀) -- `trusted-proxy`(ID 인식 리버스 프록시; [신뢰할 수 있는 프록시 인증](/ko/gateway/trusted-proxy-auth) 참조) +- `trusted-proxy`(ID 인식 리버스 프록시. [신뢰할 수 있는 프록시 인증](/ko/gateway/trusted-proxy-auth) 참조) -`tailscale.mode = "serve"`이고 `gateway.auth.allowTailscale`이 `true`이면, Control UI/WebSocket 인증은 토큰/암호를 제공하지 않고도 Tailscale ID 헤더(`tailscale-user-login`)를 사용할 수 있습니다. OpenClaw는 요청을 수락하기 전에 local Tailscale 데몬(`tailscale whois`)을 통해 `x-forwarded-for` 주소를 확인하고 이를 헤더와 매칭하여 ID를 검증합니다. OpenClaw는 loopback에서 도착하고 Tailscale의 `x-forwarded-for`, `x-forwarded-proto`, `x-forwarded-host` 헤더가 있는 요청만 Serve로 취급합니다. -브라우저 장치 ID가 포함된 Control UI 운영자 세션의 경우, 이 검증된 Serve 경로는 장치 페어링 왕복도 건너뜁니다. 브라우저 장치 ID를 우회하지는 않습니다. 장치가 없는 클라이언트는 여전히 거부되며, node 역할 또는 Control UI가 아닌 WebSocket 연결은 계속 일반적인 페어링 및 인증 검사를 따릅니다. -HTTP API 엔드포인트(예: `/v1/*`, `/tools/invoke`, `/api/channels/*`)는 Tailscale ID 헤더 인증을 사용하지 **않습니다**. 이 엔드포인트는 여전히 gateway의 일반 HTTP 인증 모드를 따릅니다. 기본적으로 공유 비밀 인증을 사용하거나, 의도적으로 구성된 trusted-proxy / 비공개 인그레스 `none` 설정을 사용합니다. -이 토큰 없는 흐름은 gateway 호스트가 신뢰된다고 가정합니다. 신뢰할 수 없는 local 코드가 같은 호스트에서 실행될 수 있다면 `gateway.auth.allowTailscale`을 비활성화하고 대신 토큰/암호 인증을 요구하세요. +`tailscale.mode = "serve"`이고 `gateway.auth.allowTailscale`이 `true`이면, Control UI/WebSocket 인증은 토큰/암호를 제공하지 않고도 Tailscale ID 헤더(`tailscale-user-login`)를 사용할 수 있습니다. OpenClaw은 로컬 Tailscale 데몬(`tailscale whois`)을 통해 `x-forwarded-for` 주소를 확인하고, 이를 헤더와 대조한 뒤에만 ID를 검증하고 수락합니다. OpenClaw은 요청이 루프백에서 도착하고 Tailscale의 `x-forwarded-for`, `x-forwarded-proto`, `x-forwarded-host` 헤더가 포함된 경우에만 해당 요청을 Serve로 처리합니다. +브라우저 장치 ID가 포함된 Control UI 운영자 세션의 경우, 이렇게 검증된 Serve 경로는 장치 페어링 왕복 과정도 건너뜁니다. 하지만 브라우저 장치 ID를 우회하지는 않습니다. 장치가 없는 클라이언트는 여전히 거부되며, 노드 역할 또는 Control UI가 아닌 WebSocket 연결은 계속 일반적인 페어링 및 인증 검사를 따릅니다. +HTTP API 엔드포인트(예: `/v1/*`, `/tools/invoke`, `/api/channels/*`)는 Tailscale ID 헤더 인증을 사용하지 **않습니다**. 이들은 여전히 Gateway의 일반 HTTP 인증 모드를 따릅니다. 기본적으로 공유 비밀 인증을 사용하거나, 의도적으로 구성된 trusted-proxy / 비공개 인그레스 `none` 설정을 사용합니다. +이 토큰 없는 흐름은 Gateway 호스트를 신뢰한다고 가정합니다. 신뢰할 수 없는 로컬 코드가 같은 호스트에서 실행될 수 있다면 `gateway.auth.allowTailscale`을 비활성화하고 대신 토큰/암호 인증을 요구하세요. 명시적인 공유 비밀 자격 증명을 요구하려면 `gateway.auth.allowTailscale: false`를 설정하고 `gateway.auth.mode: "token"` 또는 `"password"`를 사용하세요. ## 구성 예시 -### Tailnet 전용(Serve) +### 테일넷 전용(Serve) ```json5 { @@ -51,11 +51,11 @@ HTTP API 엔드포인트(예: `/v1/*`, `/tools/invoke`, `/api/channels/*`)는 Ta } ``` -열기: `https:///`(또는 구성된 `gateway.controlUi.basePath`) +열기: `https:///`(또는 구성한 `gateway.controlUi.basePath`) -### Tailnet 전용(Tailnet IP에 바인딩) +### 테일넷 전용(테일넷 IP에 바인딩) -Gateway가 Tailnet IP에서 직접 수신하도록 하려는 경우(Serve/Funnel 없음) 사용하세요. +Gateway가 테일넷 IP에서 직접 수신하게 하려는 경우 사용하세요(Serve/Funnel 없음). ```json5 { @@ -66,13 +66,13 @@ Gateway가 Tailnet IP에서 직접 수신하도록 하려는 경우(Serve/Funnel } ``` -다른 Tailnet 장치에서 연결: +다른 테일넷 장치에서 연결: - Control UI: `http://:18789/` - WebSocket: `ws://:18789` -Loopback(`http://127.0.0.1:18789`)은 이 모드에서 작동하지 **않습니다**. +이 모드에서는 루프백(`http://127.0.0.1:18789`)이 작동하지 **않습니다**. ### 공개 인터넷(Funnel + 공유 암호) @@ -87,7 +87,7 @@ Loopback(`http://127.0.0.1:18789`)은 이 모드에서 작동하지 **않습니 } ``` -암호를 디스크에 커밋하는 것보다 `OPENCLAW_GATEWAY_PASSWORD` 사용을 권장합니다. +암호를 디스크에 커밋하는 대신 `OPENCLAW_GATEWAY_PASSWORD`를 선호하세요. ## CLI 예시 @@ -100,23 +100,24 @@ openclaw gateway --tailscale funnel --auth password - Tailscale Serve/Funnel을 사용하려면 `tailscale` CLI가 설치되어 있고 로그인되어 있어야 합니다. - `tailscale.mode: "funnel"`은 공개 노출을 피하기 위해 인증 모드가 `password`가 아니면 시작을 거부합니다. -- OpenClaw가 종료 시 `tailscale serve` 또는 `tailscale funnel` 구성을 되돌리게 하려면 `gateway.tailscale.resetOnExit`를 설정하세요. -- `gateway.bind: "tailnet"`은 직접 Tailnet 바인딩입니다(HTTPS 없음, Serve/Funnel 없음). -- `gateway.bind: "auto"`는 loopback을 선호합니다. Tailnet 전용을 원하면 `tailnet`을 사용하세요. -- Serve/Funnel은 **Gateway 제어 UI + WS**만 노출합니다. 노드는 동일한 Gateway WS 엔드포인트를 통해 연결하므로, Serve는 노드 접근에도 작동할 수 있습니다. +- 종료 시 OpenClaw이 `tailscale serve` 또는 `tailscale funnel` 구성을 되돌리게 하려면 `gateway.tailscale.resetOnExit`를 설정하세요. +- `gateway.bind: "tailnet"`은 직접 테일넷 바인딩입니다(HTTPS 없음, Serve/Funnel 없음). +- `gateway.bind: "auto"`는 루프백을 선호합니다. 테일넷 전용을 원하면 `tailnet`을 사용하세요. +- Serve/Funnel은 **Gateway 제어 UI + WS**만 노출합니다. 노드는 같은 Gateway WS 엔드포인트를 통해 연결되므로, Serve는 노드 접근에도 사용할 수 있습니다. -## 브라우저 제어(원격 Gateway + local 브라우저) +## 브라우저 제어(원격 Gateway + 로컬 브라우저) -Gateway를 한 머신에서 실행하지만 다른 머신의 브라우저를 제어하려면, 브라우저 머신에서 **node 호스트**를 실행하고 둘 다 같은 tailnet에 유지하세요. Gateway가 브라우저 작업을 node로 프록시합니다. 별도의 제어 서버나 Serve URL은 필요하지 않습니다. +Gateway를 한 컴퓨터에서 실행하지만 다른 컴퓨터의 브라우저를 제어하려면 브라우저 컴퓨터에서 **노드 호스트**를 실행하고 둘 다 같은 테일넷에 두세요. +Gateway가 브라우저 동작을 노드로 프록시합니다. 별도의 제어 서버나 Serve URL은 필요하지 않습니다. 브라우저 제어에는 Funnel을 피하세요. 노드 페어링을 운영자 접근처럼 취급하세요. -## Tailscale 필수 조건 + 제한 +## Tailscale 사전 요구 사항 및 제한 -- Serve를 사용하려면 tailnet에 HTTPS가 활성화되어 있어야 합니다. 없으면 CLI가 안내합니다. -- Serve는 Tailscale ID 헤더를 삽입하지만, Funnel은 삽입하지 않습니다. -- Funnel에는 Tailscale v1.38.3 이상, MagicDNS, HTTPS 활성화, funnel 노드 속성이 필요합니다. -- Funnel은 TLS를 통한 포트 `443`, `8443`, `10000`만 지원합니다. +- Serve에는 테일넷에서 HTTPS가 활성화되어 있어야 합니다. 누락된 경우 CLI가 안내합니다. +- Serve는 Tailscale ID 헤더를 삽입합니다. Funnel은 그렇지 않습니다. +- Funnel에는 Tailscale v1.38.3 이상, MagicDNS, 활성화된 HTTPS, 그리고 Funnel 노드 속성이 필요합니다. +- Funnel은 TLS를 통해 포트 `443`, `8443`, `10000`만 지원합니다. - macOS에서 Funnel을 사용하려면 오픈 소스 Tailscale 앱 변형이 필요합니다. ## 더 알아보기 diff --git a/docs/ko/help/faq.md b/docs/ko/help/faq.md index e49ee95e0..23c96240b 100644 --- a/docs/ko/help/faq.md +++ b/docs/ko/help/faq.md @@ -2,36 +2,36 @@ read_when: - 일반적인 설정, 설치, 온보딩 또는 런타임 지원 질문에 답변하기 - 심층 디버깅 전에 사용자가 보고한 문제 분류하기 -summary: OpenClaw 설정, 구성 및 사용에 관한 자주 묻는 질문 +summary: OpenClaw 설치, 구성 및 사용에 관한 자주 묻는 질문 title: 자주 묻는 질문 x-i18n: - generated_at: "2026-05-03T21:33:55Z" + generated_at: "2026-05-06T17:56:52Z" model: gpt-5.5 provider: openai - source_hash: 372220d62f872db1427b2836662bc8cc74e07d2cdfb651c105d3df25131855dd + source_hash: 8d5724af921ab660da3d4453779f269bda440fb27518638541312e489f203318 source_path: help/faq.md workflow: 16 --- -빠른 답변과 실제 환경 설정(로컬 개발, VPS, 멀티 에이전트, OAuth/API 키, 모델 장애 조치)에 대한 더 깊은 문제 해결입니다. 런타임 진단은 [문제 해결](/ko/gateway/troubleshooting)을 참고하세요. 전체 구성 참조는 [구성](/ko/gateway/configuration)을 참고하세요. +빠른 답변과 실제 환경 설정(로컬 개발, VPS, 멀티 에이전트, OAuth/API 키, 모델 장애 조치)에 대한 더 자세한 문제 해결입니다. 런타임 진단은 [문제 해결](/ko/gateway/troubleshooting)을 참고하세요. 전체 구성 참조는 [구성](/ko/gateway/configuration)을 참고하세요. ## 문제가 발생했을 때 첫 60초 -1. **빠른 상태 확인(첫 확인)** +1. **빠른 상태(첫 확인)** ```bash openclaw status ``` - 빠른 로컬 요약: OS + 업데이트, gateway/서비스 도달 가능성, agents/sessions, provider config + runtime issues(Gateway에 도달할 수 있을 때). + 빠른 로컬 요약: OS + 업데이트, Gateway/서비스 도달 가능성, 에이전트/세션, 제공자 구성 + 런타임 문제(Gateway에 도달 가능한 경우). -2. **붙여 넣을 수 있는 보고서(공유해도 안전)** +2. **붙여넣을 수 있는 보고서(공유해도 안전)** ```bash openclaw status --all ``` - 로그 꼬리를 포함한 읽기 전용 진단(토큰은 삭제됨). + 로그 tail이 포함된 읽기 전용 진단(토큰은 수정됨). 3. **데몬 + 포트 상태** @@ -39,24 +39,24 @@ x-i18n: openclaw gateway status ``` - supervisor 런타임과 RPC 도달 가능성, probe 대상 URL, 서비스가 사용했을 가능성이 높은 구성을 표시합니다. + 슈퍼바이저 런타임과 RPC 도달 가능성, 프로브 대상 URL, 서비스가 사용했을 가능성이 높은 구성을 보여 줍니다. -4. **심층 probe** +4. **심층 프로브** ```bash openclaw status --deep ``` - 지원되는 경우 채널 probe를 포함해 실시간 Gateway 상태 probe를 실행합니다 + 지원되는 경우 채널 프로브를 포함해 실시간 Gateway 상태 프로브를 실행합니다 (도달 가능한 Gateway 필요). [상태](/ko/gateway/health)를 참고하세요. -5. **최신 로그 tail** +5. **최신 로그 추적** ```bash openclaw logs --follow ``` - RPC가 중단된 경우 다음으로 대체하세요. + RPC가 다운된 경우 다음으로 대체하세요. ```bash tail -f "$(ls -t /tmp/openclaw/openclaw-*.log | head -1)" @@ -70,47 +70,47 @@ x-i18n: openclaw doctor ``` - 구성/상태를 복구/마이그레이션하고 상태 확인을 실행합니다. [Doctor](/ko/gateway/doctor)를 참고하세요. + 구성/상태를 복구/마이그레이션하고 상태 검사를 실행합니다. [Doctor](/ko/gateway/doctor)를 참고하세요. 7. **Gateway 스냅샷** ```bash openclaw health --json - openclaw health --verbose # 오류 시 대상 URL + 구성 경로를 표시합니다 + openclaw health --verbose # shows the target URL + config path on errors ``` 실행 중인 Gateway에 전체 스냅샷을 요청합니다(WS 전용). [상태](/ko/gateway/health)를 참고하세요. -## 빠른 시작 및 최초 실행 설정 +## 빠른 시작 및 첫 실행 설정 -최초 실행 Q&A(설치, 온보딩, 인증 경로, 구독, 초기 실패)는 -[최초 실행 FAQ](/ko/help/faq-first-run)에 있습니다. +첫 실행 Q&A(설치, 온보딩, 인증 라우트, 구독, 초기 실패)는 +[첫 실행 FAQ](/ko/help/faq-first-run)에 있습니다. -## OpenClaw란 무엇인가요? +## OpenClaw란? - - OpenClaw는 사용자가 직접 자신의 기기에서 실행하는 개인 AI assistant입니다. 이미 사용하는 메시징 환경(WhatsApp, Telegram, Slack, Mattermost, Discord, Google Chat, Signal, iMessage, WebChat, 그리고 QQ Bot 같은 번들 채널 plugins)에서 응답하며, 지원되는 플랫폼에서는 음성 + 실시간 Canvas도 사용할 수 있습니다. **Gateway**는 항상 켜져 있는 control plane이고, assistant가 제품입니다. + + OpenClaw는 자신의 기기에서 실행하는 개인 AI 어시스턴트입니다. 이미 사용하는 메시징 환경(WhatsApp, Telegram, Slack, Mattermost, Discord, Google Chat, Signal, iMessage, WebChat, 그리고 QQ Bot 같은 번들 채널 Plugin)에서 응답하며, 지원되는 플랫폼에서는 음성 + 라이브 Canvas도 사용할 수 있습니다. **Gateway**는 항상 켜져 있는 제어 평면이고, 어시스턴트가 제품입니다. - OpenClaw는 "그냥 Claude wrapper"가 아닙니다. 이미 사용하는 채팅 앱에서 도달할 수 있는 - 유능한 assistant를 **자신의 하드웨어**에서 실행하게 해 주는 **로컬 우선 control plane**이며, - 상태 유지 세션, 메모리, 도구를 제공합니다. 워크플로 제어권을 호스팅된 + OpenClaw는 "단순한 Claude 래퍼"가 아닙니다. **로컬 우선 제어 평면**으로, 사용자가 이미 쓰는 채팅 앱에서 접근 가능한 + 유능한 어시스턴트를 **자체 하드웨어**에서 실행할 수 있게 해 주며, + 상태가 유지되는 세션, 메모리, 도구를 제공합니다. 워크플로의 제어권을 호스팅 SaaS에 넘기지 않아도 됩니다. 주요 특징: - - **내 기기, 내 데이터:** 원하는 곳(Mac, Linux, VPS)에서 Gateway를 실행하고 - workspace + session history를 로컬에 유지합니다. - - **웹 샌드박스가 아닌 실제 채널:** WhatsApp/Telegram/Slack/Discord/Signal/iMessage/등, + - **사용자 기기, 사용자 데이터:** 원하는 곳(Mac, Linux, VPS)에서 Gateway를 실행하고 + 작업공간 + 세션 기록을 로컬에 유지하세요. + - **웹 샌드박스가 아닌 실제 채널:** WhatsApp/Telegram/Slack/Discord/Signal/iMessage 등, 그리고 지원되는 플랫폼의 모바일 음성 및 Canvas. - - **모델 독립적:** Anthropic, OpenAI, MiniMax, OpenRouter 등을 agent별 라우팅 - 및 장애 조치와 함께 사용합니다. - - **로컬 전용 옵션:** 원하는 경우 로컬 모델을 실행해 **모든 데이터가 기기에 머물도록** 할 수 있습니다. - - **멀티 에이전트 라우팅:** 채널, 계정 또는 작업별로 별도 agents를 두고, 각각 고유한 - workspace와 기본값을 가집니다. - - **오픈 소스이며 해킹 가능:** vendor lock-in 없이 검사하고, 확장하고, self-host할 수 있습니다. + - **모델에 구애받지 않음:** Anthropic, OpenAI, MiniMax, OpenRouter 등을 에이전트별 라우팅 + 및 장애 조치와 함께 사용하세요. + - **로컬 전용 옵션:** 원하면 로컬 모델을 실행해 **모든 데이터를 기기에 유지할 수 있습니다**. + - **멀티 에이전트 라우팅:** 채널, 계정, 작업별로 에이전트를 분리하고, 각각 자체 + 작업공간과 기본값을 갖게 합니다. + - **오픈 소스이고 확장 가능:** 벤더 종속 없이 검사, 확장, 셀프 호스팅할 수 있습니다. 문서: [Gateway](/ko/gateway), [채널](/ko/channels), [멀티 에이전트](/ko/concepts/multi-agent), [메모리](/ko/concepts/memory). @@ -118,53 +118,53 @@ x-i18n: - 좋은 첫 프로젝트: + 처음 시도하기 좋은 프로젝트: - - 웹사이트를 빌드합니다(WordPress, Shopify 또는 간단한 정적 사이트). - - 모바일 앱을 프로토타이핑합니다(개요, 화면, API 계획). - - 파일과 폴더를 정리합니다(정리, 이름 지정, 태그 지정). - - Gmail을 연결하고 요약이나 후속 조치를 자동화합니다. + - 웹사이트 만들기(WordPress, Shopify 또는 간단한 정적 사이트). + - 모바일 앱 프로토타입 만들기(개요, 화면, API 계획). + - 파일과 폴더 정리(정리, 이름 지정, 태깅). + - Gmail을 연결하고 요약 또는 후속 조치 자동화. 큰 작업도 처리할 수 있지만, 단계를 나누고 - 병렬 작업에 sub agents를 사용할 때 가장 잘 작동합니다. + 병렬 작업에 하위 에이전트를 사용할 때 가장 잘 작동합니다. - + 일상적인 성과는 보통 다음과 같습니다. - - **개인 브리핑:** 받은 편지함, 캘린더, 관심 있는 뉴스 요약. - - **리서치와 초안 작성:** 이메일이나 문서를 위한 빠른 리서치, 요약, 첫 초안. - - **리마인더와 후속 조치:** Cron 또는 Heartbeat 기반 알림과 체크리스트. - - **브라우저 자동화:** 양식 작성, 데이터 수집, 웹 작업 반복. - - **기기 간 조정:** 휴대폰에서 작업을 보내고, Gateway가 서버에서 실행하게 한 뒤, 결과를 채팅으로 다시 받습니다. + - **개인 브리핑:** 받은편지함, 캘린더, 관심 있는 뉴스 요약. + - **조사 및 초안 작성:** 이메일이나 문서용 빠른 조사, 요약, 초안. + - **리마인더 및 후속 조치:** Cron 또는 Heartbeat 기반 알림과 체크리스트. + - **브라우저 자동화:** 양식 작성, 데이터 수집, 반복적인 웹 작업. + - **기기 간 조율:** 휴대폰에서 작업을 보내고, Gateway가 서버에서 실행하게 한 뒤, 결과를 채팅으로 다시 받습니다. - - **리서치, 검증, 초안 작성**에는 가능합니다. 사이트를 스캔하고, shortlist를 만들고, - prospects를 요약하고, outreach 또는 광고 문안 초안을 작성할 수 있습니다. + + **조사, 자격 검증, 초안 작성**에는 가능합니다. 사이트를 스캔하고, 후보 목록을 만들고, + 잠재 고객을 요약하고, 아웃리치나 광고 카피 초안을 작성할 수 있습니다. - **outreach 또는 광고 실행**에는 사람이 관여하게 하세요. 스팸을 피하고, 현지 법률과 - 플랫폼 정책을 따르며, 전송 전 모든 내용을 검토하세요. 가장 안전한 패턴은 - OpenClaw가 초안을 작성하고 사용자가 승인하는 것입니다. + **아웃리치 또는 광고 집행**에는 사람이 관여하도록 하세요. 스팸을 피하고, 현지 법률과 + 플랫폼 정책을 따르며, 전송 전에 모든 내용을 검토하세요. 가장 안전한 패턴은 + OpenClaw가 초안을 만들고 사용자가 승인하는 것입니다. 문서: [보안](/ko/gateway/security). - OpenClaw는 IDE 대체제가 아니라 **개인 assistant**이자 조정 계층입니다. repo 안에서 - 가장 빠른 직접 코딩 루프가 필요하면 Claude Code 또는 Codex를 사용하세요. 지속적인 메모리, - 여러 기기 접근, 도구 orchestration이 필요할 때 OpenClaw를 사용하세요. + OpenClaw는 **개인 어시스턴트**이자 조율 계층이며, IDE 대체품이 아닙니다. 저장소 내부의 + 가장 빠른 직접 코딩 루프에는 Claude Code나 Codex를 사용하세요. 지속 메모리, 기기 간 접근, + 도구 오케스트레이션이 필요할 때 OpenClaw를 사용하세요. 장점: - - 세션 전반의 **지속 메모리 + workspace** + - 세션 간 **영속 메모리 + 작업공간** - **멀티 플랫폼 접근**(WhatsApp, Telegram, TUI, WebChat) - - **도구 orchestration**(브라우저, 파일, 일정 관리, hooks) + - **도구 오케스트레이션**(브라우저, 파일, 예약, 훅) - **항상 켜져 있는 Gateway**(VPS에서 실행하고 어디서나 상호작용) - - 로컬 브라우저/화면/카메라/실행을 위한 **Nodes** + - 로컬 브라우저/화면/카메라/exec용 **Node** 쇼케이스: [https://openclaw.ai/showcase](https://openclaw.ai/showcase) @@ -174,69 +174,69 @@ x-i18n: ## Skills와 자동화 - - repo copy를 편집하는 대신 관리형 overrides를 사용하세요. 변경 사항을 `~/.openclaw/skills//SKILL.md`에 넣거나, `~/.openclaw/openclaw.json`의 `skills.load.extraDirs`를 통해 폴더를 추가하세요. 우선순위는 `/skills` → `/.agents/skills` → `~/.agents/skills` → `~/.openclaw/skills` → bundled → `skills.load.extraDirs`이므로, 관리형 overrides는 git을 건드리지 않고도 bundled skills보다 우선합니다. skill을 전역으로 설치해야 하지만 일부 agents에만 보이게 하려면, 공유 copy를 `~/.openclaw/skills`에 두고 `agents.defaults.skills` 및 `agents.list[].skills`로 표시 여부를 제어하세요. upstream할 가치가 있는 편집만 repo에 두고 PR로 제출해야 합니다. + + 저장소 사본을 편집하는 대신 관리형 재정의를 사용하세요. 변경 사항을 `~/.openclaw/skills//SKILL.md`에 넣으세요(또는 `~/.openclaw/openclaw.json`의 `skills.load.extraDirs`를 통해 폴더를 추가하세요). 우선순위는 `/skills` → `/.agents/skills` → `~/.agents/skills` → `~/.openclaw/skills` → 번들 → `skills.load.extraDirs`이므로, 관리형 재정의는 git을 건드리지 않고도 번들 Skills보다 여전히 우선합니다. Skills를 전역으로 설치하되 일부 에이전트에게만 보이게 해야 한다면, 공유 사본을 `~/.openclaw/skills`에 두고 `agents.defaults.skills` 및 `agents.list[].skills`로 가시성을 제어하세요. 업스트림에 올릴 만한 편집만 저장소에 두고 PR로 내보내야 합니다. - - 가능합니다. `~/.openclaw/openclaw.json`의 `skills.load.extraDirs`로 추가 디렉터리를 추가하세요(가장 낮은 우선순위). 기본 우선순위는 `/skills` → `/.agents/skills` → `~/.agents/skills` → `~/.openclaw/skills` → bundled → `skills.load.extraDirs`입니다. `clawhub`는 기본적으로 `./skills`에 설치하며, OpenClaw는 다음 세션에서 이를 `/skills`로 취급합니다. skill이 특정 agents에만 보여야 한다면 `agents.defaults.skills` 또는 `agents.list[].skills`와 함께 사용하세요. + + 예. `~/.openclaw/openclaw.json`의 `skills.load.extraDirs`를 통해 추가 디렉터리를 추가하세요(가장 낮은 우선순위). 기본 우선순위는 `/skills` → `/.agents/skills` → `~/.agents/skills` → `~/.openclaw/skills` → 번들 → `skills.load.extraDirs`입니다. `clawhub`는 기본적으로 `./skills`에 설치하며, OpenClaw는 다음 세션에서 이를 `/skills`로 취급합니다. Skills가 특정 에이전트에게만 보여야 한다면 `agents.defaults.skills` 또는 `agents.list[].skills`와 함께 사용하세요. - + 현재 지원되는 패턴은 다음과 같습니다. - - **Cron jobs**: 격리된 jobs는 job별 `model` override를 설정할 수 있습니다. - - **Sub-agents**: 기본 모델이 다른 별도 agents로 작업을 라우팅합니다. - - **요청 시 전환**: 언제든 `/model`을 사용해 현재 session model을 전환합니다. + - **Cron 작업**: 격리된 작업은 작업별로 `model` 재정의를 설정할 수 있습니다. + - **하위 에이전트**: 서로 다른 기본 모델을 가진 별도 에이전트로 작업을 라우팅합니다. + - **요청 시 전환**: 언제든지 `/model`을 사용해 현재 세션 모델을 전환합니다. - [Cron jobs](/ko/automation/cron-jobs), [멀티 에이전트 라우팅](/ko/concepts/multi-agent), [슬래시 명령](/ko/tools/slash-commands)을 참고하세요. + [Cron 작업](/ko/automation/cron-jobs), [멀티 에이전트 라우팅](/ko/concepts/multi-agent), [슬래시 명령](/ko/tools/slash-commands)을 참고하세요. - - 길거나 병렬인 작업에는 **sub-agents**를 사용하세요. Sub-agents는 자체 session에서 실행되고, - 요약을 반환하며, main chat을 계속 응답 가능하게 유지합니다. + + 긴 작업이나 병렬 작업에는 **하위 에이전트**를 사용하세요. 하위 에이전트는 자체 세션에서 실행되고, + 요약을 반환하며, 메인 채팅을 응답 가능하게 유지합니다. - bot에게 "spawn a sub-agent for this task"라고 요청하거나 `/subagents`를 사용하세요. - 채팅에서 `/status`를 사용해 Gateway가 지금 무엇을 하고 있는지(그리고 바쁜지)를 확인하세요. + 봇에게 "이 작업을 위해 하위 에이전트를 생성해 줘"라고 요청하거나 `/subagents`를 사용하세요. + 채팅에서 `/status`를 사용해 Gateway가 지금 무엇을 하고 있는지(그리고 바쁜지 여부)를 확인하세요. - 토큰 팁: 긴 작업과 sub-agents는 모두 토큰을 소비합니다. 비용이 걱정된다면 - `agents.defaults.subagents.model`을 통해 sub-agents에 더 저렴한 모델을 설정하세요. + 토큰 팁: 긴 작업과 하위 에이전트는 모두 토큰을 소비합니다. 비용이 걱정된다면 + `agents.defaults.subagents.model`을 통해 하위 에이전트에 더 저렴한 모델을 설정하세요. - 문서: [Sub-agents](/ko/tools/subagents), [백그라운드 작업](/ko/automation/tasks). + 문서: [하위 에이전트](/ko/tools/subagents), [백그라운드 작업](/ko/automation/tasks). - - thread bindings를 사용하세요. Discord thread를 subagent 또는 session target에 바인딩하면 해당 thread의 후속 메시지가 바인딩된 session에 유지됩니다. + + 스레드 바인딩을 사용하세요. Discord 스레드를 하위 에이전트 또는 세션 대상에 바인딩하여 해당 스레드의 후속 메시지가 바인딩된 세션에 유지되도록 할 수 있습니다. 기본 흐름: - - `thread: true`로 `sessions_spawn`을 사용해 spawn합니다(지속적인 follow-up에는 선택적으로 `mode: "session"` 사용). + - `thread: true`를 사용해 `sessions_spawn`으로 생성합니다(지속적인 후속 처리를 위해 선택적으로 `mode: "session"` 사용). - 또는 `/focus `으로 수동 바인딩합니다. - - `/agents`로 binding state를 검사합니다. - - `/session idle ` 및 `/session max-age `로 auto-unfocus를 제어합니다. - - `/unfocus`로 thread를 분리합니다. + - `/agents`를 사용해 바인딩 상태를 확인합니다. + - `/session idle ` 및 `/session max-age `를 사용해 자동 포커스 해제를 제어합니다. + - `/unfocus`를 사용해 스레드를 분리합니다. 필수 구성: - 전역 기본값: `session.threadBindings.enabled`, `session.threadBindings.idleHours`, `session.threadBindings.maxAgeHours`. - - Discord overrides: `channels.discord.threadBindings.enabled`, `channels.discord.threadBindings.idleHours`, `channels.discord.threadBindings.maxAgeHours`. - - spawn 시 자동 바인딩: `channels.discord.threadBindings.spawnSessions`의 기본값은 `true`입니다. thread-bound session spawns를 비활성화하려면 `false`로 설정하세요. + - Discord 재정의: `channels.discord.threadBindings.enabled`, `channels.discord.threadBindings.idleHours`, `channels.discord.threadBindings.maxAgeHours`. + - 생성 시 자동 바인딩: `channels.discord.threadBindings.spawnSessions`의 기본값은 `true`입니다. 스레드에 바인딩된 세션 생성을 비활성화하려면 `false`로 설정하세요. - 문서: [Sub-agents](/ko/tools/subagents), [Discord](/ko/channels/discord), [구성 참조](/ko/gateway/configuration-reference), [슬래시 명령](/ko/tools/slash-commands). + 문서: [하위 에이전트](/ko/tools/subagents), [Discord](/ko/channels/discord), [구성 참조](/ko/gateway/configuration-reference), [슬래시 명령](/ko/tools/slash-commands). - - 먼저 해결된 requester route를 확인하세요. + + 먼저 확인된 요청자 라우트를 확인하세요. - - Completion-mode subagent delivery는 존재하는 경우 bound thread 또는 conversation route를 우선합니다. - - completion origin이 channel만 가지고 있으면, OpenClaw는 direct delivery가 계속 성공할 수 있도록 requester session의 저장된 route(`lastChannel` / `lastTo` / `lastAccountId`)로 대체합니다. - - bound route도 usable stored route도 없으면 direct delivery가 실패할 수 있으며, 결과는 채팅에 즉시 게시되는 대신 queued session delivery로 대체됩니다. - - 유효하지 않거나 오래된 targets는 여전히 queue fallback 또는 final delivery failure를 강제할 수 있습니다. - - child의 마지막으로 보이는 assistant reply가 정확한 silent token `NO_REPLY` / `no_reply`이거나 정확히 `ANNOUNCE_SKIP`이면, OpenClaw는 오래된 이전 progress를 게시하는 대신 의도적으로 announce를 억제합니다. - - child가 tool calls만 수행한 뒤 timed out되면, announce는 raw tool output을 replay하는 대신 이를 짧은 partial-progress summary로 축약할 수 있습니다. + - 완료 모드 하위 에이전트 전달은 바인딩된 스레드나 대화 라우트가 있으면 그것을 우선합니다. + - 완료 출처에 채널만 포함된 경우, OpenClaw는 직접 전달이 여전히 성공할 수 있도록 요청자 세션에 저장된 라우트(`lastChannel` / `lastTo` / `lastAccountId`)로 대체합니다. + - 바인딩된 라우트도 사용 가능한 저장 라우트도 없으면, 직접 전달이 실패할 수 있으며 결과는 채팅에 즉시 게시되는 대신 대기열의 세션 전달로 대체됩니다. + - 유효하지 않거나 오래된 대상은 여전히 대기열 대체 또는 최종 전달 실패를 강제할 수 있습니다. + - 하위 에이전트의 마지막으로 표시된 어시스턴트 응답이 정확히 무음 토큰 `NO_REPLY` / `no_reply`이거나 정확히 `ANNOUNCE_SKIP`이면, OpenClaw는 오래된 이전 진행 상황을 게시하는 대신 알림을 의도적으로 억제합니다. + - 하위 에이전트가 도구 호출만 수행한 뒤 타임아웃되면, 알림은 원시 도구 출력을 재생하는 대신 짧은 부분 진행 요약으로 축약될 수 있습니다. 디버그: @@ -244,19 +244,19 @@ x-i18n: openclaw tasks show ``` - 문서: [Sub-agents](/ko/tools/subagents), [백그라운드 작업](/ko/automation/tasks), [세션 도구](/ko/concepts/session-tool). + 문서: [하위 에이전트](/ko/tools/subagents), [백그라운드 작업](/ko/automation/tasks), [세션 도구](/ko/concepts/session-tool). - Cron은 Gateway process 안에서 실행됩니다. Gateway가 계속 실행되고 있지 않으면 - scheduled jobs는 실행되지 않습니다. + Cron은 Gateway 프로세스 내부에서 실행됩니다. Gateway가 지속적으로 실행 중이지 않으면 + 예약된 작업은 실행되지 않습니다. 체크리스트: - - cron이 활성화되어 있는지(`cron.enabled`), `OPENCLAW_SKIP_CRON`이 설정되어 있지 않은지 확인하세요. - - Gateway가 24/7 실행 중인지 확인하세요(절전/재시작 없음). - - job의 timezone settings를 확인하세요(`--tz`와 host timezone 비교). + - Cron이 활성화되어 있는지(`cron.enabled`) 확인하고 `OPENCLAW_SKIP_CRON`이 설정되어 있지 않은지 확인합니다. + - Gateway가 24/7 실행 중인지 확인합니다(절전/재시작 없음). + - 작업의 시간대 설정을 확인합니다(`--tz`와 호스트 시간대). 디버그: @@ -265,20 +265,20 @@ x-i18n: openclaw cron runs --id --limit 50 ``` - 문서: [Cron jobs](/ko/automation/cron-jobs), [자동화 및 작업](/ko/automation). + 문서: [Cron 작업](/ko/automation/cron-jobs), [자동화 및 작업](/ko/automation). - - 먼저 전송 모드를 확인하세요. + + 먼저 전달 모드를 확인하세요. - - `--no-deliver` / `delivery.mode: "none"`은 runner fallback 전송이 예상되지 않는다는 뜻입니다. - - 알림 대상(`channel` / `to`)이 없거나 유효하지 않으면 runner가 아웃바운드 전송을 건너뜁니다. - - 채널 인증 실패(`unauthorized`, `Forbidden`)는 runner가 전송을 시도했지만 자격 증명에 의해 차단되었다는 뜻입니다. - - 무응답 격리 결과(`NO_REPLY` / `no_reply`만)는 의도적으로 전송할 수 없는 것으로 처리되므로 runner도 대기열의 fallback 전송을 억제합니다. + - `--no-deliver` / `delivery.mode: "none"`은 runner fallback 전송이 예상되지 않음을 의미합니다. + - announce 대상(`channel` / `to`)이 없거나 유효하지 않으면 runner가 outbound 전달을 건너뛰었다는 의미입니다. + - 채널 인증 실패(`unauthorized`, `Forbidden`)는 runner가 전달을 시도했지만 자격 증명에 의해 차단되었다는 의미입니다. + - 무음 격리 결과(`NO_REPLY` / `no_reply`만 해당)는 의도적으로 전달 불가로 처리되므로 runner도 대기 중인 fallback 전달을 억제합니다. - 격리된 cron 작업의 경우 채팅 경로를 사용할 수 있으면 agent가 여전히 `message` - tool로 직접 전송할 수 있습니다. `--announce`는 agent가 이미 전송하지 않은 + 격리된 cron 작업의 경우 채팅 경로를 사용할 수 있으면 agent가 `message` + 도구로 직접 전송할 수 있습니다. `--announce`는 agent가 이미 전송하지 않은 최종 텍스트에 대한 runner fallback 경로만 제어합니다. 디버그: @@ -288,17 +288,15 @@ x-i18n: openclaw tasks show ``` - 문서: [Cron 작업](/ko/automation/cron-jobs), [Background Tasks](/ko/automation/tasks). + 문서: [Cron 작업](/ko/automation/cron-jobs), [백그라운드 작업](/ko/automation/tasks). - 이는 보통 중복 예약이 아니라 라이브 모델 전환 경로입니다. + 이는 보통 중복 예약이 아니라 live 모델 전환 경로입니다. - 격리된 cron은 활성 실행에서 `LiveSessionModelSwitchError`가 발생할 때 - 런타임 모델 handoff를 유지하고 재시도할 수 있습니다. 재시도는 전환된 - provider/model을 유지하며, 전환에 새 auth profile override가 포함된 경우 cron은 - 재시도 전에 그것도 유지합니다. + 격리된 cron은 활성 실행에서 `LiveSessionModelSwitchError`가 발생하면 런타임 모델 인계를 유지하고 재시도할 수 있습니다. 재시도는 전환된 + provider/model을 유지하며, 전환에 새 인증 프로필 override가 포함되어 있으면 cron은 재시도 전에 그것도 유지합니다. 관련 선택 규칙: @@ -307,8 +305,8 @@ x-i18n: - 그다음 저장된 cron-session 모델 override. - 그다음 일반 agent/default 모델 선택. - 재시도 루프는 제한됩니다. 최초 시도에 더해 2번의 전환 재시도 후에는 - cron이 무한 루프 대신 중단합니다. + 재시도 루프에는 한계가 있습니다. 최초 시도와 2번의 전환 재시도 후에는 + cron이 영원히 반복하지 않고 중단합니다. 디버그: @@ -322,8 +320,8 @@ x-i18n: - 네이티브 `openclaw skills` 명령을 사용하거나 workspace에 Skills를 넣으세요. macOS Skills UI는 Linux에서 사용할 수 없습니다. - [https://clawhub.ai](https://clawhub.ai)에서 Skills를 둘러볼 수 있습니다. + 기본 `openclaw skills` 명령을 사용하거나 Skills를 workspace에 넣으세요. macOS Skills UI는 Linux에서 사용할 수 없습니다. + Skills는 [https://clawhub.ai](https://clawhub.ai)에서 찾아볼 수 있습니다. ```bash openclaw skills search "calendar" @@ -336,41 +334,40 @@ x-i18n: openclaw skills check ``` - 네이티브 `openclaw skills install`은 활성 workspace `skills/` - 디렉터리에 기록합니다. 자체 Skills를 게시하거나 동기화하려는 경우에만 별도의 `clawhub` CLI를 - 설치하세요. agent 간 공유 설치의 경우 skill을 + 기본 `openclaw skills install`은 활성 workspace의 `skills/` + 디렉터리에 기록합니다. 자체 Skills를 게시하거나 동기화하려는 경우에만 별도의 `clawhub` CLI를 설치하세요. 여러 agent에서 공유 설치를 사용하려면 skill을 `~/.openclaw/skills` 아래에 두고, 어떤 agent가 볼 수 있는지 제한하려면 `agents.defaults.skills` 또는 `agents.list[].skills`를 사용하세요. - - 예. Gateway scheduler를 사용하세요. + + 예. Gateway 스케줄러를 사용하세요. - - 예약되거나 반복되는 작업에는 **Cron 작업**을 사용합니다(재시작 후에도 유지). - - "메인 세션" 주기적 확인에는 **Heartbeat**를 사용합니다. - - 요약을 게시하거나 채팅으로 전달하는 autonomous agents에는 **격리된 작업**을 사용합니다. + - 예약 또는 반복 작업에는 **Cron 작업**을 사용합니다(재시작 후에도 유지). + - "main session" 주기적 점검에는 **Heartbeat**를 사용합니다. + - 요약을 게시하거나 채팅으로 전달하는 autonomous agent에는 **격리된 작업**을 사용합니다. - 문서: [Cron 작업](/ko/automation/cron-jobs), [Automation & Tasks](/ko/automation), + 문서: [Cron 작업](/ko/automation/cron-jobs), [자동화 및 작업](/ko/automation), [Heartbeat](/ko/gateway/heartbeat). - 직접적으로는 불가능합니다. macOS Skills는 `metadata.openclaw.os`와 필수 바이너리로 제한되며, Skills는 **Gateway host**에서 적격할 때만 system prompt에 표시됩니다. Linux에서는 gating을 override하지 않는 한 `darwin` 전용 Skills(예: `apple-notes`, `apple-reminders`, `things-mac`)가 로드되지 않습니다. + 직접적으로는 불가능합니다. macOS Skills는 `metadata.openclaw.os`와 필요한 바이너리로 제한되며, Skills는 **Gateway host**에서 적격할 때만 system prompt에 표시됩니다. Linux에서는 gating을 override하지 않는 한 `darwin` 전용 Skills(`apple-notes`, `apple-reminders`, `things-mac` 등)가 로드되지 않습니다. 지원되는 패턴은 세 가지입니다. **옵션 A - Mac에서 Gateway 실행(가장 간단).** macOS 바이너리가 있는 곳에서 Gateway를 실행한 다음, Linux에서 [remote mode](#gateway-ports-already-running-and-remote-mode) 또는 Tailscale을 통해 연결하세요. Gateway host가 macOS이므로 Skills가 정상적으로 로드됩니다. - **옵션 B - macOS node 사용(SSH 없음).** - Linux에서 Gateway를 실행하고 macOS node(메뉴바 앱)를 페어링한 뒤, Mac에서 **Node Run Commands**를 "Always Ask" 또는 "Always Allow"로 설정하세요. 필수 바이너리가 node에 있으면 OpenClaw는 macOS 전용 Skills를 적격한 것으로 처리할 수 있습니다. agent는 `nodes` tool을 통해 해당 Skills를 실행합니다. "Always Ask"를 선택한 경우 prompt에서 "Always Allow"를 승인하면 해당 명령이 허용 목록에 추가됩니다. + **옵션 B - macOS Node 사용(SSH 없음).** + Linux에서 Gateway를 실행하고, macOS Node(menubar 앱)를 페어링한 뒤 Mac에서 **Node Run Commands**를 "Always Ask" 또는 "Always Allow"로 설정하세요. OpenClaw는 필요한 바이너리가 Node에 있으면 macOS 전용 Skills를 적격한 것으로 처리할 수 있습니다. agent는 `nodes` 도구를 통해 해당 Skills를 실행합니다. "Always Ask"를 선택한 경우 prompt에서 "Always Allow"를 승인하면 해당 명령이 allowlist에 추가됩니다. **옵션 C - SSH를 통해 macOS 바이너리 프록시(고급).** - Gateway는 Linux에 유지하되, 필수 CLI 바이너리가 Mac에서 실행되는 SSH wrapper로 해석되도록 만드세요. 그런 다음 skill이 계속 적격하도록 Linux를 허용하게 override하세요. + Gateway는 Linux에 유지하되, 필요한 CLI 바이너리가 Mac에서 실행되는 SSH wrapper로 resolve되도록 만드세요. 그런 다음 skill을 override하여 Linux를 허용하면 계속 적격 상태로 유지됩니다. - 1. 바이너리에 대한 SSH wrapper를 만듭니다(예: Apple Notes용 `memo`). + 1. 바이너리에 대한 SSH wrapper를 생성합니다(예: Apple Notes용 `memo`). ```bash #!/usr/bin/env bash @@ -378,7 +375,7 @@ x-i18n: exec ssh -T user@mac-host /opt/homebrew/bin/memo "$@" ``` - 2. Linux host의 `PATH`에 wrapper를 두세요(예: `~/bin/memo`). + 2. Linux host의 `PATH`에 wrapper를 둡니다(예: `~/bin/memo`). 3. Linux를 허용하도록 skill metadata(workspace 또는 `~/.openclaw/skills`)를 override합니다. ```markdown @@ -389,25 +386,25 @@ x-i18n: --- ``` - 4. Skills snapshot이 새로고침되도록 새 세션을 시작하세요. + 4. Skills snapshot이 새로고침되도록 새 session을 시작합니다. - 현재 기본 제공되지는 않습니다. + 현재는 기본 제공되지 않습니다. 옵션: - - **Custom skill / Plugin:** 안정적인 API 접근에 가장 적합합니다(Notion/HeyGen 모두 API가 있음). - - **브라우저 자동화:** 코드 없이 동작하지만 더 느리고 취약합니다. + - **사용자 지정 skill / Plugin:** 안정적인 API 접근에 가장 적합합니다(Notion/HeyGen은 둘 다 API가 있습니다). + - **브라우저 자동화:** 코드 없이 작동하지만 더 느리고 취약합니다. - 클라이언트별로 컨텍스트를 유지하려는 경우(에이전시 워크플로), 간단한 패턴은 다음과 같습니다. + 클라이언트별로 context를 유지하려는 경우(에이전시 workflow), 간단한 패턴은 다음과 같습니다. - - 클라이언트마다 Notion 페이지 하나(컨텍스트 + 선호도 + 활성 작업). - - 세션 시작 시 agent에게 해당 페이지를 가져오도록 요청합니다. + - 클라이언트마다 Notion 페이지 하나(context + preferences + active work). + - session 시작 시 agent에게 해당 페이지를 가져오도록 요청합니다. - 네이티브 통합을 원한다면 기능 요청을 열거나 - 해당 API를 대상으로 하는 skill을 빌드하세요. + native integration을 원한다면 feature request를 열거나 해당 API를 대상으로 하는 skill을 + 빌드하세요. Skills 설치: @@ -416,32 +413,32 @@ x-i18n: openclaw skills update --all ``` - 네이티브 설치는 활성 workspace `skills/` 디렉터리에 위치합니다. agent 간 공유 Skills의 경우 `~/.openclaw/skills//SKILL.md`에 두세요. 일부 agent만 공유 설치를 볼 수 있어야 한다면 `agents.defaults.skills` 또는 `agents.list[].skills`를 구성하세요. 일부 Skills는 Homebrew로 설치한 바이너리를 기대합니다. Linux에서는 Linuxbrew를 의미합니다(위의 Homebrew Linux FAQ 항목 참조). [Skills](/ko/tools/skills), [Skills 구성](/ko/tools/skills-config), [ClawHub](/ko/tools/clawhub)을 참조하세요. + 기본 설치는 활성 workspace의 `skills/` 디렉터리에 저장됩니다. agent 간 공유 Skills의 경우 `~/.openclaw/skills//SKILL.md`에 배치하세요. 일부 agent만 공유 설치를 볼 수 있어야 한다면 `agents.defaults.skills` 또는 `agents.list[].skills`를 구성하세요. 일부 Skills는 Homebrew로 설치된 바이너리를 기대합니다. Linux에서는 Linuxbrew를 의미합니다(위의 Homebrew Linux FAQ 항목 참조). [Skills](/ko/tools/skills), [Skills 설정](/ko/tools/skills-config), [ClawHub](/ko/tools/clawhub)를 참조하세요. - - Chrome DevTools MCP를 통해 연결되는 기본 제공 `user` 브라우저 프로필을 사용하세요. + + Chrome DevTools MCP를 통해 연결되는 내장 `user` 브라우저 프로필을 사용하세요. ```bash openclaw browser --browser-profile user tabs openclaw browser --browser-profile user snapshot ``` - 사용자 지정 이름을 원하면 명시적 MCP 프로필을 만드세요. + 사용자 지정 이름을 원하면 명시적인 MCP 프로필을 생성하세요. ```bash openclaw browser create-profile --name chrome-live --driver existing-session openclaw browser --browser-profile chrome-live tabs ``` - 이 경로는 로컬 host 브라우저 또는 연결된 브라우저 node를 사용할 수 있습니다. Gateway가 다른 곳에서 실행 중이면 브라우저 머신에서 node host를 실행하거나 remote CDP를 대신 사용하세요. + 이 경로는 local host 브라우저 또는 연결된 browser node를 사용할 수 있습니다. Gateway가 다른 곳에서 실행 중이면 브라우저 머신에서 node host를 실행하거나 대신 remote CDP를 사용하세요. `existing-session` / `user`의 현재 제한: - - actions는 CSS-selector 기반이 아니라 ref 기반입니다 - - 업로드에는 `ref` / `inputRef`가 필요하며 현재 한 번에 파일 하나를 지원합니다 - - `responsebody`, PDF 내보내기, 다운로드 가로채기, batch actions에는 여전히 managed browser 또는 raw CDP profile이 필요합니다 + - actions는 CSS-selector 기반이 아니라 ref 기반입니다. + - uploads에는 `ref` / `inputRef`가 필요하며 현재 한 번에 파일 하나만 지원합니다. + - `responsebody`, PDF export, download interception, batch actions에는 여전히 managed browser 또는 raw CDP profile이 필요합니다. @@ -450,38 +447,38 @@ x-i18n: - 예. [샌드박싱](/ko/gateway/sandboxing)을 참조하세요. Docker별 설정(전체 gateway를 Docker에서 실행하거나 sandbox images 사용)은 [Docker](/ko/install/docker)를 참조하세요. + 예. [샌드박싱](/ko/gateway/sandboxing)을 참조하세요. Docker 관련 설정(Docker 내 전체 Gateway 또는 sandbox image)은 [Docker](/ko/install/docker)를 참조하세요. 기본 이미지는 보안을 우선하며 `node` 사용자로 실행되므로 - system packages, Homebrew, bundled browsers를 포함하지 않습니다. 더 완전한 설정을 하려면: + 시스템 package, Homebrew 또는 bundled browser를 포함하지 않습니다. 더 완전한 설정을 위해서는: - - 캐시가 유지되도록 `OPENCLAW_HOME_VOLUME`로 `/home/node`를 유지합니다. - - `OPENCLAW_DOCKER_APT_PACKAGES`로 system deps를 이미지에 bake합니다. - - 번들 CLI로 Playwright browsers를 설치합니다: + - cache가 유지되도록 `OPENCLAW_HOME_VOLUME`으로 `/home/node`를 persist합니다. + - `OPENCLAW_DOCKER_APT_PACKAGES`로 system deps를 image에 bake합니다. + - bundled CLI를 통해 Playwright browser를 설치합니다: `node /app/node_modules/playwright-core/cli.js install chromium` - - `PLAYWRIGHT_BROWSERS_PATH`를 설정하고 해당 경로가 유지되는지 확인합니다. + - `PLAYWRIGHT_BROWSERS_PATH`를 설정하고 해당 경로가 persist되는지 확인합니다. 문서: [Docker](/ko/install/docker), [브라우저](/ko/tools/browser). - 예. 비공개 트래픽이 **DM**이고 공개 트래픽이 **그룹**인 경우 가능합니다. + 예. private traffic이 **DM**이고 public traffic이 **groups**인 경우 가능합니다. - `agents.defaults.sandbox.mode: "non-main"`을 사용하면 그룹/채널 세션(non-main keys)은 구성된 sandbox backend에서 실행되고, 메인 DM 세션은 on-host에 유지됩니다. backend를 선택하지 않으면 Docker가 기본값입니다. 그런 다음 `tools.sandbox.tools`를 통해 sandboxed sessions에서 사용할 수 있는 tool을 제한하세요. + `agents.defaults.sandbox.mode: "non-main"`을 사용하면 group/channel session(non-main key)은 구성된 sandbox backend에서 실행되고, main DM session은 on-host에 유지됩니다. backend를 선택하지 않으면 Docker가 기본값입니다. 그런 다음 `tools.sandbox.tools`를 통해 sandboxed session에서 사용할 수 있는 도구를 제한하세요. - 설정 안내 + 예시 구성: [그룹: 개인 DM + 공개 그룹](/ko/channels/groups#pattern-personal-dms-public-groups-single-agent) + 설정 walkthrough + 예시 config: [그룹: 개인 DM + 공개 그룹](/ko/channels/groups#pattern-personal-dms-public-groups-single-agent) - 주요 구성 참조: [Gateway 구성](/ko/gateway/config-agents#agentsdefaultssandbox) + 주요 config reference: [Gateway 구성](/ko/gateway/config-agents#agentsdefaultssandbox) - - `agents.defaults.sandbox.docker.binds`를 `["host:path:mode"]`로 설정하세요(예: `"/home/user/src:/src:ro"`). 전역 bind와 agent별 bind는 병합됩니다. `scope: "shared"`일 때는 agent별 bind가 무시됩니다. 민감한 항목에는 `:ro`를 사용하고, bind는 sandbox 파일 시스템 벽을 우회한다는 점을 기억하세요. + + `agents.defaults.sandbox.docker.binds`를 `["host:path:mode"]`로 설정하세요(예: `"/home/user/src:/src:ro"`). global + per-agent binds는 merge됩니다. `scope: "shared"`일 때는 per-agent binds가 무시됩니다. 민감한 항목에는 `:ro`를 사용하고, binds는 sandbox filesystem walls를 우회한다는 점을 기억하세요. - OpenClaw는 bind source를 정규화된 경로와 가장 깊이 존재하는 ancestor를 통해 확인된 canonical path 모두에 대해 검증합니다. 즉, 마지막 path segment가 아직 존재하지 않더라도 symlink-parent escape는 여전히 안전하게 실패하며, symlink resolution 후에도 allowed-root checks가 계속 적용됩니다. + OpenClaw는 정규화된 경로와 가장 깊이 존재하는 ancestor를 통해 resolve된 canonical path 둘 다에 대해 bind sources를 검증합니다. 즉, 마지막 path segment가 아직 존재하지 않더라도 symlink-parent escape는 fail closed되며, symlink resolution 후에도 allowed-root checks가 계속 적용됩니다. 예시와 안전 참고 사항은 [샌드박싱](/ko/gateway/sandboxing#custom-bind-mounts) 및 [Sandbox vs Tool Policy vs Elevated](/ko/gateway/sandbox-vs-tool-policy-vs-elevated#bind-mounts-security-quick-check)를 참조하세요. @@ -490,108 +487,106 @@ x-i18n: OpenClaw 메모리는 agent workspace의 Markdown 파일일 뿐입니다. - - 일일 노트는 `memory/YYYY-MM-DD.md` - - 큐레이션된 장기 노트는 `MEMORY.md`에 있습니다(main/private sessions만 해당) + - `memory/YYYY-MM-DD.md`의 daily notes + - `MEMORY.md`의 curated long-term notes(main/private sessions만 해당) - OpenClaw는 auto-compaction 전에 모델이 durable notes를 작성하도록 상기시키기 위해 - **silent pre-compaction memory flush**도 실행합니다. 이는 workspace가 - 쓰기 가능한 경우에만 실행됩니다(read-only sandboxes는 건너뜀). [Memory](/ko/concepts/memory)를 참조하세요. + OpenClaw는 auto-compaction 전에 durable notes를 작성하라고 모델에 알리기 위해 **무음 pre-compaction memory flush**도 실행합니다. 이는 workspace가 쓰기 가능한 경우에만 실행됩니다(read-only sandboxes는 건너뜁니다). [메모리](/ko/concepts/memory)를 참조하세요. - - 봇에게 **사실을 메모리에 쓰라**고 요청하세요. 장기 노트는 `MEMORY.md`에, - 단기 컨텍스트는 `memory/YYYY-MM-DD.md`에 들어갑니다. + + 봇에게 **해당 사실을 memory에 쓰도록** 요청하세요. long-term notes는 `MEMORY.md`에, + short-term context는 `memory/YYYY-MM-DD.md`에 넣습니다. - 이는 아직 개선 중인 영역입니다. 모델에게 메모리를 저장하라고 상기시키면 도움이 됩니다. + 이는 아직 개선 중인 영역입니다. 모델에게 memories를 저장하라고 상기시키면 도움이 됩니다. 모델은 무엇을 해야 하는지 알 것입니다. 계속 잊어버린다면 Gateway가 모든 실행에서 동일한 workspace를 사용하고 있는지 확인하세요. - 문서: [Memory](/ko/concepts/memory), [Agent workspace](/ko/concepts/agent-workspace). + 문서: [메모리](/ko/concepts/memory), [Agent workspace](/ko/concepts/agent-workspace). - - 메모리 파일은 디스크에 있으며 삭제할 때까지 유지됩니다. 한계는 모델이 아니라 - 저장 공간입니다. **session context**는 여전히 모델 context window의 제한을 받으므로 - 긴 대화는 compact되거나 truncate될 수 있습니다. 이것이 memory search가 존재하는 이유입니다. 관련 부분만 context로 다시 가져옵니다. + + 메모리 파일은 디스크에 있으며 삭제할 때까지 유지됩니다. 제한은 모델이 아니라 + 스토리지입니다. **session context**는 여전히 모델 context window의 제한을 받으므로 긴 대화는 compact되거나 truncate될 수 있습니다. 그래서 + memory search가 존재합니다. 관련 부분만 context로 다시 가져옵니다. - 문서: [Memory](/ko/concepts/memory), [Context](/ko/concepts/context). + 문서: [메모리](/ko/concepts/memory), [Context](/ko/concepts/context). - - **OpenAI embeddings**를 사용하는 경우에만 필요합니다. Codex OAuth는 채팅/완성을 지원하지만 - embeddings 접근 권한은 **부여하지 않으므로**, **Codex로 로그인(OAuth 또는 - Codex CLI 로그인)**해도 시맨틱 메모리 검색에는 도움이 되지 않습니다. OpenAI embeddings에는 + + **OpenAI 임베딩**을 사용하는 경우에만 필요합니다. Codex OAuth는 채팅/완성을 처리하며 + 임베딩 접근 권한을 부여하지 **않으므로**, **Codex(OAuth 또는 + Codex CLI 로그인)로 로그인**해도 시맨틱 메모리 검색에는 도움이 되지 않습니다. OpenAI 임베딩에는 여전히 실제 API 키(`OPENAI_API_KEY` 또는 `models.providers.openai.apiKey`)가 필요합니다. - 제공자를 명시적으로 설정하지 않으면, OpenClaw는 API 키(인증 프로필, - `models.providers.*.apiKey`, 또는 환경 변수)를 확인할 수 있을 때 제공자를 자동으로 선택합니다. - OpenAI 키가 확인되면 OpenAI를 우선 사용하고, 그렇지 않으면 Gemini 키가 - 확인될 때 Gemini를 사용한 다음 Voyage, Mistral 순으로 사용합니다. 원격 키가 없으면 + 제공자를 명시적으로 설정하지 않으면, OpenClaw는 API 키(인증 프로필, `models.providers.*.apiKey`, 또는 env vars)를 + 해석할 수 있을 때 제공자를 자동 선택합니다. + OpenAI 키가 해석되면 OpenAI를 우선 사용하고, 그렇지 않으면 Gemini 키가 + 해석될 때 Gemini, 그다음 Voyage, 그다음 Mistral 순으로 사용합니다. 원격 키를 사용할 수 없으면, 메모리 검색은 구성할 때까지 비활성화된 상태로 유지됩니다. 로컬 모델 경로가 구성되어 있고 존재하면 OpenClaw는 `local`을 우선 사용합니다. Ollama는 - `memorySearch.provider = "ollama"`를 명시적으로 설정하면 지원됩니다. + `memorySearch.provider = "ollama"`를 명시적으로 설정할 때 지원됩니다. - 로컬로만 유지하려면 `memorySearch.provider = "local"`을 설정하세요(선택적으로 - `memorySearch.fallback = "none"`도 설정). Gemini embeddings를 원하면 + 로컬로 유지하고 싶다면 `memorySearch.provider = "local"`을 설정하세요(선택적으로 + `memorySearch.fallback = "none"`도 설정). Gemini 임베딩을 원한다면 `memorySearch.provider = "gemini"`를 설정하고 `GEMINI_API_KEY`(또는 - `memorySearch.remote.apiKey`)를 제공하세요. **OpenAI, Gemini, Voyage, Mistral, Ollama 또는 local** embedding - 모델을 지원합니다. 설정 세부 정보는 [메모리](/ko/concepts/memory)를 참조하세요. + `memorySearch.remote.apiKey`)를 제공하세요. **OpenAI, Gemini, Voyage, Mistral, Ollama 또는 로컬** 임베딩 + 모델을 지원합니다. 설정 세부 정보는 [메모리](/ko/concepts/memory)를 참고하세요. -## 디스크에서 항목이 저장되는 위치 +## 디스크에서 항목이 있는 위치 - - 아니요. **OpenClaw의 상태는 로컬에 있지만**, **외부 서비스는 여전히 사용자가 보내는 내용을 볼 수 있습니다**. + + 아니요. **OpenClaw의 상태는 로컬**이지만, **외부 서비스는 여전히 사용자가 보내는 내용을 볼 수 있습니다**. - - **기본적으로 로컬:** 세션, 메모리 파일, 구성, 워크스페이스는 Gateway 호스트에 있습니다 - (`~/.openclaw` + 사용자의 워크스페이스 디렉터리). + - **기본적으로 로컬:** 세션, 메모리 파일, 구성, 워크스페이스는 Gateway 호스트 + (`~/.openclaw` + 사용자의 워크스페이스 디렉터리)에 있습니다. - **필요에 따라 원격:** 모델 제공자(Anthropic/OpenAI 등)에 보내는 메시지는 해당 API로 전송되고, 채팅 플랫폼(WhatsApp/Telegram/Slack 등)은 메시지 데이터를 - 해당 서버에 저장합니다. - - **사용자가 범위를 제어:** 로컬 모델을 사용하면 프롬프트가 사용자 머신에 남지만, 채널 - 트래픽은 여전히 채널 서버를 거칩니다. + 자체 서버에 저장합니다. + - **범위는 사용자가 제어:** 로컬 모델을 사용하면 프롬프트가 사용자의 머신에 남지만, 채널 + 트래픽은 여전히 해당 채널의 서버를 통과합니다. 관련 항목: [Agent workspace](/ko/concepts/agent-workspace), [메모리](/ko/concepts/memory). - 모든 항목은 `$OPENCLAW_STATE_DIR` 아래에 있습니다(기본값: `~/.openclaw`). + 모든 것은 `$OPENCLAW_STATE_DIR` 아래에 있습니다(기본값: `~/.openclaw`): | 경로 | 목적 | | --------------------------------------------------------------- | ------------------------------------------------------------------ | | `$OPENCLAW_STATE_DIR/openclaw.json` | 기본 구성(JSON5) | - | `$OPENCLAW_STATE_DIR/credentials/oauth.json` | 기존 OAuth 가져오기(처음 사용할 때 인증 프로필로 복사됨) | + | `$OPENCLAW_STATE_DIR/credentials/oauth.json` | 레거시 OAuth 가져오기(처음 사용할 때 인증 프로필로 복사됨) | | `$OPENCLAW_STATE_DIR/agents//agent/auth-profiles.json` | 인증 프로필(OAuth, API 키, 선택적 `keyRef`/`tokenRef`) | - | `$OPENCLAW_STATE_DIR/secrets.json` | `file` SecretRef 제공자를 위한 선택적 파일 기반 secret 페이로드 | - | `$OPENCLAW_STATE_DIR/agents//agent/auth.json` | 기존 호환성 파일(정적 `api_key` 항목 제거됨) | + | `$OPENCLAW_STATE_DIR/secrets.json` | `file` SecretRef 제공자를 위한 선택적 파일 기반 비밀 페이로드 | + | `$OPENCLAW_STATE_DIR/agents//agent/auth.json` | 레거시 호환성 파일(정적 `api_key` 항목은 제거됨) | | `$OPENCLAW_STATE_DIR/credentials/` | 제공자 상태(예: `whatsapp//creds.json`) | | `$OPENCLAW_STATE_DIR/agents/` | 에이전트별 상태(agentDir + 세션) | | `$OPENCLAW_STATE_DIR/agents//sessions/` | 대화 기록 및 상태(에이전트별) | | `$OPENCLAW_STATE_DIR/agents//sessions/sessions.json` | 세션 메타데이터(에이전트별) | - 기존 단일 에이전트 경로: `~/.openclaw/agent/*`(`openclaw doctor`로 마이그레이션됨). + 레거시 단일 에이전트 경로: `~/.openclaw/agent/*`(`openclaw doctor`로 마이그레이션됨). - 사용자의 **워크스페이스**(AGENTS.md, 메모리 파일, skills 등)는 별도이며 `agents.defaults.workspace`로 구성됩니다(기본값: `~/.openclaw/workspace`). + 사용자의 **워크스페이스**(AGENTS.md, 메모리 파일, Skills 등)는 별도이며 `agents.defaults.workspace`를 통해 구성됩니다(기본값: `~/.openclaw/workspace`). - 이 파일들은 `~/.openclaw`가 아니라 **에이전트 워크스페이스**에 있습니다. + 이러한 파일은 `~/.openclaw`가 아니라 **에이전트 워크스페이스**에 있습니다. - **워크스페이스(에이전트별)**: `AGENTS.md`, `SOUL.md`, `IDENTITY.md`, `USER.md`, `MEMORY.md`, `memory/YYYY-MM-DD.md`, 선택적 `HEARTBEAT.md`. - 루트의 소문자 `memory.md`는 기존 복구 입력 전용입니다. 두 파일이 모두 있으면 `openclaw doctor --fix`가 + 루트의 소문자 `memory.md`는 레거시 복구 입력 전용입니다. 두 파일이 모두 있을 때 `openclaw doctor --fix`가 이를 `MEMORY.md`로 병합할 수 있습니다. - **상태 디렉터리(`~/.openclaw`)**: 구성, 채널/제공자 상태, 인증 프로필, 세션, 로그, - 공유 skills(`~/.openclaw/skills`). + 공유 Skills(`~/.openclaw/skills`). 기본 워크스페이스는 `~/.openclaw/workspace`이며, 다음으로 구성할 수 있습니다. @@ -601,42 +596,42 @@ x-i18n: } ``` - 재시작 후 봇이 "잊어버리는" 경우, Gateway가 시작될 때마다 동일한 - 워크스페이스를 사용하는지 확인하세요(그리고 원격 모드는 사용자의 로컬 노트북이 아니라 **gateway 호스트의** - 워크스페이스를 사용한다는 점을 기억하세요). + 재시작 후 봇이 "잊어버린" 것 같다면, Gateway가 매번 실행될 때 동일한 + 워크스페이스를 사용하고 있는지 확인하세요(그리고 기억하세요: 원격 모드는 사용자의 로컬 노트북이 아니라 **gateway 호스트의** + 워크스페이스를 사용합니다). - 팁: 지속적인 동작이나 선호 사항을 원한다면 채팅 기록에 의존하지 말고 봇에게 이를 **AGENTS.md 또는 MEMORY.md에 - 쓰도록** 요청하세요. + 팁: 오래 유지해야 하는 동작이나 선호가 있다면, 채팅 기록에 의존하지 말고 봇에게 이를 + **AGENTS.md 또는 MEMORY.md에 작성**하라고 요청하세요. - [Agent workspace](/ko/concepts/agent-workspace)와 [메모리](/ko/concepts/memory)를 참조하세요. + [Agent workspace](/ko/concepts/agent-workspace) 및 [메모리](/ko/concepts/memory)를 참고하세요. - **에이전트 워크스페이스**를 **비공개** git 저장소에 두고, 비공개 위치(예: GitHub private)에 + **에이전트 워크스페이스**를 **비공개** git 저장소에 넣고, 비공개 위치(예: GitHub 비공개)에 백업하세요. 이렇게 하면 메모리 + AGENTS/SOUL/USER - 파일을 보존하고 나중에 어시스턴트의 "마음"을 복원할 수 있습니다. + 파일을 보존하고, 나중에 어시스턴트의 "마음"을 복원할 수 있습니다. - `~/.openclaw` 아래의 항목(자격 증명, 세션, 토큰, 암호화된 secrets 페이로드)은 **커밋하지 마세요**. - 전체 복원이 필요하면 워크스페이스와 상태 디렉터리를 - 별도로 백업하세요(위의 마이그레이션 질문 참조). + `~/.openclaw` 아래의 항목(자격 증명, 세션, 토큰 또는 암호화된 비밀 페이로드)은 **커밋하지 마세요**. + 전체 복원이 필요하다면 워크스페이스와 상태 디렉터리를 + 별도로 모두 백업하세요(위의 마이그레이션 질문 참고). 문서: [Agent workspace](/ko/concepts/agent-workspace). - 전용 가이드를 참조하세요: [제거](/ko/install/uninstall). + 전용 가이드를 참고하세요: [제거](/ko/install/uninstall). - 예. 워크스페이스는 **기본 cwd**이자 메모리 기준점이지, 강제 sandbox가 아닙니다. - 상대 경로는 워크스페이스 안에서 해석되지만, sandboxing이 활성화되어 있지 않으면 절대 경로로 다른 - 호스트 위치에 접근할 수 있습니다. 격리가 필요하면 - [`agents.defaults.sandbox`](/ko/gateway/sandboxing) 또는 에이전트별 sandbox 설정을 사용하세요. 저장소를 + 예. 워크스페이스는 **기본 cwd**이자 메모리 기준점이지, 엄격한 샌드박스가 아닙니다. + 상대 경로는 워크스페이스 안에서 해석되지만, 샌드박싱이 활성화되어 있지 않으면 절대 경로로 다른 + 호스트 위치에 접근할 수 있습니다. 격리가 필요하다면 + [`agents.defaults.sandbox`](/ko/gateway/sandboxing) 또는 에이전트별 샌드박스 설정을 사용하세요. 저장소를 기본 작업 디렉터리로 사용하려면 해당 에이전트의 - `workspace`를 저장소 루트로 지정하세요. OpenClaw 저장소는 소스 코드일 뿐입니다. 에이전트가 그 안에서 작업하길 의도한 경우가 아니라면 - 워크스페이스를 별도로 유지하세요. + `workspace`를 저장소 루트로 지정하세요. OpenClaw 저장소는 소스 코드일 뿐입니다. 의도적으로 에이전트가 그 안에서 작업하게 하려는 경우가 아니라면 + 워크스페이스는 별도로 유지하세요. 예시(저장소를 기본 cwd로 사용): @@ -653,7 +648,7 @@ x-i18n: - 세션 상태는 **gateway 호스트**가 소유합니다. 원격 모드라면 사용자가 신경 써야 할 세션 저장소는 로컬 노트북이 아니라 원격 머신에 있습니다. [세션 관리](/ko/concepts/session)를 참조하세요. + 세션 상태는 **gateway 호스트**가 소유합니다. 원격 모드에 있다면, 신경 써야 할 세션 저장소는 사용자의 로컬 노트북이 아니라 원격 머신에 있습니다. [세션 관리](/ko/concepts/session)를 참고하세요. @@ -667,15 +662,15 @@ x-i18n: $OPENCLAW_CONFIG_PATH ``` - 파일이 없으면 안전한 편인 기본값(`~/.openclaw/workspace`의 기본 워크스페이스 포함)을 사용합니다. + 파일이 없으면 안전에 가까운 기본값(`~/.openclaw/workspace`의 기본 워크스페이스 포함)을 사용합니다. - non-loopback 바인드는 **유효한 gateway 인증 경로가 필요합니다**. 실제로는 다음을 의미합니다. + 비-loopback 바인드는 **유효한 gateway 인증 경로가 필요합니다**. 실제로는 다음을 의미합니다. - - 공유 secret 인증: 토큰 또는 비밀번호 - - 올바르게 구성된 identity-aware reverse proxy 뒤의 `gateway.auth.mode: "trusted-proxy"` + - 공유 비밀 인증: 토큰 또는 비밀번호 + - 올바르게 구성된 ID 인식 리버스 프록시 뒤의 `gateway.auth.mode: "trusted-proxy"` ```json5 { @@ -691,31 +686,31 @@ x-i18n: 참고: - - `gateway.remote.token` / `.password`는 그 자체로 local gateway 인증을 활성화하지 않습니다. - - 로컬 호출 경로는 `gateway.auth.*`가 설정되지 않은 경우에만 `gateway.remote.*`를 fallback으로 사용할 수 있습니다. + - `gateway.remote.token` / `.password` 자체만으로는 로컬 gateway 인증이 활성화되지 않습니다. + - 로컬 호출 경로는 `gateway.auth.*`가 설정되지 않은 경우에만 `gateway.remote.*`를 대체값으로 사용할 수 있습니다. - 비밀번호 인증의 경우 대신 `gateway.auth.mode: "password"`와 `gateway.auth.password`(또는 `OPENCLAW_GATEWAY_PASSWORD`)를 설정하세요. - - `gateway.auth.token` / `gateway.auth.password`가 SecretRef로 명시적으로 구성되어 있고 확인되지 않으면, 확인은 닫힌 상태로 실패합니다(원격 fallback이 가리지 않음). - - 공유 secret Control UI 설정은 `connect.params.auth.token` 또는 `connect.params.auth.password`(앱/UI 설정에 저장됨)로 인증합니다. Tailscale Serve 또는 `trusted-proxy` 같은 identity-bearing 모드는 대신 요청 헤더를 사용합니다. URL에 공유 secrets를 넣지 마세요. - - `gateway.auth.mode: "trusted-proxy"`에서 같은 호스트의 loopback reverse proxy는 명시적인 `gateway.auth.trustedProxy.allowLoopback = true`와 `gateway.trustedProxies`의 loopback 항목이 필요합니다. + - `gateway.auth.token` / `gateway.auth.password`가 SecretRef를 통해 명시적으로 구성되어 있고 해석되지 않으면, 해석은 닫힌 상태로 실패합니다(원격 대체값으로 가려지지 않음). + - 공유 비밀 Control UI 설정은 `connect.params.auth.token` 또는 `connect.params.auth.password`(앱/UI 설정에 저장됨)를 통해 인증합니다. Tailscale Serve 또는 `trusted-proxy` 같은 ID 포함 모드는 대신 요청 헤더를 사용합니다. 공유 비밀을 URL에 넣지 마세요. + - `gateway.auth.mode: "trusted-proxy"`에서는 동일 호스트 loopback 리버스 프록시에 명시적인 `gateway.auth.trustedProxy.allowLoopback = true`와 `gateway.trustedProxies`의 loopback 항목이 필요합니다. - - OpenClaw는 loopback을 포함해 기본적으로 gateway 인증을 강제합니다. 일반적인 기본 경로에서는 토큰 인증을 의미합니다. 명시적인 인증 경로가 구성되어 있지 않으면 gateway 시작 시 토큰 모드로 해석되고 토큰을 자동 생성해 `gateway.auth.token`에 저장하므로 **로컬 WS 클라이언트도 인증해야 합니다**. 이렇게 하면 다른 로컬 프로세스가 Gateway를 호출하지 못하게 됩니다. + + OpenClaw는 loopback을 포함해 기본적으로 gateway 인증을 강제합니다. 일반적인 기본 경로에서는 토큰 인증을 의미합니다. 명시적 인증 경로가 구성되어 있지 않으면, gateway 시작 시 토큰 모드로 해석되고 해당 시작에만 유효한 런타임 전용 토큰을 생성하므로 **로컬 WS 클라이언트도 인증해야 합니다**. 클라이언트가 재시작 사이에도 안정적인 비밀을 필요로 한다면 `gateway.auth.token`, `gateway.auth.password`, `OPENCLAW_GATEWAY_TOKEN` 또는 `OPENCLAW_GATEWAY_PASSWORD`를 명시적으로 구성하세요. 이렇게 하면 다른 로컬 프로세스가 Gateway를 호출하지 못하게 됩니다. - 다른 인증 경로를 선호한다면 비밀번호 모드를 명시적으로 선택할 수 있습니다(또는 identity-aware reverse proxy의 경우 `trusted-proxy`). **정말로** open loopback을 원한다면 구성에서 `gateway.auth.mode: "none"`을 명시적으로 설정하세요. Doctor는 언제든지 토큰을 생성할 수 있습니다: `openclaw doctor --generate-gateway-token`. + 다른 인증 경로를 선호한다면 비밀번호 모드(또는 ID 인식 리버스 프록시의 경우 `trusted-proxy`)를 명시적으로 선택할 수 있습니다. **정말로** 열린 loopback을 원한다면 구성에서 `gateway.auth.mode: "none"`을 명시적으로 설정하세요. Doctor는 언제든지 토큰을 생성할 수 있습니다: `openclaw doctor --generate-gateway-token`. - - Gateway는 구성을 감시하고 hot-reload를 지원합니다. + + Gateway는 구성을 감시하고 핫 리로드를 지원합니다. - - `gateway.reload.mode: "hybrid"`(기본값): 안전한 변경은 hot-apply하고, 중요한 변경은 재시작 - - `hot`, `restart`, `off`도 지원됩니다 + - `gateway.reload.mode: "hybrid"`(기본값): 안전한 변경은 핫 적용하고, 중요한 변경은 재시작 + - `hot`, `restart`, `off`도 지원됩니다. - + 구성에서 `cli.banner.taglineMode`를 설정하세요. ```json5 @@ -728,10 +723,10 @@ x-i18n: } ``` - - `off`: tagline 텍스트를 숨기지만 배너 제목/버전 줄은 유지합니다. + - `off`: 태그라인 텍스트는 숨기지만 배너 제목/버전 줄은 유지합니다. - `default`: 매번 `All your chats, one OpenClaw.`를 사용합니다. - - `random`: 재미있거나 계절성 있는 tagline을 순환 표시합니다(기본 동작). - - 배너를 아예 원하지 않으면 env `OPENCLAW_HIDE_BANNER=1`을 설정하세요. + - `random`: 재미있거나 계절성 있는 태그라인을 순환 표시합니다(기본 동작). + - 배너를 전혀 표시하지 않으려면 env `OPENCLAW_HIDE_BANNER=1`을 설정하세요. @@ -740,12 +735,12 @@ x-i18n: 제공자에 따라 달라집니다. - Brave, Exa, Firecrawl, Gemini, Grok, Kimi, MiniMax Search, Perplexity, Tavily 같은 API 기반 제공자는 일반적인 API 키 설정이 필요합니다. - - Ollama Web Search는 키가 필요 없지만, 구성된 Ollama 호스트를 사용하고 `ollama signin`이 필요합니다. + - Ollama Web Search는 키가 필요 없지만, 구성된 Ollama 호스트를 사용하며 `ollama signin`이 필요합니다. - DuckDuckGo는 키가 필요 없지만, 비공식 HTML 기반 통합입니다. - - SearXNG는 키가 필요 없거나 self-hosted입니다. `SEARXNG_BASE_URL` 또는 `plugins.entries.searxng.config.webSearch.baseUrl`을 구성하세요. + - SearXNG는 키가 필요 없고 자체 호스팅됩니다. `SEARXNG_BASE_URL` 또는 `plugins.entries.searxng.config.webSearch.baseUrl`을 구성하세요. **권장:** `openclaw configure --section web`을 실행하고 제공자를 선택하세요. - 환경 변수 대안: + 환경 대안: - Brave: `BRAVE_API_KEY` - Exa: `EXA_API_KEY` @@ -787,69 +782,69 @@ x-i18n: } ``` - 제공자별 웹 검색 구성은 이제 `plugins.entries..config.webSearch.*` 아래에 있습니다. - 레거시 `tools.web.search.*` 제공자 경로는 호환성을 위해 일시적으로 계속 로드되지만, 새 구성에는 사용하지 않아야 합니다. - Firecrawl 웹 가져오기 대체 구성은 `plugins.entries.firecrawl.config.webFetch.*` 아래에 있습니다. + 제공자별 웹 검색 설정은 이제 `plugins.entries..config.webSearch.*` 아래에 있습니다. + 레거시 `tools.web.search.*` 제공자 경로는 호환성을 위해 일시적으로 계속 로드되지만, 새 설정에는 사용하지 않아야 합니다. + Firecrawl 웹 가져오기 폴백 설정은 `plugins.entries.firecrawl.config.webFetch.*` 아래에 있습니다. 참고: - 허용 목록을 사용하는 경우 `web_search`/`web_fetch`/`x_search` 또는 `group:web`을 추가하세요. - - `web_fetch`는 기본적으로 활성화됩니다(명시적으로 비활성화하지 않는 한). - - `tools.web.fetch.provider`를 생략하면 OpenClaw는 사용 가능한 자격 증명에서 처음으로 준비된 가져오기 대체 제공자를 자동 감지합니다. 현재 번들 제공자는 Firecrawl입니다. - - 데몬은 `~/.openclaw/.env`(또는 서비스 환경)에서 env vars를 읽습니다. + - `web_fetch`는 기본적으로 활성화되어 있습니다(명시적으로 비활성화하지 않는 한). + - `tools.web.fetch.provider`가 생략되면 OpenClaw는 사용 가능한 자격 증명에서 준비된 첫 번째 가져오기 폴백 제공자를 자동 감지합니다. 현재 번들 제공자는 Firecrawl입니다. + - 데몬은 `~/.openclaw/.env`(또는 서비스 환경)에서 환경 변수를 읽습니다. 문서: [웹 도구](/ko/tools/web). - - `config.apply`는 **전체 구성**을 교체합니다. 부분 객체를 보내면 그 밖의 모든 항목이 + + `config.apply`는 **전체 설정**을 대체합니다. 부분 객체를 보내면 그 외 모든 항목이 제거됩니다. - 현재 OpenClaw는 여러 우발적 덮어쓰기를 방지합니다. + 현재 OpenClaw는 많은 우발적 덮어쓰기를 방지합니다. - - OpenClaw가 소유한 구성 쓰기는 쓰기 전에 변경 후 전체 구성을 검증합니다. + - OpenClaw가 소유한 설정 쓰기는 쓰기 전에 변경 후 전체 설정을 검증합니다. - 유효하지 않거나 파괴적인 OpenClaw 소유 쓰기는 거부되고 `openclaw.json.rejected.*`로 저장됩니다. - - 직접 편집으로 시작 또는 핫 리로드가 깨지면 Gateway는 닫힌 상태로 실패하거나 리로드를 건너뜁니다. `openclaw.json`을 다시 쓰지 않습니다. - - `openclaw doctor --fix`가 복구를 담당하며, 거부된 파일을 `openclaw.json.clobbered.*`로 저장하면서 마지막으로 정상 작동한 구성을 복원할 수 있습니다. + - 직접 편집으로 시작 또는 핫 리로드가 깨지면 Gateway는 실패 시 닫히거나 리로드를 건너뜁니다. `openclaw.json`을 다시 쓰지 않습니다. + - `openclaw doctor --fix`가 복구를 담당하며, 거부된 파일을 `openclaw.json.clobbered.*`로 저장하면서 마지막으로 알려진 정상 상태를 복원할 수 있습니다. 복구: - - `openclaw logs --follow`에서 `Invalid config at`, `Config write rejected:`, 또는 `config reload skipped (invalid config)`를 확인하세요. - - 활성 구성 옆의 최신 `openclaw.json.clobbered.*` 또는 `openclaw.json.rejected.*`를 검사하세요. + - `openclaw logs --follow`에서 `Invalid config at`, `Config write rejected:` 또는 `config reload skipped (invalid config)`를 확인하세요. + - 활성 설정 옆에 있는 최신 `openclaw.json.clobbered.*` 또는 `openclaw.json.rejected.*`를 검사하세요. - `openclaw config validate`와 `openclaw doctor --fix`를 실행하세요. - 의도한 키만 `openclaw config set` 또는 `config.patch`로 다시 복사하세요. - - 마지막 정상 구성이나 거부된 페이로드가 없으면 백업에서 복원하거나, `openclaw doctor`를 다시 실행하고 채널/모델을 다시 구성하세요. - - 예상치 못한 일이었다면 버그를 제출하고 마지막으로 알고 있는 구성이나 백업을 포함하세요. - - 로컬 코딩 에이전트는 로그나 기록에서 작동하는 구성을 재구성할 수 있는 경우가 많습니다. + - 마지막으로 알려진 정상 상태나 거부된 페이로드가 없다면 백업에서 복원하거나, `openclaw doctor`를 다시 실행하고 채널/모델을 다시 설정하세요. + - 예상치 못한 일이었다면 버그를 등록하고 마지막으로 알려진 설정이나 백업을 포함하세요. + - 로컬 코딩 에이전트는 로그나 기록에서 작동하는 설정을 재구성할 수 있는 경우가 많습니다. 방지: - 작은 변경에는 `openclaw config set`을 사용하세요. - 대화형 편집에는 `openclaw configure`를 사용하세요. - - 정확한 경로나 필드 형태가 확실하지 않으면 먼저 `config.schema.lookup`을 사용하세요. 드릴다운을 위한 얕은 스키마 노드와 직계 자식 요약을 반환합니다. - - 부분 RPC 편집에는 `config.patch`를 사용하세요. `config.apply`는 전체 구성 교체에만 사용하세요. - - 에이전트 실행에서 소유자 전용 `gateway` 도구를 사용하는 경우에도 `tools.exec.ask` / `tools.exec.security` 쓰기는 계속 거부됩니다(동일한 보호된 exec 경로로 정규화되는 레거시 `tools.bash.*` 별칭 포함). + - 정확한 경로나 필드 형태가 확실하지 않으면 먼저 `config.schema.lookup`을 사용하세요. 드릴다운을 위한 얕은 스키마 노드와 즉시 하위 요약을 반환합니다. + - 부분 RPC 편집에는 `config.patch`를 사용하세요. `config.apply`는 전체 설정 대체에만 사용하세요. + - 에이전트 실행에서 소유자 전용 `gateway` 도구를 사용하는 경우에도 `tools.exec.ask` / `tools.exec.security`에 대한 쓰기는 여전히 거부됩니다(동일한 보호된 실행 경로로 정규화되는 레거시 `tools.bash.*` 별칭 포함). 문서: [Config](/ko/cli/config), [Configure](/ko/cli/configure), [Gateway 문제 해결](/ko/gateway/troubleshooting#gateway-rejected-invalid-config), [Doctor](/ko/gateway/doctor). - - 일반적인 패턴은 **하나의 Gateway**(예: Raspberry Pi)와 **Node** 및 **에이전트**를 함께 사용하는 것입니다. + + 일반적인 패턴은 **하나의 Gateway**(예: Raspberry Pi)와 **노드** 및 **에이전트**입니다. - **Gateway(중앙):** 채널(Signal/WhatsApp), 라우팅, 세션을 소유합니다. - - **Node(기기):** Mac/iOS/Android가 주변 장치로 연결되어 로컬 도구(`system.run`, `canvas`, `camera`)를 노출합니다. + - **노드(기기):** Mac/iOS/Android가 주변 장치로 연결되어 로컬 도구(`system.run`, `canvas`, `camera`)를 노출합니다. - **에이전트(작업자):** 특수 역할(예: "Hetzner 운영", "개인 데이터")을 위한 별도의 두뇌/작업 공간입니다. - - **하위 에이전트:** 병렬 처리가 필요할 때 기본 에이전트에서 백그라운드 작업을 생성합니다. + - **하위 에이전트:** 병렬 처리가 필요할 때 주 에이전트에서 백그라운드 작업을 생성합니다. - **TUI:** Gateway에 연결하고 에이전트/세션을 전환합니다. - 문서: [Node](/ko/nodes), [원격 액세스](/ko/gateway/remote), [다중 에이전트 라우팅](/ko/concepts/multi-agent), [하위 에이전트](/ko/tools/subagents), [TUI](/ko/web/tui). + 문서: [노드](/ko/nodes), [원격 액세스](/ko/gateway/remote), [Multi-Agent Routing](/ko/concepts/multi-agent), [하위 에이전트](/ko/tools/subagents), [TUI](/ko/web/tui). - - 예. 구성 옵션입니다. + + 예. 설정 옵션입니다. ```json5 { @@ -862,62 +857,62 @@ x-i18n: } ``` - 기본값은 `false`(headful)입니다. Headless는 일부 사이트에서 안티봇 검사를 트리거할 가능성이 더 높습니다. [브라우저](/ko/tools/browser)를 참조하세요. + 기본값은 `false`(헤드풀)입니다. 헤드리스는 일부 사이트에서 안티봇 검사를 유발할 가능성이 더 큽니다. [브라우저](/ko/tools/browser)를 참고하세요. - Headless는 **동일한 Chromium 엔진**을 사용하며 대부분의 자동화(양식, 클릭, 스크래핑, 로그인)에 작동합니다. 주요 차이점은 다음과 같습니다. + 헤드리스는 **동일한 Chromium 엔진**을 사용하며 대부분의 자동화(양식, 클릭, 스크래핑, 로그인)에 작동합니다. 주요 차이점은 다음과 같습니다. - 보이는 브라우저 창이 없습니다(시각 자료가 필요하면 스크린샷을 사용하세요). - - 일부 사이트는 headless 모드의 자동화에 더 엄격합니다(CAPTCHA, 안티봇). - 예를 들어 X/Twitter는 headless 세션을 차단하는 경우가 많습니다. + - 일부 사이트는 헤드리스 모드에서 자동화에 더 엄격합니다(CAPTCHA, 안티봇). + 예를 들어 X/Twitter는 헤드리스 세션을 자주 차단합니다. `browser.executablePath`를 Brave 바이너리(또는 Chromium 기반 브라우저)로 설정하고 Gateway를 다시 시작하세요. - 전체 구성 예시는 [브라우저](/ko/tools/browser#use-brave-or-another-chromium-based-browser)를 참조하세요. + 전체 설정 예시는 [브라우저](/ko/tools/browser#use-brave-or-another-chromium-based-browser)에서 확인하세요. -## 원격 Gateway와 Node +## 원격 게이트웨이 및 노드 - - Telegram 메시지는 **gateway**가 처리합니다. gateway는 에이전트를 실행하고, - Node 도구가 필요할 때만 **Gateway WebSocket**을 통해 Node를 호출합니다. + + Telegram 메시지는 **gateway**가 처리합니다. gateway는 에이전트를 실행한 다음 + 노드 도구가 필요할 때만 **Gateway WebSocket**을 통해 노드를 호출합니다. - Telegram → Gateway → 에이전트 → `node.*` → Node → Gateway → Telegram + Telegram → Gateway → 에이전트 → `node.*` → 노드 → Gateway → Telegram - Node는 인바운드 제공자 트래픽을 보지 않습니다. Node RPC 호출만 받습니다. + 노드는 인바운드 제공자 트래픽을 보지 않습니다. 노드는 노드 RPC 호출만 수신합니다. - - 짧게 말하면: **컴퓨터를 Node로 페어링하세요**. Gateway는 다른 곳에서 실행되지만 Gateway WebSocket을 통해 로컬 머신의 `node.*` 도구(화면, 카메라, 시스템)를 호출할 수 있습니다. + + 짧은 답: **컴퓨터를 노드로 페어링하세요**. Gateway는 다른 곳에서 실행되지만, Gateway WebSocket을 통해 로컬 머신의 `node.*` 도구(화면, 카메라, 시스템)를 호출할 수 있습니다. 일반적인 설정: 1. 항상 켜져 있는 호스트(VPS/홈 서버)에서 Gateway를 실행합니다. 2. Gateway 호스트와 컴퓨터를 같은 tailnet에 둡니다. - 3. Gateway WS에 접근 가능한지 확인합니다(tailnet 바인드 또는 SSH 터널). - 4. macOS 앱을 로컬에서 열고 **SSH를 통한 원격** 모드(또는 직접 tailnet)로 연결하여 - Node로 등록할 수 있게 합니다. - 5. Gateway에서 Node를 승인합니다. + 3. Gateway WS에 접근할 수 있는지 확인합니다(tailnet 바인딩 또는 SSH 터널). + 4. macOS 앱을 로컬에서 열고 **Remote over SSH** 모드(또는 직접 tailnet)로 연결하여 + 노드로 등록할 수 있게 합니다. + 5. Gateway에서 노드를 승인합니다. ```bash openclaw devices list openclaw devices approve ``` - 별도의 TCP 브리지는 필요하지 않습니다. Node는 Gateway WebSocket을 통해 연결됩니다. + 별도의 TCP 브리지는 필요하지 않습니다. 노드는 Gateway WebSocket을 통해 연결됩니다. - 보안 알림: macOS Node를 페어링하면 해당 머신에서 `system.run`을 사용할 수 있습니다. 신뢰하는 + 보안 알림: macOS 노드를 페어링하면 해당 머신에서 `system.run`이 허용됩니다. 신뢰하는 기기만 페어링하고 [보안](/ko/gateway/security)을 검토하세요. - 문서: [Node](/ko/nodes), [Gateway 프로토콜](/ko/gateway/protocol), [macOS 원격 모드](/ko/platforms/mac/remote), [보안](/ko/gateway/security). + 문서: [노드](/ko/nodes), [Gateway 프로토콜](/ko/gateway/protocol), [macOS 원격 모드](/ko/platforms/mac/remote), [보안](/ko/gateway/security). - + 기본 사항을 확인하세요. - Gateway 실행 중: `openclaw gateway status` @@ -927,87 +922,87 @@ x-i18n: 그런 다음 인증과 라우팅을 확인하세요. - Tailscale Serve를 사용하는 경우 `gateway.auth.allowTailscale`이 올바르게 설정되어 있는지 확인하세요. - - SSH 터널로 연결하는 경우 로컬 터널이 실행 중이고 올바른 포트를 가리키는지 확인하세요. - - 허용 목록(DM 또는 그룹)에 계정이 포함되어 있는지 확인하세요. + - SSH 터널로 연결하는 경우 로컬 터널이 실행 중이며 올바른 포트를 가리키는지 확인하세요. + - 허용 목록(DM 또는 그룹)에 내 계정이 포함되어 있는지 확인하세요. 문서: [Tailscale](/ko/gateway/tailscale), [원격 액세스](/ko/gateway/remote), [채널](/ko/channels). - 예. 내장된 "봇 간" 브리지는 없지만, 몇 가지 - 신뢰할 수 있는 방식으로 연결할 수 있습니다. + 예. 내장된 "봇 대 봇" 브리지는 없지만, 몇 가지 + 안정적인 방식으로 연결할 수 있습니다. - **가장 간단한 방법:** 두 봇이 모두 접근할 수 있는 일반 채팅 채널(Telegram/Slack/WhatsApp)을 사용합니다. - Bot A가 Bot B에게 메시지를 보내게 한 뒤 Bot B가 평소처럼 답하도록 합니다. + **가장 간단한 방법:** 두 봇이 모두 접근할 수 있는 일반 채팅 채널(Telegram/Slack/WhatsApp)을 사용하세요. + 봇 A가 봇 B에게 메시지를 보내게 한 다음, 봇 B가 평소처럼 답장하게 하세요. - **CLI 브리지(범용):** 다른 봇이 수신하는 채팅을 대상으로 하여 - `openclaw agent --message ... --deliver`로 다른 Gateway를 호출하는 스크립트를 실행합니다. - 한 봇이 원격 VPS에 있으면 SSH/Tailscale을 통해 CLI가 해당 원격 Gateway를 가리키게 하세요 - ([원격 액세스](/ko/gateway/remote) 참조). + **CLI 브리지(일반):** 다른 봇이 수신하는 채팅을 대상으로 하여 + `openclaw agent --message ... --deliver`로 다른 Gateway를 호출하는 스크립트를 실행하세요. + 한 봇이 원격 VPS에 있다면 SSH/Tailscale을 통해 CLI가 해당 원격 Gateway를 가리키게 하세요 + ([원격 액세스](/ko/gateway/remote) 참고). - 예시 패턴(대상 Gateway에 도달할 수 있는 머신에서 실행): + 예시 패턴(대상 Gateway에 접근할 수 있는 머신에서 실행): ```bash openclaw agent --message "Hello from local bot" --deliver --channel telegram --reply-to ``` - 팁: 두 봇이 끝없이 반복하지 않도록 안전장치를 추가하세요(멘션 전용, 채널 - 허용 목록, 또는 "봇 메시지에는 답하지 않음" 규칙). + 팁: 두 봇이 끝없이 반복되지 않도록 안전장치를 추가하세요(멘션 전용, 채널 + 허용 목록 또는 "봇 메시지에는 답장하지 않기" 규칙). - 문서: [원격 액세스](/ko/gateway/remote), [에이전트 CLI](/ko/cli/agent), [에이전트 보내기](/ko/tools/agent-send). + 문서: [원격 액세스](/ko/gateway/remote), [에이전트 CLI](/ko/cli/agent), [에이전트 전송](/ko/tools/agent-send). - + 아니요. 하나의 Gateway가 여러 에이전트를 호스팅할 수 있으며, 각 에이전트는 자체 작업 공간, 모델 기본값, - 라우팅을 가질 수 있습니다. 이것이 일반적인 설정이며 에이전트마다 VPS 하나를 실행하는 것보다 훨씬 저렴하고 간단합니다. + 라우팅을 가질 수 있습니다. 이것이 일반적인 설정이며 에이전트마다 하나의 VPS를 실행하는 것보다 훨씬 저렴하고 간단합니다. - 별도의 VPS는 강한 격리(보안 경계)가 필요하거나 공유하고 싶지 않은 매우 - 다른 구성이 있을 때만 사용하세요. 그 외에는 하나의 Gateway를 유지하고 + 강한 격리(보안 경계)가 필요하거나 공유하고 싶지 않은 매우 + 다른 설정이 필요할 때만 별도의 VPS를 사용하세요. 그 외에는 하나의 Gateway를 유지하고 여러 에이전트 또는 하위 에이전트를 사용하세요. - - 예. Node는 원격 Gateway에서 노트북에 접근하는 공식적인 방법이며, - 셸 접근 이상의 기능을 제공합니다. Gateway는 macOS/Linux(Windows는 WSL2 통해)에서 실행되고 - 가볍기 때문에(소형 VPS나 Raspberry Pi급 장비로 충분하며, 4GB RAM이면 충분) 일반적인 - 설정은 항상 켜져 있는 호스트와 노트북을 Node로 사용하는 것입니다. + + 예 - 노드는 원격 Gateway에서 노트북에 접근하는 일급 방식이며, 단순한 셸 액세스 이상의 기능을 + 제공합니다. Gateway는 macOS/Linux(Windows는 WSL2 경유)에서 실행되며 + 가볍습니다(작은 VPS나 Raspberry Pi급 장치면 충분합니다. RAM 4GB면 넉넉합니다). 따라서 일반적인 + 설정은 항상 켜져 있는 호스트와 노트북을 노드로 사용하는 방식입니다. - - **인바운드 SSH가 필요 없습니다.** Node는 Gateway WebSocket으로 나가는 연결을 만들고 기기 페어링을 사용합니다. - - **더 안전한 실행 제어.** `system.run`은 해당 노트북의 Node 허용 목록/승인으로 제어됩니다. - - **더 많은 기기 도구.** Node는 `system.run` 외에도 `canvas`, `camera`, `screen`을 노출합니다. - - **로컬 브라우저 자동화.** Gateway는 VPS에 두되, 노트북의 Node 호스트를 통해 Chrome을 로컬에서 실행하거나 Chrome MCP를 통해 호스트의 로컬 Chrome에 연결하세요. + - **인바운드 SSH가 필요 없습니다.** 노드는 Gateway WebSocket으로 아웃바운드 연결하고 기기 페어링을 사용합니다. + - **더 안전한 실행 제어.** `system.run`은 해당 노트북의 노드 허용 목록/승인으로 제한됩니다. + - **더 많은 기기 도구.** 노드는 `system.run` 외에도 `canvas`, `camera`, `screen`을 노출합니다. + - **로컬 브라우저 자동화.** Gateway는 VPS에 두되, 노트북의 노드 호스트를 통해 Chrome을 로컬에서 실행하거나 Chrome MCP를 통해 호스트의 로컬 Chrome에 연결하세요. - SSH는 임시 셸 접근에는 괜찮지만, 지속적인 에이전트 워크플로와 - 기기 자동화에는 Node가 더 간단합니다. + SSH는 임시 셸 액세스에는 괜찮지만, 지속적인 에이전트 워크플로와 + 기기 자동화에는 노드가 더 간단합니다. - 문서: [Node](/ko/nodes), [Node CLI](/ko/cli/nodes), [브라우저](/ko/tools/browser). + 문서: [노드](/ko/nodes), [노드 CLI](/ko/cli/nodes), [브라우저](/ko/tools/browser). - - 아니요. 의도적으로 격리된 프로필을 실행하는 경우가 아니라면 호스트당 **하나의 gateway**만 실행해야 합니다([여러 Gateway](/ko/gateway/multiple-gateways) 참조). Node는 gateway에 연결되는 주변 장치입니다 - (iOS/Android Node 또는 macOS 메뉴 막대 앱의 "node mode"). Headless Node - 호스트와 CLI 제어는 [Node 호스트 CLI](/ko/cli/node)를 참조하세요. + + 아니요. 의도적으로 격리된 프로필을 실행하는 경우가 아니라면 호스트당 **하나의 gateway**만 실행해야 합니다([여러 gateway](/ko/gateway/multiple-gateways) 참고). 노드는 gateway에 연결되는 주변 장치입니다 + (iOS/Android 노드 또는 메뉴바 앱의 macOS "노드 모드"). 헤드리스 노드 + 호스트와 CLI 제어는 [노드 호스트 CLI](/ko/cli/node)를 참고하세요. `gateway`, `discovery`, `canvasHost` 변경에는 전체 재시작이 필요합니다. - + 예. - - `config.schema.lookup`: 쓰기 전에 얕은 스키마 노드, 일치하는 UI 힌트, 직계 자식 요약과 함께 구성 하위 트리 하나를 검사합니다. - - `config.get`: 현재 스냅샷 + 해시를 가져옵니다. - - `config.patch`: 안전한 부분 업데이트(대부분의 RPC 편집에 권장). 가능하면 핫 리로드하고 필요하면 다시 시작합니다. - - `config.apply`: 전체 구성을 검증하고 교체합니다. 가능하면 핫 리로드하고 필요하면 다시 시작합니다. - - 소유자 전용 `gateway` 런타임 도구는 여전히 `tools.exec.ask` / `tools.exec.security` 재쓰기를 거부합니다. 레거시 `tools.bash.*` 별칭은 동일한 보호된 exec 경로로 정규화됩니다. + - `config.schema.lookup`: 쓰기 전에 얕은 스키마 노드, 일치하는 UI 힌트, 즉시 하위 요약과 함께 하나의 config 하위 트리를 검사합니다 + - `config.get`: 현재 스냅샷 + 해시를 가져옵니다 + - `config.patch`: 안전한 부분 업데이트(대부분의 RPC 편집에 권장); 가능하면 핫 리로드하고 필요하면 재시작합니다 + - `config.apply`: 전체 config를 검증 + 교체합니다; 가능하면 핫 리로드하고 필요하면 재시작합니다 + - 소유자 전용 `gateway` 런타임 도구는 여전히 `tools.exec.ask` / `tools.exec.security` 재작성을 거부합니다. 레거시 `tools.bash.*` 별칭은 동일한 보호된 exec 경로로 정규화됩니다 - + ```json5 { agents: { defaults: { workspace: "~/.openclaw/workspace" } }, @@ -1015,7 +1010,7 @@ x-i18n: } ``` - 이렇게 하면 워크스페이스가 설정되고 누가 봇을 트리거할 수 있는지 제한됩니다. + 이렇게 하면 워크스페이스를 설정하고 봇을 트리거할 수 있는 사용자를 제한합니다. @@ -1032,30 +1027,30 @@ x-i18n: 2. **Mac에 설치 + 로그인** - Tailscale 앱을 사용하고 같은 tailnet에 로그인합니다. 3. **MagicDNS 활성화(권장)** - - Tailscale 관리 콘솔에서 MagicDNS를 활성화하여 VPS가 안정적인 이름을 갖도록 합니다. + - Tailscale 관리자 콘솔에서 MagicDNS를 활성화해 VPS가 안정적인 이름을 갖게 합니다. 4. **tailnet 호스트 이름 사용** - SSH: `ssh user@your-vps.tailnet-xxxx.ts.net` - Gateway WS: `ws://your-vps.tailnet-xxxx.ts.net:18789` - SSH 없이 Control UI를 사용하려면 VPS에서 Tailscale Serve를 사용하세요. + SSH 없이 Control UI를 사용하려면 VPS에서 Tailscale Serve를 사용합니다. ```bash openclaw gateway --tailscale serve ``` - 이렇게 하면 Gateway가 루프백에 바인딩된 상태로 유지되고 Tailscale을 통해 HTTPS가 노출됩니다. [Tailscale](/ko/gateway/tailscale)을 참조하세요. + 이렇게 하면 gateway가 loopback에 바인딩된 상태로 유지되고 Tailscale을 통해 HTTPS가 노출됩니다. [Tailscale](/ko/gateway/tailscale)을 참고하세요. - - Serve는 **Gateway Control UI + WS**를 노출합니다. Node는 같은 Gateway WS 엔드포인트를 통해 연결됩니다. + + Serve는 **Gateway Control UI + WS**를 노출합니다. Node는 동일한 Gateway WS 엔드포인트를 통해 연결됩니다. 권장 설정: 1. **VPS + Mac이 같은 tailnet에 있는지 확인합니다**. - 2. **원격 모드에서 macOS 앱을 사용합니다**(SSH 대상은 tailnet 호스트 이름일 수 있음). - 앱이 Gateway 포트를 터널링하고 Node로 연결합니다. - 3. Gateway에서 **Node를 승인**합니다. + 2. **Remote 모드에서 macOS 앱을 사용합니다**(SSH 대상은 tailnet 호스트 이름일 수 있음). + 앱은 Gateway 포트를 터널링하고 node로 연결됩니다. + 3. gateway에서 **node를 승인합니다**. ```bash openclaw devices list @@ -1066,30 +1061,30 @@ x-i18n: - + 두 번째 노트북에서 **로컬 도구**(화면/카메라/exec)만 필요하다면 - **Node**로 추가하세요. 그러면 단일 Gateway를 유지하고 중복 구성을 피할 수 있습니다. 로컬 Node 도구는 + **node**로 추가하세요. 이렇게 하면 단일 Gateway를 유지하고 중복 config를 피할 수 있습니다. 로컬 node 도구는 현재 macOS 전용이지만, 다른 OS로 확장할 계획입니다. - **강한 격리**가 필요하거나 완전히 분리된 봇 두 개가 필요한 경우에만 두 번째 Gateway를 설치하세요. + **강한 격리** 또는 완전히 분리된 두 봇이 필요할 때만 두 번째 Gateway를 설치하세요. 문서: [Node](/ko/nodes), [Node CLI](/ko/cli/nodes), [여러 Gateway](/ko/gateway/multiple-gateways). -## 환경 변수와 .env 로딩 +## Env vars 및 .env 로딩 - OpenClaw는 부모 프로세스(shell, launchd/systemd, CI 등)의 환경 변수를 읽고, 추가로 다음을 로드합니다. + OpenClaw는 부모 프로세스(shell, launchd/systemd, CI 등)에서 env vars를 읽고, 추가로 다음을 로드합니다. - 현재 작업 디렉터리의 `.env` - - `~/.openclaw/.env`의 전역 폴백 `.env`(일명 `$OPENCLAW_STATE_DIR/.env`) + - `~/.openclaw/.env`의 전역 fallback `.env`(즉 `$OPENCLAW_STATE_DIR/.env`) - 어느 `.env` 파일도 기존 환경 변수를 덮어쓰지 않습니다. + 두 `.env` 파일 모두 기존 env vars를 덮어쓰지 않습니다. - 구성에서 인라인 환경 변수를 정의할 수도 있습니다(프로세스 환경에 없을 때만 적용됨). + config에서 인라인 env vars를 정의할 수도 있습니다(프로세스 env에 없을 때만 적용됨). ```json5 { @@ -1100,15 +1095,15 @@ x-i18n: } ``` - 전체 우선순위와 소스는 [/environment](/ko/help/environment)를 참조하세요. + 전체 우선순위와 소스는 [/environment](/ko/help/environment)를 참고하세요. - + 일반적인 해결 방법 두 가지: - 1. 서비스가 shell 환경을 상속하지 않더라도 선택될 수 있도록 누락된 키를 `~/.openclaw/.env`에 넣습니다. - 2. shell 가져오기를 활성화합니다(선택적 편의 기능). + 1. 누락된 키를 `~/.openclaw/.env`에 넣어 서비스가 shell env를 상속하지 않아도 선택되도록 합니다. + 2. shell import를 활성화합니다(선택적 편의 기능). ```json5 { @@ -1121,17 +1116,16 @@ x-i18n: } ``` - 이는 로그인 shell을 실행하고 누락된 예상 키만 가져옵니다(절대 덮어쓰지 않음). 해당 환경 변수: + 이는 로그인 shell을 실행하고 누락된 예상 키만 가져옵니다(절대 덮어쓰지 않음). Env var 대응 항목: `OPENCLAW_LOAD_SHELL_ENV=1`, `OPENCLAW_SHELL_ENV_TIMEOUT_MS=15000`. - - `openclaw models status`는 **shell 환경 가져오기**가 활성화되어 있는지 보고합니다. "Shell env: off"는 - 환경 변수가 없다는 뜻이 **아닙니다**. OpenClaw가 로그인 shell을 - 자동으로 로드하지 않는다는 뜻일 뿐입니다. + + `openclaw models status`는 **shell env import**가 활성화되어 있는지 보고합니다. "Shell env: off"는 + env vars가 없다는 뜻이 **아닙니다**. OpenClaw가 로그인 shell을 자동으로 로드하지 않는다는 뜻일 뿐입니다. - Gateway가 서비스(launchd/systemd)로 실행되는 경우 shell + Gateway가 서비스(launchd/systemd)로 실행되면 shell 환경을 상속하지 않습니다. 다음 중 하나로 해결하세요. 1. 토큰을 `~/.openclaw/.env`에 넣습니다. @@ -1140,33 +1134,33 @@ x-i18n: COPILOT_GITHUB_TOKEN=... ``` - 2. 또는 shell 가져오기를 활성화합니다(`env.shellEnv.enabled: true`). - 3. 또는 구성의 `env` 블록에 추가합니다(누락된 경우에만 적용됨). + 2. 또는 shell import를 활성화합니다(`env.shellEnv.enabled: true`). + 3. 또는 config `env` 블록에 추가합니다(없을 때만 적용). - 그런 다음 Gateway를 다시 시작하고 다시 확인합니다. + 그런 다음 gateway를 재시작하고 다시 확인합니다. ```bash openclaw models status ``` - Copilot 토큰은 `COPILOT_GITHUB_TOKEN`에서 읽습니다(`GH_TOKEN` / `GITHUB_TOKEN`도 가능). - [/concepts/model-providers](/ko/concepts/model-providers) 및 [/environment](/ko/help/environment)를 참조하세요. + Copilot 토큰은 `COPILOT_GITHUB_TOKEN`에서 읽습니다(`GH_TOKEN` / `GITHUB_TOKEN`도 포함). + [/concepts/model-providers](/ko/concepts/model-providers) 및 [/environment](/ko/help/environment)를 참고하세요. -## 세션과 여러 채팅 +## 세션 및 여러 채팅 - 독립 메시지로 `/new` 또는 `/reset`을 보내세요. [세션 관리](/ko/concepts/session)를 참조하세요. + 독립 메시지로 `/new` 또는 `/reset`을 보내세요. [세션 관리](/ko/concepts/session)를 참고하세요. - 세션은 `session.idleMinutes` 후 만료될 수 있지만, 이는 **기본적으로 비활성화**되어 있습니다(기본값 **0**). - 유휴 만료를 활성화하려면 양수 값으로 설정하세요. 활성화되면 유휴 기간 이후의 **다음** - 메시지가 해당 채팅 키에 대해 새 세션 ID를 시작합니다. - 이는 transcript를 삭제하지 않습니다. 새 세션을 시작할 뿐입니다. + 세션은 `session.idleMinutes` 이후 만료될 수 있지만, 이는 **기본적으로 비활성화**되어 있습니다(기본값 **0**). + idle 만료를 활성화하려면 양수 값으로 설정하세요. 활성화된 경우, idle 기간 이후의 **다음** + 메시지가 해당 채팅 키에 대해 새로운 세션 ID를 시작합니다. + 이는 transcript를 삭제하지 않고 새 세션을 시작할 뿐입니다. ```json5 { @@ -1178,34 +1172,34 @@ x-i18n: - - 예, **다중 agent 라우팅**과 **하위 agent**를 통해 가능합니다. 하나의 coordinator - agent와 자체 워크스페이스 및 모델을 가진 여러 worker agent를 만들 수 있습니다. + + 예, **multi-agent routing** 및 **sub-agents**를 통해 가능합니다. 하나의 coordinator + agent와 자체 workspace 및 model을 가진 여러 worker agent를 만들 수 있습니다. - 다만 이는 **재미있는 실험**으로 보는 것이 가장 좋습니다. 토큰 사용량이 많고, 별도 세션이 있는 하나의 봇을 사용하는 것보다 - 효율이 떨어지는 경우가 많습니다. 우리가 상정하는 일반적인 모델은 사용자가 대화하는 하나의 봇과 병렬 작업을 위한 여러 세션입니다. 그 - 봇은 필요할 때 하위 agent를 생성할 수도 있습니다. + 다만 이는 **재미있는 실험**으로 보는 것이 가장 좋습니다. 토큰을 많이 사용하며 별도 세션이 있는 하나의 봇을 사용하는 것보다 + 효율이 떨어지는 경우가 많습니다. 우리가 상정하는 일반적인 모델은 사용자가 대화하는 하나의 봇과 병렬 작업을 위한 서로 다른 세션입니다. 그 + 봇은 필요할 때 sub-agents도 생성할 수 있습니다. - 문서: [다중 agent 라우팅](/ko/concepts/multi-agent), [하위 agent](/ko/tools/subagents), [Agent CLI](/ko/cli/agents). + 문서: [Multi-agent routing](/ko/concepts/multi-agent), [Sub-agents](/ko/tools/subagents), [Agents CLI](/ko/cli/agents). - - 세션 컨텍스트는 모델 창에 의해 제한됩니다. 긴 채팅, 큰 도구 출력 또는 많은 - 파일은 Compaction이나 잘림을 유발할 수 있습니다. + + 세션 context는 모델 window에 의해 제한됩니다. 긴 채팅, 큰 도구 출력, 많은 + 파일은 Compaction 또는 truncation을 유발할 수 있습니다. 도움이 되는 방법: - 봇에게 현재 상태를 요약해 파일에 쓰도록 요청합니다. - 긴 작업 전에는 `/compact`를 사용하고, 주제를 바꿀 때는 `/new`를 사용합니다. - - 중요한 컨텍스트는 워크스페이스에 보관하고 봇에게 다시 읽어 달라고 요청합니다. - - 길거나 병렬인 작업에는 하위 agent를 사용해 기본 채팅을 더 작게 유지합니다. - - 이런 일이 자주 발생하면 더 큰 컨텍스트 창을 가진 모델을 선택합니다. + - 중요한 context는 workspace에 보관하고 봇에게 다시 읽도록 요청합니다. + - 긴 작업이나 병렬 작업에는 sub-agents를 사용해 메인 채팅을 더 작게 유지합니다. + - 이런 일이 자주 발생하면 더 큰 context window를 가진 모델을 선택합니다. - - reset 명령을 사용하세요. + + reset 명령을 사용합니다. ```bash openclaw reset @@ -1217,7 +1211,7 @@ x-i18n: openclaw reset --scope full --yes --non-interactive ``` - 그런 다음 설정을 다시 실행합니다. + 그런 다음 setup을 다시 실행합니다. ```bash openclaw onboard --install-daemon @@ -1225,16 +1219,16 @@ x-i18n: 참고: - - 기존 구성을 발견하면 온보딩에서도 **Reset**을 제공합니다. [온보딩(CLI)](/ko/start/wizard)을 참조하세요. - - 프로필(`--profile` / `OPENCLAW_PROFILE`)을 사용했다면 각 상태 디렉터리를 reset하세요(기본값은 `~/.openclaw-`). - - 개발 reset: `openclaw gateway --dev --reset`(개발 전용; 개발 구성 + 자격 증명 + 세션 + 워크스페이스를 지움). + - Onboarding은 기존 config를 발견하면 **Reset**도 제공합니다. [Onboarding (CLI)](/ko/start/wizard)를 참고하세요. + - profile(`--profile` / `OPENCLAW_PROFILE`)을 사용했다면 각 state dir을 reset하세요(기본값은 `~/.openclaw-`). + - Dev reset: `openclaw gateway --dev --reset`(dev 전용; dev config + credentials + sessions + workspace를 지움). 다음 중 하나를 사용하세요. - - **Compact**(대화를 유지하되 오래된 턴을 요약함): + - **Compact**(대화를 유지하되 이전 turn을 요약): ``` /compact @@ -1249,26 +1243,26 @@ x-i18n: /reset ``` - 계속 발생하는 경우: + 계속 발생한다면: - - 오래된 도구 출력을 줄이도록 **세션 가지치기**(`agents.defaults.contextPruning`)를 활성화하거나 조정합니다. - - 더 큰 컨텍스트 창을 가진 모델을 사용합니다. + - **session pruning**(`agents.defaults.contextPruning`)을 활성화하거나 조정해 오래된 도구 출력을 줄입니다. + - 더 큰 context window를 가진 모델을 사용합니다. - 문서: [Compaction](/ko/concepts/compaction), [세션 가지치기](/ko/concepts/session-pruning), [세션 관리](/ko/concepts/session). + 문서: [Compaction](/ko/concepts/compaction), [세션 pruning](/ko/concepts/session-pruning), [세션 관리](/ko/concepts/session). - 이는 provider 검증 오류입니다. 모델이 필수 `input` 없이 `tool_use` 블록을 내보냈다는 뜻입니다. - 일반적으로 세션 기록이 오래되었거나 손상되었음을 의미합니다(긴 스레드 이후나 - 도구/스키마 변경 후에 자주 발생). + 이는 provider 검증 오류입니다. 모델이 필요한 `input` 없이 `tool_use` 블록을 내보냈다는 뜻입니다. + 일반적으로 세션 기록이 오래되었거나 손상되었음을 의미합니다(긴 thread + 또는 도구/schema 변경 이후에 자주 발생). - 해결: `/new`로 새 세션을 시작하세요(독립 메시지). + 해결: `/new`(독립 메시지)로 새 세션을 시작합니다. - - Heartbeat는 기본적으로 **30m**마다 실행됩니다(OAuth 인증을 사용할 때는 **1h**). 조정하거나 비활성화하세요. + + Heartbeat는 기본적으로 **30m**마다 실행됩니다(OAuth auth 사용 시 **1h**). 조정하거나 비활성화하세요. ```json5 { @@ -1283,18 +1277,18 @@ x-i18n: ``` `HEARTBEAT.md`가 있지만 사실상 비어 있는 경우(빈 줄과 `# Heading` 같은 markdown - 헤더만 있는 경우) OpenClaw는 API 호출을 절약하기 위해 Heartbeat 실행을 건너뜁니다. - 파일이 없으면 Heartbeat는 계속 실행되고 모델이 수행할 작업을 결정합니다. + header만 있는 경우), OpenClaw는 API 호출을 절약하기 위해 heartbeat 실행을 건너뜁니다. + 파일이 없으면 heartbeat는 계속 실행되고 모델이 무엇을 할지 결정합니다. - agent별 재정의는 `agents.list[].heartbeat`를 사용합니다. 문서: [Heartbeat](/ko/gateway/heartbeat). + agent별 override는 `agents.list[].heartbeat`를 사용합니다. 문서: [Heartbeat](/ko/gateway/heartbeat). - - 아니요. OpenClaw는 **사용자 자신의 계정**에서 실행되므로, 사용자가 그룹에 있으면 OpenClaw도 볼 수 있습니다. - 기본적으로 그룹 답장은 발신자를 허용할 때까지 차단됩니다(`groupPolicy: "allowlist"`). + + 아니요. OpenClaw는 **사용자 자신의 account**에서 실행되므로, 사용자가 그룹에 있으면 OpenClaw도 볼 수 있습니다. + 기본적으로 그룹 reply는 보낸 사람을 허용할 때까지 차단됩니다(`groupPolicy: "allowlist"`). - 그룹 답장을 트리거할 수 있는 사람을 **사용자 본인**으로만 제한하려면 다음과 같이 설정하세요. + **사용자만** 그룹 reply를 트리거할 수 있게 하려면: ```json5 { @@ -1309,8 +1303,8 @@ x-i18n: - - 옵션 1(가장 빠름): 로그를 따라가며 그룹에 테스트 메시지를 보냅니다. + + 옵션 1(가장 빠름): 로그를 tail하고 그룹에 테스트 메시지를 보냅니다. ```bash openclaw logs --follow --json @@ -1319,51 +1313,51 @@ x-i18n: `@g.us`로 끝나는 `chatId`(또는 `from`)를 찾으세요. 예: `1234567890-1234567890@g.us`. - 옵션 2(이미 구성/허용 목록에 있는 경우): 구성에서 그룹 목록을 표시합니다. + 옵션 2(이미 구성/allowlist된 경우): config에서 그룹을 나열합니다. ```bash openclaw directory groups list --channel whatsapp ``` - 문서: [WhatsApp](/ko/channels/whatsapp), [디렉터리](/ko/cli/directory), [로그](/ko/cli/logs). + 문서: [WhatsApp](/ko/channels/whatsapp), [Directory](/ko/cli/directory), [Logs](/ko/cli/logs). - + 일반적인 원인 두 가지: - - 멘션 게이팅이 켜져 있습니다(기본값). 봇을 @멘션해야 합니다(또는 `mentionPatterns`와 일치해야 함). - - `channels.whatsapp.groups`를 `"*"` 없이 구성했고 해당 그룹이 허용 목록에 없습니다. + - Mention gating이 켜져 있습니다(기본값). 봇을 @mention해야 합니다(또는 `mentionPatterns`와 일치해야 함). + - `channels.whatsapp.groups`를 `"*"` 없이 구성했고 그룹이 allowlist되지 않았습니다. - [그룹](/ko/channels/groups) 및 [그룹 메시지](/ko/channels/group-messages)를 참조하세요. + [그룹](/ko/channels/groups) 및 [그룹 메시지](/ko/channels/group-messages)를 참고하세요. - - 직접 채팅은 기본적으로 메인 세션으로 축약됩니다. 그룹/채널은 자체 세션 키를 가지며, Telegram 주제 / Discord 스레드는 별도 세션입니다. [그룹](/ko/channels/groups) 및 [그룹 메시지](/ko/channels/group-messages)를 참조하세요. + + Direct chat은 기본적으로 main session으로 합쳐집니다. 그룹/channel은 자체 session key를 가지며, Telegram topic / Discord thread는 별도 session입니다. [그룹](/ko/channels/groups) 및 [그룹 메시지](/ko/channels/group-messages)를 참고하세요. - - 엄격한 제한은 없습니다. 수십 개(심지어 수백 개)도 괜찮지만 다음을 주의하세요. + + 엄격한 제한은 없습니다. 수십 개(심지어 수백 개)도 괜찮지만, 다음 사항에 유의하세요. - - **디스크 증가:** 세션 + transcript는 `~/.openclaw/agents//sessions/` 아래에 있습니다. - - **토큰 비용:** agent가 많을수록 동시 모델 사용이 늘어납니다. - - **운영 부담:** agent별 auth 프로필, 워크스페이스, 채널 라우팅. + - **디스크 증가:** 세션과 transcript는 `~/.openclaw/agents//sessions/` 아래에 저장됩니다. + - **토큰 비용:** 에이전트가 많을수록 동시 모델 사용량도 늘어납니다. + - **운영 부담:** 에이전트별 인증 프로필, 워크스페이스, 채널 라우팅이 필요합니다. 팁: - - agent마다 하나의 **활성** 워크스페이스를 유지하세요(`agents.defaults.workspace`). - - 디스크가 커지면 오래된 세션(JSONL 또는 저장소 항목)을 정리하세요. - - `openclaw doctor`를 사용해 남은 워크스페이스와 프로필 불일치를 찾으세요. + - 에이전트마다 하나의 **활성** 워크스페이스를 유지하세요(`agents.defaults.workspace`). + - 디스크 사용량이 늘어나면 오래된 세션(JSONL 또는 저장소 항목)을 정리하세요. + - `openclaw doctor`를 사용해 남은 워크스페이스와 프로필 불일치를 확인하세요. - - 예. **Multi-Agent Routing**을 사용해 격리된 여러 에이전트를 실행하고 수신 메시지를 + + 예. **다중 에이전트 라우팅**을 사용해 여러 격리된 에이전트를 실행하고 수신 메시지를 채널/계정/피어별로 라우팅하세요. Slack은 채널로 지원되며 특정 에이전트에 바인딩할 수 있습니다. - 브라우저 접근은 강력하지만 "사람이 할 수 있는 모든 일을 한다"는 의미는 아닙니다. 봇 방지, CAPTCHA, MFA가 - 여전히 자동화를 차단할 수 있습니다. 가장 안정적인 브라우저 제어를 위해서는 호스트에서 로컬 Chrome MCP를 사용하거나, + 브라우저 접근은 강력하지만 "사람이 할 수 있는 모든 것을 수행"하지는 못합니다. 안티봇, CAPTCHA, MFA가 + 여전히 자동화를 막을 수 있습니다. 가장 안정적인 브라우저 제어를 위해서는 호스트의 로컬 Chrome MCP를 사용하거나, 실제로 브라우저를 실행하는 머신에서 CDP를 사용하세요. 권장 설정: @@ -1371,24 +1365,24 @@ x-i18n: - 항상 켜져 있는 Gateway 호스트(VPS/Mac mini). - 역할별 에이전트 하나(바인딩). - 해당 에이전트에 바인딩된 Slack 채널. - - 필요할 때 Chrome MCP 또는 Node를 통한 로컬 브라우저. + - 필요할 때 Chrome MCP 또는 노드를 통한 로컬 브라우저. - 문서: [Multi-Agent Routing](/ko/concepts/multi-agent), [Slack](/ko/channels/slack), - [Browser](/ko/tools/browser), [Nodes](/ko/nodes). + 문서: [다중 에이전트 라우팅](/ko/concepts/multi-agent), [Slack](/ko/channels/slack), + [브라우저](/ko/tools/browser), [노드](/ko/nodes). -## 모델, 장애 조치, 인증 프로필 +## 모델, failover, 인증 프로필 -모델 Q&A — 기본값, 선택, 별칭, 전환, 장애 조치, 인증 프로필 — -는 [모델 FAQ](/ko/help/faq-models)에 있습니다. +기본값, 선택, 별칭, 전환, failover, 인증 프로필에 대한 모델 Q&A는 +[모델 FAQ](/ko/help/faq-models)에 있습니다. ## Gateway: 포트, "already running", 원격 모드 - `gateway.port`는 WebSocket + HTTP(Control UI, hook 등)를 위한 단일 멀티플렉스 포트를 제어합니다. + `gateway.port`는 WebSocket + HTTP(제어 UI, 훅 등)를 위한 단일 다중화 포트를 제어합니다. 우선순위: @@ -1398,39 +1392,39 @@ x-i18n: - - "running"은 **슈퍼바이저의** 관점(launchd/systemd/schtasks)이기 때문입니다. 연결 프로브는 CLI가 실제로 Gateway WebSocket에 연결하는 것입니다. + + "running"은 **supervisor의** 관점(launchd/systemd/schtasks)이기 때문입니다. 연결성 probe는 CLI가 실제로 gateway WebSocket에 연결하는 것입니다. - `openclaw gateway status`를 사용하고 다음 줄을 신뢰하세요: + `openclaw gateway status`를 사용하고 다음 줄을 확인하세요. - - `Probe target:`(프로브가 실제로 사용한 URL) - - `Listening:`(포트에 실제로 바인딩된 항목) - - `Last gateway error:`(프로세스는 살아 있지만 포트가 수신 대기 중이 아닐 때의 일반적인 근본 원인) + - `Probe target:` (probe가 실제로 사용한 URL) + - `Listening:` (포트에 실제로 바인딩된 항목) + - `Last gateway error:` (프로세스는 살아 있지만 포트가 수신 중이 아닐 때 흔한 근본 원인) - - 서비스가 다른 구성 파일로 실행되는 동안 다른 구성 파일을 편집하고 있습니다(대개 `--profile` / `OPENCLAW_STATE_DIR` 불일치). + + 서비스가 다른 설정 파일로 실행 중인 동안 다른 설정 파일을 편집하고 있습니다(대개 `--profile` / `OPENCLAW_STATE_DIR` 불일치). - 수정: + 해결: ```bash openclaw gateway install --force ``` - 서비스가 사용하기를 원하는 동일한 `--profile` / 환경에서 이를 실행하세요. + 서비스가 사용하길 원하는 동일한 `--profile` / 환경에서 실행하세요. - - OpenClaw는 시작 시 WebSocket 리스너를 즉시 바인딩하여 런타임 잠금을 강제합니다(기본값 `ws://127.0.0.1:18789`). 바인딩이 `EADDRINUSE`로 실패하면 다른 인스턴스가 이미 수신 대기 중임을 나타내는 `GatewayLockError`를 발생시킵니다. + + OpenClaw는 시작 즉시 WebSocket 리스너를 바인딩하여 런타임 잠금을 강제합니다(기본값 `ws://127.0.0.1:18789`). 바인딩이 `EADDRINUSE`로 실패하면 다른 인스턴스가 이미 수신 중임을 나타내는 `GatewayLockError`가 발생합니다. - 수정: 다른 인스턴스를 중지하거나, 포트를 비우거나, `openclaw gateway --port `로 실행하세요. + 해결: 다른 인스턴스를 중지하거나, 포트를 비우거나, `openclaw gateway --port `로 실행하세요. - - `gateway.mode: "remote"`를 설정하고 원격 WebSocket URL을 지정하세요. 선택적으로 공유 비밀 원격 자격 증명을 사용할 수 있습니다: + + `gateway.mode: "remote"`를 설정하고 원격 WebSocket URL을 지정하세요. 선택적으로 공유 비밀 원격 자격 증명을 함께 사용할 수 있습니다. ```json5 { @@ -1447,92 +1441,92 @@ x-i18n: 참고: - - `openclaw gateway`는 `gateway.mode`가 `local`일 때만 시작됩니다(또는 재정의 플래그를 전달한 경우). - - macOS 앱은 구성 파일을 감시하며 이 값들이 변경되면 실시간으로 모드를 전환합니다. - - `gateway.remote.token` / `.password`는 클라이언트 측 원격 자격 증명일 뿐이며, 그 자체로 로컬 Gateway 인증을 활성화하지 않습니다. + - `openclaw gateway`는 `gateway.mode`가 `local`일 때만 시작됩니다(또는 override 플래그를 전달한 경우). + - macOS 앱은 설정 파일을 감시하며 이 값들이 바뀌면 모드를 실시간으로 전환합니다. + - `gateway.remote.token` / `.password`는 클라이언트 측 원격 자격 증명일 뿐이며, 자체적으로 로컬 gateway 인증을 활성화하지 않습니다. - - Gateway 인증 경로와 UI의 인증 방식이 일치하지 않습니다. + + gateway 인증 경로와 UI의 인증 방식이 일치하지 않습니다. 사실(코드 기준): - - Control UI는 현재 브라우저 탭 세션과 선택한 Gateway URL에 대해 토큰을 `sessionStorage`에 보관하므로, 같은 탭 새로고침은 장기 localStorage 토큰 지속성을 복원하지 않고도 계속 작동합니다. - - `AUTH_TOKEN_MISMATCH`에서 신뢰할 수 있는 클라이언트는 Gateway가 재시도 힌트(`canRetryWithDeviceToken=true`, `recommendedNextStep=retry_with_device_token`)를 반환할 때 캐시된 디바이스 토큰으로 한 번의 제한된 재시도를 시도할 수 있습니다. - - 이제 해당 캐시 토큰 재시도는 디바이스 토큰과 함께 저장된 캐시된 승인 scope를 재사용합니다. 명시적 `deviceToken` / 명시적 `scopes` 호출자는 여전히 캐시된 scope를 상속하지 않고 요청한 scope 집합을 유지합니다. - - 해당 재시도 경로 밖에서 연결 인증 우선순위는 명시적 공유 토큰/비밀번호, 그다음 명시적 `deviceToken`, 그다음 저장된 디바이스 토큰, 그다음 bootstrap 토큰입니다. - - Bootstrap 토큰 scope 검사는 역할 접두사가 붙습니다. 기본 제공 bootstrap operator 허용 목록은 operator 요청만 충족합니다. Node나 다른 비-operator 역할에는 여전히 자체 역할 접두사 아래의 scope가 필요합니다. + - 제어 UI는 현재 브라우저 탭 세션과 선택한 gateway URL에 대해 토큰을 `sessionStorage`에 보관하므로, 같은 탭에서 새로고침해도 장기 localStorage 토큰 지속성을 복원하지 않고 계속 작동합니다. + - `AUTH_TOKEN_MISMATCH`에서 신뢰된 클라이언트는 gateway가 재시도 힌트(`canRetryWithDeviceToken=true`, `recommendedNextStep=retry_with_device_token`)를 반환할 때 캐시된 디바이스 토큰으로 한 번의 제한된 재시도를 시도할 수 있습니다. + - 이제 해당 캐시 토큰 재시도는 디바이스 토큰과 함께 저장된 캐시된 승인 scope를 재사용합니다. 명시적 `deviceToken` / 명시적 `scopes` 호출자는 여전히 캐시된 scope를 상속하지 않고 요청한 scope 세트를 유지합니다. + - 해당 재시도 경로 밖에서 연결 인증 우선순위는 명시적 공유 토큰/비밀번호, 명시적 `deviceToken`, 저장된 디바이스 토큰, bootstrap 토큰 순입니다. + - Bootstrap 토큰 scope 검사는 역할 접두사를 사용합니다. 내장 bootstrap operator allowlist는 operator 요청만 충족합니다. node 또는 다른 비-operator 역할은 여전히 자체 역할 접두사 아래의 scope가 필요합니다. - 수정: + 해결: - - 가장 빠른 방법: `openclaw dashboard`(대시보드 URL을 출력 + 복사하고, 열기를 시도하며, 헤드리스인 경우 SSH 힌트를 표시). + - 가장 빠른 방법: `openclaw dashboard`(대시보드 URL을 출력하고 복사하며, 열기를 시도합니다. headless이면 SSH 힌트를 표시합니다). - 아직 토큰이 없다면: `openclaw doctor --generate-gateway-token`. - - 원격이라면 먼저 터널링하세요: `ssh -N -L 18789:127.0.0.1:18789 user@host` 그런 다음 `http://127.0.0.1:18789/`를 여세요. - - 공유 비밀 모드: `gateway.auth.token` / `OPENCLAW_GATEWAY_TOKEN` 또는 `gateway.auth.password` / `OPENCLAW_GATEWAY_PASSWORD`를 설정한 다음, 일치하는 비밀을 Control UI 설정에 붙여넣으세요. - - Tailscale Serve 모드: `gateway.auth.allowTailscale`이 활성화되어 있고 Tailscale ID 헤더를 우회하는 원시 loopback/tailnet URL이 아니라 Serve URL을 열고 있는지 확인하세요. - - 신뢰할 수 있는 프록시 모드: 원시 Gateway URL이 아니라 구성된 ID 인식 프록시를 통해 접속하고 있는지 확인하세요. 같은 호스트의 loopback 프록시도 `gateway.auth.trustedProxy.allowLoopback = true`가 필요합니다. - - 한 번의 재시도 후에도 불일치가 지속되면 페어링된 디바이스 토큰을 교체/재승인하세요: + - 원격이라면 먼저 터널링하세요: `ssh -N -L 18789:127.0.0.1:18789 user@host` 후 `http://127.0.0.1:18789/`를 여세요. + - 공유 비밀 모드: `gateway.auth.token` / `OPENCLAW_GATEWAY_TOKEN` 또는 `gateway.auth.password` / `OPENCLAW_GATEWAY_PASSWORD`를 설정한 다음, 일치하는 비밀을 제어 UI 설정에 붙여넣으세요. + - Tailscale Serve 모드: `gateway.auth.allowTailscale`이 활성화되어 있고, Tailscale 식별 헤더를 우회하는 원시 loopback/tailnet URL이 아니라 Serve URL을 열고 있는지 확인하세요. + - 신뢰 프록시 모드: 원시 gateway URL이 아니라 설정된 identity-aware 프록시를 통해 들어오고 있는지 확인하세요. 동일 호스트 loopback 프록시에도 `gateway.auth.trustedProxy.allowLoopback = true`가 필요합니다. + - 한 번의 재시도 후에도 불일치가 지속되면 페어링된 디바이스 토큰을 순환/재승인하세요. - `openclaw devices list` - `openclaw devices rotate --device --role operator` - - 해당 rotate 호출이 거부되었다고 표시되면 두 가지를 확인하세요: - - 페어링된 디바이스 세션은 `operator.admin`도 보유하지 않는 한 **자신의** 디바이스만 교체할 수 있습니다 - - 명시적 `--scope` 값은 호출자의 현재 operator scope를 초과할 수 없습니다 - - 아직 막혀 있나요? `openclaw status --all`을 실행하고 [문제 해결](/ko/gateway/troubleshooting)을 따르세요. 인증 세부 정보는 [Dashboard](/ko/web/dashboard)를 참조하세요. + - 해당 rotate 호출이 거부되었다고 표시되면 두 가지를 확인하세요. + - 페어링된 디바이스 세션은 `operator.admin`도 가지고 있지 않은 한 **자신의** 디바이스만 순환할 수 있습니다. + - 명시적 `--scope` 값은 호출자의 현재 operator scope를 초과할 수 없습니다. + - 아직 막혀 있나요? `openclaw status --all`을 실행하고 [문제 해결](/ko/gateway/troubleshooting)을 따르세요. 인증 세부 정보는 [대시보드](/ko/web/dashboard)를 참고하세요. - - `tailnet` 바인딩은 네트워크 인터페이스에서 Tailscale IP(100.64.0.0/10)를 선택합니다. 머신이 Tailscale에 없거나 인터페이스가 내려가 있으면 바인딩할 대상이 없습니다. + + `tailnet` 바인딩은 네트워크 인터페이스에서 Tailscale IP를 선택합니다(100.64.0.0/10). 머신이 Tailscale에 없거나 인터페이스가 내려가 있으면 바인딩할 대상이 없습니다. - 수정: + 해결: - - 해당 호스트에서 Tailscale을 시작하세요(100.x 주소를 갖도록). 또는 + - 해당 호스트에서 Tailscale을 시작하거나(100.x 주소를 갖도록), 또는 - `gateway.bind: "loopback"` / `"lan"`으로 전환하세요. - 참고: `tailnet`은 명시적입니다. `auto`는 loopback을 선호합니다. tailnet 전용 바인딩을 원할 때는 `gateway.bind: "tailnet"`을 사용하세요. + 참고: `tailnet`은 명시적입니다. `auto`는 loopback을 선호합니다. tailnet 전용 바인딩을 원하면 `gateway.bind: "tailnet"`을 사용하세요. - 보통은 아니요. 하나의 Gateway가 여러 메시징 채널과 에이전트를 실행할 수 있습니다. 중복성(예: 구조용 봇)이나 강한 격리가 필요할 때만 여러 Gateway를 사용하세요. + 일반적으로는 아니요. 하나의 Gateway가 여러 메시징 채널과 에이전트를 실행할 수 있습니다. 중복성(예: 구조 봇) 또는 강한 격리가 필요할 때만 여러 Gateway를 사용하세요. - 가능하지만 반드시 격리해야 합니다: + 가능하지만 다음을 격리해야 합니다. - - `OPENCLAW_CONFIG_PATH`(인스턴스별 구성) - - `OPENCLAW_STATE_DIR`(인스턴스별 상태) - - `agents.defaults.workspace`(워크스페이스 격리) - - `gateway.port`(고유 포트) + - `OPENCLAW_CONFIG_PATH` (인스턴스별 설정) + - `OPENCLAW_STATE_DIR` (인스턴스별 상태) + - `agents.defaults.workspace` (워크스페이스 격리) + - `gateway.port` (고유 포트) 빠른 설정(권장): - - 인스턴스별로 `openclaw --profile ...`를 사용하세요(`~/.openclaw-`을 자동 생성). - - 각 프로필 구성에서 고유한 `gateway.port`를 설정하세요(또는 수동 실행 시 `--port` 전달). + - 인스턴스마다 `openclaw --profile ...`를 사용하세요(`~/.openclaw-` 자동 생성). + - 각 프로필 설정에서 고유한 `gateway.port`를 설정하세요(또는 수동 실행 시 `--port` 전달). - 프로필별 서비스를 설치하세요: `openclaw --profile gateway install`. 프로필은 서비스 이름에도 접미사를 붙입니다(`ai.openclaw.`; 레거시 `com.openclaw.*`, `openclaw-gateway-.service`, `OpenClaw Gateway ()`). - 전체 가이드: [여러 Gateway](/ko/gateway/multiple-gateways). + 전체 가이드: [여러 gateway](/ko/gateway/multiple-gateways). - - Gateway는 **WebSocket 서버**이며, 첫 번째 메시지가 - `connect` 프레임이기를 기대합니다. 다른 것을 받으면 **코드 1008**(정책 위반)로 + + Gateway는 **WebSocket 서버**이며, 맨 처음 메시지로 + `connect` 프레임을 기대합니다. 그 외의 것을 받으면 **코드 1008**(정책 위반)로 연결을 닫습니다. - 일반적인 원인: + 흔한 원인: - WS 클라이언트 대신 브라우저에서 **HTTP** URL(`http://...`)을 열었습니다. - - 잘못된 포트나 경로를 사용했습니다. + - 잘못된 포트 또는 경로를 사용했습니다. - 프록시나 터널이 인증 헤더를 제거했거나 Gateway가 아닌 요청을 보냈습니다. - 빠른 수정: + 빠른 해결: - 1. WS URL을 사용하세요: `ws://:18789`(또는 HTTPS인 경우 `wss://...`). + 1. WS URL을 사용하세요: `ws://:18789`(HTTPS이면 `wss://...`). 2. 일반 브라우저 탭에서 WS 포트를 열지 마세요. 3. 인증이 켜져 있으면 `connect` 프레임에 토큰/비밀번호를 포함하세요. - CLI 또는 TUI를 사용하는 경우 URL은 다음과 같아야 합니다: + CLI 또는 TUI를 사용하는 경우 URL은 다음과 같아야 합니다. ``` openclaw tui --url ws://:18789 --token @@ -1553,7 +1547,7 @@ x-i18n: /tmp/openclaw/openclaw-YYYY-MM-DD.log ``` - `logging.file`을 통해 안정적인 경로를 설정할 수 있습니다. 파일 로그 레벨은 `logging.level`로 제어됩니다. 콘솔 상세도는 `--verbose`와 `logging.consoleLevel`로 제어됩니다. + `logging.file`을 통해 안정적인 경로를 설정할 수 있습니다. 파일 로그 레벨은 `logging.level`로 제어합니다. 콘솔 상세도는 `--verbose`와 `logging.consoleLevel`로 제어합니다. 가장 빠른 로그 tail: @@ -1561,34 +1555,34 @@ x-i18n: openclaw logs --follow ``` - 서비스/슈퍼바이저 로그(Gateway가 launchd/systemd를 통해 실행될 때): + 서비스/supervisor 로그(gateway가 launchd/systemd를 통해 실행될 때): - macOS: `$OPENCLAW_STATE_DIR/logs/gateway.log` 및 `gateway.err.log`(기본값: `~/.openclaw/logs/...`; 프로필은 `~/.openclaw-/logs/...` 사용) - Linux: `journalctl --user -u openclaw-gateway[-].service -n 200 --no-pager` - Windows: `schtasks /Query /TN "OpenClaw Gateway ()" /V /FO LIST` - 자세한 내용은 [문제 해결](/ko/gateway/troubleshooting)을 참조하세요. + 자세한 내용은 [문제 해결](/ko/gateway/troubleshooting)을 참고하세요. - Gateway 헬퍼를 사용하세요: + gateway helper를 사용하세요. ```bash openclaw gateway status openclaw gateway restart ``` - Gateway를 수동으로 실행하는 경우 `openclaw gateway --force`로 포트를 회수할 수 있습니다. [Gateway](/ko/gateway)를 참조하세요. + gateway를 수동으로 실행하는 경우 `openclaw gateway --force`가 포트를 회수할 수 있습니다. [Gateway](/ko/gateway)를 참고하세요. - **두 가지 Windows 설치 모드**가 있습니다: + **두 가지 Windows 설치 모드**가 있습니다. - **1) WSL2(권장):** Gateway가 Linux 내부에서 실행됩니다. + **1) WSL2(권장):** Gateway가 Linux 안에서 실행됩니다. - PowerShell을 열고 WSL에 들어간 다음 재시작하세요: + PowerShell을 열고 WSL에 들어간 다음 재시작하세요. ```powershell wsl @@ -1596,7 +1590,7 @@ x-i18n: openclaw gateway restart ``` - 서비스를 설치한 적이 없다면 포그라운드에서 시작하세요: + 서비스를 설치한 적이 없다면 foreground에서 시작하세요. ```bash openclaw gateway run @@ -1604,25 +1598,25 @@ x-i18n: **2) 네이티브 Windows(권장하지 않음):** Gateway가 Windows에서 직접 실행됩니다. - PowerShell을 열고 실행하세요: + PowerShell을 열고 실행하세요. ```powershell openclaw gateway status openclaw gateway restart ``` - 수동으로 실행하는 경우(서비스 없음) 다음을 사용하세요: + 수동으로 실행하는 경우(서비스 없음) 다음을 사용하세요. ```powershell openclaw gateway run ``` - 문서: [Windows (WSL2)](/ko/platforms/windows), [Gateway 서비스 runbook](/ko/gateway). + 문서: [Windows(WSL2)](/ko/platforms/windows), [Gateway 서비스 runbook](/ko/gateway). - - 빠른 상태 점검부터 시작하세요: + + 빠른 상태 점검부터 시작하세요. ```bash openclaw status @@ -1631,13 +1625,13 @@ x-i18n: openclaw logs --follow ``` - 일반적인 원인: + 흔한 원인: - - 모델 인증이 **Gateway 호스트**에 로드되지 않음(`models status` 확인). + - **Gateway 호스트**에서 모델 인증이 로드되지 않음(`models status` 확인). - 채널 페어링/허용 목록이 응답을 차단함(채널 구성 + 로그 확인). - - 올바른 토큰 없이 WebChat/Dashboard가 열려 있음. + - WebChat/Dashboard가 올바른 토큰 없이 열려 있음. - 원격이라면 터널/Tailscale 연결이 올라와 있고 + 원격 환경이라면 터널/Tailscale 연결이 활성화되어 있고 Gateway WebSocket에 도달할 수 있는지 확인하세요. 문서: [채널](/ko/channels), [문제 해결](/ko/gateway/troubleshooting), [원격 접근](/ko/gateway/remote). @@ -1645,44 +1639,44 @@ x-i18n: - 이는 일반적으로 UI가 WebSocket 연결을 잃었다는 뜻입니다. 다음을 확인하세요: + 이는 보통 UI가 WebSocket 연결을 잃었다는 뜻입니다. 다음을 확인하세요. 1. Gateway가 실행 중인가요? `openclaw gateway status` 2. Gateway가 정상인가요? `openclaw status` 3. UI에 올바른 토큰이 있나요? `openclaw dashboard` - 4. 원격이라면 터널/Tailscale 링크가 연결되어 있나요? + 4. 원격 환경이라면 터널/Tailscale 링크가 활성화되어 있나요? - 그런 다음 로그를 추적하세요. + 그런 다음 로그를 tail하세요. ```bash openclaw logs --follow ``` - 문서: [대시보드](/ko/web/dashboard), [원격 액세스](/ko/gateway/remote), [문제 해결](/ko/gateway/troubleshooting). + 문서: [Dashboard](/ko/web/dashboard), [원격 접근](/ko/gateway/remote), [문제 해결](/ko/gateway/troubleshooting). - 로그와 채널 상태부터 시작하세요. + 로그와 채널 상태부터 확인하세요. ```bash openclaw channels status openclaw channels logs --channel telegram ``` - 그런 다음 오류를 대조하세요. + 그런 다음 오류와 맞춰 보세요. - - `BOT_COMMANDS_TOO_MUCH`: Telegram 메뉴 항목이 너무 많습니다. OpenClaw는 이미 Telegram 제한에 맞게 줄이고 더 적은 명령으로 다시 시도하지만, 일부 메뉴 항목은 여전히 제거해야 합니다. Plugin/skill/사용자 지정 명령을 줄이거나, 메뉴가 필요 없다면 `channels.telegram.commands.native`를 비활성화하세요. - - `TypeError: fetch failed`, `Network request for 'setMyCommands' failed!` 또는 유사한 네트워크 오류: VPS를 사용 중이거나 프록시 뒤에 있다면 아웃바운드 HTTPS가 허용되어 있고 `api.telegram.org`에 대해 DNS가 작동하는지 확인하세요. + - `BOT_COMMANDS_TOO_MUCH`: Telegram 메뉴 항목이 너무 많습니다. OpenClaw는 이미 Telegram 제한에 맞게 줄인 뒤 더 적은 명령으로 다시 시도하지만, 그래도 일부 메뉴 항목을 제거해야 합니다. Plugin/skill/사용자 지정 명령을 줄이거나, 메뉴가 필요하지 않다면 `channels.telegram.commands.native`를 비활성화하세요. + - `TypeError: fetch failed`, `Network request for 'setMyCommands' failed!` 또는 유사한 네트워크 오류: VPS를 사용 중이거나 프록시 뒤에 있다면 아웃바운드 HTTPS가 허용되고 `api.telegram.org`에 대한 DNS가 작동하는지 확인하세요. - Gateway가 원격이라면 Gateway 호스트의 로그를 보고 있는지 확인하세요. + Gateway가 원격에 있다면 Gateway 호스트의 로그를 보고 있는지 확인하세요. 문서: [Telegram](/ko/channels/telegram), [채널 문제 해결](/ko/channels/troubleshooting). - 먼저 Gateway에 연결할 수 있고 에이전트가 실행될 수 있는지 확인하세요. + 먼저 Gateway에 도달할 수 있고 에이전트가 실행될 수 있는지 확인하세요. ```bash openclaw status @@ -1690,14 +1684,14 @@ x-i18n: openclaw logs --follow ``` - TUI에서 현재 상태를 보려면 `/status`를 사용하세요. 채팅 - 채널에서 답장을 기대한다면 전송이 활성화되어 있는지 확인하세요(`/deliver on`). + TUI에서 `/status`를 사용해 현재 상태를 확인하세요. 채팅 + 채널에서 응답을 기대한다면 전달이 활성화되어 있는지 확인하세요(`/deliver on`). 문서: [TUI](/ko/web/tui), [슬래시 명령](/ko/tools/slash-commands). - + 서비스를 설치했다면: ```bash @@ -1708,7 +1702,7 @@ x-i18n: 이는 **감독되는 서비스**(macOS의 launchd, Linux의 systemd)를 중지/시작합니다. Gateway가 데몬으로 백그라운드에서 실행될 때 사용하세요. - 포그라운드에서 실행 중이라면 Ctrl-C로 중지한 다음: + 포그라운드에서 실행 중이라면 Ctrl-C로 중지한 뒤 다음을 실행하세요. ```bash openclaw gateway run @@ -1722,13 +1716,13 @@ x-i18n: - `openclaw gateway restart`: **백그라운드 서비스**(launchd/systemd)를 다시 시작합니다. - `openclaw gateway`: 이 터미널 세션에서 Gateway를 **포그라운드로** 실행합니다. - 서비스를 설치했다면 gateway 명령을 사용하세요. 일회성 포그라운드 실행을 + 서비스를 설치했다면 Gateway 명령을 사용하세요. 일회성 포그라운드 실행을 원할 때는 `openclaw gateway`를 사용하세요. - - 더 많은 콘솔 세부 정보를 얻으려면 `--verbose`로 Gateway를 시작하세요. 그런 다음 채널 인증, 모델 라우팅, RPC 오류를 로그 파일에서 검사하세요. + + 더 자세한 콘솔 정보를 얻으려면 `--verbose`로 Gateway를 시작하세요. 그런 다음 채널 인증, 모델 라우팅, RPC 오류를 로그 파일에서 확인하세요. @@ -1736,7 +1730,7 @@ x-i18n: - 에이전트의 아웃바운드 첨부 파일에는 `MEDIA:` 줄이 포함되어야 합니다(별도 줄). [OpenClaw 어시스턴트 설정](/ko/start/openclaw) 및 [에이전트 전송](/ko/tools/agent-send)을 참조하세요. + 에이전트의 아웃바운드 첨부 파일에는 반드시 `MEDIA:` 줄이 포함되어야 합니다(그 자체로 한 줄). [OpenClaw 어시스턴트 설정](/ko/start/openclaw) 및 [에이전트 전송](/ko/tools/agent-send)을 참조하세요. CLI 전송: @@ -1744,11 +1738,11 @@ x-i18n: openclaw message send --target +15555550123 --message "Here you go" --media /path/to/file.png ``` - 다음도 확인하세요. + 또한 다음을 확인하세요. - - 대상 채널이 아웃바운드 미디어를 지원하며 허용 목록에 의해 차단되지 않았습니다. - - 파일이 제공자의 크기 제한 내에 있습니다(이미지는 최대 2048px로 크기 조정됨). - - `tools.fs.workspaceOnly=true`는 로컬 경로 전송을 워크스페이스, 임시/미디어 저장소, sandbox 검증 파일로 제한합니다. + - 대상 채널이 아웃바운드 미디어를 지원하며 허용 목록에 의해 차단되지 않았는지. + - 파일이 제공자의 크기 제한 내에 있는지(이미지는 최대 2048px로 크기가 조정됩니다). + - `tools.fs.workspaceOnly=true`는 로컬 경로 전송을 workspace, temp/media-store, 샌드박스 검증 파일로 제한합니다. - `tools.fs.workspaceOnly=false`는 에이전트가 이미 읽을 수 있는 호스트 로컬 파일을 `MEDIA:`로 보낼 수 있게 하지만, 미디어와 안전한 문서 유형(이미지, 오디오, 비디오, PDF, Office 문서)에만 해당합니다. 일반 텍스트와 비밀처럼 보이는 파일은 여전히 차단됩니다. [이미지](/ko/nodes/images)를 참조하세요. @@ -1756,60 +1750,60 @@ x-i18n: -## 보안 및 액세스 제어 +## 보안 및 접근 제어 - 인바운드 DM을 신뢰할 수 없는 입력으로 취급하세요. 기본값은 위험을 줄이도록 설계되어 있습니다. + 인바운드 DM은 신뢰할 수 없는 입력으로 취급하세요. 기본값은 위험을 줄이도록 설계되어 있습니다. - DM 가능 채널의 기본 동작은 **페어링**입니다. - 알 수 없는 발신자는 페어링 코드를 받으며, 봇은 해당 메시지를 처리하지 않습니다. - - 다음으로 승인하세요: `openclaw pairing approve --channel [--account ] ` + - 승인: `openclaw pairing approve --channel [--account ] ` - 대기 중인 요청은 **채널당 3개**로 제한됩니다. 코드가 도착하지 않았다면 `openclaw pairing list --channel [--account ]`를 확인하세요. - - DM을 공개로 열려면 명시적인 옵트인이 필요합니다(`dmPolicy: "open"` 및 허용 목록 `"*"`). + - DM을 공개적으로 열려면 명시적인 옵트인이 필요합니다(`dmPolicy: "open"` 및 허용 목록 `"*"`). 위험한 DM 정책을 드러내려면 `openclaw doctor`를 실행하세요. - - 아닙니다. 프롬프트 인젝션은 봇에게 DM을 보낼 수 있는 사람이 누구인지뿐 아니라 **신뢰할 수 없는 콘텐츠**에 관한 문제입니다. + + 아닙니다. 프롬프트 인젝션은 봇에 DM을 보낼 수 있는 사람이 아니라 **신뢰할 수 없는 콘텐츠**에 관한 문제입니다. 어시스턴트가 외부 콘텐츠(웹 검색/가져오기, 브라우저 페이지, 이메일, 문서, 첨부 파일, 붙여넣은 로그)를 읽는다면, 그 콘텐츠에는 모델을 - 탈취하려는 지시가 포함될 수 있습니다. 이는 **당신이 유일한 발신자**인 경우에도 발생할 수 있습니다. + 가로채려는 지시가 포함될 수 있습니다. 이는 **당신이 유일한 발신자**인 경우에도 발생할 수 있습니다. - 가장 큰 위험은 도구가 활성화되어 있을 때입니다. 모델이 속아서 - 컨텍스트를 유출하거나 사용자를 대신해 도구를 호출할 수 있습니다. 다음으로 영향 범위를 줄이세요. + 가장 큰 위험은 도구가 활성화되어 있을 때입니다. 모델이 속아서 컨텍스트를 + 유출하거나 당신을 대신해 도구를 호출할 수 있습니다. 영향을 줄이려면: - - 신뢰할 수 없는 콘텐츠를 요약할 때 읽기 전용 또는 도구가 비활성화된 "reader" 에이전트 사용 - - 도구 활성화 에이전트에서는 `web_search` / `web_fetch` / `browser` 끄기 - - 디코딩된 파일/문서 텍스트도 신뢰할 수 없는 것으로 취급: OpenResponses - `input_file` 및 미디어 첨부 파일 추출은 모두 원시 파일 텍스트를 전달하는 대신 + - 신뢰할 수 없는 콘텐츠를 요약할 때 읽기 전용 또는 도구 비활성화 "reader" 에이전트를 사용하세요. + - 도구 활성화 에이전트에서는 `web_search` / `web_fetch` / `browser`를 꺼 두세요. + - 디코딩된 파일/문서 텍스트도 신뢰할 수 없는 것으로 취급하세요. OpenResponses + `input_file`과 미디어 첨부 파일 추출은 모두 원시 파일 텍스트를 전달하는 대신 추출된 텍스트를 명시적인 외부 콘텐츠 경계 마커로 감쌉니다. - - sandbox와 엄격한 도구 허용 목록 사용 + - 샌드박싱과 엄격한 도구 허용 목록을 사용하세요. - 세부 정보: [보안](/ko/gateway/security). + 자세히: [보안](/ko/gateway/security). - 대부분의 설정에서는 그렇습니다. 별도 계정과 전화번호로 봇을 격리하면 - 문제가 발생했을 때 영향 범위를 줄일 수 있습니다. 또한 개인 계정에 영향을 주지 않고 - 자격 증명을 교체하거나 액세스를 취소하기가 더 쉬워집니다. + 대부분의 설정에서는 그렇습니다. 봇을 별도의 계정과 전화번호로 격리하면 + 문제가 생겼을 때 영향을 줄일 수 있습니다. 또한 개인 계정에 영향을 주지 않고 + 자격 증명을 교체하거나 접근 권한을 취소하기가 더 쉬워집니다. - 작게 시작하세요. 실제로 필요한 도구와 계정에만 액세스를 부여하고, 필요할 때 + 작게 시작하세요. 실제로 필요한 도구와 계정에만 접근 권한을 주고, 필요하면 나중에 확장하세요. 문서: [보안](/ko/gateway/security), [페어링](/ko/channels/pairing). - - 개인 메시지에 대한 완전한 자율성은 권장하지 **않습니다**. 가장 안전한 패턴은 다음과 같습니다. + + 개인 메시지에 대한 완전한 자율성은 권장하지 않습니다. 가장 안전한 패턴은 다음과 같습니다. - DM을 **페어링 모드** 또는 엄격한 허용 목록으로 유지하세요. - - 대신 메시지를 보내게 하려면 **별도 번호 또는 계정**을 사용하세요. - - 초안을 작성하게 한 뒤 **전송 전에 승인**하세요. + - 대신 메시지를 보내게 하려면 **별도 번호나 계정**을 사용하세요. + - 먼저 초안을 만들게 한 뒤, **전송 전에 승인**하세요. 실험하고 싶다면 전용 계정에서 수행하고 격리 상태를 유지하세요. [보안](/ko/gateway/security)을 참조하세요. @@ -1817,9 +1811,9 @@ x-i18n: 예, 에이전트가 채팅 전용이고 입력을 신뢰할 수 **있다면** 가능합니다. 더 작은 티어는 - 지시 탈취에 더 취약하므로, 도구 활성화 에이전트나 - 신뢰할 수 없는 콘텐츠를 읽을 때는 피하세요. 더 작은 모델을 반드시 사용해야 한다면 - 도구를 잠그고 sandbox 안에서 실행하세요. [보안](/ko/gateway/security)을 참조하세요. + 지시 가로채기에 더 취약하므로, 도구 활성화 에이전트나 + 신뢰할 수 없는 콘텐츠를 읽을 때는 피하세요. 더 작은 모델을 꼭 사용해야 한다면 + 도구를 잠그고 샌드박스 안에서 실행하세요. [보안](/ko/gateway/security)을 참조하세요. @@ -1832,15 +1826,14 @@ x-i18n: openclaw pairing list telegram ``` - 즉시 액세스하려면 발신자 ID를 허용 목록에 추가하거나 해당 계정의 `dmPolicy: "open"`을 - 설정하세요. + 즉시 접근하려면 발신자 ID를 허용 목록에 추가하거나 해당 계정의 `dmPolicy: "open"`을 설정하세요. - - 아닙니다. 기본 WhatsApp DM 정책은 **페어링**입니다. 알 수 없는 발신자는 페어링 코드만 받고 해당 메시지는 **처리되지 않습니다**. OpenClaw는 수신한 채팅이나 사용자가 명시적으로 트리거한 전송에만 답장합니다. + + 아닙니다. 기본 WhatsApp DM 정책은 **페어링**입니다. 알 수 없는 발신자는 페어링 코드만 받으며, 해당 메시지는 **처리되지 않습니다**. OpenClaw는 수신한 채팅이나 사용자가 명시적으로 트리거한 전송에만 응답합니다. - 다음으로 페어링을 승인하세요. + 다음으로 페어링 승인: ```bash openclaw pairing approve whatsapp @@ -1852,7 +1845,7 @@ x-i18n: openclaw pairing list whatsapp ``` - 마법사의 전화번호 프롬프트: 자신의 DM이 허용되도록 **허용 목록/소유자**를 설정하는 데 사용됩니다. 자동 전송에는 사용되지 않습니다. 개인 WhatsApp 번호에서 실행한다면 그 번호를 사용하고 `channels.whatsapp.selfChatMode`를 활성화하세요. + 마법사의 전화번호 프롬프트: 자신의 DM을 허용하기 위해 **허용 목록/소유자**를 설정하는 데 사용됩니다. 자동 전송에는 사용되지 않습니다. 개인 WhatsApp 번호에서 실행한다면 해당 번호를 사용하고 `channels.whatsapp.selfChatMode`를 활성화하세요. @@ -1861,10 +1854,9 @@ x-i18n: - 대부분의 내부 또는 도구 메시지는 해당 세션에서 **verbose**, **trace** 또는 **reasoning**이 활성화된 경우에만 - 나타납니다. + 대부분의 내부 메시지 또는 도구 메시지는 해당 세션에서 **verbose**, **trace** 또는 **reasoning**이 활성화된 경우에만 나타납니다. - 메시지가 보이는 채팅에서 수정하세요. + 해당 메시지가 보이는 채팅에서 수정하세요. ``` /verbose off @@ -1872,16 +1864,16 @@ x-i18n: /reasoning off ``` - 여전히 시끄럽다면 Control UI에서 세션 설정을 확인하고 verbose를 - **inherit**으로 설정하세요. 또한 구성에서 `verboseDefault`가 `on`으로 설정된 봇 프로필을 - 사용하고 있지 않은지도 확인하세요. + 그래도 여전히 시끄럽다면 Control UI에서 세션 설정을 확인하고 verbose를 + **inherit**으로 설정하세요. 또한 구성에서 `verboseDefault`가 + `on`으로 설정된 봇 프로필을 사용 중이 아닌지도 확인하세요. - 문서: [사고 및 verbose](/ko/tools/thinking), [보안](/ko/gateway/security/index#reasoning-and-verbose-output-in-groups). + 문서: [사고 과정과 verbose](/ko/tools/thinking), [보안](/ko/gateway/security/index#reasoning-and-verbose-output-in-groups). - 다음 중 하나를 **독립 메시지로** 보내세요(슬래시 없음). + 다음 중 하나를 **단독 메시지로** 보내세요(슬래시 없음). ``` stop @@ -1905,25 +1897,25 @@ x-i18n: interrupt ``` - 이들은 중단 트리거입니다(슬래시 명령이 아님). + 이는 중단 트리거입니다(슬래시 명령이 아님). - 백그라운드 프로세스(exec 도구에서 시작된 경우)의 경우 에이전트에게 다음을 실행하도록 요청할 수 있습니다. + 백그라운드 프로세스(exec 도구에서 시작한 것)의 경우 에이전트에게 다음을 실행하도록 요청할 수 있습니다. ``` process action:kill sessionId:XXX ``` - 슬래시 명령 개요는 [슬래시 명령](/ko/tools/slash-commands)을 참조하세요. + 슬래시 명령 개요: [슬래시 명령](/ko/tools/slash-commands)을 참조하세요. - 대부분의 명령은 `/`로 시작하는 **독립** 메시지로 보내야 하지만, 일부 바로가기(`/status` 등)는 허용 목록에 있는 발신자에게 인라인으로도 작동합니다. + 대부분의 명령은 `/`로 시작하는 **단독** 메시지로 보내야 하지만, 몇 가지 단축 명령(`/status` 등)은 허용 목록에 있는 발신자에게 인라인으로도 작동합니다. OpenClaw는 기본적으로 **교차 제공자** 메시징을 차단합니다. 도구 호출이 - Telegram에 바인딩되어 있으면 명시적으로 허용하지 않는 한 Discord로 전송되지 않습니다. + Telegram에 바인딩되어 있다면 명시적으로 허용하지 않는 한 Discord로 전송되지 않습니다. - 에이전트에 교차 제공자 메시징을 활성화하세요. + 에이전트에 대해 교차 제공자 메시징을 활성화하세요. ```json5 { @@ -1938,21 +1930,21 @@ x-i18n: } ``` - 구성을 편집한 후 Gateway를 다시 시작하세요. + 구성을 편집한 뒤 Gateway를 다시 시작하세요. - - 큐 모드는 새 메시지가 진행 중인 실행과 상호작용하는 방식을 제어합니다. 모드를 변경하려면 `/queue`를 사용하세요. + + 큐 모드는 새 메시지가 진행 중인 실행과 상호 작용하는 방식을 제어합니다. 모드를 변경하려면 `/queue`를 사용하세요. - - `steer` - 현재 실행의 다음 모델 경계까지 모든 대기 중인 steering을 큐에 넣음 - - `queue` - 레거시 한 번에 하나씩 steering - - `followup` - 메시지를 하나씩 실행 - - `collect` - 메시지를 일괄 처리하고 한 번만 답장 - - `steer-backlog` - 지금 steer한 다음 backlog 처리 + - `steer` - 현재 실행의 다음 모델 경계까지 대기 중인 모든 조향을 큐에 넣습니다. + - `queue` - 기존의 한 번에 하나씩 처리하는 조향 + - `followup` - 메시지를 한 번에 하나씩 실행 + - `collect` - 메시지를 묶어서 한 번만 응답 + - `steer-backlog` - 지금 조향한 뒤 백로그 처리 - `interrupt` - 현재 실행을 중단하고 새로 시작 - 기본 모드는 `steer`입니다. followup 모드에는 `debounce:0.5s cap:25 drop:summarize` 같은 옵션을 추가할 수 있습니다. [명령 큐](/ko/concepts/queue) 및 [Steering 큐](/ko/concepts/queue-steering)를 참조하세요. + 기본 모드는 `steer`입니다. 후속 모드에는 `debounce:0.5s cap:25 drop:summarize` 같은 옵션을 추가할 수 있습니다. [명령 큐](/ko/concepts/queue) 및 [Steering 큐](/ko/concepts/queue-steering)를 참조하세요. @@ -1961,16 +1953,16 @@ x-i18n: - OpenClaw에서는 자격 증명과 모델 선택이 별개입니다. `ANTHROPIC_API_KEY`를 설정하거나 Anthropic API 키를 인증 프로필에 저장하면 인증이 활성화되지만, 실제 기본 모델은 `agents.defaults.model.primary`에 구성한 값입니다(예: `anthropic/claude-sonnet-4-6` 또는 `anthropic/claude-opus-4-6`). `No credentials found for profile "anthropic:default"`가 표시되면 실행 중인 에이전트의 예상 `auth-profiles.json`에서 Gateway가 Anthropic 자격 증명을 찾지 못했다는 뜻입니다. + OpenClaw에서는 자격 증명과 모델 선택이 분리되어 있습니다. `ANTHROPIC_API_KEY`를 설정하거나 auth profiles에 Anthropic API 키를 저장하면 인증이 활성화되지만, 실제 기본 모델은 `agents.defaults.model.primary`에 구성한 값입니다(예: `anthropic/claude-sonnet-4-6` 또는 `anthropic/claude-opus-4-6`). `No credentials found for profile "anthropic:default"`가 표시되면 실행 중인 agent의 예상 `auth-profiles.json`에서 Gateway가 Anthropic 자격 증명을 찾지 못했다는 뜻입니다. --- -아직 막혀 있나요? [Discord](https://discord.com/invite/clawd)에서 질문하거나 [GitHub 토론](https://github.com/openclaw/openclaw/discussions)을 열어 주세요. +아직 막혀 있나요? [Discord](https://discord.com/invite/clawd)에서 문의하거나 [GitHub discussion](https://github.com/openclaw/openclaw/discussions)을 여세요. -## 관련 문서 +## 관련 항목 -- [최초 실행 FAQ](/ko/help/faq-first-run) — 설치, 온보딩, 인증, 구독, 초기 오류 -- [모델 FAQ](/ko/help/faq-models) — 모델 선택, 장애 조치, 인증 프로필 +- [첫 실행 FAQ](/ko/help/faq-first-run) — 설치, 온보딩, 인증, 구독, 초기 오류 +- [모델 FAQ](/ko/help/faq-models) — 모델 선택, 장애 조치, auth profiles - [문제 해결](/ko/help/troubleshooting) — 증상 우선 분류 diff --git a/docs/ko/install/fly.md b/docs/ko/install/fly.md index f4e6cef40..a8c27b3de 100644 --- a/docs/ko/install/fly.md +++ b/docs/ko/install/fly.md @@ -1,38 +1,36 @@ --- read_when: - - Fly.io에 OpenClaw 배포하기 - - Fly 볼륨, 시크릿 및 최초 실행 구성 설정 -summary: 영구 저장소와 HTTPS를 사용하는 OpenClaw의 단계별 Fly.io 배포 + - Fly.io에서 OpenClaw 배포하기 + - Fly 볼륨, 시크릿 및 첫 실행 구성 설정하기 +summary: 영구 스토리지와 HTTPS를 사용하는 OpenClaw의 단계별 Fly.io 배포 title: Fly.io x-i18n: - generated_at: "2026-05-03T21:34:44Z" + generated_at: "2026-05-06T17:57:17Z" model: gpt-5.5 provider: openai - source_hash: d9b98b2d1c102195e31ee7e93ba075e6cfa16080e78f8e17fc006a62d300ce1a + source_hash: 534a94e4ff69542604ba3112d468b7274492c18b3c5054f47379c21421f518bd source_path: install/fly.md workflow: 16 --- -# Fly.io 배포 - -**목표:** 영구 저장소, 자동 HTTPS, Discord/채널 접근 권한을 갖춘 [Fly.io](https://fly.io) 머신에서 OpenClaw Gateway를 실행합니다. +**목표:** 영구 스토리지, 자동 HTTPS, Discord/채널 접근이 포함된 [Fly.io](https://fly.io) 머신에서 OpenClaw Gateway 실행. ## 필요한 것 - [flyctl CLI](https://fly.io/docs/hands-on/install-flyctl/) 설치 - Fly.io 계정(무료 티어 사용 가능) -- 모델 인증: 선택한 모델 제공자의 API 키 +- 모델 인증: 선택한 모델 제공업체의 API 키 - 채널 자격 증명: Discord 봇 토큰, Telegram 토큰 등 ## 초보자 빠른 경로 -1. 저장소 복제 → `fly.toml` 사용자 지정 +1. 저장소 클론 → `fly.toml` 사용자 지정 2. 앱 + 볼륨 생성 → 시크릿 설정 3. `fly deploy`로 배포 -4. SSH로 접속해 설정을 만들거나 제어 UI 사용 +4. SSH로 접속해 구성 생성 또는 Control UI 사용 - + ```bash # Clone the repo git clone https://github.com/openclaw/openclaw.git @@ -45,14 +43,14 @@ x-i18n: fly volumes create openclaw_data --size 1 --region iad ``` - **팁:** 가까운 리전을 선택하세요. 일반적인 옵션: `lhr`(런던), `iad`(버지니아), `sjc`(샌호세). + **팁:** 가까운 리전을 선택하세요. 일반적인 옵션: `lhr`(런던), `iad`(버지니아), `sjc`(산호세). - 앱 이름과 요구 사항에 맞게 `fly.toml`을 편집합니다. + 앱 이름과 요구사항에 맞게 `fly.toml`을 편집하세요. - **보안 참고:** 기본 설정은 공개 URL을 노출합니다. 공개 IP가 없는 강화된 배포는 [비공개 배포](#private-deployment-hardened)를 보거나 `deploy/fly.private.toml`을 사용하세요. + **보안 참고:** 기본 구성은 공개 URL을 노출합니다. 공개 IP가 없는 강화된 배포는 [비공개 배포](#private-deployment-hardened)를 보거나 `deploy/fly.private.toml`을 사용하세요. ```toml app = "my-openclaw" # Your app name @@ -92,10 +90,10 @@ x-i18n: | 설정 | 이유 | | ------------------------------ | --------------------------------------------------------------------------- | | `--bind lan` | Fly 프록시가 Gateway에 도달할 수 있도록 `0.0.0.0`에 바인딩합니다 | - | `--allow-unconfigured` | 설정 파일 없이 시작합니다(나중에 만들게 됩니다) | - | `internal_port = 3000` | Fly 상태 확인을 위해 `--port 3000`(또는 `OPENCLAW_GATEWAY_PORT`)과 일치해야 합니다 | - | `memory = "2048mb"` | 512MB는 너무 작으며 2GB를 권장합니다 | - | `OPENCLAW_STATE_DIR = "/data"` | 볼륨에 상태를 유지합니다 | + | `--allow-unconfigured` | 구성 파일 없이 시작합니다(나중에 생성) | + | `internal_port = 3000` | Fly 헬스 체크를 위해 `--port 3000`(또는 `OPENCLAW_GATEWAY_PORT`)과 일치해야 합니다 | + | `memory = "2048mb"` | 512MB는 너무 작으며, 2GB를 권장합니다 | + | `OPENCLAW_STATE_DIR = "/data"` | 볼륨에 상태를 영구 저장합니다 | @@ -117,9 +115,9 @@ x-i18n: **참고:** - - 루프백이 아닌 바인딩(`--bind lan`)에는 유효한 Gateway 인증 경로가 필요합니다. 이 Fly.io 예시는 `OPENCLAW_GATEWAY_TOKEN`을 사용하지만, `gateway.auth.password` 또는 올바르게 구성된 루프백이 아닌 `trusted-proxy` 배포도 요구 사항을 충족합니다. - - 이러한 토큰은 비밀번호처럼 취급하세요. - - 모든 API 키와 토큰에는 **설정 파일보다 환경 변수 사용을 권장합니다**. 이렇게 하면 시크릿이 실수로 노출되거나 로그에 기록될 수 있는 `openclaw.json`에 들어가지 않습니다. + - 비 loopback 바인딩(`--bind lan`)에는 유효한 Gateway 인증 경로가 필요합니다. 이 Fly.io 예제는 `OPENCLAW_GATEWAY_TOKEN`을 사용하지만, `gateway.auth.password` 또는 올바르게 구성된 비 loopback `trusted-proxy` 배포도 요구사항을 충족합니다. + - 이 토큰들을 비밀번호처럼 취급하세요. + - 모든 API 키와 토큰에는 구성 파일보다 **환경 변수를 선호**하세요. 이렇게 하면 실수로 노출되거나 로그에 남을 수 있는 `openclaw.json`에 시크릿이 들어가지 않습니다. @@ -130,14 +128,14 @@ x-i18n: 첫 배포는 Docker 이미지를 빌드합니다(약 2~3분). 이후 배포는 더 빠릅니다. - 배포 후 확인합니다. + 배포 후 확인하세요. ```bash fly status fly logs ``` - 다음이 표시되어야 합니다. + 다음과 같이 표시되어야 합니다. ``` [gateway] listening on ws://0.0.0.0:3000 (PID xxx) @@ -146,14 +144,14 @@ x-i18n: - - 머신에 SSH로 접속해 적절한 설정을 만듭니다. + + 머신에 SSH로 접속해 적절한 구성을 생성합니다. ```bash fly ssh console ``` - 설정 디렉터리와 파일을 만듭니다. + 구성 디렉터리와 파일을 생성합니다. ```bash mkdir -p /data @@ -214,22 +212,22 @@ x-i18n: EOF ``` - **참고:** `OPENCLAW_STATE_DIR=/data`를 사용하면 설정 경로는 `/data/openclaw.json`입니다. + **참고:** `OPENCLAW_STATE_DIR=/data`를 사용하면 구성 경로는 `/data/openclaw.json`입니다. **참고:** `https://my-openclaw.fly.dev`를 실제 Fly 앱 - 원본으로 바꾸세요. Gateway 시작 시 런타임의 `--bind` 및 `--port` - 값에서 로컬 제어 UI 원본을 시드하므로 설정이 아직 없어도 첫 부팅을 - 진행할 수 있지만, Fly를 통한 브라우저 접근에는 정확한 HTTPS 원본이 - `gateway.controlUi.allowedOrigins`에 나열되어 있어야 합니다. + origin으로 바꾸세요. Gateway 시작 시 런타임의 + `--bind` 및 `--port` 값에서 로컬 Control UI origin을 시드하므로 구성 파일이 없어도 + 첫 부팅을 진행할 수 있지만, Fly를 통한 브라우저 접근에는 + `gateway.controlUi.allowedOrigins`에 정확한 HTTPS origin이 나열되어 있어야 합니다. **참고:** Discord 토큰은 다음 중 하나에서 가져올 수 있습니다. - 환경 변수: `DISCORD_BOT_TOKEN`(시크릿에 권장) - - 설정 파일: `channels.discord.token` + - 구성 파일: `channels.discord.token` - 환경 변수를 사용한다면 설정에 토큰을 추가할 필요가 없습니다. Gateway는 `DISCORD_BOT_TOKEN`을 자동으로 읽습니다. + 환경 변수를 사용하는 경우 구성에 토큰을 추가할 필요가 없습니다. Gateway는 `DISCORD_BOT_TOKEN`을 자동으로 읽습니다. - 적용하려면 다시 시작합니다. + 적용하려면 재시작하세요. ```bash exit @@ -239,7 +237,7 @@ x-i18n: - ### 제어 UI + ### Control UI 브라우저에서 엽니다. @@ -247,10 +245,11 @@ x-i18n: fly open ``` - 또는 `https://my-openclaw.fly.dev/`를 방문합니다. + 또는 `https://my-openclaw.fly.dev/`를 방문하세요. - 구성된 공유 시크릿으로 인증합니다. 이 가이드는 `OPENCLAW_GATEWAY_TOKEN`의 Gateway - 토큰을 사용합니다. 비밀번호 인증으로 전환했다면 대신 해당 비밀번호를 사용하세요. + 구성된 공유 시크릿으로 인증하세요. 이 가이드는 + `OPENCLAW_GATEWAY_TOKEN`의 Gateway 토큰을 사용합니다. 비밀번호 인증으로 전환했다면 + 대신 해당 비밀번호를 사용하세요. ### 로그 @@ -276,7 +275,7 @@ Gateway가 `0.0.0.0` 대신 `127.0.0.1`에 바인딩하고 있습니다. **수정:** `fly.toml`의 프로세스 명령에 `--bind lan`을 추가하세요. -### 상태 확인 실패 / 연결 거부 +### 헬스 체크 실패 / 연결 거부 Fly가 구성된 포트에서 Gateway에 도달할 수 없습니다. @@ -284,7 +283,7 @@ Fly가 구성된 포트에서 Gateway에 도달할 수 없습니다. ### OOM / 메모리 문제 -컨테이너가 계속 다시 시작되거나 종료됩니다. 징후: `SIGABRT`, `v8::internal::Runtime_AllocateInYoungGeneration` 또는 조용한 재시작. +컨테이너가 계속 재시작되거나 종료됩니다. 징후: `SIGABRT`, `v8::internal::Runtime_AllocateInYoungGeneration` 또는 조용한 재시작. **수정:** `fly.toml`에서 메모리를 늘리세요. @@ -293,19 +292,19 @@ Fly가 구성된 포트에서 Gateway에 도달할 수 없습니다. memory = "2048mb" ``` -또는 기존 머신을 업데이트합니다. +또는 기존 머신을 업데이트하세요. ```bash fly machine update --vm-memory 2048 -y ``` -**참고:** 512MB는 너무 작습니다. 1GB도 동작할 수 있지만 부하가 있거나 자세한 로깅을 사용할 때 OOM이 발생할 수 있습니다. **2GB를 권장합니다.** +**참고:** 512MB는 너무 작습니다. 1GB는 동작할 수 있지만 부하가 있거나 자세한 로깅을 사용할 때 OOM이 발생할 수 있습니다. **2GB를 권장합니다.** ### Gateway 잠금 문제 Gateway가 "already running" 오류와 함께 시작을 거부합니다. -컨테이너가 다시 시작되었지만 PID 잠금 파일이 볼륨에 남아 있을 때 발생합니다. +컨테이너가 재시작되었지만 PID 잠금 파일이 볼륨에 남아 있을 때 발생합니다. **수정:** 잠금 파일을 삭제하세요. @@ -316,19 +315,19 @@ fly machine restart 잠금 파일은 하위 디렉터리가 아니라 `/data/gateway.*.lock`에 있습니다. -### 설정을 읽지 못함 +### 구성을 읽지 못함 -`--allow-unconfigured`는 시작 가드만 우회합니다. `/data/openclaw.json`을 만들거나 복구하지 않으므로, 일반 로컬 Gateway 시작을 원할 때 실제 설정이 존재하고 `gateway.mode="local"`을 포함하는지 확인하세요. +`--allow-unconfigured`는 시작 가드만 우회합니다. `/data/openclaw.json`을 생성하거나 복구하지 않으므로, 일반적인 로컬 Gateway 시작을 원할 때 실제 구성이 존재하고 `gateway.mode="local"`을 포함하는지 확인하세요. -설정이 존재하는지 확인합니다. +구성이 존재하는지 확인하세요. ```bash fly ssh console --command "cat /data/openclaw.json" ``` -### SSH로 설정 쓰기 +### SSH를 통한 구성 작성 -`fly ssh console -C` 명령은 셸 리디렉션을 지원하지 않습니다. 설정 파일을 쓰려면 다음을 사용하세요. +`fly ssh console -C` 명령은 셸 리디렉션을 지원하지 않습니다. 구성 파일을 작성하려면 다음을 사용하세요. ```bash # Use echo + tee (pipe from local to remote) @@ -345,10 +344,10 @@ fly sftp shell fly ssh console --command "rm /data/openclaw.json" ``` -### 상태가 유지되지 않음 +### 상태가 영구 저장되지 않음 -다시 시작한 후 인증 프로필, 채널/제공자 상태 또는 세션이 사라진다면 -상태 디렉터리가 컨테이너 파일 시스템에 쓰이고 있는 것입니다. +재시작 후 인증 프로필, 채널/제공업체 상태 또는 세션이 사라진다면, +상태 디렉터리가 컨테이너 파일시스템에 쓰이고 있는 것입니다. **수정:** `fly.toml`에 `OPENCLAW_STATE_DIR=/data`가 설정되어 있는지 확인하고 다시 배포하세요. @@ -381,31 +380,31 @@ fly machine update --command "node dist/index.js gateway --port 300 fly machine update --vm-memory 2048 --command "node dist/index.js gateway --port 3000 --bind lan" -y ``` -**참고:** `fly deploy` 후 머신 명령이 `fly.toml`에 있는 내용으로 재설정될 수 있습니다. 수동으로 변경했다면 배포 후 다시 적용하세요. +**참고:** `fly deploy` 후 머신 명령이 `fly.toml`의 내용으로 재설정될 수 있습니다. 수동 변경을 했다면 배포 후 다시 적용하세요. ## 비공개 배포(강화) -기본적으로 Fly는 공개 IP를 할당하므로 Gateway가 `https://your-app.fly.dev`에서 접근 가능해집니다. 이는 편리하지만, 배포가 인터넷 스캐너(Shodan, Censys 등)에 발견될 수 있음을 의미합니다. +기본적으로 Fly는 공개 IP를 할당하여 Gateway를 `https://your-app.fly.dev`에서 접근 가능하게 만듭니다. 편리하지만 배포가 인터넷 스캐너(Shodan, Censys 등)에 발견될 수 있다는 의미입니다. **공개 노출이 없는** 강화된 배포에는 비공개 템플릿을 사용하세요. ### 비공개 배포를 사용할 때 -- **아웃바운드** 호출/메시지만 보냅니다(인바운드 Webhook 없음) -- Webhook 콜백에 **ngrok 또는 Tailscale** 터널을 사용합니다 -- 브라우저 대신 **SSH, 프록시 또는 WireGuard**를 통해 Gateway에 접근합니다 -- 배포를 **인터넷 스캐너에서 숨기고** 싶습니다 +- **아웃바운드** 호출/메시지만 수행하는 경우(인바운드 Webhook 없음) +- Webhook 콜백에 **ngrok 또는 Tailscale** 터널을 사용하는 경우 +- 브라우저 대신 **SSH, 프록시 또는 WireGuard**를 통해 Gateway에 접근하는 경우 +- 배포를 **인터넷 스캐너로부터 숨기고** 싶은 경우 ### 설정 -표준 설정 대신 `deploy/fly.private.toml`을 사용하세요. +표준 구성 대신 `deploy/fly.private.toml`을 사용하세요. ```bash # Deploy with private config fly deploy -c deploy/fly.private.toml ``` -또는 기존 배포를 변환합니다. +또는 기존 배포를 전환하세요. ```bash # List current IPs @@ -430,11 +429,11 @@ VERSION IP TYPE REGION v6 fdaa:x:x:x:x::x private global ``` -### 비공개 배포 접근 +### 비공개 배포에 접근하기 공개 URL이 없으므로 다음 방법 중 하나를 사용하세요. -**옵션 1: 로컬 프록시(가장 간단함)** +**옵션 1: 로컬 프록시(가장 간단)** ```bash # Forward local port 3000 to the app @@ -459,15 +458,15 @@ fly wireguard create fly ssh console -a my-openclaw ``` -### 비공개 배포에서 Webhook 사용 +### 비공개 배포에서의 Webhook 공개 노출 없이 Webhook 콜백(Twilio, Telnyx 등)이 필요한 경우: -1. **ngrok 터널** - 컨테이너 내부에서 또는 사이드카로 ngrok 실행 +1. **ngrok 터널** - 컨테이너 내부 또는 사이드카로 ngrok 실행 2. **Tailscale Funnel** - Tailscale을 통해 특정 경로 노출 -3. **아웃바운드 전용** - 일부 제공업체(Twilio)는 Webhook 없이도 아웃바운드 호출이 정상적으로 작동합니다 +3. **아웃바운드 전용** - 일부 제공업체(Twilio)는 Webhook 없이도 아웃바운드 통화에 문제없이 작동합니다 -ngrok을 사용하는 음성 통화 구성 예시: +ngrok을 사용한 음성 통화 설정 예시: ```json5 { @@ -492,12 +491,12 @@ ngrok 터널은 컨테이너 내부에서 실행되며 Fly 앱 자체를 노출 ### 보안 이점 -| 측면 | 공개 | 비공개 | -| ----------------- | ------------ | ---------- | -| 인터넷 스캐너 | 발견 가능 | 숨김 | -| 직접 공격 | 가능 | 차단 | -| 제어 UI 접근 | 브라우저 | 프록시/VPN | -| Webhook 전달 | 직접 | 터널 경유 | +| 항목 | 공개 | 비공개 | +| ----------------- | ----------- | ----------- | +| 인터넷 스캐너 | 발견 가능 | 숨김 | +| 직접 공격 | 가능 | 차단됨 | +| Control UI 접근 | 브라우저 | 프록시/VPN | +| Webhook 전달 | 직접 | 터널 경유 | ## 참고 @@ -505,14 +504,14 @@ ngrok 터널은 컨테이너 내부에서 실행되며 Fly 앱 자체를 노출 - Dockerfile은 두 아키텍처 모두와 호환됩니다 - WhatsApp/Telegram 온보딩에는 `fly ssh console`을 사용하세요 - 영구 데이터는 `/data`의 볼륨에 저장됩니다 -- Signal에는 Java + signal-cli가 필요합니다. 사용자 지정 이미지를 사용하고 메모리를 2GB 이상으로 유지하세요. +- Signal에는 Java + signal-cli가 필요합니다. 커스텀 이미지를 사용하고 메모리는 2GB 이상으로 유지하세요. ## 비용 -권장 구성(`shared-cpu-2x`, 2GB RAM) 기준: +권장 구성(`shared-cpu-2x`, 2GB RAM) 사용 시: -- 사용량에 따라 월 약 $10~15 -- 무료 티어에 일부 허용량 포함 +- 사용량에 따라 월 ~$10-15 +- 무료 티어에는 일부 허용량이 포함됩니다 자세한 내용은 [Fly.io 가격](https://fly.io/docs/about/pricing/)을 참조하세요. @@ -520,9 +519,9 @@ ngrok 터널은 컨테이너 내부에서 실행되며 Fly 앱 자체를 노출 - 메시징 채널 설정: [채널](/ko/channels) - Gateway 구성: [Gateway 구성](/ko/gateway/configuration) -- OpenClaw 최신 상태 유지: [업데이트](/ko/install/updating) +- OpenClaw를 최신 상태로 유지: [업데이트](/ko/install/updating) -## 관련 항목 +## 관련 - [설치 개요](/ko/install) - [Hetzner](/ko/install/hetzner) diff --git a/docs/ko/install/gcp.md b/docs/ko/install/gcp.md index 0ab92b4fe..2ed0e7247 100644 --- a/docs/ko/install/gcp.md +++ b/docs/ko/install/gcp.md @@ -1,70 +1,70 @@ --- read_when: - GCP에서 OpenClaw를 24/7 실행하려는 경우 - - 자체 VM에서 프로덕션급 상시 가동 Gateway를 원합니다 + - 자체 VM에서 프로덕션급 상시 실행 Gateway가 필요한 경우 - 지속성, 바이너리, 재시작 동작을 완전히 제어하려는 경우 -summary: 지속성 있는 상태로 GCP Compute Engine VM(Docker)에서 OpenClaw Gateway를 24/7 실행하기 +summary: 내구성 있는 상태로 GCP Compute Engine VM(Docker)에서 OpenClaw Gateway를 24/7 실행하기 title: GCP x-i18n: - generated_at: "2026-05-06T06:30:12Z" + generated_at: "2026-05-06T17:57:41Z" model: gpt-5.5 provider: openai - source_hash: eefd3a324ababdaa3072cda5354c1d59ddfe80c2f88f24a4ad21208f54636e89 + source_hash: 678253bd90f0694668400ffddba957e442f8aaed3f5308af3c2481940e104733 source_path: install/gcp.md workflow: 16 --- -Docker를 사용해 GCP Compute Engine VM에서 지속 실행되는 OpenClaw Gateway를 실행합니다. 영구 상태, 내장된 바이너리, 안전한 재시작 동작을 포함합니다. +GCP Compute Engine VM에서 Docker를 사용해 영구 실행되는 OpenClaw Gateway를 실행합니다. 내구성 있는 상태, 내장 바이너리, 안전한 재시작 동작을 제공합니다. -"월 약 $5-12로 OpenClaw를 24/7 실행"하고 싶다면, Google Cloud에서 신뢰할 수 있는 설정입니다. +"월 약 $5-12로 OpenClaw 24/7"을 원한다면, Google Cloud에서 신뢰할 수 있는 설정입니다. 가격은 머신 유형과 리전에 따라 달라집니다. 워크로드에 맞는 가장 작은 VM을 선택하고, OOM이 발생하면 확장하세요. ## 무엇을 하나요(간단히)? -- GCP 프로젝트를 만들고 결제를 사용 설정합니다 +- GCP 프로젝트를 만들고 결제를 활성화합니다 - Compute Engine VM을 만듭니다 -- Docker를 설치합니다(격리된 앱 런타임) +- Docker(격리된 앱 런타임)를 설치합니다 - Docker에서 OpenClaw Gateway를 시작합니다 -- 호스트에 `~/.openclaw` + `~/.openclaw/workspace`를 영구 저장합니다(재시작/재빌드 후에도 유지) -- SSH 터널을 통해 노트북에서 Control UI에 액세스합니다 +- 호스트에 `~/.openclaw` + `~/.openclaw/workspace`를 유지합니다(재시작/재빌드 후에도 유지) +- 노트북에서 SSH 터널을 통해 Control UI에 접속합니다 마운트된 `~/.openclaw` 상태에는 `openclaw.json`, 에이전트별 -`agents//agent/auth-profiles.json`, `.env`가 포함됩니다. +`agents//agent/auth-profiles.json`, 그리고 `.env`가 포함됩니다. -Gateway에는 다음 방식으로 액세스할 수 있습니다. +Gateway에는 다음 방식으로 접근할 수 있습니다. - 노트북에서 SSH 포트 포워딩 -- 방화벽과 토큰을 직접 관리하는 경우 포트를 직접 노출 +- 방화벽과 토큰을 직접 관리하는 경우 직접 포트 노출 이 가이드는 GCP Compute Engine의 Debian을 사용합니다. -Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요. +Ubuntu도 작동합니다. 패키지는 그에 맞게 매핑하세요. 일반 Docker 흐름은 [Docker](/ko/install/docker)를 참조하세요. --- ## 빠른 경로(숙련된 운영자) -1. GCP 프로젝트 생성 + Compute Engine API 사용 설정 +1. GCP 프로젝트 생성 + Compute Engine API 활성화 2. Compute Engine VM 생성(e2-small, Debian 12, 20GB) -3. VM에 SSH로 접속 +3. VM에 SSH 접속 4. Docker 설치 5. OpenClaw 저장소 클론 6. 영구 호스트 디렉터리 생성 -7. `.env` 및 `docker-compose.yml` 구성 -8. 필요한 바이너리를 내장하고 빌드한 뒤 실행 +7. `.env`와 `docker-compose.yml` 구성 +8. 필요한 바이너리를 이미지에 포함하고, 빌드한 뒤 실행 --- ## 필요한 것 -- GCP 계정(e2-micro 무료 등급 사용 가능) +- GCP 계정(e2-micro 무료 등급 가능) - gcloud CLI 설치됨(또는 Cloud Console 사용) -- 노트북에서 SSH 액세스 -- SSH + 복사/붙여넣기에 대한 기본적인 익숙함 +- 노트북에서 SSH 접근 +- SSH + 복사/붙여넣기에 대한 기본 이해 - 약 20-30분 - Docker 및 Docker Compose - 모델 인증 자격 증명 -- 선택적 제공자 자격 증명 +- 선택적 provider 자격 증명 - WhatsApp QR - Telegram 봇 토큰 - Gmail OAuth @@ -86,11 +86,11 @@ Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요. **옵션 B: Cloud Console** - 모든 단계는 [https://console.cloud.google.com](https://console.cloud.google.com)의 웹 UI를 통해 수행할 수 있습니다. + 모든 단계는 [https://console.cloud.google.com](https://console.cloud.google.com)의 웹 UI에서 수행할 수 있습니다. - + **CLI:** ```bash @@ -98,9 +98,9 @@ Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요. gcloud config set project my-openclaw-project ``` - [https://console.cloud.google.com/billing](https://console.cloud.google.com/billing)에서 결제를 사용 설정하세요(Compute Engine에 필요). + [https://console.cloud.google.com/billing](https://console.cloud.google.com/billing)에서 결제를 활성화하세요(Compute Engine에 필요). - Compute Engine API를 사용 설정합니다. + Compute Engine API를 활성화합니다. ```bash gcloud services enable compute.googleapis.com @@ -110,19 +110,19 @@ Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요. 1. IAM & Admin > Create Project로 이동합니다 2. 이름을 지정하고 생성합니다 - 3. 프로젝트의 결제를 사용 설정합니다 - 4. APIs & Services > Enable APIs로 이동 > "Compute Engine API" 검색 > 사용 설정 + 3. 프로젝트의 결제를 활성화합니다 + 4. APIs & Services > Enable APIs로 이동 > "Compute Engine API" 검색 > 활성화 - + **머신 유형:** | 유형 | 사양 | 비용 | 참고 | | --------- | ------------------------ | ------------------ | -------------------------------------------- | - | e2-medium | 2 vCPU, 4GB RAM | 월 약 $25 | 로컬 Docker 빌드에 가장 안정적 | - | e2-small | 2 vCPU, 2GB RAM | 월 약 $12 | Docker 빌드에 권장되는 최소 사양 | - | e2-micro | 2 vCPU(공유), 1GB RAM | 무료 등급 사용 가능 | Docker 빌드 OOM으로 실패하는 경우가 많음(exit 137) | + | e2-medium | 2 vCPU, 4GB RAM | 월 약 $25 | 로컬 Docker 빌드에 가장 안정적 | + | e2-small | 2 vCPU, 2GB RAM | 월 약 $12 | Docker 빌드에 권장되는 최소 사양 | + | e2-micro | 2 vCPU(공유), 1GB RAM | 무료 등급 가능 | Docker 빌드 OOM으로 자주 실패(exit 137) | **CLI:** @@ -146,7 +146,7 @@ Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요. - + **CLI:** ```bash @@ -157,7 +157,7 @@ Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요. Compute Engine 대시보드에서 VM 옆의 "SSH" 버튼을 클릭합니다. - 참고: VM 생성 후 SSH 키 전파에는 1-2분이 걸릴 수 있습니다. 연결이 거부되면 기다렸다가 다시 시도하세요. + 참고: VM 생성 후 SSH 키 전파에 1-2분이 걸릴 수 있습니다. 연결이 거부되면 기다린 뒤 다시 시도하세요. @@ -169,7 +169,7 @@ Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요. sudo usermod -aG docker $USER ``` - 그룹 변경 사항을 적용하려면 로그아웃했다가 다시 로그인합니다. + 그룹 변경이 적용되도록 로그아웃한 뒤 다시 로그인합니다. ```bash exit @@ -200,9 +200,9 @@ Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요. - + Docker 컨테이너는 일시적입니다. - 오래 유지되어야 하는 모든 상태는 호스트에 있어야 합니다. + 장기 상태는 모두 호스트에 있어야 합니다. ```bash mkdir -p ~/.openclaw @@ -227,8 +227,7 @@ Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요. XDG_CONFIG_HOME=/home/node/.openclaw ``` - `.env`를 통해 명시적으로 관리하려는 경우가 아니라면 `OPENCLAW_GATEWAY_TOKEN`은 비워 두세요. OpenClaw는 첫 시작 시 무작위 Gateway 토큰을 구성에 기록합니다. 키링 비밀번호를 생성하고 - `GOG_KEYRING_PASSWORD`에 붙여넣으세요. + 안정적인 gateway 토큰을 `.env`를 통해 관리하려면 `OPENCLAW_GATEWAY_TOKEN`을 설정하세요. 그렇지 않으면 재시작 후에도 클라이언트에 의존하기 전에 `gateway.auth.token`을 구성하세요. 어느 소스도 없으면 OpenClaw는 해당 시작에만 유효한 런타임 전용 토큰을 사용합니다. 키링 비밀번호를 생성하고 `GOG_KEYRING_PASSWORD`에 붙여넣습니다. ```bash openssl rand -hex 32 @@ -236,8 +235,8 @@ Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요. **이 파일을 커밋하지 마세요.** - 이 `.env` 파일은 `OPENCLAW_GATEWAY_TOKEN` 같은 컨테이너/런타임 환경을 위한 것입니다. - 저장된 제공자 OAuth/API 키 인증은 마운트된 + 이 `.env` 파일은 `OPENCLAW_GATEWAY_TOKEN` 같은 컨테이너/런타임 env용입니다. + 저장된 provider OAuth/API-key 인증은 마운트된 `~/.openclaw/agents//agent/auth-profiles.json`에 있습니다. @@ -283,14 +282,14 @@ Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요. ] ``` - `--allow-unconfigured`는 부트스트랩 편의를 위한 것일 뿐이며, 적절한 Gateway 구성을 대체하지 않습니다. 배포에 맞게 인증(`gateway.auth.token` 또는 비밀번호)을 설정하고 안전한 바인드 설정을 사용하세요. + `--allow-unconfigured`는 부트스트랩 편의를 위한 것일 뿐이며, 적절한 gateway 구성을 대체하지 않습니다. 배포 환경에 맞게 인증(`gateway.auth.token` 또는 비밀번호)을 설정하고 안전한 bind 설정을 사용하세요. - 일반적인 Docker 호스트 흐름에는 공유 런타임 가이드를 사용하세요. + 일반적인 Docker 호스트 흐름은 공유 런타임 가이드를 사용하세요. - - [필요한 바이너리를 이미지에 내장](/ko/install/docker-vm-runtime#bake-required-binaries-into-the-image) + - [필요한 바이너리를 이미지에 포함](/ko/install/docker-vm-runtime#bake-required-binaries-into-the-image) - [빌드 및 실행](/ko/install/docker-vm-runtime#build-and-launch) - [무엇이 어디에 유지되는지](/ko/install/docker-vm-runtime#what-persists-where) - [업데이트](/ko/install/docker-vm-runtime#updates) @@ -298,20 +297,20 @@ Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요. - GCP에서 `pnpm install --frozen-lockfile` 중 빌드가 `Killed` 또는 `exit code 137`로 실패하면 VM의 메모리가 부족한 것입니다. 최소 `e2-small`을 사용하거나, 더 안정적인 첫 빌드를 위해 `e2-medium`을 사용하세요. + GCP에서 `pnpm install --frozen-lockfile` 중 `Killed` 또는 `exit code 137`로 빌드가 실패하면 VM의 메모리가 부족한 것입니다. 최소 `e2-small`을 사용하거나, 더 안정적인 첫 빌드를 위해 `e2-medium`을 사용하세요. - LAN에 바인딩할 때(`OPENCLAW_GATEWAY_BIND=lan`) 계속하기 전에 신뢰할 수 있는 브라우저 출처를 구성하세요. + LAN에 바인딩할 때(`OPENCLAW_GATEWAY_BIND=lan`) 계속하기 전에 신뢰할 수 있는 브라우저 origin을 구성하세요. ```bash docker compose run --rm openclaw-cli config set gateway.controlUi.allowedOrigins '["http://127.0.0.1:18789"]' --strict-json ``` - Gateway 포트를 변경했다면 `18789`를 구성한 포트로 바꾸세요. + gateway 포트를 변경했다면 `18789`를 구성한 포트로 바꾸세요. - - Gateway 포트를 전달하도록 SSH 터널을 만듭니다. + + Gateway 포트를 포워딩하는 SSH 터널을 만듭니다. ```bash gcloud compute ssh openclaw-gateway --zone=us-central1-a -- -L 18789:127.0.0.1:18789 @@ -327,16 +326,16 @@ Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요. docker compose run --rm openclaw-cli dashboard --no-open ``` - UI에서 공유 시크릿 인증을 요구하면 구성된 토큰 또는 비밀번호를 Control UI 설정에 붙여넣으세요. 이 Docker 흐름은 기본적으로 토큰을 기록합니다. 컨테이너 구성을 비밀번호 인증으로 전환했다면 대신 해당 비밀번호를 사용하세요. + UI에서 shared-secret 인증을 요청하면 구성한 토큰 또는 비밀번호를 Control UI 설정에 붙여넣으세요. 이 Docker 흐름은 기본적으로 토큰을 씁니다. 컨테이너 구성을 비밀번호 인증으로 전환한 경우에는 대신 해당 비밀번호를 사용하세요. - Control UI에 `unauthorized` 또는 `disconnected (1008): pairing required`가 표시되면 브라우저 기기를 승인하세요. + Control UI에 `unauthorized` 또는 `disconnected (1008): pairing required`가 표시되면 브라우저 디바이스를 승인하세요. ```bash docker compose run --rm openclaw-cli devices list docker compose run --rm openclaw-cli devices approve ``` - 공유 지속성과 업데이트 참조가 다시 필요한가요? + 공유 지속성과 업데이트 참고 자료가 다시 필요하신가요? [Docker VM Runtime](/ko/install/docker-vm-runtime#what-persists-where) 및 [Docker VM Runtime 업데이트](/ko/install/docker-vm-runtime#updates)를 참조하세요. @@ -346,9 +345,9 @@ Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요. ## 문제 해결 -**SSH 연결이 거부됨** +**SSH 연결 거부됨** -VM 생성 후 SSH 키 전파에는 1-2분이 걸릴 수 있습니다. 기다렸다가 다시 시도하세요. +VM 생성 후 SSH 키 전파에 1-2분이 걸릴 수 있습니다. 기다린 뒤 다시 시도하세요. **OS Login 문제** @@ -409,10 +408,10 @@ IAM 역할 세부 정보는 [https://cloud.google.com/iam/docs/understanding-rol ## 다음 단계 - 메시징 채널 설정: [채널](/ko/channels) -- 로컬 디바이스를 노드로 페어링: [노드](/ko/nodes) +- 로컬 기기를 노드로 페어링: [노드](/ko/nodes) - Gateway 구성: [Gateway 구성](/ko/gateway/configuration) -## 관련 항목 +## 관련 - [설치 개요](/ko/install) - [Azure](/ko/install/azure) diff --git a/docs/ko/install/hetzner.md b/docs/ko/install/hetzner.md index caaf17712..13ecc909e 100644 --- a/docs/ko/install/hetzner.md +++ b/docs/ko/install/hetzner.md @@ -1,34 +1,32 @@ --- read_when: - - OpenClaw를 노트북이 아닌 클라우드 VPS에서 24시간 연중무휴로 실행하려는 경우 - - 자체 VPS에서 프로덕션급으로 상시 실행되는 Gateway가 필요합니다 - - 지속성, 바이너리, 재시작 동작을 완전히 제어하고 싶습니다 - - Hetzner 또는 유사한 제공업체에서 Docker로 OpenClaw를 실행하고 있습니다 -summary: 저렴한 Hetzner VPS(Docker)에서 영구 상태와 내장 바이너리를 갖춘 OpenClaw Gateway를 24/7 실행하기 + - 클라우드 VPS(노트북이 아님)에서 OpenClaw를 24/7 실행하려는 경우 + - 자체 VPS에서 프로덕션급 상시 가동 Gateway를 원합니다 + - 지속성, 바이너리, 재시작 동작을 완전히 제어하고 싶은 경우 + - Hetzner 또는 유사한 제공업체에서 Docker로 OpenClaw를 실행 중입니다 +summary: 저렴한 Hetzner VPS(Docker)에서 영속 상태와 내장 바이너리로 OpenClaw Gateway를 24시간 연중무휴 실행하기 title: Hetzner x-i18n: - generated_at: "2026-05-06T06:30:28Z" + generated_at: "2026-05-06T17:57:56Z" model: gpt-5.5 provider: openai - source_hash: 2625a028b6242f653d29b8f45035bf2d796c5c60453582cf269fd1c3776eca52 + source_hash: 6102649b381b3b1ecd6f52e1cf518fc36147fe143ebc8fd4be5f44ab26cb3b4d source_path: install/hetzner.md workflow: 16 --- -# Hetzner에서 OpenClaw (Docker, 프로덕션 VPS 가이드) - ## 목표 -Docker를 사용해 Hetzner VPS에서 지속 실행되는 OpenClaw Gateway를 실행하고, 영구 상태, 이미지에 포함된 바이너리, 안전한 재시작 동작을 구성합니다. +Docker를 사용해 Hetzner VPS에서 지속 실행되는 OpenClaw Gateway를 운영합니다. 내구성 있는 상태, 이미지에 포함된 바이너리, 안전한 재시작 동작을 갖춥니다. "월 약 $5로 OpenClaw 24/7"을 원한다면, 이것이 가장 단순하고 신뢰할 수 있는 설정입니다. -Hetzner 가격은 변경될 수 있으므로, 가장 작은 Debian/Ubuntu VPS를 선택하고 OOM이 발생하면 확장하세요. +Hetzner 가격은 변경될 수 있으니, 가장 작은 Debian/Ubuntu VPS를 선택하고 OOM이 발생하면 확장하세요. -보안 모델 참고: +보안 모델 알림: -- 회사에서 공유하는 에이전트는 모두가 같은 신뢰 경계 안에 있고 런타임이 업무 전용일 때는 괜찮습니다. +- 회사 공유 에이전트는 모두가 동일한 신뢰 경계 안에 있고 런타임이 업무 전용일 때 괜찮습니다. - 엄격히 분리하세요: 전용 VPS/런타임 + 전용 계정; 해당 호스트에 개인 Apple/Google/브라우저/비밀번호 관리자 프로필을 두지 마세요. -- 사용자들이 서로 적대적일 수 있다면 gateway/호스트/OS 사용자 단위로 분리하세요. +- 사용자가 서로 적대적일 수 있다면 gateway/호스트/OS 사용자 단위로 분리하세요. [보안](/ko/gateway/security) 및 [VPS 호스팅](/ko/vps)을 참고하세요. @@ -37,19 +35,19 @@ Hetzner 가격은 변경될 수 있으므로, 가장 작은 Debian/Ubuntu VPS를 - 작은 Linux 서버(Hetzner VPS)를 임대합니다 - Docker(격리된 앱 런타임)를 설치합니다 - Docker에서 OpenClaw Gateway를 시작합니다 -- 호스트에 `~/.openclaw` + `~/.openclaw/workspace`를 영구 저장합니다(재시작/재빌드 후에도 유지) -- 노트북에서 SSH 터널을 통해 제어 UI에 액세스합니다 +- 호스트에 `~/.openclaw` + `~/.openclaw/workspace`를 영구 보존합니다(재시작/재빌드 후에도 유지) +- 노트북에서 SSH 터널을 통해 Control UI에 접근합니다 마운트된 `~/.openclaw` 상태에는 `openclaw.json`, 에이전트별 `agents//agent/auth-profiles.json`, 그리고 `.env`가 포함됩니다. -Gateway에는 다음 방식으로 액세스할 수 있습니다: +Gateway에는 다음 방식으로 접근할 수 있습니다: - 노트북에서 SSH 포트 포워딩 - 방화벽과 토큰을 직접 관리하는 경우 직접 포트 노출 이 가이드는 Hetzner의 Ubuntu 또는 Debian을 가정합니다. -다른 Linux VPS를 사용 중이라면 패키지를 그에 맞게 매핑하세요. +다른 Linux VPS를 사용 중이라면 패키지를 그에 맞게 대응하세요. 일반 Docker 흐름은 [Docker](/ko/install/docker)를 참고하세요. --- @@ -63,19 +61,19 @@ Gateway에는 다음 방식으로 액세스할 수 있습니다: 5. `.env` 및 `docker-compose.yml` 구성 6. 필요한 바이너리를 이미지에 포함 7. `docker compose up -d` -8. 영속성과 Gateway 액세스 확인 +8. 지속성 및 Gateway 접근 확인 --- ## 필요한 것 -- root 액세스가 있는 Hetzner VPS -- 노트북에서 SSH 액세스 +- root 접근 권한이 있는 Hetzner VPS +- 노트북에서 SSH 접근 - SSH + 복사/붙여넣기에 대한 기본적인 익숙함 - 약 20분 - Docker 및 Docker Compose - 모델 인증 자격 증명 -- 선택적 provider 자격 증명 +- 선택적 제공자 자격 증명 - WhatsApp QR - Telegram 봇 토큰 - Gmail OAuth @@ -93,7 +91,7 @@ Gateway에는 다음 방식으로 액세스할 수 있습니다: ``` 이 가이드는 VPS가 상태를 유지한다고 가정합니다. - 이를 일회용 인프라로 취급하지 마세요. + 이를 폐기 가능한 인프라로 취급하지 마세요. @@ -104,7 +102,7 @@ Gateway에는 다음 방식으로 액세스할 수 있습니다: curl -fsSL https://get.docker.com | sh ``` - 확인합니다: + 확인: ```bash docker --version @@ -119,13 +117,13 @@ Gateway에는 다음 방식으로 액세스할 수 있습니다: cd openclaw ``` - 이 가이드는 바이너리 영속성을 보장하기 위해 사용자 지정 이미지를 빌드한다고 가정합니다. + 이 가이드는 바이너리 지속성을 보장하기 위해 사용자 지정 이미지를 빌드한다고 가정합니다. Docker 컨테이너는 일시적입니다. - 장기 상태는 모두 호스트에 있어야 합니다. + 장기 보존 상태는 모두 호스트에 있어야 합니다. ```bash mkdir -p /root/.openclaw/workspace @@ -152,8 +150,7 @@ Gateway에는 다음 방식으로 액세스할 수 있습니다: XDG_CONFIG_HOME=/home/node/.openclaw ``` - `.env`를 통해 명시적으로 관리하려는 경우가 아니라면 `OPENCLAW_GATEWAY_TOKEN`은 비워 두세요. OpenClaw는 처음 시작할 때 임의의 gateway 토큰을 구성에 기록합니다. 키링 비밀번호를 생성하여 - `GOG_KEYRING_PASSWORD`에 붙여넣으세요: + 안정적인 gateway 토큰을 `.env`로 관리하려면 `OPENCLAW_GATEWAY_TOKEN`을 설정하세요. 그렇지 않으면 재시작 후 클라이언트가 의존하기 전에 `gateway.auth.token`을 구성하세요. 두 소스가 모두 없으면 OpenClaw는 해당 시작에만 유효한 런타임 전용 토큰을 사용합니다. 키링 비밀번호를 생성해 `GOG_KEYRING_PASSWORD`에 붙여넣으세요: ```bash openssl rand -hex 32 @@ -161,8 +158,8 @@ Gateway에는 다음 방식으로 액세스할 수 있습니다: **이 파일을 커밋하지 마세요.** - 이 `.env` 파일은 `OPENCLAW_GATEWAY_TOKEN` 같은 컨테이너/런타임 환경 변수용입니다. - 저장된 provider OAuth/API 키 인증은 마운트된 + 이 `.env` 파일은 `OPENCLAW_GATEWAY_TOKEN` 같은 컨테이너/런타임 env용입니다. + 저장된 제공자 OAuth/API 키 인증은 마운트된 `~/.openclaw/agents//agent/auth-profiles.json`에 있습니다. @@ -208,34 +205,34 @@ Gateway에는 다음 방식으로 액세스할 수 있습니다: ] ``` - `--allow-unconfigured`는 부트스트랩 편의를 위한 것일 뿐이며, 적절한 gateway 구성을 대체하지 않습니다. 배포 환경에 맞게 인증(`gateway.auth.token` 또는 비밀번호)을 설정하고 안전한 bind 설정을 사용하세요. + `--allow-unconfigured`는 부트스트랩 편의를 위한 것일 뿐이며, 적절한 gateway 구성을 대체하지 않습니다. 배포 환경에는 여전히 인증(`gateway.auth.token` 또는 비밀번호)을 설정하고 안전한 바인딩 설정을 사용하세요. - 일반적인 Docker 호스트 흐름에는 공유 런타임 가이드를 사용하세요: + 공통 Docker 호스트 흐름에는 공유 런타임 가이드를 사용하세요: - [필요한 바이너리를 이미지에 포함](/ko/install/docker-vm-runtime#bake-required-binaries-into-the-image) - [빌드 및 실행](/ko/install/docker-vm-runtime#build-and-launch) - - [무엇이 어디에 유지되는지](/ko/install/docker-vm-runtime#what-persists-where) + - [무엇이 어디에 지속되는가](/ko/install/docker-vm-runtime#what-persists-where) - [업데이트](/ko/install/docker-vm-runtime#updates) - - 공유 빌드 및 실행 단계를 완료한 후, 터널을 열기 위해 다음 설정을 완료합니다: + + 공유 빌드 및 실행 단계를 마친 후, 터널을 열기 위해 다음 설정을 완료하세요: - **필수 조건:** VPS sshd 구성에서 TCP 포워딩을 허용하는지 확인하세요. SSH 구성을 강화했다면 `/etc/ssh/sshd_config`를 확인하고 다음을 설정하세요: + **전제 조건:** VPS sshd 구성이 TCP 포워딩을 허용하는지 확인하세요. SSH 구성을 강화했다면 `/etc/ssh/sshd_config`를 확인하고 다음을 설정하세요: ``` AllowTcpForwarding local ``` - `local`은 서버에서의 원격 포워딩은 차단하면서 노트북에서 `ssh -L` 로컬 포워딩을 허용합니다. 이를 `no`로 설정하면 터널이 다음 오류와 함께 실패합니다: + `local`은 서버에서 원격 포워딩을 차단하면서 노트북의 `ssh -L` 로컬 포워딩을 허용합니다. `no`로 설정하면 터널이 다음 오류와 함께 실패합니다: `channel 3: open failed: administratively prohibited: open failed` - TCP 포워딩이 활성화되어 있음을 확인한 후 SSH 서비스를 재시작하고 - (`systemctl restart ssh`) 노트북에서 터널을 실행합니다: + TCP 포워딩이 활성화되었는지 확인한 뒤 SSH 서비스를 재시작하고 + (`systemctl restart ssh`) 노트북에서 터널을 실행하세요: ```bash ssh -N -L 18789:127.0.0.1:18789 root@YOUR_VPS_IP @@ -245,32 +242,32 @@ Gateway에는 다음 방식으로 액세스할 수 있습니다: `http://127.0.0.1:18789/` - 구성된 공유 비밀 값을 붙여넣으세요. 이 가이드는 기본적으로 gateway 토큰을 사용합니다. 비밀번호 인증으로 전환했다면 대신 해당 비밀번호를 사용하세요. + 구성한 공유 비밀값을 붙여넣으세요. 이 가이드는 기본적으로 gateway 토큰을 사용합니다. 비밀번호 인증으로 전환했다면 대신 해당 비밀번호를 사용하세요. -공유 영속성 맵은 [Docker VM Runtime](/ko/install/docker-vm-runtime#what-persists-where)에 있습니다. +공유 지속성 맵은 [Docker VM Runtime](/ko/install/docker-vm-runtime#what-persists-where)에 있습니다. ## 코드형 인프라(Terraform) -코드형 인프라 워크플로를 선호하는 팀을 위해, 커뮤니티에서 유지 관리하는 Terraform 설정은 다음을 제공합니다: +코드형 인프라 워크플로를 선호하는 팀을 위해, 커뮤니티가 유지 관리하는 Terraform 설정은 다음을 제공합니다: -- 원격 상태 관리가 포함된 모듈식 Terraform 구성 +- 원격 상태 관리를 포함한 모듈식 Terraform 구성 - cloud-init을 통한 자동 프로비저닝 -- 배포 스크립트(bootstrap, deploy, backup/restore) -- 보안 강화(방화벽, UFW, SSH 전용 액세스) -- gateway 액세스를 위한 SSH 터널 구성 +- 배포 스크립트(부트스트랩, 배포, 백업/복원) +- 보안 강화(방화벽, UFW, SSH 전용 접근) +- gateway 접근을 위한 SSH 터널 구성 **저장소:** - 인프라: [openclaw-terraform-hetzner](https://github.com/andreesg/openclaw-terraform-hetzner) - Docker 구성: [openclaw-docker-config](https://github.com/andreesg/openclaw-docker-config) -이 접근 방식은 재현 가능한 배포, 버전 관리되는 인프라, 자동화된 재해 복구를 통해 위의 Docker 설정을 보완합니다. +이 접근 방식은 재현 가능한 배포, 버전 관리되는 인프라, 자동화된 재해 복구를 통해 위 Docker 설정을 보완합니다. -커뮤니티에서 유지 관리합니다. 문제나 기여는 위의 저장소 링크를 참고하세요. +커뮤니티에서 유지 관리합니다. 문제나 기여는 위 저장소 링크를 참고하세요. ## 다음 단계 diff --git a/docs/ko/install/nix.md b/docs/ko/install/nix.md index 0549c0245..09e667ba4 100644 --- a/docs/ko/install/nix.md +++ b/docs/ko/install/nix.md @@ -1,54 +1,54 @@ --- read_when: - - 재현 가능하고 롤백 가능한 설치를 원한다면 + - 재현 가능하고 롤백 가능한 설치를 원합니다 - 이미 Nix/NixOS/Home Manager를 사용 중입니다 - - 모든 것을 고정하고 선언적으로 관리하려는 경우 + - 모든 것을 고정하고 선언적으로 관리하고 싶습니다 summary: Nix로 OpenClaw를 선언적으로 설치하기 title: Nix x-i18n: - generated_at: "2026-05-06T06:31:09Z" + generated_at: "2026-05-06T17:57:55Z" model: gpt-5.5 provider: openai - source_hash: f0c25b97fb46a906bb726a13de095ead1e6c3642d28f66173b488acfbc5e0001 + source_hash: 1b4c2eca298ac7ae60baea4d06855edb73c0b8bfe253a3f478d93e934b31253b source_path: install/nix.md workflow: 16 --- -OpenClaw를 선언적으로 설치하려면 모든 기능이 포함된 Home Manager 모듈인 **[nix-openclaw](https://github.com/openclaw/nix-openclaw)**을 사용하세요. +OpenClaw를 선언적으로 설치하려면 **[nix-openclaw](https://github.com/openclaw/nix-openclaw)**를 사용하세요. 이는 필요한 기능이 모두 포함된 공식 Home Manager 모듈입니다. -[nix-openclaw](https://github.com/openclaw/nix-openclaw) 저장소는 Nix 설치의 기준 소스입니다. 이 페이지는 간단한 개요입니다. +[nix-openclaw](https://github.com/openclaw/nix-openclaw) 저장소는 Nix 설치의 단일 기준입니다. 이 페이지는 간단한 개요입니다. ## 제공되는 것 - Gateway + macOS 앱 + 도구(whisper, spotify, cameras) -- 모두 고정됨 - 재부팅 후에도 유지되는 launchd 서비스 -- 선언적 구성을 지원하는 Plugin 시스템 +- 선언적 설정을 지원하는 Plugin 시스템 - 즉시 롤백: `home-manager switch --rollback` ## 빠른 시작 - - Nix가 아직 설치되어 있지 않다면 [Determinate Nix installer](https://github.com/DeterminateSystems/nix-installer) 안내를 따르세요. + + Nix가 아직 설치되어 있지 않다면 [Determinate Nix installer](https://github.com/DeterminateSystems/nix-installer) 지침을 따르세요. - - nix-openclaw 저장소의 에이전트 우선 템플릿을 사용하세요. + + nix-openclaw 저장소의 agent-first 템플릿을 사용하세요. ```bash mkdir -p ~/code/openclaw-local # Copy templates/agent-first/flake.nix from the nix-openclaw repo ``` - + 메시징 봇 토큰과 모델 제공자 API 키를 설정하세요. `~/.secrets/`의 일반 파일로도 충분합니다. - + ```bash home-manager switch ``` - + launchd 서비스가 실행 중이고 봇이 메시지에 응답하는지 확인하세요. @@ -57,7 +57,7 @@ OpenClaw를 선언적으로 설치하려면 모든 기능이 포함된 Home Mana ## Nix 모드 런타임 동작 -`OPENCLAW_NIX_MODE=1`이 설정되면(nix-openclaw에서는 자동), OpenClaw는 자동 설치 흐름을 비활성화하는 결정적 모드로 전환됩니다. +`OPENCLAW_NIX_MODE=1`이 설정되면(nix-openclaw에서는 자동), OpenClaw는 Nix로 관리되는 설치를 위한 결정적 모드로 들어갑니다. 다른 Nix 패키지도 같은 모드를 설정할 수 있으며, nix-openclaw가 공식 참조 구현입니다. 수동으로 설정할 수도 있습니다. @@ -71,15 +71,17 @@ macOS에서는 GUI 앱이 셸 환경 변수를 자동으로 상속하지 않습 defaults write ai.openclaw.mac openclaw.nixMode -bool true ``` -### Nix 모드에서 변경되는 것 +### Nix 모드에서 변경되는 사항 -- 자동 설치 및 자체 변경 흐름이 비활성화됩니다 -- 누락된 종속성에 대해 Nix 전용 해결 메시지가 표시됩니다 -- UI에 읽기 전용 Nix 모드 배너가 표시됩니다 +- 자동 설치 및 자체 변경 흐름이 비활성화됩니다. +- `openclaw.json`은 변경 불가능한 것으로 취급됩니다. 시작 시 파생되는 기본값은 런타임에만 유지되며, setup, onboarding, 변경을 수행하는 `openclaw update`, Plugin install/update/uninstall/enable, `doctor --fix`, `doctor --generate-gateway-token`, `openclaw config set` 같은 설정 작성기는 파일 편집을 거부합니다. +- 대신 에이전트는 Nix 소스를 편집해야 합니다. nix-openclaw의 경우 agent-first [빠른 시작](https://github.com/openclaw/nix-openclaw#quick-start)을 사용하고 `programs.openclaw.config` 또는 `instances..config` 아래에 설정을 지정하세요. +- 누락된 의존성은 Nix 전용 해결 메시지로 표시됩니다. +- UI는 읽기 전용 Nix 모드 배너를 표시합니다. -### 구성 및 상태 경로 +### 설정 및 상태 경로 -OpenClaw는 `OPENCLAW_CONFIG_PATH`에서 JSON5 구성을 읽고 변경 가능한 데이터를 `OPENCLAW_STATE_DIR`에 저장합니다. Nix에서 실행할 때는 런타임 상태와 구성이 불변 스토어 밖에 있도록 이를 Nix에서 관리하는 위치로 명시적으로 설정하세요. +OpenClaw는 `OPENCLAW_CONFIG_PATH`에서 JSON5 설정을 읽고 `OPENCLAW_STATE_DIR`에 변경 가능한 데이터를 저장합니다. Nix에서 실행할 때는 런타임 상태와 설정이 변경 불가능한 저장소 밖에 있도록 이를 Nix가 관리하는 위치로 명시적으로 설정하세요. | 변수 | 기본값 | | ---------------------- | --------------------------------------- | @@ -89,11 +91,12 @@ OpenClaw는 `OPENCLAW_CONFIG_PATH`에서 JSON5 구성을 읽고 변경 가능한 ### 서비스 PATH 검색 -launchd/systemd gateway 서비스는 Nix 프로필 바이너리를 자동으로 검색하므로 -`nix`로 설치된 실행 파일을 셸에서 호출하는 Plugin과 도구가 +launchd/systemd Gateway 서비스는 Nix 프로필 바이너리를 자동으로 검색하므로 +`shell`로 `nix`로 설치된 실행 파일을 호출하는 Plugin과 도구가 수동 PATH 설정 없이 작동합니다. -- `NIX_PROFILES`가 설정된 경우, 모든 항목이 오른쪽에서 왼쪽으로 우선순위를 적용해 서비스 PATH에 추가됩니다(Nix 셸 우선순위와 일치 -- 가장 오른쪽이 우선). +- `NIX_PROFILES`가 설정된 경우, 모든 항목이 오른쪽에서 왼쪽으로 우선순위를 적용하여 서비스 PATH에 추가됩니다 + (Nix 셸 우선순위와 일치 - 가장 오른쪽이 우선). - `NIX_PROFILES`가 설정되지 않은 경우, `~/.nix-profile/bin`이 대체 경로로 추가됩니다. 이는 macOS launchd와 Linux systemd 서비스 환경 모두에 적용됩니다. @@ -102,15 +105,15 @@ launchd/systemd gateway 서비스는 Nix 프로필 바이너리를 자동으로 - 기준 소스 Home Manager 모듈 및 전체 설정 가이드입니다. + 단일 기준인 Home Manager 모듈 및 전체 설정 가이드입니다. - + Nix를 사용하지 않는 CLI 설정 안내입니다. - Nix를 사용하지 않는 대안인 컨테이너 기반 설정입니다. + Nix 대안으로 컨테이너화된 설정입니다. - + 패키지와 함께 Home Manager로 관리되는 설치를 업데이트합니다. diff --git a/docs/ko/logging.md b/docs/ko/logging.md index edf6d349f..fa4d2c411 100644 --- a/docs/ko/logging.md +++ b/docs/ko/logging.md @@ -1,38 +1,38 @@ --- read_when: - - OpenClaw 로깅에 대한 초보자도 이해하기 쉬운 개요가 필요합니다 - - 로그 수준, 형식 또는 민감 정보 마스킹을 구성하려는 경우 + - OpenClaw 로깅에 대한 입문자 친화적인 개요가 필요합니다 + - 로그 수준, 형식 또는 마스킹을 구성하려는 경우 - 문제를 해결하는 중이며 로그를 빠르게 찾아야 합니다 -summary: 파일 로그, 콘솔 출력, CLI 테일링 및 Control UI 로그 탭 +summary: 파일 로그, 콘솔 출력, CLI 실시간 추적, 제어 UI 로그 탭 title: 로깅 x-i18n: - generated_at: "2026-05-06T06:31:27Z" + generated_at: "2026-05-06T17:58:15Z" model: gpt-5.5 provider: openai - source_hash: abcdfeb0f9fbd13715762a1829198d0285738855c50f2ee531cab1e989d936b1 + source_hash: 218f68c5111b6de01dc14707dad132d15d5e78c8e906af8a5416e618807663ac source_path: logging.md workflow: 16 --- OpenClaw에는 두 가지 주요 로그 표면이 있습니다. -- Gateway가 기록하는 **파일 로그**(JSON lines). -- 터미널과 Gateway 디버그 UI에 표시되는 **콘솔 출력**. +- Gateway가 작성하는 **파일 로그**(JSON lines). +- 터미널과 Gateway Debug UI에 표시되는 **콘솔 출력**. -제어 UI의 **로그** 탭은 gateway 파일 로그를 tail합니다. 이 페이지에서는 로그가 -저장되는 위치, 읽는 방법, 로그 수준과 형식을 구성하는 방법을 설명합니다. +Control UI **로그** 탭은 Gateway 파일 로그를 tail합니다. 이 페이지에서는 +로그가 있는 위치, 로그를 읽는 방법, 로그 수준과 형식을 구성하는 방법을 설명합니다. ## 로그 위치 -기본적으로 Gateway는 다음 위치 아래에 롤링 로그 파일을 기록합니다. +기본적으로 Gateway는 다음 위치 아래에 롤링 로그 파일을 작성합니다. `/tmp/openclaw/openclaw-YYYY-MM-DD.log` -날짜는 gateway 호스트의 로컬 시간대를 사용합니다. +날짜는 Gateway 호스트의 로컬 시간대를 사용합니다. -각 파일은 `logging.maxFileBytes`(기본값: 100 MB)에 도달하면 순환됩니다. -OpenClaw는 활성 파일 옆에 `openclaw-YYYY-MM-DD.1.log` 같은 번호가 붙은 -아카이브를 최대 5개까지 유지하며, 진단을 억제하는 대신 새 활성 로그에 계속 기록합니다. +각 파일은 `logging.maxFileBytes`(기본값: 100 MB)에 도달하면 회전됩니다. +OpenClaw는 활성 파일 옆에 `openclaw-YYYY-MM-DD.1.log`와 같은 번호가 붙은 +아카이브를 최대 5개까지 보관하며, 진단을 억제하지 않고 새 활성 로그에 계속 씁니다. `~/.openclaw/openclaw.json`에서 이를 재정의할 수 있습니다. @@ -48,54 +48,54 @@ OpenClaw는 활성 파일 옆에 `openclaw-YYYY-MM-DD.1.log` 같은 번호가 ### CLI: 실시간 tail(권장) -CLI를 사용해 RPC를 통해 gateway 로그 파일을 tail합니다. +RPC를 통해 Gateway 로그 파일을 tail하려면 CLI를 사용합니다. ```bash openclaw logs --follow ``` -유용한 현재 옵션: +현재 유용한 옵션: - `--local-time`: 타임스탬프를 로컬 시간대로 렌더링 - `--url ` / `--token ` / `--timeout `: 표준 Gateway RPC 플래그 -- `--expect-final`: agent 기반 RPC 최종 응답 대기 플래그(공유 클라이언트 계층을 통해 여기에서도 허용됨) +- `--expect-final`: 에이전트 기반 RPC 최종 응답 대기 플래그(공유 클라이언트 계층을 통해 여기서도 허용됨) 출력 모드: -- **TTY 세션**: 보기 좋고, 색상이 적용된 구조화된 로그 줄. +- **TTY 세션**: 보기 좋고, 색상이 적용된 구조화 로그 줄. - **비 TTY 세션**: 일반 텍스트. -- `--json`: 줄 단위 JSON(줄당 로그 이벤트 하나). +- `--json`: 줄 단위 JSON(줄당 하나의 로그 이벤트). - `--plain`: TTY 세션에서 일반 텍스트 강제. - `--no-color`: ANSI 색상 비활성화. -명시적 `--url`을 전달하면 CLI는 구성 또는 환경 자격 증명을 자동 적용하지 않습니다. -대상 Gateway에 인증이 필요한 경우 `--token`을 직접 포함하세요. +명시적인 `--url`을 전달하면 CLI는 구성 또는 환경 자격 증명을 자동으로 적용하지 않습니다. +대상 Gateway에 인증이 필요하면 `--token`을 직접 포함하세요. JSON 모드에서 CLI는 `type` 태그가 지정된 객체를 내보냅니다. -- `meta`: 스트림 메타데이터(file, cursor, size) +- `meta`: 스트림 메타데이터(파일, 커서, 크기) - `log`: 파싱된 로그 항목 -- `notice`: 잘림 / 순환 힌트 +- `notice`: 잘림 / 회전 힌트 - `raw`: 파싱되지 않은 로그 줄 암시적 local loopback Gateway가 페어링을 요청하거나, 연결 중 닫히거나, -`logs.tail`이 응답하기 전에 시간 초과되면 `openclaw logs`는 구성된 Gateway 파일 -로그로 자동 대체됩니다. 명시적 `--url` 대상은 이 대체 동작을 사용하지 않습니다. +`logs.tail`이 응답하기 전에 시간 초과되면 `openclaw logs`는 구성된 +Gateway 파일 로그로 자동 폴백합니다. 명시적인 `--url` 대상은 이 폴백을 사용하지 않습니다. -Gateway에 연결할 수 없는 경우 CLI는 다음을 실행하라는 짧은 힌트를 출력합니다. +Gateway에 연결할 수 없으면 CLI는 다음을 실행하라는 짧은 힌트를 출력합니다. ```bash openclaw doctor ``` -### 제어 UI(웹) +### Control UI(웹) -제어 UI의 **로그** 탭은 `logs.tail`을 사용해 같은 파일을 tail합니다. -여는 방법은 [제어 UI](/ko/web/control-ui)를 참조하세요. +Control UI의 **로그** 탭은 `logs.tail`을 사용하여 같은 파일을 tail합니다. +여는 방법은 [Control UI](/ko/web/control-ui)를 참조하세요. ### 채널 전용 로그 -채널 활동(WhatsApp/Telegram 등)을 필터링하려면 다음을 사용하세요. +채널 활동(WhatsApp/Telegram 등)을 필터링하려면 다음을 사용합니다. ```bash openclaw channels logs --channel whatsapp @@ -105,26 +105,31 @@ openclaw channels logs --channel whatsapp ### 파일 로그(JSONL) -로그 파일의 각 줄은 JSON 객체입니다. CLI와 제어 UI는 이러한 항목을 파싱해 +로그 파일의 각 줄은 JSON 객체입니다. CLI와 Control UI는 이러한 항목을 파싱해 구조화된 출력(시간, 수준, 하위 시스템, 메시지)을 렌더링합니다. 파일 로그 JSONL 레코드는 사용 가능한 경우 기계적으로 필터링 가능한 최상위 필드도 포함합니다. -- `hostname`: gateway 호스트 이름. -- `message`: 전체 텍스트 검색을 위한 평면화된 로그 메시지 텍스트. -- `agent_id`: 로그 호출에 agent 컨텍스트가 포함된 경우 활성 agent id. -- `session_id`: 로그 호출에 세션 컨텍스트가 포함된 경우 활성 세션 id/key. +- `hostname`: Gateway 호스트 이름. +- `message`: 전체 텍스트 검색용으로 평탄화된 로그 메시지 텍스트. +- `agent_id`: 로그 호출에 에이전트 컨텍스트가 포함된 경우 활성 에이전트 id. +- `session_id`: 로그 호출에 세션 컨텍스트가 포함된 경우 활성 세션 id/키. - `channel`: 로그 호출에 채널 컨텍스트가 포함된 경우 활성 채널. -OpenClaw는 이러한 필드와 함께 원래의 구조화된 로그 인수를 보존하므로, -번호가 지정된 tslog 인수 키를 읽는 기존 파서도 계속 작동합니다. +OpenClaw는 이러한 필드와 함께 원래의 구조화된 로그 인수를 보존하므로 +번호가 매겨진 tslog 인수 키를 읽는 기존 파서도 계속 동작합니다. + +Talk, 실시간 음성, 관리형 룸 활동은 이 동일한 파일 로그 파이프라인을 통해 +제한된 수명 주기 로그 레코드를 내보냅니다. 이러한 레코드에는 사용 가능한 경우 이벤트 유형, +모드, 전송, 제공자, 크기/타이밍 측정값이 포함되지만, transcript 텍스트, 오디오 페이로드, +turn id, call id, 제공자 item id는 제외됩니다. ### 콘솔 출력 -콘솔 로그는 **TTY 인식** 방식이며 가독성을 위해 형식이 지정됩니다. +콘솔 로그는 **TTY 인식** 방식이며 가독성을 위해 형식화됩니다. - 하위 시스템 접두사(예: `gateway/channels/whatsapp`) -- 수준 색상(info/warn/error) +- 수준 색상 표시(info/warn/error) - 선택적 compact 또는 JSON 모드 콘솔 형식은 `logging.consoleStyle`로 제어됩니다. @@ -133,9 +138,9 @@ OpenClaw는 이러한 필드와 함께 원래의 구조화된 로그 인수를 `openclaw gateway`에는 RPC 트래픽을 위한 WebSocket 프로토콜 로깅도 있습니다. -- 일반 모드: 관심 있는 결과만(오류, 파싱 오류, 느린 호출) +- 일반 모드: 주목할 만한 결과만(오류, 파싱 오류, 느린 호출) - `--verbose`: 모든 요청/응답 트래픽 -- `--ws-log auto|compact|full`: verbose 렌더링 스타일 선택 +- `--ws-log auto|compact|full`: 자세한 렌더링 스타일 선택 - `--compact`: `--ws-log compact`의 별칭 예시: @@ -166,93 +171,97 @@ openclaw gateway --verbose --ws-log full ### 로그 수준 - `logging.level`: **파일 로그**(JSONL) 수준. -- `logging.consoleLevel`: **콘솔** 상세 수준. +- `logging.consoleLevel`: **콘솔** 상세도 수준. -두 값 모두 **`OPENCLAW_LOG_LEVEL`** 환경 변수(예: `OPENCLAW_LOG_LEVEL=debug`)로 재정의할 수 있습니다. 이 환경 변수는 구성 파일보다 우선하므로 `openclaw.json`을 편집하지 않고도 단일 실행의 상세 수준을 높일 수 있습니다. 전역 CLI 옵션 **`--log-level `**(예: `openclaw --log-level debug gateway run`)도 전달할 수 있으며, 해당 명령에 대해 환경 변수를 재정의합니다. +**`OPENCLAW_LOG_LEVEL`** 환경 변수(예: `OPENCLAW_LOG_LEVEL=debug`)로 둘 다 재정의할 수 있습니다. 환경 변수는 구성 파일보다 우선하므로 `openclaw.json`을 편집하지 않고 단일 실행의 상세도를 높일 수 있습니다. 또한 전역 CLI 옵션 **`--log-level `**(예: `openclaw --log-level debug gateway run`)을 전달할 수 있으며, 이 옵션은 해당 명령에 대해 환경 변수를 재정의합니다. -`--verbose`는 콘솔 출력과 WS 로그 상세 수준에만 영향을 줍니다. 파일 로그 수준은 변경하지 않습니다. +`--verbose`는 콘솔 출력과 WS 로그 상세도에만 영향을 주며, +파일 로그 수준은 변경하지 않습니다. -### 추적 상관관계 +### 트레이스 상관관계 -파일 로그는 JSONL입니다. 로그 호출에 유효한 진단 추적 컨텍스트가 포함된 경우, -OpenClaw는 외부 로그 처리기가 해당 줄을 OTEL span 및 제공자 `traceparent` -전파와 상관시킬 수 있도록 추적 필드를 최상위 JSON 키(`traceId`, `spanId`, -`parentSpanId`, `traceFlags`)로 기록합니다. +파일 로그는 JSONL입니다. 로그 호출에 유효한 진단 trace 컨텍스트가 포함되면 +OpenClaw는 trace 필드를 최상위 JSON 키(`traceId`, `spanId`, +`parentSpanId`, `traceFlags`)로 작성하여 외부 로그 처리기가 해당 줄을 +OTEL span 및 제공자 `traceparent` 전파와 상관시킬 수 있게 합니다. -Gateway HTTP 요청과 Gateway WebSocket 프레임은 내부 요청 추적 범위를 설정합니다. -해당 비동기 범위 안에서 발생한 로그와 진단 이벤트는 명시적 추적 컨텍스트를 전달하지 -않을 때 요청 추적을 상속합니다. Agent 실행 및 모델 호출 추적은 활성 요청 추적의 -자식이 되므로, 로컬 로그, 진단 스냅샷, OTEL span, 신뢰할 수 있는 제공자 -`traceparent` 헤더를 원시 요청 또는 모델 콘텐츠를 로깅하지 않고도 `traceId`로 -연결할 수 있습니다. +Gateway HTTP 요청과 Gateway WebSocket 프레임은 내부 요청 trace 범위를 설정합니다. +해당 async 범위 안에서 내보낸 로그와 진단 이벤트는 명시적 trace 컨텍스트를 전달하지 않을 때 +요청 trace를 상속합니다. 에이전트 실행 및 모델 호출 trace는 활성 요청 trace의 자식이 되므로 +로컬 로그, 진단 스냅샷, OTEL span, 신뢰할 수 있는 제공자 `traceparent` 헤더를 +원시 요청 또는 모델 콘텐츠를 로깅하지 않고도 `traceId`로 결합할 수 있습니다. + +OpenTelemetry 로그 내보내기가 활성화된 경우 Talk 수명 주기 로그 레코드도 +파일 로그와 동일한 제한된 속성을 사용해 OTLP 로그로 흐릅니다. ### 모델 호출 크기 및 타이밍 -모델 호출 진단은 원시 프롬프트 또는 응답 콘텐츠를 캡처하지 않고 제한된 -요청/응답 측정값을 기록합니다. +모델 호출 진단은 원시 프롬프트 또는 응답 콘텐츠를 캡처하지 않고 +제한된 요청/응답 측정값을 기록합니다. - `requestPayloadBytes`: 최종 모델 요청 페이로드의 UTF-8 바이트 크기 - `responseStreamBytes`: 스트리밍된 모델 응답 이벤트의 UTF-8 바이트 크기 -- `timeToFirstByteMs`: 첫 번째 스트리밍 응답 이벤트 전까지의 경과 시간 -- `durationMs`: 전체 모델 호출 지속 시간 +- `timeToFirstByteMs`: 첫 번째 스트리밍 응답 이벤트 전까지 경과한 시간 +- `durationMs`: 총 모델 호출 지속 시간 -진단 내보내기가 활성화된 경우 이러한 필드는 진단 스냅샷, 모델 호출 Plugin 훅, -OTEL 모델 호출 span/메트릭에서 사용할 수 있습니다. +이러한 필드는 진단 내보내기가 활성화된 경우 진단 스냅샷, 모델 호출 Plugin 후크, +OTEL 모델 호출 span/metric에서 사용할 수 있습니다. ### 콘솔 스타일 `logging.consoleStyle`: -- `pretty`: 사람이 읽기 쉽고, 색상이 적용되며, 타임스탬프가 포함됨. +- `pretty`: 사람이 읽기 쉽고, 색상이 적용되며, 타임스탬프 포함. - `compact`: 더 간결한 출력(긴 세션에 적합). - `json`: 줄당 JSON(로그 처리기용). -### 마스킹 +### 수정 -OpenClaw는 민감한 토큰이 콘솔 출력, 파일 로그, OTLP 로그 레코드, 저장된 세션 -대화록 텍스트 또는 제어 UI 도구 이벤트 페이로드(도구 시작 인수, 부분/최종 결과 -페이로드, 파생된 exec 출력, 패치 요약)에 도달하기 전에 마스킹할 수 있습니다. +OpenClaw는 민감한 토큰이 콘솔 출력, 파일 로그, +OTLP 로그 레코드, 영구 저장된 세션 transcript 텍스트 또는 Control UI 도구 +이벤트 페이로드(도구 시작 인수, 부분/최종 결과 페이로드, 파생된 +exec 출력, 패치 요약)에 도달하기 전에 수정할 수 있습니다. - `logging.redactSensitive`: `off` | `tools`(기본값: `tools`) -- `logging.redactPatterns`: 기본 집합을 재정의할 정규식 문자열 목록. 사용자 지정 패턴은 제어 UI 도구 페이로드의 내장 기본값 위에 추가로 적용되므로, 패턴을 추가해도 기본값에 이미 걸리는 값의 마스킹이 약화되지 않습니다. +- `logging.redactPatterns`: 기본 세트를 재정의할 정규식 문자열 목록. 사용자 지정 패턴은 Control UI 도구 페이로드에 대한 내장 기본값 위에 추가로 적용되므로, 패턴을 추가해도 기본값이 이미 포착하는 값의 수정이 약해지지 않습니다. -파일 로그와 세션 대화록은 JSONL로 유지되지만, 일치하는 비밀 값은 줄 또는 메시지가 -디스크에 기록되기 전에 마스킹됩니다. 마스킹은 최선의 노력 방식입니다. 모든 식별자 -또는 바이너리 페이로드 필드가 아니라 텍스트를 포함하는 메시지 콘텐츠와 로그 문자열에 -적용됩니다. +파일 로그와 세션 transcript는 JSONL로 유지되지만, 일치하는 비밀 값은 +줄 또는 메시지가 디스크에 쓰이기 전에 마스킹됩니다. 수정은 최선 노력 방식입니다. +텍스트를 포함하는 메시지 콘텐츠와 로그 문자열에는 적용되지만, 모든 +식별자 또는 바이너리 페이로드 필드에 적용되지는 않습니다. -내장 기본값은 카드 번호, CVC/CVV, 공유 결제 토큰, 결제 자격 증명 같은 일반적인 API -자격 증명 및 결제 자격 증명 필드 이름이 JSON 필드, URL 매개변수, CLI 플래그 또는 -할당으로 나타날 때 이를 포괄합니다. +내장 기본값은 카드 번호, CVC/CVV, 공유 결제 토큰, 결제 자격 증명과 같은 +일반적인 API 자격 증명 및 결제 자격 증명 필드 이름이 JSON 필드, URL 매개변수, +CLI 플래그 또는 할당으로 나타날 때 이를 처리합니다. -`logging.redactSensitive: "off"`는 이 일반 로그/대화록 정책만 비활성화합니다. -OpenClaw는 UI 클라이언트, 지원 번들, 진단 관찰자, 승인 프롬프트 또는 agent 도구에 -표시될 수 있는 안전 경계 페이로드는 계속 마스킹합니다. 예로는 제어 UI 도구 호출 -이벤트, `sessions_history` 출력, 진단 지원 내보내기, 제공자 오류 관찰, exec 승인 -명령 표시, Gateway WebSocket 프로토콜 로그가 있습니다. 사용자 지정 -`logging.redactPatterns`는 이러한 표면에도 프로젝트별 패턴을 추가할 수 있습니다. +`logging.redactSensitive: "off"`는 이 일반 로그/transcript 정책만 비활성화합니다. +OpenClaw는 UI 클라이언트, 지원 번들, 진단 관찰자, 승인 프롬프트 또는 에이전트 +도구에 표시될 수 있는 안전 경계 페이로드를 계속 수정합니다. 예시로는 Control UI 도구 호출 이벤트, +`sessions_history` 출력, 진단 지원 내보내기, 제공자 오류 관찰, exec 승인 명령 +표시, Gateway WebSocket 프로토콜 로그가 있습니다. 사용자 지정 `logging.redactPatterns`는 +이러한 표면에도 프로젝트별 패턴을 계속 추가할 수 있습니다. ## 진단 및 OpenTelemetry -진단은 모델 실행과 메시지 흐름 원격 측정(Webhook, 큐잉, 세션 상태)을 위한 -구조화된 기계 판독 가능 이벤트입니다. 진단은 로그를 대체하지 **않습니다**. 진단은 -메트릭, 추적, 내보내기에 공급됩니다. 이벤트는 내보내기 여부와 관계없이 프로세스 -내에서 발생합니다. +진단은 모델 실행 및 메시지 흐름 텔레메트리(Webhook, 큐잉, 세션 상태)를 위한 +구조화되고 기계가 읽을 수 있는 이벤트입니다. 이는 로그를 대체하지 않습니다. +메트릭, trace, exporter에 공급됩니다. 이벤트는 내보내기 여부와 관계없이 +프로세스 내에서 내보내집니다. 인접한 두 표면: -- **OpenTelemetry 내보내기** — OTLP/HTTP를 통해 메트릭, 추적, 로그를 - OpenTelemetry 호환 컬렉터 또는 백엔드(Grafana, Datadog, Honeycomb, - New Relic, Tempo 등)로 전송합니다. 전체 구성, 신호 카탈로그, - 메트릭/span 이름, 환경 변수, 개인정보 모델은 전용 페이지에 있습니다. +- **OpenTelemetry 내보내기** — OTLP/HTTP를 통해 메트릭, trace, 로그를 + OpenTelemetry 호환 수집기 또는 백엔드(Grafana, Datadog, + Honeycomb, New Relic, Tempo 등)로 보냅니다. 전체 구성, 신호 카탈로그, + metric/span 이름, 환경 변수, 개인정보 모델은 전용 페이지에 있습니다. [OpenTelemetry 내보내기](/ko/gateway/opentelemetry). -- **진단 플래그** — `logging.level`을 올리지 않고 추가 로그를 `logging.file`로 - 라우팅하는 대상 지정 debug 로그 플래그입니다. 플래그는 대소문자를 구분하지 않고 - 와일드카드(`telegram.*`, `*`)를 지원합니다. `diagnostics.flags` 아래에서 - 또는 `OPENCLAW_DIAGNOSTICS=...` 환경 재정의로 구성하세요. 전체 가이드: +- **진단 플래그** — `logging.level`을 높이지 않고 추가 로그를 + `logging.file`로 라우팅하는 대상 지정 debug-log 플래그입니다. 플래그는 대소문자를 구분하지 않으며 + 와일드카드(`telegram.*`, `*`)를 지원합니다. `diagnostics.flags` 아래에서 구성하거나 + `OPENCLAW_DIAGNOSTICS=...` 환경 재정의로 구성하세요. 전체 가이드: [진단 플래그](/ko/diagnostics/flags). -OTLP 내보내기 없이 Plugin 또는 사용자 지정 sink용 진단 이벤트를 활성화하려면: +OTLP 내보내기 없이 Plugin 또는 사용자 지정 sink에 대한 진단 이벤트를 활성화하려면: ```json5 { @@ -260,18 +269,18 @@ OTLP 내보내기 없이 Plugin 또는 사용자 지정 sink용 진단 이벤트 } ``` -컬렉터로 OTLP를 내보내려면 [OpenTelemetry 내보내기](/ko/gateway/opentelemetry)를 참조하세요. +수집기로 OTLP 내보내기를 하려면 [OpenTelemetry 내보내기](/ko/gateway/opentelemetry)를 참조하세요. ## 문제 해결 팁 - **Gateway에 연결할 수 없나요?** 먼저 `openclaw doctor`를 실행하세요. -- **로그가 비어 있나요?** Gateway가 실행 중이고 `logging.file`의 파일 경로에 - 기록 중인지 확인하세요. -- **더 자세한 정보가 필요한가요?** `logging.level`을 `debug` 또는 `trace`로 설정하고 다시 시도하세요. +- **로그가 비어 있나요?** Gateway가 실행 중이며 `logging.file`의 파일 경로에 + 쓰고 있는지 확인하세요. +- **더 많은 세부 정보가 필요한가요?** `logging.level`을 `debug` 또는 `trace`로 설정하고 다시 시도하세요. ## 관련 항목 -- [OpenTelemetry 내보내기](/ko/gateway/opentelemetry) — OTLP/HTTP 내보내기, 메트릭/span 카탈로그, 개인정보 모델 -- [진단 플래그](/ko/diagnostics/flags) — 대상 지정 debug 로그 플래그 -- [Gateway 로깅 내부 구조](/ko/gateway/logging) — WS 로그 스타일, 하위 시스템 접두사, 콘솔 캡처 +- [OpenTelemetry 내보내기](/ko/gateway/opentelemetry) — OTLP/HTTP 내보내기, metric/span 카탈로그, 개인정보 모델 +- [진단 플래그](/ko/diagnostics/flags) — 대상 지정 debug-log 플래그 +- [Gateway 로깅 내부](/ko/gateway/logging) — WS 로그 스타일, 하위 시스템 접두사, 콘솔 캡처 - [구성 참조](/ko/gateway/configuration-reference#diagnostics) — 전체 `diagnostics.*` 필드 참조 diff --git a/docs/ko/nodes/audio.md b/docs/ko/nodes/audio.md index ff57bf122..a2431bdb8 100644 --- a/docs/ko/nodes/audio.md +++ b/docs/ko/nodes/audio.md @@ -1,52 +1,50 @@ --- read_when: - - 오디오 전사 또는 미디어 처리 변경 -summary: 수신 오디오/음성 메모가 다운로드되고, 전사되며, 답장에 삽입되는 방식 + - 오디오 전사 또는 미디어 처리 변경하기 +summary: 수신 오디오/음성 메모가 다운로드되고 전사되어 답장에 삽입되는 방식 title: 오디오 및 음성 메모 x-i18n: - generated_at: "2026-05-06T06:31:38Z" + generated_at: "2026-05-06T17:58:32Z" model: gpt-5.5 provider: openai - source_hash: 520620da5a643bb8e17318d7304ae4be3bd2586b0866614ad741685de5b8ef05 + source_hash: baa96453ce279d05933281eafe930e3573c5cbe694cec8704b1d064f4b0de242 source_path: nodes/audio.md workflow: 16 --- -# 오디오 / 음성 메모 (2026-01-17) - ## 작동하는 기능 -- **미디어 이해(오디오)**: 오디오 이해가 활성화되어 있거나 자동 감지되면 OpenClaw는 다음을 수행합니다. - 1. 첫 번째 오디오 첨부 파일(로컬 경로 또는 URL)을 찾고, 필요한 경우 다운로드합니다. +- **미디어 이해(오디오)**: 오디오 이해가 활성화되어 있거나 자동 감지되면 OpenClaw는: + 1. 첫 번째 오디오 첨부 파일(로컬 경로 또는 URL)을 찾고 필요하면 다운로드합니다. 2. 각 모델 항목으로 보내기 전에 `maxBytes`를 적용합니다. - 3. 순서대로 첫 번째 적격 모델 항목(provider 또는 CLI)을 실행합니다. - 4. 실패하거나 건너뛰면(크기/타임아웃) 다음 항목을 시도합니다. - 5. 성공하면 `Body`를 `[Audio]` 블록으로 교체하고 `{{Transcript}}`를 설정합니다. + 3. 순서대로 첫 번째 사용 가능한 모델 항목(프로바이더 또는 CLI)을 실행합니다. + 4. 실패하거나 건너뛰면(크기/시간 초과) 다음 항목을 시도합니다. + 5. 성공하면 `Body`를 `[Audio]` 블록으로 바꾸고 `{{Transcript}}`를 설정합니다. - **명령 파싱**: 전사가 성공하면 슬래시 명령이 계속 작동하도록 `CommandBody`/`RawBody`가 전사문으로 설정됩니다. -- **상세 로깅**: `--verbose`에서는 전사가 실행될 때와 본문을 교체할 때 로그를 남깁니다. +- **자세한 로깅**: `--verbose`에서는 전사가 실행될 때와 본문을 대체할 때 로그를 남깁니다. ## 자동 감지(기본값) -**모델을 구성하지 않았고** `tools.media.audio.enabled`가 `false`로 설정되어 있지 않으면, -OpenClaw는 다음 순서로 자동 감지하며 첫 번째로 작동하는 옵션에서 중지합니다. +**모델을 구성하지 않았고** `tools.media.audio.enabled`가 `false`로 설정되어 **있지 않으면**, +OpenClaw는 다음 순서로 자동 감지하며 첫 번째로 작동하는 옵션에서 중단합니다. -1. provider가 오디오 이해를 지원하는 경우 **활성 답장 모델**. +1. 프로바이더가 오디오 이해를 지원하는 경우 **활성 응답 모델** 2. **로컬 CLI**(설치된 경우) - - `sherpa-onnx-offline`(encoder/decoder/joiner/tokens가 포함된 `SHERPA_ONNX_MODEL_DIR` 필요) - - `whisper-cli`(`whisper-cpp`에서 제공, `WHISPER_CPP_MODEL` 또는 번들된 tiny 모델 사용) + - `sherpa-onnx-offline`(encoder/decoder/joiner/tokens가 있는 `SHERPA_ONNX_MODEL_DIR` 필요) + - `whisper-cli`(`whisper-cpp` 제공, `WHISPER_CPP_MODEL` 또는 번들 tiny 모델 사용) - `whisper`(Python CLI, 모델을 자동으로 다운로드) 3. `read_many_files`를 사용하는 **Gemini CLI**(`gemini`) -4. **Provider 인증** - - 오디오를 지원하는 구성된 `models.providers.*` 항목을 먼저 시도합니다. - - 번들된 폴백 순서: OpenAI → Groq → xAI → Deepgram → Google → SenseAudio → ElevenLabs → Mistral +4. **프로바이더 인증** + - 오디오를 지원하는 구성된 `models.providers.*` 항목을 먼저 시도합니다 + - 번들 fallback 순서: OpenAI → Groq → xAI → Deepgram → Google → SenseAudio → ElevenLabs → Mistral 자동 감지를 비활성화하려면 `tools.media.audio.enabled: false`를 설정하세요. 사용자 지정하려면 `tools.media.audio.models`를 설정하세요. -참고: 바이너리 감지는 macOS/Linux/Windows 전반에서 최선의 방식으로 동작합니다. CLI가 `PATH`에 있는지 확인하거나(`~`를 확장함), 전체 명령 경로로 명시적인 CLI 모델을 설정하세요. +참고: 바이너리 감지는 macOS/Linux/Windows 전반에서 최선의 방식으로 수행됩니다. CLI가 `PATH`에 있는지 확인하거나(`~`를 확장함), 전체 명령 경로가 포함된 명시적 CLI 모델을 설정하세요. ## 구성 예시 -### Provider + CLI 폴백(OpenAI + Whisper CLI) +### 프로바이더 + CLI fallback(OpenAI + Whisper CLI) ```json5 { @@ -70,7 +68,7 @@ OpenClaw는 다음 순서로 자동 감지하며 첫 번째로 작동하는 옵 } ``` -### 범위 게이팅이 있는 Provider 전용 +### 범위 게이팅이 있는 프로바이더 전용 ```json5 { @@ -89,7 +87,7 @@ OpenClaw는 다음 순서로 자동 감지하며 첫 번째로 작동하는 옵 } ``` -### Provider 전용(Deepgram) +### 프로바이더 전용(Deepgram) ```json5 { @@ -104,7 +102,7 @@ OpenClaw는 다음 순서로 자동 감지하며 첫 번째로 작동하는 옵 } ``` -### Provider 전용(Mistral Voxtral) +### 프로바이더 전용(Mistral Voxtral) ```json5 { @@ -119,7 +117,7 @@ OpenClaw는 다음 순서로 자동 감지하며 첫 번째로 작동하는 옵 } ``` -### Provider 전용(SenseAudio) +### 프로바이더 전용(SenseAudio) ```json5 { @@ -134,7 +132,7 @@ OpenClaw는 다음 순서로 자동 감지하며 첫 번째로 작동하는 옵 } ``` -### 전사문을 채팅에 에코(선택 사항) +### 채팅에 전사문 에코(선택 사항) ```json5 { @@ -151,30 +149,30 @@ OpenClaw는 다음 순서로 자동 감지하며 첫 번째로 작동하는 옵 } ``` -## 참고 사항 및 제한 +## 참고 및 제한 사항 -- Provider 인증은 표준 모델 인증 순서(인증 프로필, 환경 변수, `models.providers.*.apiKey`)를 따릅니다. +- 프로바이더 인증은 표준 모델 인증 순서(인증 프로필, 환경 변수, `models.providers.*.apiKey`)를 따릅니다. - Groq 설정 세부 정보: [Groq](/ko/providers/groq). -- `provider: "deepgram"`이 사용되면 Deepgram은 `DEEPGRAM_API_KEY`를 사용합니다. +- `provider: "deepgram"`을 사용할 때 Deepgram은 `DEEPGRAM_API_KEY`를 가져옵니다. - Deepgram 설정 세부 정보: [Deepgram(오디오 전사)](/ko/providers/deepgram). - Mistral 설정 세부 정보: [Mistral](/ko/providers/mistral). -- `provider: "senseaudio"`가 사용되면 SenseAudio는 `SENSEAUDIO_API_KEY`를 사용합니다. +- `provider: "senseaudio"`를 사용할 때 SenseAudio는 `SENSEAUDIO_API_KEY`를 가져옵니다. - SenseAudio 설정 세부 정보: [SenseAudio](/ko/providers/senseaudio). -- 오디오 provider는 `tools.media.audio`를 통해 `baseUrl`, `headers`, `providerOptions`를 재정의할 수 있습니다. -- 기본 크기 제한은 20MB(`tools.media.audio.maxBytes`)입니다. 크기가 초과된 오디오는 해당 모델에서 건너뛰고 다음 항목을 시도합니다. -- 1024바이트 미만의 아주 작거나 비어 있는 오디오 파일은 provider/CLI 전사 전에 건너뜁니다. +- 오디오 프로바이더는 `tools.media.audio`를 통해 `baseUrl`, `headers`, `providerOptions`를 재정의할 수 있습니다. +- 기본 크기 제한은 20MB(`tools.media.audio.maxBytes`)입니다. 크기를 초과하는 오디오는 해당 모델에서 건너뛰고 다음 항목을 시도합니다. +- 1024바이트 미만의 작거나 빈 오디오 파일은 프로바이더/CLI 전사 전에 건너뜁니다. - 오디오의 기본 `maxChars`는 **설정되지 않음**(전체 전사문)입니다. 출력을 자르려면 `tools.media.audio.maxChars` 또는 항목별 `maxChars`를 설정하세요. - OpenAI 자동 기본값은 `gpt-4o-mini-transcribe`입니다. 더 높은 정확도를 원하면 `model: "gpt-4o-transcribe"`를 설정하세요. - 여러 음성 메모를 처리하려면 `tools.media.audio.attachments`를 사용하세요(`mode: "all"` + `maxAttachments`). - 전사문은 템플릿에서 `{{Transcript}}`로 사용할 수 있습니다. -- `tools.media.audio.echoTranscript`는 기본적으로 꺼져 있습니다. 에이전트 처리 전에 원본 채팅으로 전사 확인을 보내려면 활성화하세요. -- `tools.media.audio.echoFormat`은 에코 텍스트를 사용자 지정합니다(플레이스홀더: `{transcript}`). +- `tools.media.audio.echoTranscript`는 기본적으로 꺼져 있습니다. 에이전트 처리 전에 원래 채팅으로 전사 확인을 보내려면 활성화하세요. +- `tools.media.audio.echoFormat`은 에코 텍스트를 사용자 지정합니다(placeholder: `{transcript}`). - CLI stdout은 제한됩니다(5MB). CLI 출력을 간결하게 유지하세요. -- CLI `args`는 로컬 오디오 파일 경로에 `{{MediaPath}}`를 사용해야 합니다. 오래된 `audio.transcription.command` 구성의 사용 중단된 `{input}` 플레이스홀더를 마이그레이션하려면 `openclaw doctor --fix`를 실행하세요. +- CLI `args`는 로컬 오디오 파일 경로에 `{{MediaPath}}`를 사용해야 합니다. 이전 `audio.transcription.command` 구성의 더 이상 사용되지 않는 `{input}` placeholder를 마이그레이션하려면 `openclaw doctor --fix`를 실행하세요. ### 프록시 환경 지원 -Provider 기반 오디오 전사는 표준 아웃바운드 프록시 환경 변수를 따릅니다. +프로바이더 기반 오디오 전사는 표준 outbound 프록시 환경 변수를 따릅니다. - `HTTPS_PROXY` - `HTTP_PROXY` @@ -183,42 +181,42 @@ Provider 기반 오디오 전사는 표준 아웃바운드 프록시 환경 변 - `http_proxy` - `all_proxy` -프록시 환경 변수가 설정되어 있지 않으면 직접 송신이 사용됩니다. 프록시 구성이 잘못된 형식이면 OpenClaw는 경고를 로그에 남기고 직접 가져오기로 폴백합니다. +프록시 환경 변수가 설정되어 있지 않으면 직접 egress가 사용됩니다. 프록시 구성이 잘못된 형식이면 OpenClaw가 경고를 로그에 남기고 direct fetch로 fallback합니다. ## 그룹의 멘션 감지 -그룹 채팅에 `requireMention: true`가 설정되어 있으면, 이제 OpenClaw는 멘션을 확인하기 **전에** 오디오를 전사합니다. 이를 통해 음성 메모에 멘션이 포함되어 있어도 처리할 수 있습니다. +그룹 채팅에 `requireMention: true`가 설정된 경우, OpenClaw는 이제 멘션을 확인하기 **전에** 오디오를 전사합니다. 이를 통해 음성 메모에 멘션이 포함되어 있어도 처리할 수 있습니다. **작동 방식:** -1. 음성 메시지에 텍스트 본문이 없고 그룹에서 멘션을 요구하는 경우, OpenClaw는 "preflight" 전사를 수행합니다. +1. 음성 메시지에 텍스트 본문이 없고 그룹에서 멘션이 필요한 경우, OpenClaw는 "preflight" 전사를 수행합니다. 2. 전사문에서 멘션 패턴(예: `@BotName`, 이모지 트리거)을 확인합니다. -3. 멘션이 발견되면 메시지는 전체 답장 파이프라인을 진행합니다. +3. 멘션이 발견되면 메시지는 전체 응답 pipeline을 진행합니다. 4. 음성 메모가 멘션 게이트를 통과할 수 있도록 전사문이 멘션 감지에 사용됩니다. -**폴백 동작:** +**Fallback 동작:** -- preflight 중 전사가 실패하면(타임아웃, API 오류 등) 메시지는 텍스트 전용 멘션 감지를 기준으로 처리됩니다. -- 이를 통해 혼합 메시지(텍스트 + 오디오)가 잘못 삭제되지 않도록 보장합니다. +- preflight 중 전사가 실패하면(시간 초과, API 오류 등) 메시지는 텍스트 전용 멘션 감지를 기준으로 처리됩니다. +- 이렇게 하면 혼합 메시지(텍스트 + 오디오)가 잘못 삭제되지 않습니다. -**Telegram 그룹/주제별 옵트아웃:** +**Telegram 그룹/topic별 옵트아웃:** -- 해당 그룹에서 preflight 전사문 멘션 검사를 건너뛰려면 `channels.telegram.groups..disableAudioPreflight: true`를 설정하세요. -- 주제별로 재정의하려면 `channels.telegram.groups..topics..disableAudioPreflight`를 설정하세요(건너뛰려면 `true`, 강제로 활성화하려면 `false`). +- 해당 그룹의 preflight 전사문 멘션 확인을 건너뛰려면 `channels.telegram.groups..disableAudioPreflight: true`를 설정하세요. +- topic별로 재정의하려면 `channels.telegram.groups..topics..disableAudioPreflight`를 설정하세요(`true`는 건너뛰기, `false`는 강제 활성화). - 기본값은 `false`입니다(멘션 게이트 조건이 일치하면 preflight 활성화). -**예시:** 사용자가 `requireMention: true`가 설정된 Telegram 그룹에서 "Hey @Claude, what's the weather?"라고 말하는 음성 메모를 보냅니다. 음성 메모가 전사되고, 멘션이 감지되며, 에이전트가 답장합니다. +**예시:** 한 사용자가 `requireMention: true`가 설정된 Telegram 그룹에서 "Hey @Claude, what's the weather?"라고 말하는 음성 메모를 보냅니다. 음성 메모가 전사되고, 멘션이 감지되며, 에이전트가 응답합니다. ## 주의 사항 -- 범위 규칙은 처음 일치한 항목이 우선합니다. `chatType`은 `direct`, `group` 또는 `room`으로 정규화됩니다. +- 범위 규칙은 첫 번째 일치 항목이 우선합니다. `chatType`은 `direct`, `group`, `room`으로 정규화됩니다. - CLI가 0으로 종료되고 일반 텍스트를 출력하는지 확인하세요. JSON은 `jq -r .text`를 통해 가공해야 합니다. -- `parakeet-mlx`의 경우 `--output-dir`를 전달하면, `--output-format`이 `txt`이거나 생략되었을 때 OpenClaw는 `/.txt`를 읽습니다. `txt`가 아닌 출력 형식은 stdout 파싱으로 폴백합니다. -- 답장 큐가 차단되지 않도록 타임아웃을 합리적으로 유지하세요(`timeoutSeconds`, 기본값 60초). +- `parakeet-mlx`의 경우 `--output-dir`를 전달하면, `--output-format`이 `txt`이거나 생략되었을 때 OpenClaw는 `/.txt`를 읽습니다. `txt`가 아닌 출력 형식은 stdout 파싱으로 fallback합니다. +- 응답 큐가 차단되지 않도록 시간 초과(`timeoutSeconds`, 기본값 60초)를 합리적으로 유지하세요. - preflight 전사는 멘션 감지를 위해 **첫 번째** 오디오 첨부 파일만 처리합니다. 추가 오디오는 기본 미디어 이해 단계에서 처리됩니다. ## 관련 항목 - [미디어 이해](/ko/nodes/media-understanding) - [대화 모드](/ko/nodes/talk) -- [음성 깨우기](/ko/nodes/voicewake) +- [음성 wake](/ko/nodes/voicewake) diff --git a/docs/ko/nodes/images.md b/docs/ko/nodes/images.md index d59ef7522..87acbf673 100644 --- a/docs/ko/nodes/images.md +++ b/docs/ko/nodes/images.md @@ -1,41 +1,39 @@ --- read_when: - 미디어 파이프라인 또는 첨부 파일 수정 -summary: send, Gateway 및 에이전트 응답의 이미지 및 미디어 처리 규칙 +summary: 전송, Gateway 및 에이전트 응답을 위한 이미지 및 미디어 처리 규칙 title: 이미지 및 미디어 지원 x-i18n: - generated_at: "2026-05-06T06:31:48Z" + generated_at: "2026-05-06T17:58:39Z" model: gpt-5.5 provider: openai - source_hash: a38224fdf42f32fe206ad8cf3fcc3b06a078b1978d447adeb671fdb3ff4e4b32 + source_hash: 069140a3ad3bade166d4576ead604b4675006a01e546672872379ce83291471c source_path: nodes/images.md workflow: 16 --- -# 이미지 및 미디어 지원 (2025-12-05) - -WhatsApp 채널은 **Baileys Web**을 통해 실행됩니다. 이 문서는 보내기, Gateway, 에이전트 응답에 대한 현재 미디어 처리 규칙을 정리합니다. +WhatsApp 채널은 **Baileys Web**을 통해 실행됩니다. 이 문서는 전송, Gateway, 에이전트 응답에 대한 현재 미디어 처리 규칙을 설명합니다. ## 목표 -- `openclaw message send --media`를 통해 선택적 캡션과 함께 미디어를 보냅니다. -- 웹 받은 편지함의 자동 응답에 텍스트와 함께 미디어가 포함되도록 허용합니다. +- `openclaw message send --media`로 선택적 캡션과 함께 미디어를 전송합니다. +- 웹 받은편지함의 자동 응답이 텍스트와 함께 미디어를 포함할 수 있도록 합니다. - 유형별 제한을 합리적이고 예측 가능하게 유지합니다. ## CLI 인터페이스 - `openclaw message send --media [--message ]` - - `--media`는 선택 사항이며, 미디어만 보내는 경우 캡션은 비워 둘 수 있습니다. - - `--dry-run`은 해석된 페이로드를 출력하고, `--json`은 `{ channel, to, messageId, mediaUrl, caption }`을 내보냅니다. + - `--media`는 선택 사항이며, 미디어만 전송할 때 캡션은 비워둘 수 있습니다. + - `--dry-run`은 확인된 페이로드를 출력하고, `--json`은 `{ channel, to, messageId, mediaUrl, caption }`을 내보냅니다. ## WhatsApp Web 채널 동작 - 입력: 로컬 파일 경로 **또는** HTTP(S) URL. - 흐름: Buffer로 로드하고, 미디어 종류를 감지한 뒤, 올바른 페이로드를 빌드합니다. - **이미지:** `channels.whatsapp.mediaMaxMb`(기본값: 50 MB)를 목표로 JPEG로 크기 조정 및 재압축(최대 변 2048px). - - **오디오/음성/동영상:** 최대 16 MB까지 그대로 전달하며, 오디오는 음성 메모(`ptt: true`)로 전송됩니다. - - **문서:** 그 밖의 모든 항목은 최대 100 MB까지 허용하며, 사용 가능한 경우 파일 이름을 보존합니다. -- WhatsApp GIF 스타일 재생: 모바일 클라이언트가 인라인으로 반복 재생하도록 `gifPlayback: true`가 포함된 MP4를 보냅니다(CLI: `--gif-playback`). + - **오디오/음성/비디오:** 최대 16 MB까지 그대로 전달하며, 오디오는 음성 메모(`ptt: true`)로 전송됩니다. + - **문서:** 그 외 모든 항목은 최대 100 MB까지 지원하며, 가능한 경우 파일 이름을 보존합니다. +- WhatsApp GIF 스타일 재생: 모바일 클라이언트에서 인라인으로 반복 재생되도록 MP4를 `gifPlayback: true`(CLI: `--gif-playback`)와 함께 전송합니다. - MIME 감지는 매직 바이트, 헤더, 파일 확장자 순으로 우선합니다. - 캡션은 `--message` 또는 `reply.text`에서 가져오며, 빈 캡션도 허용됩니다. - 로깅: 비상세 모드는 `↩️`/`✅`를 표시하고, 상세 모드는 크기와 소스 경로/URL을 포함합니다. @@ -43,40 +41,40 @@ WhatsApp 채널은 **Baileys Web**을 통해 실행됩니다. 이 문서는 보 ## 자동 응답 파이프라인 - `getReplyFromConfig`는 `{ text?, mediaUrl?, mediaUrls? }`를 반환합니다. -- 미디어가 있는 경우, 웹 전송기는 `openclaw message send`와 동일한 파이프라인을 사용해 로컬 경로 또는 URL을 해석합니다. +- 미디어가 있으면 웹 전송기는 `openclaw message send`와 동일한 파이프라인을 사용해 로컬 경로 또는 URL을 확인합니다. - 여러 미디어 항목이 제공되면 순차적으로 전송됩니다. -## 명령으로 전달되는 인바운드 미디어(Pi) +## 명령으로 전달되는 인바운드 미디어 (Pi) -- 인바운드 웹 메시지에 미디어가 포함된 경우, OpenClaw는 임시 파일로 다운로드하고 템플릿 변수를 노출합니다. - - 인바운드 미디어용 의사 URL인 `{{MediaUrl}}`. - - 명령을 실행하기 전에 작성되는 로컬 임시 경로인 `{{MediaPath}}`. -- 세션별 Docker 샌드박스가 활성화된 경우, 인바운드 미디어는 샌드박스 작업 공간으로 복사되고 `MediaPath`/`MediaUrl`은 `media/inbound/` 같은 상대 경로로 다시 작성됩니다. -- 미디어 이해(`tools.media.*` 또는 공유 `tools.media.models`를 통해 구성된 경우)는 템플릿 처리 전에 실행되며, `Body`에 `[Image]`, `[Audio]`, `[Video]` 블록을 삽입할 수 있습니다. - - 오디오는 `{{Transcript}}`를 설정하고 명령 파싱에 전사를 사용하므로 슬래시 명령이 계속 작동합니다. - - 동영상 및 이미지 설명은 명령 파싱을 위해 모든 캡션 텍스트를 보존합니다. - - 활성 기본 이미지 모델이 이미 비전을 기본 지원하는 경우, OpenClaw는 `[Image]` 요약 블록을 건너뛰고 원본 이미지를 대신 모델에 전달합니다. -- 기본적으로 일치하는 첫 번째 이미지/오디오/동영상 첨부 파일만 처리됩니다. 여러 첨부 파일을 처리하려면 `tools.media..attachments`를 설정하세요. +- 인바운드 웹 메시지에 미디어가 포함된 경우 OpenClaw는 임시 파일로 다운로드하고 템플릿 변수를 노출합니다. + - 인바운드 미디어용 `{{MediaUrl}}` 의사 URL. + - 명령 실행 전에 작성되는 `{{MediaPath}}` 로컬 임시 경로. +- 세션별 Docker 샌드박스가 활성화된 경우 인바운드 미디어는 샌드박스 워크스페이스로 복사되고, `MediaPath`/`MediaUrl`은 `media/inbound/` 같은 상대 경로로 다시 작성됩니다. +- 미디어 이해가 `tools.media.*` 또는 공유 `tools.media.models`를 통해 구성된 경우 템플릿 처리 전에 실행되며, `[Image]`, `[Audio]`, `[Video]` 블록을 `Body`에 삽입할 수 있습니다. + - 오디오는 `{{Transcript}}`를 설정하고 명령 파싱에 전사문을 사용하므로 슬래시 명령도 계속 작동합니다. + - 비디오 및 이미지 설명은 명령 파싱을 위해 모든 캡션 텍스트를 보존합니다. + - 활성 기본 이미지 모델이 이미 기본적으로 비전을 지원하는 경우 OpenClaw는 `[Image]` 요약 블록을 건너뛰고 대신 원본 이미지를 모델에 전달합니다. +- 기본적으로 일치하는 첫 번째 이미지/오디오/비디오 첨부 파일만 처리됩니다. 여러 첨부 파일을 처리하려면 `tools.media..attachments`를 설정하세요. ## 제한 및 오류 -**아웃바운드 전송 한도(WhatsApp 웹 전송)** +**아웃바운드 전송 한도(WhatsApp web 전송)** - 이미지: 재압축 후 최대 `channels.whatsapp.mediaMaxMb`(기본값: 50 MB). -- 오디오/음성/동영상: 16 MB 한도, 문서: 100 MB 한도. -- 너무 크거나 읽을 수 없는 미디어 → 로그에 명확한 오류를 남기고 응답은 건너뜁니다. +- 오디오/음성/비디오: 16 MB 한도, 문서: 100 MB 한도. +- 너무 크거나 읽을 수 없는 미디어 → 로그에 명확한 오류가 기록되고 응답은 건너뜁니다. **미디어 이해 한도(전사/설명)** - 이미지 기본값: 10 MB(`tools.media.image.maxBytes`). - 오디오 기본값: 20 MB(`tools.media.audio.maxBytes`). -- 동영상 기본값: 50 MB(`tools.media.video.maxBytes`). -- 너무 큰 미디어는 이해를 건너뛰지만, 응답은 원래 본문으로 계속 진행됩니다. +- 비디오 기본값: 50 MB(`tools.media.video.maxBytes`). +- 너무 큰 미디어는 이해 단계를 건너뛰지만, 응답은 원본 본문으로 계속 진행됩니다. ## 테스트 참고 사항 - 이미지/오디오/문서 사례에 대한 전송 및 응답 흐름을 다룹니다. -- 이미지의 재압축(크기 제한)과 오디오의 음성 메모 플래그를 검증합니다. +- 이미지 재압축(크기 제한)과 오디오의 음성 메모 플래그를 검증합니다. - 여러 미디어 응답이 순차 전송으로 확장되는지 확인합니다. ## 관련 항목 diff --git a/docs/ko/plugins/agent-tools.md b/docs/ko/plugins/agent-tools.md index 112249d79..53fa47227 100644 --- a/docs/ko/plugins/agent-tools.md +++ b/docs/ko/plugins/agent-tools.md @@ -1,22 +1,20 @@ --- read_when: - - agent-tools의 레거시 링크 -summary: Plugins 빌드하기(도구 등록 섹션)로 리디렉션 + - agent-tools에 대한 레거시 링크 +summary: Plugin 빌드(도구 등록 섹션)로 리디렉션 title: 도구 등록하기 x-i18n: - generated_at: "2026-04-24T06:25:16Z" - model: gpt-5.4 + generated_at: "2026-05-06T17:58:44Z" + model: gpt-5.5 provider: openai - source_hash: c84450ddc31f8f6a605bd553a1a9d7d295f5b575504a134b5c50a2c7d77e3e63 + source_hash: e73137487a9394454dd037d449bc2a0896725cddc7d0f174eda41f5fdc451982 source_path: plugins/agent-tools.md - workflow: 15 + workflow: 16 --- -# Plugin에서 도구 등록하기 - -이 페이지는 이동되었습니다. [Plugins 빌드하기: 에이전트 도구 등록하기](/ko/plugins/building-plugins#registering-agent-tools)를 참조하세요. +이 페이지는 이동되었습니다. [Plugin 빌드하기: 에이전트 도구 등록](/ko/plugins/building-plugins#registering-agent-tools)을 참조하세요. ## 관련 -- [Plugins 빌드하기](/ko/plugins/building-plugins) +- [Plugin 빌드하기](/ko/plugins/building-plugins) - [Plugin SDK 설정](/ko/plugins/sdk-setup) diff --git a/docs/ko/plugins/dependency-resolution.md b/docs/ko/plugins/dependency-resolution.md index e37af7e39..17bcb6156 100644 --- a/docs/ko/plugins/dependency-resolution.md +++ b/docs/ko/plugins/dependency-resolution.md @@ -1,51 +1,46 @@ --- read_when: - Plugin 패키지 설치를 디버깅하는 중입니다 - - Plugin 시작, 진단 또는 패키지 관리자 설치 동작을 변경하는 경우 - - 패키지된 OpenClaw 설치본 또는 번들된 Plugin 매니페스트를 유지 관리하고 있습니다 + - Plugin 시작, doctor 또는 패키지 관리자 설치 동작을 변경하는 경우 + - 패키지된 OpenClaw 설치본 또는 번들된 Plugin 매니페스트를 유지 관리하는 경우 sidebarTitle: Dependencies -summary: OpenClaw가 Plugin 패키지를 설치하고 Plugin 종속성을 해결하는 방식 +summary: OpenClaw가 Plugin 패키지를 설치하고 Plugin 의존성을 해결하는 방식 title: Plugin 의존성 해결 x-i18n: - generated_at: "2026-05-06T09:03:51Z" + generated_at: "2026-05-06T17:58:57Z" model: gpt-5.5 provider: openai - source_hash: e06f1fdc34c8392cbf0e399484fd59af11b9b7d73c5c7e68b3617a7cfd433a36 + source_hash: 15cdc75d92a675fd5474c49572639ab7510618e393fb7cf9f8b94506c859bee8 source_path: plugins/dependency-resolution.md workflow: 16 --- -# Plugin 종속성 해결 - -OpenClaw는 Plugin 종속성 작업을 설치/업데이트 시점에 유지합니다. 런타임 로딩은 -패키지 관리자를 실행하거나, 종속성 트리를 복구하거나, OpenClaw 패키지 -디렉터리를 변경하지 않습니다. +OpenClaw는 Plugin 의존성 작업을 설치/업데이트 시점에 유지합니다. 런타임 로딩은 패키지 관리자를 실행하거나, 의존성 트리를 복구하거나, OpenClaw 패키지 디렉터리를 변경하지 않습니다. ## 책임 분리 -Plugin 패키지는 자체 종속성 그래프를 소유합니다. +Plugin 패키지는 자체 의존성 그래프를 소유합니다. -- 런타임 종속성은 Plugin 패키지 `dependencies` 또는 - `optionalDependencies`에 있습니다 -- SDK/코어 가져오기는 피어 또는 OpenClaw가 제공하는 가져오기입니다 -- 로컬 개발 Plugin은 이미 설치된 자체 종속성을 가져옵니다 -- npm 및 git Plugin은 OpenClaw 소유 패키지 루트에 설치됩니다 +- 런타임 의존성은 Plugin 패키지의 `dependencies` 또는 `optionalDependencies`에 있습니다. +- SDK/코어 가져오기는 peer 또는 OpenClaw가 제공하는 가져오기입니다. +- 로컬 개발 Plugin은 이미 설치된 자체 의존성을 가져옵니다. +- npm 및 git Plugin은 OpenClaw가 소유한 패키지 루트에 설치됩니다. OpenClaw는 Plugin 수명 주기만 소유합니다. - Plugin 소스 발견 - 명시적으로 요청된 경우 패키지 설치 또는 업데이트 - 설치 메타데이터 기록 -- Plugin 엔트리포인트 로드 -- 종속성이 누락된 경우 실행 가능한 오류로 실패 +- Plugin 진입점 로드 +- 의존성이 누락된 경우 실행 가능한 오류로 실패 ## 설치 루트 -OpenClaw는 소스별 안정적인 루트를 사용합니다. +OpenClaw는 소스별로 안정적인 루트를 사용합니다. -- npm 패키지는 `~/.openclaw/npm` 아래에 설치됩니다 -- git 패키지는 `~/.openclaw/git` 아래에 클론됩니다 -- 로컬/경로/아카이브 설치는 종속성 복구 없이 복사되거나 참조됩니다 +- npm 패키지는 `~/.openclaw/npm` 아래에 설치됩니다. +- git 패키지는 `~/.openclaw/git` 아래에 클론됩니다. +- local/path/archive 설치는 의존성 복구 없이 복사되거나 참조됩니다. npm 설치는 npm 루트에서 다음과 같이 실행됩니다. @@ -53,52 +48,31 @@ npm 설치는 npm 루트에서 다음과 같이 실행됩니다. npm install --prefix ~/.openclaw/npm --omit=dev --ignore-scripts --no-audit --no-fund ``` -`openclaw plugins install npm-pack:`는 로컬 npm-pack 타볼에 대해 -동일한 관리형 npm 루트를 사용합니다. OpenClaw는 타볼의 npm 메타데이터를 -읽고, 복사된 `file:` 종속성으로 관리형 루트에 추가한 뒤, 일반 npm 설치를 -실행하고, Plugin을 신뢰하기 전에 설치된 lockfile 메타데이터를 검증합니다. -이는 로컬 pack 산출물이 시뮬레이션하는 레지스트리 산출물처럼 동작해야 하는 -패키지 수락 및 릴리스 후보 증명 용도입니다. +`openclaw plugins install npm-pack:`는 로컬 npm-pack tarball에 동일한 관리형 npm 루트를 사용합니다. OpenClaw는 tarball의 npm 메타데이터를 읽고, 이를 복사된 `file:` 의존성으로 관리형 루트에 추가한 뒤, 일반 npm install을 실행하고, Plugin을 신뢰하기 전에 설치된 lockfile 메타데이터를 확인합니다. 이는 로컬 pack 아티팩트가 시뮬레이션하는 레지스트리 아티팩트처럼 동작해야 하는 패키지 승인 및 릴리스 후보 증명용입니다. -npm은 전이 종속성을 Plugin 패키지 옆의 `~/.openclaw/npm/node_modules`로 -호이스트할 수 있습니다. OpenClaw는 설치를 신뢰하기 전에 관리형 npm 루트를 -스캔하고, 제거 중에는 npm을 사용해 npm 관리 패키지를 제거하므로, 호이스트된 -런타임 종속성은 관리형 정리 경계 안에 유지됩니다. +npm은 전이 의존성을 Plugin 패키지 옆의 `~/.openclaw/npm/node_modules`로 호이스트할 수 있습니다. OpenClaw는 설치를 신뢰하기 전에 관리형 npm 루트를 스캔하고, uninstall 중에는 npm을 사용해 npm 관리 패키지를 제거하므로 호이스트된 런타임 의존성은 관리형 정리 경계 안에 남습니다. -`openclaw/plugin-sdk/*`를 가져오는 Plugin은 `openclaw`를 피어 종속성으로 -선언합니다. OpenClaw는 npm이 호스트 패키지의 별도 레지스트리 사본을 관리형 -루트에 설치하도록 허용하지 않습니다. 오래된 호스트 패키지가 나중의 Plugin -설치 중 npm 피어 해결에 영향을 줄 수 있기 때문입니다. 대신 npm이 설치, -업데이트 또는 제거 중 공유 루트를 변경한 뒤, OpenClaw는 호스트 피어를 선언한 -설치된 패키지에 대해 Plugin 로컬 `node_modules/openclaw` 링크를 다시 -보장합니다. +`openclaw/plugin-sdk/*`를 가져오는 Plugin은 `openclaw`를 peer dependency로 선언합니다. OpenClaw는 npm이 호스트 패키지의 별도 레지스트리 복사본을 관리형 루트에 설치하도록 두지 않습니다. 오래된 호스트 패키지가 이후 Plugin 설치 중 npm peer resolution에 영향을 줄 수 있기 때문입니다. 대신 npm이 install, update, uninstall 중 공유 루트를 변경한 뒤, OpenClaw는 host peer를 선언하는 설치된 패키지에 대해 Plugin 로컬 `node_modules/openclaw` 링크를 다시 보장합니다. -git 설치는 저장소를 클론하거나 새로 고친 뒤 다음을 실행합니다. +git 설치는 저장소를 클론하거나 새로 고친 다음 다음을 실행합니다. ```bash npm install --omit=dev --ignore-scripts --no-audit --no-fund ``` -그런 다음 설치된 Plugin은 해당 패키지 디렉터리에서 로드되므로, 패키지 로컬 -및 상위 `node_modules` 해결은 일반 Node 패키지와 같은 방식으로 동작합니다. +설치된 Plugin은 그 패키지 디렉터리에서 로드되므로, 패키지 로컬 및 상위 `node_modules` 해석은 일반 Node 패키지에서와 같은 방식으로 동작합니다. ## 로컬 Plugin -로컬 Plugin은 개발자가 제어하는 디렉터리로 취급됩니다. OpenClaw는 이를 위해 -`npm install`, `pnpm install` 또는 종속성 복구를 실행하지 않습니다. 로컬 -Plugin에 종속성이 있으면 로드하기 전에 해당 Plugin 안에 설치하세요. +로컬 Plugin은 개발자가 제어하는 디렉터리로 취급됩니다. OpenClaw는 이들에 대해 `npm install`, `pnpm install` 또는 의존성 복구를 실행하지 않습니다. 로컬 Plugin에 의존성이 있는 경우, 로드하기 전에 해당 Plugin 안에 설치하세요. -타사 TypeScript 로컬 Plugin은 긴급 Jiti 경로를 사용할 수 있습니다. 패키징된 -JavaScript Plugin 및 번들 내부 Plugin은 Jiti 대신 네이티브 import/require를 -통해 로드됩니다. +서드파티 TypeScript 로컬 Plugin은 비상 Jiti 경로를 사용할 수 있습니다. 패키징된 JavaScript Plugin과 번들된 내부 Plugin은 Jiti 대신 네이티브 import/require를 통해 로드됩니다. ## 시작 및 다시 로드 -Gateway 시작 및 설정 다시 로드는 Plugin 종속성을 설치하지 않습니다. 이들은 -Plugin 설치 기록을 읽고, 엔트리포인트를 계산한 뒤, 로드합니다. +Gateway 시작 및 config 다시 로드는 Plugin 의존성을 설치하지 않습니다. Plugin 설치 레코드를 읽고, 진입점을 계산한 뒤, 이를 로드합니다. -런타임에 종속성이 누락된 경우 Plugin 로드가 실패하며, 오류는 운영자에게 -명시적인 수정 방법을 안내해야 합니다. +런타임에 의존성이 누락된 경우, Plugin 로드는 실패하고 오류는 운영자에게 명시적인 수정 방법을 안내해야 합니다. ```bash openclaw plugins update @@ -106,44 +80,26 @@ openclaw plugins install openclaw doctor --fix ``` -`doctor --fix`는 레거시 OpenClaw 생성 종속성 상태를 정리하고, 설정에서 -참조하지만 로컬 설치 기록에 없는 다운로드 가능한 Plugin을 복구할 수 있습니다. -Doctor는 이미 설치된 로컬 Plugin의 종속성을 복구하지 않습니다. +`doctor --fix`는 레거시 OpenClaw 생성 의존성 상태를 정리하고, config에서 참조하지만 로컬 설치 레코드에 없는 다운로드 가능한 Plugin을 복구할 수 있습니다. Doctor는 이미 설치된 로컬 Plugin의 의존성을 복구하지 않습니다. ## 번들 Plugin -가볍고 코어에 중요한 번들 Plugin은 OpenClaw의 일부로 제공됩니다. 이들은 -무거운 런타임 종속성 트리가 없어야 하며, 그렇지 않으면 ClawHub/npm의 -다운로드 가능한 패키지로 옮겨야 합니다. +가볍고 코어에 중요한 번들 Plugin은 OpenClaw의 일부로 제공됩니다. 이들은 무거운 런타임 의존성 트리가 없거나 ClawHub/npm의 다운로드 가능한 패키지로 옮겨져야 합니다. -코어 패키지에 함께 제공되거나, 외부에서 설치되거나, 소스 전용으로 유지되는 -Plugin의 현재 생성 목록은 [Plugin 인벤터리](/ko/plugins/plugin-inventory)를 참조하세요. +코어 패키지에 포함되거나, 외부에서 설치되거나, 소스 전용으로 유지되는 Plugin의 현재 생성된 목록은 [Plugin 인벤터리](/ko/plugins/plugin-inventory)를 참조하세요. -번들 Plugin 매니페스트는 종속성 스테이징을 요청해서는 안 됩니다. 크거나 -선택적인 Plugin 기능은 일반 Plugin으로 패키징하고, 타사 Plugin과 동일한 -npm/git/ClawHub 경로를 통해 설치해야 합니다. +번들 Plugin 매니페스트는 의존성 staging을 요청해서는 안 됩니다. 크거나 선택적인 Plugin 기능은 일반 Plugin으로 패키징하고 서드파티 Plugin과 동일한 npm/git/ClawHub 경로를 통해 설치해야 합니다. -소스 체크아웃에서 OpenClaw는 저장소를 pnpm 모노레포로 취급합니다. -`pnpm install` 후 번들 Plugin은 `extensions/`에서 로드되므로 패키지 -로컬 워크스페이스 종속성을 사용할 수 있고 편집 내용이 직접 반영됩니다. 소스 -체크아웃 개발은 pnpm 전용입니다. 저장소 루트에서 일반 `npm install`을 -실행하는 것은 번들 Plugin 종속성을 준비하는 지원되는 방법이 아닙니다. +소스 checkout에서 OpenClaw는 저장소를 pnpm monorepo로 취급합니다. `pnpm install` 후에는 번들 Plugin이 `extensions/`에서 로드되므로 패키지 로컬 workspace 의존성을 사용할 수 있고, 편집 내용이 직접 반영됩니다. 소스 checkout 개발은 pnpm 전용입니다. 저장소 루트에서 일반 `npm install`을 실행하는 것은 번들 Plugin 의존성을 준비하는 지원 방식이 아닙니다. -| 설치 형태 | 번들 Plugin 위치 | 종속성 소유자 | +| 설치 형태 | 번들 Plugin 위치 | 의존성 소유자 | | -------------------------------- | ------------------------------------- | -------------------------------------------------------------------- | -| `npm install -g openclaw` | 패키지 내부의 빌드된 런타임 트리 | OpenClaw 패키지 및 명시적 Plugin 설치/업데이트/doctor 흐름 | -| Git 체크아웃 및 `pnpm install` | `extensions/` 워크스페이스 패키지 | 각 Plugin 패키지의 자체 종속성을 포함한 pnpm 워크스페이스 | -| `openclaw plugins install ...` | 관리형 npm/git/ClawHub Plugin 루트 | Plugin 설치/업데이트 흐름 | +| `npm install -g openclaw` | 패키지 내부의 빌드된 런타임 트리 | OpenClaw 패키지 및 명시적 Plugin install/update/doctor 흐름 | +| Git checkout plus `pnpm install` | `extensions/` workspace 패키지 | 각 Plugin 패키지의 자체 의존성을 포함한 pnpm workspace | +| `openclaw plugins install ...` | 관리형 npm/git/ClawHub Plugin 루트 | Plugin install/update 흐름 | ## 레거시 정리 -이전 OpenClaw 버전은 시작 시 또는 doctor 복구 중 번들 Plugin 종속성 루트를 -생성했습니다. 현재 doctor 정리는 `--fix`가 사용될 때 오래된 `plugin-runtime-deps` -루트, 정리된 `plugin-runtime-deps` 대상리를 가리키는 전역 Node-prefix 패키지 -심볼릭 링크, `.openclaw-runtime-deps*` 매니페스트, 생성된 Plugin -`node_modules`, 설치 스테이지 디렉터리, 패키지 로컬 pnpm 스토어를 포함한 -오래된 디렉터리와 심볼릭 링크를 제거합니다. 패키징된 postinstall도 레거시 -대상 루트를 정리하기 전에 이러한 전역 심볼릭 링크를 제거하여 업그레이드 후 -끊어진 ESM 패키지 가져오기가 남지 않게 합니다. +이전 OpenClaw 버전은 시작 시 또는 doctor repair 중 번들 Plugin 의존성 루트를 생성했습니다. 현재 doctor cleanup은 `--fix`를 사용할 때 이러한 오래된 디렉터리와 symlink를 제거합니다. 여기에는 오래된 `plugin-runtime-deps` 루트, 정리된 `plugin-runtime-deps` 대상의 global Node-prefix 패키지 symlink, `.openclaw-runtime-deps*` 매니페스트, 생성된 Plugin `node_modules`, install stage 디렉터리, 패키지 로컬 pnpm store가 포함됩니다. 패키징된 postinstall도 레거시 대상 루트를 정리하기 전에 이러한 global symlink를 제거하므로 업그레이드 후 끊어진 ESM 패키지 import가 남지 않습니다. -이 경로들은 레거시 잔여물일 뿐입니다. 새 설치에서는 이를 생성하지 않아야 합니다. +이 경로들은 레거시 잔여물일 뿐입니다. 새 설치가 이들을 생성해서는 안 됩니다. diff --git a/docs/ko/plugins/google-meet.md b/docs/ko/plugins/google-meet.md index 9e15c4f83..ac2345ad0 100644 --- a/docs/ko/plugins/google-meet.md +++ b/docs/ko/plugins/google-meet.md @@ -1,36 +1,36 @@ --- read_when: - - OpenClaw 에이전트가 Google Meet 통화에 참여하게 하려는 경우 + - OpenClaw 에이전트가 Google Meet 통화에 참여하도록 하려는 경우 - OpenClaw 에이전트가 새 Google Meet 통화를 만들도록 하려는 경우 - Chrome, Chrome 노드 또는 Twilio를 Google Meet 전송 수단으로 구성하고 있습니다 -summary: 'Google Meet Plugin: Chrome 또는 Twilio를 통해 명시적인 Meet URL에 참여하고 에이전트 응답 기본값 사용' +summary: 'Google Meet Plugin: Chrome 또는 Twilio를 통해 명시적인 Meet URL에 참여하고 에이전트 응답 기본값을 사용' title: Google Meet Plugin x-i18n: - generated_at: "2026-05-06T09:03:46Z" + generated_at: "2026-05-06T17:59:18Z" model: gpt-5.5 provider: openai - source_hash: 9c1de7528ddabe6411598eea362d4a21c6f95f374700046c18294b215a1333d3 + source_hash: 4b154e9cbce560dbc8327a140b27c17d2614d13d7011032a48b110314772ab0c source_path: plugins/google-meet.md workflow: 16 --- -OpenClaw용 Google Meet 참가자 지원은 설계상 Plugin이 명시적으로 동작합니다. +OpenClaw의 Google Meet 참가자 지원은 의도적으로 명시적인 Plugin입니다. - 명시적인 `https://meet.google.com/...` URL에만 참여합니다. -- Google Meet API를 통해 새 Meet 공간을 만든 다음 반환된 URL에 참여할 수 있습니다. -- `agent`는 기본 응답 음성 모드입니다. 실시간 전사가 수신하고, 구성된 OpenClaw agent가 답변하며, 일반 OpenClaw TTS가 Meet에서 말합니다. -- `bidi`는 직접 실시간 음성 모델 모드의 폴백으로 계속 사용할 수 있습니다. -- Agent는 `mode`로 참여 동작을 선택합니다. 실시간 듣기/응답에는 `agent`, 직접 실시간 음성 폴백에는 `bidi`, 응답 음성 브리지 없이 브라우저에 참여/제어하려면 `transcribe`를 사용합니다. +- Google Meet API를 통해 새 Meet 공간을 만든 다음, 반환된 URL에 참여할 수 있습니다. +- `agent`는 기본 응답 모드입니다. 실시간 전사가 듣고, 구성된 OpenClaw 에이전트가 답변하며, 일반 OpenClaw TTS가 Meet에서 말합니다. +- `bidi`는 대체 직접 실시간 음성 모델 모드로 계속 사용할 수 있습니다. +- 에이전트는 `mode`로 참여 동작을 선택합니다. 실시간 듣기/응답에는 `agent`, 직접 실시간 음성 대체에는 `bidi`, 응답 브리지 없이 브라우저에 참여/제어하려면 `transcribe`를 사용합니다. - 인증은 개인 Google OAuth 또는 이미 로그인된 Chrome 프로필로 시작합니다. - 자동 동의 안내는 없습니다. - 기본 Chrome 오디오 백엔드는 `BlackHole 2ch`입니다. -- Chrome은 로컬에서 실행하거나 페어링된 Node 호스트에서 실행할 수 있습니다. -- Twilio는 전화 접속 번호와 선택적 PIN 또는 DTMF 시퀀스를 받지만, Meet URL로 직접 전화를 걸 수는 없습니다. -- CLI 명령은 `googlemeet`입니다. `meet`는 더 넓은 agent 원격 회의 워크플로용으로 예약되어 있습니다. +- Chrome은 로컬 또는 페어링된 Node 호스트에서 실행할 수 있습니다. +- Twilio는 다이얼인 번호와 선택적 PIN 또는 DTMF 시퀀스를 허용합니다. Meet URL로 직접 전화를 걸 수는 없습니다. +- CLI 명령은 `googlemeet`입니다. `meet`는 더 넓은 에이전트 원격 회의 워크플로를 위해 예약되어 있습니다. ## 빠른 시작 -로컬 오디오 종속성을 설치하고 실시간 전사 제공자와 일반 OpenClaw TTS를 구성합니다. OpenAI가 기본 전사 제공자입니다. Google Gemini Live도 `realtime.voiceProvider: "google"`과 함께 별도의 `bidi` 음성 폴백으로 동작합니다. +로컬 오디오 의존성을 설치하고 실시간 전사 제공자와 일반 OpenClaw TTS를 구성합니다. OpenAI가 기본 전사 제공자입니다. Google Gemini Live도 `realtime.voiceProvider: "google"`을 사용하는 별도의 `bidi` 음성 대체로 작동합니다. ```bash brew install blackhole-2ch sox @@ -45,7 +45,7 @@ export GEMINI_API_KEY=... sudo reboot ``` -재부팅 후 두 항목을 모두 확인합니다. +재부팅 후 두 구성 요소를 모두 확인합니다. ```bash system_profiler SPAudioDataType | grep -i BlackHole @@ -73,21 +73,21 @@ Plugin을 활성화합니다. openclaw googlemeet setup ``` -설정 출력은 agent가 읽을 수 있고 모드를 인식하도록 설계되었습니다. Chrome 프로필, Node 고정, 그리고 실시간 Chrome 참여의 경우 BlackHole/SoX 오디오 브리지와 지연된 실시간 인트로 확인을 보고합니다. 관찰 전용 참여의 경우 `--mode transcribe`로 동일한 전송을 확인합니다. 이 모드는 브리지를 통해 듣거나 말하지 않으므로 실시간 오디오 전제 조건을 건너뜁니다. +설정 출력은 에이전트가 읽을 수 있고 모드를 인식하도록 되어 있습니다. Chrome 프로필, Node 고정, 그리고 실시간 Chrome 참여의 경우 BlackHole/SoX 오디오 브리지와 지연된 실시간 소개 확인을 보고합니다. 관찰 전용 참여의 경우 `--mode transcribe`로 동일한 전송을 확인합니다. 이 모드는 브리지를 통해 듣거나 말하지 않으므로 실시간 오디오 필수 조건을 건너뜁니다. ```bash openclaw googlemeet setup --transport chrome-node --mode transcribe ``` -Twilio 위임이 구성된 경우, 설정은 `voice-call` Plugin, Twilio 자격 증명, 공개 Webhook 노출 준비 여부도 보고합니다. Agent에게 참여를 요청하기 전에 확인된 전송과 모드에 대해 `ok: false` 확인은 모두 차단 요인으로 처리합니다. 스크립트나 기계가 읽을 수 있는 출력에는 `openclaw googlemeet setup --json`을 사용합니다. Agent가 시도하기 전에 특정 전송을 사전 점검하려면 `--transport chrome`, `--transport chrome-node`, 또는 `--transport twilio`를 사용합니다. +Twilio 위임이 구성된 경우 설정은 `voice-call` Plugin, Twilio 자격 증명, 공개 Webhook 노출이 준비되었는지도 보고합니다. 에이전트에게 참여를 요청하기 전에 모든 `ok: false` 확인을 해당 전송 및 모드의 차단 요소로 취급합니다. 스크립트 또는 기계가 읽을 수 있는 출력에는 `openclaw googlemeet setup --json`을 사용합니다. 에이전트가 시도하기 전에 특정 전송을 사전 점검하려면 `--transport chrome`, `--transport chrome-node`, 또는 `--transport twilio`를 사용합니다. -Twilio의 경우 기본 전송이 Chrome이면 항상 전송을 명시적으로 사전 점검합니다. +Twilio의 경우 기본 전송이 Chrome일 때 항상 전송을 명시적으로 사전 점검합니다. ```bash openclaw googlemeet setup --transport twilio ``` -이렇게 하면 agent가 회의에 전화를 걸기 전에 누락된 `voice-call` 연결, Twilio 자격 증명, 또는 접근할 수 없는 Webhook 노출을 잡아낼 수 있습니다. +이렇게 하면 에이전트가 회의에 전화를 걸기 전에 누락된 `voice-call` 연결, Twilio 자격 증명, 또는 도달할 수 없는 Webhook 노출을 잡아냅니다. 회의에 참여합니다. @@ -95,7 +95,7 @@ openclaw googlemeet setup --transport twilio openclaw googlemeet join https://meet.google.com/abc-defg-hij ``` -또는 agent가 `google_meet` 도구를 통해 참여하도록 합니다. +또는 에이전트가 `google_meet` 도구를 통해 참여하게 합니다. ```json { @@ -106,7 +106,7 @@ openclaw googlemeet join https://meet.google.com/abc-defg-hij } ``` -Agent용 `google_meet` 도구는 macOS가 아닌 호스트에서도 아티팩트, 캘린더, 설정, 전사, Twilio, `chrome-node` 흐름에 계속 사용할 수 있습니다. 로컬 Chrome 응답 음성 작업은 현재 번들 Chrome 오디오 경로가 macOS `BlackHole 2ch`에 의존하므로 해당 호스트에서 차단됩니다. Linux에서는 Chrome 응답 음성 참여에 `mode: "transcribe"`, Twilio 전화 접속, 또는 macOS `chrome-node` 호스트를 사용합니다. +에이전트용 `google_meet` 도구는 macOS가 아닌 호스트에서도 아티팩트, 캘린더, 설정, 전사, Twilio, `chrome-node` 흐름에 계속 사용할 수 있습니다. 번들 Chrome 오디오 경로가 현재 macOS `BlackHole 2ch`에 의존하므로 로컬 Chrome 응답 작업은 그곳에서 차단됩니다. Linux에서는 Chrome 응답 참여에 `mode: "transcribe"`, Twilio 다이얼인, 또는 macOS `chrome-node` 호스트를 사용합니다. 새 회의를 만들고 참여합니다. @@ -114,15 +114,15 @@ Agent용 `google_meet` 도구는 macOS가 아닌 호스트에서도 아티팩트 openclaw googlemeet create --transport chrome-node --mode agent ``` -API로 만든 방에서 Google 계정 기본값에서 상속하는 대신 방의 노크 없음 정책을 명시하고 싶다면 Google Meet `SpaceConfig.accessType`을 사용합니다. +API로 생성한 회의실의 경우 회의실의 노크 없는 입장 정책을 Google 계정 기본값에서 상속하지 않고 명시하려면 Google Meet `SpaceConfig.accessType`을 사용합니다. ```bash openclaw googlemeet create --access-type OPEN --transport chrome-node --mode agent ``` -`OPEN`은 Meet URL이 있는 누구나 노크 없이 참여할 수 있게 합니다. `TRUSTED`는 호스트 조직의 신뢰할 수 있는 사용자, 초대된 외부 사용자, 전화 접속 사용자가 노크 없이 참여할 수 있게 합니다. `RESTRICTED`는 노크 없는 입장을 초대받은 사람으로 제한합니다. 이 설정은 공식 Google Meet API 생성 경로에만 적용되므로 OAuth 자격 증명을 구성해야 합니다. +`OPEN`은 Meet URL을 가진 누구나 노크 없이 참여할 수 있게 합니다. `TRUSTED`는 호스트 조직의 신뢰된 사용자, 초대된 외부 사용자, 다이얼인 사용자가 노크 없이 참여할 수 있게 합니다. `RESTRICTED`는 노크 없는 입장을 초대받은 사람으로 제한합니다. 이 설정은 공식 Google Meet API 생성 경로에만 적용되므로 OAuth 자격 증명이 구성되어 있어야 합니다. -이 옵션이 제공되기 전에 Google Meet을 인증했다면 Google OAuth 동의 화면에 `meetings.space.settings` 범위를 추가한 뒤 `openclaw googlemeet auth login --json`을 다시 실행합니다. +이 옵션이 제공되기 전에 Google Meet을 인증했다면 Google OAuth 동의 화면에 `meetings.space.settings` 범위를 추가한 후 `openclaw googlemeet auth login --json`을 다시 실행합니다. 참여하지 않고 URL만 만듭니다. @@ -130,15 +130,16 @@ openclaw googlemeet create --access-type OPEN --transport chrome-node --mode age openclaw googlemeet create --no-join ``` -`googlemeet create`에는 두 가지 경로가 있습니다. +`googlemeet create`에는 두 경로가 있습니다. - API 생성: Google Meet OAuth 자격 증명이 구성된 경우 사용됩니다. 가장 결정적인 경로이며 브라우저 UI 상태에 의존하지 않습니다. -- 브라우저 폴백: OAuth 자격 증명이 없을 때 사용됩니다. OpenClaw는 고정된 Chrome Node를 사용하고, `https://meet.google.com/new`를 열고, Google이 실제 회의 코드 URL로 리디렉션할 때까지 기다린 다음 해당 URL을 반환합니다. 이 경로에서는 Node의 OpenClaw Chrome 프로필이 이미 Google에 로그인되어 있어야 합니다. 브라우저 자동화는 Meet 자체의 최초 실행 마이크 프롬프트를 처리합니다. 해당 프롬프트는 Google 로그인 실패로 처리되지 않습니다. - 참여 및 생성 흐름은 새 탭을 열기 전에 기존 Meet 탭도 재사용하려고 시도합니다. 매칭은 `authuser` 같은 무해한 URL 쿼리 문자열을 무시하므로, agent 재시도는 두 번째 Chrome 탭을 만들기보다 이미 열린 회의에 포커스해야 합니다. +- 브라우저 대체: OAuth 자격 증명이 없을 때 사용됩니다. OpenClaw는 고정된 Chrome Node를 사용해 `https://meet.google.com/new`를 열고, Google이 실제 회의 코드 URL로 리디렉션할 때까지 기다린 다음 해당 URL을 반환합니다. 이 경로는 Node의 OpenClaw Chrome 프로필이 이미 Google에 로그인되어 있어야 합니다. + 브라우저 자동화는 Meet 자체의 최초 실행 마이크 프롬프트를 처리합니다. 해당 프롬프트는 Google 로그인 실패로 취급되지 않습니다. + 참여 및 생성 흐름은 새 탭을 열기 전에 기존 Meet 탭 재사용도 시도합니다. 매칭은 `authuser` 같은 무해한 URL 쿼리 문자열을 무시하므로, 에이전트 재시도는 두 번째 Chrome 탭을 만들지 않고 이미 열린 회의에 포커스해야 합니다. -명령/도구 출력에는 agent가 어떤 경로가 사용되었는지 설명할 수 있도록 `source` 필드(`api` 또는 `browser`)가 포함됩니다. `create`는 기본적으로 새 회의에 참여하며 `joined: true`와 참여 세션을 반환합니다. URL만 만들려면 CLI에서 `create --no-join`을 사용하거나 도구에 `"join": false`를 전달합니다. +명령/도구 출력에는 에이전트가 어떤 경로를 사용했는지 설명할 수 있도록 `source` 필드(`api` 또는 `browser`)가 포함됩니다. `create`는 기본적으로 새 회의에 참여하고 `joined: true`와 참여 세션을 반환합니다. URL만 발급하려면 CLI에서 `create --no-join`을 사용하거나 도구에 `"join": false`를 전달합니다. -또는 agent에게 다음처럼 지시합니다. "Google Meet을 만들고, agent 응답 음성 모드로 참여한 다음, 링크를 보내줘." Agent는 `action: "create"`로 `google_meet`를 호출한 다음 반환된 `meetingUri`를 공유해야 합니다. +또는 에이전트에게 “Google Meet을 만들고, 에이전트 응답 모드로 참여한 다음, 링크를 보내줘.”라고 말합니다. 에이전트는 `action: "create"`로 `google_meet`를 호출한 다음 반환된 `meetingUri`를 공유해야 합니다. ```json { @@ -148,30 +149,30 @@ openclaw googlemeet create --no-join } ``` -관찰 전용/브라우저 제어 참여의 경우 `"mode": "transcribe"`를 설정합니다. 이 모드는 양방향 실시간 음성 브리지를 시작하지 않고, BlackHole이나 SoX가 필요하지 않으며, 회의에서 응답하지 않습니다. 이 모드의 Chrome 참여는 OpenClaw의 마이크/카메라 권한 부여와 Meet **마이크 사용** 경로도 피합니다. Meet이 오디오 선택 중간 화면을 표시하면 자동화가 마이크 없는 경로를 시도하고, 그렇지 않으면 로컬 마이크를 열지 않고 수동 작업을 보고합니다. 전사 모드에서 관리형 Chrome 전송은 최선의 Meet 캡션 관찰자도 설치합니다. `googlemeet status --json` 및 `googlemeet doctor`는 `captioning`, `captionsEnabledAttempted`, `transcriptLines`, `lastCaptionAt`, `lastCaptionSpeaker`, `lastCaptionText`, 그리고 짧은 `recentTranscript` 꼬리를 표시하여 운영자가 브라우저가 통화에 참여했는지, Meet 캡션이 텍스트를 생성하는지 확인할 수 있게 합니다. -예/아니요 프로브가 필요할 때는 `openclaw googlemeet test-listen --transport chrome-node`를 사용합니다. 이 명령은 전사 모드로 참여하고, 새 캡션 또는 전사 변화가 생길 때까지 기다린 뒤 `listenVerified`, `listenTimedOut`, 수동 작업 필드, 최신 캡션 상태를 반환합니다. +관찰 전용/브라우저 제어 참여의 경우 `"mode": "transcribe"`를 설정합니다. 이는 양방향 실시간 음성 브리지를 시작하지 않고, BlackHole 또는 SoX를 요구하지 않으며, 회의에서 응답하지 않습니다. 이 모드의 Chrome 참여는 OpenClaw의 마이크/카메라 권한 부여와 Meet **마이크 사용** 경로도 피합니다. Meet이 오디오 선택 중간 화면을 표시하면 자동화는 마이크 없는 경로를 시도하고, 그렇지 않으면 로컬 마이크를 열지 않고 수동 작업을 보고합니다. 전사 모드에서 관리형 Chrome 전송은 최선의 Meet 자막 관찰자도 설치합니다. `googlemeet status --json` 및 `googlemeet doctor`는 `captioning`, `captionsEnabledAttempted`, `transcriptLines`, `lastCaptionAt`, `lastCaptionSpeaker`, `lastCaptionText`, 그리고 짧은 `recentTranscript` 꼬리를 표시하여 운영자가 브라우저가 통화에 참여했는지와 Meet 자막이 텍스트를 생성하는지 알 수 있게 합니다. +예/아니요 탐지가 필요할 때는 `openclaw googlemeet test-listen --transport chrome-node`를 사용합니다. 이 명령은 전사 모드로 참여하고, 새 자막 또는 전사 변화가 생길 때까지 기다린 뒤 `listenVerified`, `listenTimedOut`, 수동 작업 필드, 최신 자막 상태를 반환합니다. -실시간 세션 중 `google_meet` 상태에는 `inCall`, `manualActionRequired`, `providerConnected`, `realtimeReady`, `audioInputActive`, `audioOutputActive`, 마지막 입력/출력 타임스탬프, 바이트 카운터, 브리지 닫힘 상태 같은 브라우저 및 오디오 브리지 상태가 포함됩니다. 안전한 Meet 페이지 프롬프트가 나타나면 브라우저 자동화가 가능한 경우 이를 처리합니다. 로그인, 호스트 입장 승인, 브라우저/OS 권한 프롬프트는 agent가 전달할 수 있도록 이유와 메시지가 포함된 수동 작업으로 보고됩니다. 관리형 Chrome 세션은 브라우저 상태가 `inCall: true`를 보고한 뒤에만 인트로나 테스트 문구를 내보냅니다. 그렇지 않으면 agent가 회의에서 말한 척하지 않고 상태가 `speechReady: false`를 보고하며 말하기 시도가 차단됩니다. +실시간 세션 중 `google_meet` 상태에는 `inCall`, `manualActionRequired`, `providerConnected`, `realtimeReady`, `audioInputActive`, `audioOutputActive`, 마지막 입력/출력 타임스탬프, 바이트 카운터, 브리지 닫힘 상태 같은 브라우저 및 오디오 브리지 상태가 포함됩니다. 안전한 Meet 페이지 프롬프트가 나타나면 브라우저 자동화가 가능한 경우 이를 처리합니다. 로그인, 호스트 승인, 브라우저/OS 권한 프롬프트는 에이전트가 전달할 수 있도록 이유와 메시지가 포함된 수동 작업으로 보고됩니다. 관리형 Chrome 세션은 브라우저 상태가 `inCall: true`를 보고한 후에만 소개 또는 테스트 문구를 내보냅니다. 그렇지 않으면 상태가 `speechReady: false`를 보고하고, 에이전트가 회의에서 말한 것처럼 가장하는 대신 음성 시도가 차단됩니다. -로컬 Chrome은 로그인된 OpenClaw 브라우저 프로필을 통해 참여합니다. 실시간 모드에는 OpenClaw가 사용하는 마이크/스피커 경로를 위해 `BlackHole 2ch`가 필요합니다. 깨끗한 양방향 오디오를 위해서는 별도의 가상 장치나 Loopback 스타일 그래프를 사용합니다. 단일 BlackHole 장치도 첫 스모크 테스트에는 충분하지만 에코가 발생할 수 있습니다. +로컬 Chrome 참여는 로그인된 OpenClaw 브라우저 프로필을 통해 이루어집니다. 실시간 모드는 OpenClaw가 사용하는 마이크/스피커 경로에 `BlackHole 2ch`가 필요합니다. 깨끗한 양방향 오디오를 위해서는 별도의 가상 장치 또는 Loopback 스타일 그래프를 사용합니다. 단일 BlackHole 장치만으로도 첫 스모크 테스트에는 충분하지만 에코가 생길 수 있습니다. ### 로컬 Gateway + Parallels Chrome -VM이 Chrome을 소유하게 하려고 macOS VM 내부에 전체 OpenClaw Gateway나 모델 API 키가 필요하지는 않습니다. Gateway와 agent를 로컬에서 실행한 다음, VM에서 Node 호스트를 실행합니다. VM에서 번들 Plugin을 한 번 활성화하여 Node가 Chrome 명령을 광고하게 합니다. +VM이 Chrome을 소유하게 하려는 목적만으로 macOS VM 내부에 전체 OpenClaw Gateway 또는 모델 API 키가 필요하지는 않습니다. Gateway와 에이전트는 로컬에서 실행하고, VM에서 Node 호스트를 실행합니다. Node가 Chrome 명령을 알리도록 VM에서 번들 Plugin을 한 번 활성화합니다. -각 위치에서 실행되는 항목: +실행 위치: -- Gateway 호스트: OpenClaw Gateway, agent 작업 영역, 모델/API 키, 실시간 제공자, Google Meet Plugin 구성. +- Gateway 호스트: OpenClaw Gateway, 에이전트 워크스페이스, 모델/API 키, 실시간 제공자, Google Meet Plugin 구성. - Parallels macOS VM: OpenClaw CLI/Node 호스트, Google Chrome, SoX, BlackHole 2ch, Google에 로그인된 Chrome 프로필. -- VM에 필요하지 않은 항목: Gateway 서비스, agent 구성, OpenAI/GPT 키, 또는 모델 제공자 설정. +- VM에 필요하지 않은 항목: Gateway 서비스, 에이전트 구성, OpenAI/GPT 키, 모델 제공자 설정. -VM 종속성을 설치합니다. +VM 의존성을 설치합니다. ```bash brew install blackhole-2ch sox ``` -BlackHole 설치 후 macOS가 `BlackHole 2ch`를 노출하도록 VM을 재부팅합니다. +BlackHole을 설치한 후 macOS가 `BlackHole 2ch`를 노출하도록 VM을 재부팅합니다. ```bash sudo reboot @@ -184,7 +185,7 @@ system_profiler SPAudioDataType | grep -i BlackHole command -v sox ``` -VM에서 OpenClaw를 설치하거나 업데이트한 다음, 그곳에서 번들 Plugin을 활성화합니다. +VM에 OpenClaw를 설치하거나 업데이트한 다음, 그곳에서 번들 Plugin을 활성화합니다. ```bash openclaw plugins enable google-meet @@ -196,14 +197,14 @@ VM에서 Node 호스트를 시작합니다. openclaw node run --host --port 18789 --display-name parallels-macos ``` -``가 LAN IP이고 TLS를 사용하지 않는 경우, 해당 신뢰된 사설 네트워크에 명시적으로 동의하지 않으면 Node가 평문 WebSocket을 거부합니다. +``가 LAN IP이고 TLS를 사용하지 않는 경우, 해당 신뢰된 사설 네트워크에 옵트인하지 않으면 Node가 평문 WebSocket을 거부합니다. ```bash OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 \ openclaw node run --host --port 18789 --display-name parallels-macos ``` -Node를 LaunchAgent로 설치할 때도 동일한 환경 변수를 사용합니다. +Node를 LaunchAgent로 설치할 때도 같은 환경 변수를 사용합니다. ```bash OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 \ @@ -211,7 +212,7 @@ OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 \ openclaw node restart ``` -`OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`은 프로세스 환경이며 `openclaw.json` 설정이 아닙니다. `openclaw node install`은 설치 명령에 해당 변수가 있으면 LaunchAgent 환경에 저장합니다. +`OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`은 프로세스 환경이지 `openclaw.json` 설정이 아닙니다. `openclaw node install`은 설치 명령에 이 값이 있으면 LaunchAgent 환경에 저장합니다. Gateway 호스트에서 Node를 승인합니다. @@ -220,13 +221,13 @@ openclaw devices list openclaw devices approve ``` -Gateway가 Node를 보고 있으며 Node가 `googlemeet.chrome` 및 브라우저 기능/`browser.proxy`를 모두 광고하는지 확인합니다. +Gateway가 Node를 보고, 해당 Node가 `googlemeet.chrome`과 브라우저 기능/`browser.proxy`를 모두 알리는지 확인합니다. ```bash openclaw nodes status ``` -Gateway 호스트에서 Meet을 해당 Node를 통해 라우팅합니다. +Gateway 호스트에서 해당 Node를 통해 Meet를 라우팅합니다. ```json5 { @@ -256,112 +257,112 @@ Gateway 호스트에서 Meet을 해당 Node를 통해 라우팅합니다. } ``` -이제 Gateway 호스트에서 정상적으로 참여합니다. +이제 Gateway 호스트에서 일반적으로 참여합니다. ```bash openclaw googlemeet join https://meet.google.com/abc-defg-hij ``` -또는 agent에게 `transport: "chrome-node"`로 `google_meet` 도구를 사용하라고 요청합니다. +또는 에이전트에게 `transport: "chrome-node"`로 `google_meet` 도구를 사용하라고 요청합니다. -세션을 만들거나 재사용하고, 알려진 문구를 말한 뒤, 세션 상태를 출력하는 단일 명령 스모크 테스트: +세션을 생성하거나 재사용하고, 알려진 문구를 말하며, 세션 상태를 출력하는 단일 명령 스모크 테스트: ```bash openclaw googlemeet test-speech https://meet.google.com/abc-defg-hij ``` -실시간 참여 중 OpenClaw 브라우저 자동화는 게스트 이름을 입력하고 -참여/참여 요청을 클릭하며, 해당 프롬프트가 나타나면 Meet의 최초 실행 -"마이크 사용" 선택을 수락합니다. 관찰 전용 참여 또는 브라우저 전용 회의 생성 중에는 -해당 선택지를 사용할 수 있을 때 마이크 없이 같은 프롬프트를 지나갑니다. -브라우저 프로필에 로그인되어 있지 않거나, Meet이 호스트 승인 대기 중이거나, -Chrome이 실시간 참여를 위해 마이크/카메라 권한을 필요로 하거나, Meet이 자동화로 -해결할 수 없는 프롬프트에서 멈춘 경우, 참여/test-speech 결과는 -`manualActionRequired: true`와 함께 `manualActionReason` 및 -`manualActionMessage`를 보고합니다. 에이전트는 참여 재시도를 중지하고, 해당 -정확한 메시지와 현재 `browserUrl`/`browserTitle`을 보고한 뒤, 수동 브라우저 -작업이 완료된 후에만 다시 시도해야 합니다. +실시간 참가 중에는 OpenClaw 브라우저 자동화가 게스트 이름을 입력하고, +Join/Ask to join을 클릭하며, 해당 프롬프트가 나타나면 Meet의 최초 실행 +"마이크 사용" 선택을 수락합니다. 관찰 전용 참가 또는 브라우저 전용 회의 생성 +중에는 해당 선택을 사용할 수 있을 때 마이크 없이 같은 프롬프트를 계속 +진행합니다. 브라우저 프로필이 로그인되어 있지 않거나, Meet이 호스트 승인을 +기다리고 있거나, 실시간 참가를 위해 Chrome에 마이크/카메라 권한이 필요하거나, +자동화로 해결할 수 없는 프롬프트에서 Meet이 멈춘 경우, 참가/test-speech 결과는 +`manualActionRequired: true`를 `manualActionReason` 및 +`manualActionMessage`와 함께 보고합니다. 에이전트는 참가 재시도를 중지하고, +현재 `browserUrl`/`browserTitle`과 함께 그 정확한 메시지를 보고한 뒤, 수동 +브라우저 작업이 완료된 후에만 다시 시도해야 합니다. -`chromeNode.node`가 생략되면, 정확히 하나의 연결된 Node가 -`googlemeet.chrome`과 브라우저 제어를 모두 알릴 때만 OpenClaw가 자동 선택합니다. -여러 개의 가능한 Node가 연결되어 있으면 `chromeNode.node`를 Node ID, -표시 이름 또는 원격 IP로 설정하세요. +`chromeNode.node`가 생략되면, OpenClaw는 정확히 하나의 연결된 노드가 +`googlemeet.chrome`과 브라우저 제어를 모두 알릴 때만 자동 선택합니다. 여러 +사용 가능한 노드가 연결되어 있으면 `chromeNode.node`를 노드 ID, 표시 이름 +또는 원격 IP로 설정하세요. -일반적인 실패 확인: +일반적인 실패 확인 사항: -- `Configured Google Meet node ... is not usable: offline`: 고정된 Node는 - Gateway에 알려져 있지만 사용할 수 없습니다. 에이전트는 해당 Node를 사용할 수 - 있는 Chrome 호스트가 아니라 진단 상태로 취급해야 하며, 사용자가 요청하지 않은 - 한 다른 전송으로 대체하지 말고 설정 차단 요인을 보고해야 합니다. -- `No connected Google Meet-capable node`: VM에서 `openclaw node run`을 시작하고, - 페어링을 승인한 뒤, VM에서 `openclaw plugins enable google-meet` 및 - `openclaw plugins enable browser`가 실행되었는지 확인하세요. 또한 +- `Configured Google Meet node ... is not usable: offline`: 고정된 노드는 + Gateway에 알려져 있지만 사용할 수 없습니다. 에이전트는 해당 노드를 사용 + 가능한 Chrome 호스트가 아니라 진단 상태로 취급해야 하며, 사용자가 요청하지 + 않는 한 다른 전송 방식으로 대체하지 말고 설정 차단 요인을 보고해야 합니다. +- `No connected Google Meet-capable node`: VM에서 `openclaw node run`을 + 시작하고, 페어링을 승인한 다음, VM에서 `openclaw plugins enable google-meet` + 및 `openclaw plugins enable browser`가 실행되었는지 확인하세요. 또한 Gateway 호스트가 `gateway.nodes.allowCommands: ["googlemeet.chrome", "browser.proxy"]`로 - 두 Node 명령을 모두 허용하는지 확인하세요. + 두 노드 명령을 모두 허용하는지도 확인하세요. - `BlackHole 2ch audio device not found`: 확인 중인 호스트에 `blackhole-2ch`를 설치하고 로컬 Chrome 오디오를 사용하기 전에 재부팅하세요. - `BlackHole 2ch audio device not found on the node`: VM에 `blackhole-2ch`를 설치하고 VM을 재부팅하세요. -- Chrome이 열리지만 참여할 수 없음: VM 안의 브라우저 프로필에 로그인하거나, - 게스트 참여를 위해 `chrome.guestName`을 설정된 상태로 유지하세요. 게스트 - 자동 참여는 Node 브라우저 프록시를 통한 OpenClaw 브라우저 자동화를 사용합니다. - Node 브라우저 구성이 원하는 프로필을 가리키는지 확인하세요. 예: +- Chrome이 열리지만 참가할 수 없음: VM 내부의 브라우저 프로필에 로그인하거나, + 게스트 참가를 위해 `chrome.guestName`을 설정된 상태로 유지하세요. 게스트 자동 + 참가는 노드 브라우저 프록시를 통한 OpenClaw 브라우저 자동화를 사용합니다. + 노드 브라우저 설정이 원하는 프로필을 가리키는지 확인하세요. 예: `browser.defaultProfile: "user"` 또는 이름이 지정된 기존 세션 프로필. -- 중복 Meet 탭: `chrome.reuseExistingTab: true`를 활성화된 상태로 두세요. OpenClaw는 - 새 탭을 열기 전에 같은 Meet URL의 기존 탭을 활성화하며, 브라우저 회의 생성은 - 다른 탭을 열기 전에 진행 중인 `https://meet.google.com/new` 또는 Google 계정 - 프롬프트 탭을 재사용합니다. +- 중복 Meet 탭: `chrome.reuseExistingTab: true`를 활성화된 상태로 두세요. + OpenClaw는 새 탭을 열기 전에 동일한 Meet URL의 기존 탭을 활성화하며, + 브라우저 회의 생성도 다른 탭을 열기 전에 진행 중인 + `https://meet.google.com/new` 또는 Google 계정 프롬프트 탭을 재사용합니다. - 오디오 없음: Meet에서 마이크/스피커를 OpenClaw가 사용하는 가상 오디오 장치 - 경로를 통해 라우팅하세요. 깨끗한 양방향 오디오를 위해 별도의 가상 장치 또는 + 경로로 라우팅하세요. 깔끔한 양방향 오디오를 위해 별도의 가상 장치 또는 Loopback 방식 라우팅을 사용하세요. ## 설치 참고 사항 -Chrome talk-back 기본값은 두 가지 외부 도구를 사용합니다. +Chrome 토크백 기본값은 두 가지 외부 도구를 사용합니다: - `sox`: 명령줄 오디오 유틸리티입니다. Plugin은 기본 24 kHz PCM16 오디오 - 브리지를 위해 명시적인 CoreAudio 장치 명령을 사용합니다. -- `blackhole-2ch`: macOS 가상 오디오 드라이버입니다. Chrome/Meet가 라우팅할 수 - 있는 `BlackHole 2ch` 오디오 장치를 만듭니다. + 브리지에 명시적 CoreAudio 장치 명령을 사용합니다. +- `blackhole-2ch`: macOS 가상 오디오 드라이버입니다. Chrome/Meet이 라우팅할 + 수 있는 `BlackHole 2ch` 오디오 장치를 생성합니다. -OpenClaw는 두 패키지 중 어느 것도 번들로 제공하거나 재배포하지 않습니다. 문서는 -사용자에게 Homebrew를 통해 호스트 의존성으로 설치하라고 안내합니다. SoX의 -라이선스는 `LGPL-2.0-only AND GPL-2.0-only`이고, BlackHole은 GPL-3.0입니다. BlackHole을 -OpenClaw와 함께 번들로 포함하는 설치 프로그램이나 어플라이언스를 빌드하는 경우, -BlackHole의 업스트림 라이선스 조건을 검토하거나 Existential Audio에서 별도 -라이선스를 받으세요. +OpenClaw는 두 패키지 중 어느 것도 번들하거나 재배포하지 않습니다. 문서는 +사용자에게 Homebrew를 통해 호스트 의존성으로 설치하도록 안내합니다. SoX의 +라이선스는 `LGPL-2.0-only AND GPL-2.0-only`이고, BlackHole은 GPL-3.0입니다. +BlackHole을 OpenClaw와 함께 번들하는 설치 프로그램이나 어플라이언스를 빌드하는 +경우, BlackHole의 업스트림 라이선스 조건을 검토하거나 Existential Audio에서 +별도 라이선스를 받으세요. -## 전송 +## 전송 방식 ### Chrome -Chrome 전송은 OpenClaw 브라우저 제어를 통해 Meet URL을 열고 로그인된 OpenClaw -브라우저 프로필로 참여합니다. macOS에서 Plugin은 실행 전에 `BlackHole 2ch`를 -확인합니다. 구성된 경우 Chrome을 열기 전에 오디오 브리지 상태 명령과 시작 명령도 -실행합니다. Chrome/오디오가 Gateway 호스트에 있을 때는 `chrome`을 사용하고, -Chrome/오디오가 Parallels macOS VM 같은 페어링된 Node에 있을 때는 `chrome-node`를 -사용하세요. 로컬 Chrome의 경우 `browser.defaultProfile`로 프로필을 선택하세요. -`chrome.browserProfile`은 `chrome-node` 호스트에 전달됩니다. +Chrome 전송 방식은 OpenClaw 브라우저 제어를 통해 Meet URL을 열고, 로그인된 +OpenClaw 브라우저 프로필로 참가합니다. macOS에서는 Plugin이 실행 전에 +`BlackHole 2ch`를 확인합니다. 설정된 경우 Chrome을 열기 전에 오디오 브리지 +상태 명령과 시작 명령도 실행합니다. Chrome/오디오가 Gateway 호스트에 있을 때는 +`chrome`을 사용하고, Chrome/오디오가 Parallels macOS VM 같은 페어링된 노드에 +있을 때는 `chrome-node`를 사용하세요. 로컬 Chrome의 경우 `browser.defaultProfile`로 +프로필을 선택하세요. `chrome.browserProfile`은 `chrome-node` 호스트로 전달됩니다. ```bash openclaw googlemeet join https://meet.google.com/abc-defg-hij --transport chrome openclaw googlemeet join https://meet.google.com/abc-defg-hij --transport chrome-node ``` -Chrome 마이크와 스피커 오디오를 로컬 OpenClaw 오디오 브리지를 통해 라우팅하세요. -`BlackHole 2ch`가 설치되어 있지 않으면, 참여는 오디오 경로 없이 조용히 참여하는 -대신 설정 오류와 함께 실패합니다. +Chrome 마이크와 스피커 오디오를 로컬 OpenClaw 오디오 브리지를 통해 +라우팅하세요. `BlackHole 2ch`가 설치되어 있지 않으면 오디오 경로 없이 조용히 +참가하는 대신 설정 오류로 참가가 실패합니다. ### Twilio -Twilio 전송은 Voice Call Plugin에 위임되는 엄격한 다이얼 플랜입니다. Meet +Twilio 전송 방식은 Voice Call Plugin에 위임되는 엄격한 다이얼 플랜입니다. Meet 페이지에서 전화번호를 파싱하지 않습니다. -Chrome 참여를 사용할 수 없거나 전화 접속 대체 경로가 필요할 때 사용하세요. -Google Meet는 회의에 대한 전화 접속 번호와 PIN을 노출해야 합니다. OpenClaw는 -Meet 페이지에서 이를 발견하지 않습니다. +Chrome 참여를 사용할 수 없거나 전화 다이얼인 대체 경로가 필요할 때 사용하세요. +Google Meet은 회의용 전화 다이얼인 번호와 PIN을 노출해야 하며, OpenClaw는 Meet +페이지에서 이를 발견하지 않습니다. -Voice Call Plugin은 Chrome Node가 아니라 Gateway 호스트에서 활성화하세요. +Voice Call Plugin은 Chrome 노드가 아니라 Gateway 호스트에서 활성화하세요: ```json5 { @@ -402,8 +403,8 @@ Voice Call Plugin은 Chrome Node가 아니라 Gateway 호스트에서 활성화 } ``` -Twilio 자격 증명은 환경 또는 구성으로 제공하세요. 환경을 사용하면 비밀 값을 -`openclaw.json` 밖에 둘 수 있습니다. +환경 또는 설정을 통해 Twilio 자격 증명을 제공하세요. 환경을 사용하면 비밀이 +`openclaw.json`에 들어가지 않습니다: ```bash export TWILIO_ACCOUNT_SID=AC... @@ -412,13 +413,14 @@ export TWILIO_FROM_NUMBER=+15550001234 export GEMINI_API_KEY=... ``` -이것이 사용 중인 실시간 음성 공급자라면 대신 OpenAI 공급자 Plugin 및 -`OPENAI_API_KEY`와 함께 `realtime.provider: "openai"`를 사용하세요. +실시간 음성 제공자가 그것이라면 대신 OpenAI 제공자 Plugin과 `OPENAI_API_KEY`로 +`realtime.provider: "openai"`를 사용하세요. -`voice-call`을 활성화한 뒤 Gateway를 재시작하거나 다시 로드하세요. Plugin 구성 -변경은 이미 실행 중인 Gateway 프로세스가 다시 로드되기 전까지 나타나지 않습니다. +`voice-call`을 활성화한 후 Gateway를 다시 시작하거나 다시 로드하세요. Plugin +설정 변경은 이미 실행 중인 Gateway 프로세스가 다시 로드될 때까지 반영되지 +않습니다. -그런 다음 확인하세요. +그런 다음 확인하세요: ```bash openclaw config validate @@ -426,7 +428,7 @@ openclaw plugins list | grep -E 'google-meet|voice-call' openclaw googlemeet setup ``` -Twilio 위임이 연결되면 `googlemeet setup`에는 성공한 +Twilio 위임이 연결되면 `googlemeet setup`에 성공한 `twilio-voice-call-plugin`, `twilio-voice-call-credentials`, `twilio-voice-call-webhook` 확인이 포함됩니다. @@ -437,7 +439,7 @@ openclaw googlemeet join https://meet.google.com/abc-defg-hij \ --pin 123456 ``` -회의에 사용자 지정 시퀀스가 필요할 때는 `--dtmf-sequence`를 사용하세요. +회의에 사용자 지정 시퀀스가 필요할 때는 `--dtmf-sequence`를 사용하세요: ```bash openclaw googlemeet join https://meet.google.com/abc-defg-hij \ @@ -446,21 +448,21 @@ openclaw googlemeet join https://meet.google.com/abc-defg-hij \ --dtmf-sequence ww123456# ``` -## OAuth 및 사전 검사 +## OAuth와 사전 확인 -`googlemeet create`가 브라우저 자동화로 대체될 수 있으므로 Meet 링크 생성에는 -OAuth가 선택 사항입니다. 공식 API 생성, 스페이스 확인 또는 Meet Media API 사전 -검사가 필요할 때 OAuth를 구성하세요. +`googlemeet create`가 브라우저 자동화로 대체될 수 있으므로 Meet 링크 생성을 +위한 OAuth는 선택 사항입니다. 공식 API 생성, 공간 해석 또는 Meet Media API +사전 확인이 필요할 때 OAuth를 구성하세요. -Google Meet API 접근은 사용자 OAuth를 사용합니다. Google Cloud OAuth 클라이언트를 -만들고, 필요한 범위를 요청하고, Google 계정을 승인한 다음, 결과 refresh token을 -Google Meet Plugin 구성에 저장하거나 `OPENCLAW_GOOGLE_MEET_*` 환경 변수를 -제공하세요. +Google Meet API 접근은 사용자 OAuth를 사용합니다. Google Cloud OAuth +클라이언트를 만들고, 필요한 범위를 요청하고, Google 계정을 승인한 다음, 생성된 +새로고침 토큰을 Google Meet Plugin 설정에 저장하거나 +`OPENCLAW_GOOGLE_MEET_*` 환경 변수를 제공하세요. -OAuth는 Chrome 참여 경로를 대체하지 않습니다. Chrome 및 Chrome-node 전송은 -브라우저 참여를 사용할 때 여전히 로그인된 Chrome 프로필, BlackHole/SoX 및 연결된 -Node를 통해 참여합니다. OAuth는 공식 Google Meet API 경로에만 사용됩니다. 회의 -스페이스 생성, 스페이스 확인 및 Meet Media API 사전 검사를 실행합니다. +OAuth는 Chrome 참가 경로를 대체하지 않습니다. Chrome 및 Chrome-node 전송 +방식은 브라우저 참여를 사용할 때 여전히 로그인된 Chrome 프로필, BlackHole/SoX, +연결된 노드를 통해 참가합니다. OAuth는 공식 Google Meet API 경로에만 +사용됩니다: 회의 공간 생성, 공간 해석, Meet Media API 사전 확인 실행. ### Google 자격 증명 생성 @@ -469,15 +471,15 @@ Google Cloud Console에서: 1. Google Cloud 프로젝트를 만들거나 선택합니다. 2. 해당 프로젝트에 **Google Meet REST API**를 활성화합니다. 3. OAuth 동의 화면을 구성합니다. - - **Internal**은 Google Workspace 조직에 가장 간단합니다. - - **External**은 개인/테스트 설정에 사용할 수 있습니다. 앱이 Testing 상태인 - 동안 앱을 승인할 각 Google 계정을 테스트 사용자로 추가하세요. -4. OpenClaw가 요청하는 범위를 추가합니다. + - Google Workspace 조직에서는 **Internal**이 가장 간단합니다. + - 개인/테스트 설정에는 **External**이 작동합니다. 앱이 Testing 상태인 동안, + 앱을 승인할 각 Google 계정을 테스트 사용자로 추가하세요. +4. OpenClaw가 요청하는 범위를 추가합니다: - `https://www.googleapis.com/auth/meetings.space.created` - `https://www.googleapis.com/auth/meetings.space.readonly` - `https://www.googleapis.com/auth/meetings.space.settings` - `https://www.googleapis.com/auth/meetings.conference.media.readonly` -5. OAuth 클라이언트 ID를 만듭니다. +5. OAuth 클라이언트 ID를 생성합니다. - 애플리케이션 유형: **Web application**. - 승인된 리디렉션 URI: @@ -488,25 +490,27 @@ Google Cloud Console에서: 6. 클라이언트 ID와 클라이언트 보안 비밀을 복사합니다. `meetings.space.created`는 Google Meet `spaces.create`에 필요합니다. -`meetings.space.readonly`를 사용하면 OpenClaw가 Meet URL/코드를 스페이스로 확인할 -수 있습니다. `meetings.space.settings`를 사용하면 OpenClaw가 API 방 생성 중 -`accessType` 같은 `SpaceConfig` 설정을 전달할 수 있습니다. -`meetings.conference.media.readonly`는 Meet Media API 사전 검사와 미디어 작업을 -위한 것입니다. 실제 Media API 사용에는 Google이 Developer Preview 등록을 요구할 -수 있습니다. 브라우저 기반 Chrome 참여만 필요하다면 OAuth를 완전히 건너뛰세요. +`meetings.space.readonly`를 사용하면 OpenClaw가 Meet URL/코드를 공간으로 +해석할 수 있습니다. +`meetings.space.settings`를 사용하면 OpenClaw가 API 방 생성 중 `accessType` 같은 +`SpaceConfig` 설정을 전달할 수 있습니다. +`meetings.conference.media.readonly`는 Meet Media API 사전 확인 및 미디어 작업을 +위한 것입니다. 실제 Media API 사용에는 Google이 Developer Preview 등록을 +요구할 수 있습니다. 브라우저 기반 Chrome 참가만 필요하다면 OAuth를 완전히 +건너뛰세요. -### refresh token 발급 +### 새로고침 토큰 발급 -`oauth.clientId`와 선택적으로 `oauth.clientSecret`을 구성하거나 환경 변수로 전달한 -다음 실행하세요. +`oauth.clientId` 및 선택적으로 `oauth.clientSecret`을 구성하거나 환경 변수로 +전달한 다음 실행하세요: ```bash openclaw googlemeet auth login --json ``` -명령은 refresh token이 포함된 `oauth` 구성 블록을 출력합니다. PKCE, -`http://localhost:8085/oauth2callback`의 localhost 콜백, 그리고 `--manual`을 통한 -수동 복사/붙여넣기 흐름을 사용합니다. +이 명령은 새로고침 토큰이 포함된 `oauth` 설정 블록을 출력합니다. PKCE, +`http://localhost:8085/oauth2callback`의 localhost 콜백, 그리고 `--manual`을 +사용한 수동 복사/붙여넣기 흐름을 사용합니다. 예: @@ -516,7 +520,7 @@ OPENCLAW_GOOGLE_MEET_CLIENT_SECRET="your-client-secret" \ openclaw googlemeet auth login --json ``` -브라우저가 로컬 콜백에 도달할 수 없을 때는 수동 모드를 사용하세요. +브라우저가 로컬 콜백에 도달할 수 없을 때는 수동 모드를 사용하세요: ```bash OPENCLAW_GOOGLE_MEET_CLIENT_ID="your-client-id" \ @@ -524,7 +528,7 @@ OPENCLAW_GOOGLE_MEET_CLIENT_SECRET="your-client-secret" \ openclaw googlemeet auth login --json --manual ``` -JSON 출력에는 다음이 포함됩니다. +JSON 출력에는 다음이 포함됩니다: ```json { @@ -539,7 +543,7 @@ JSON 출력에는 다음이 포함됩니다. } ``` -`oauth` 객체를 Google Meet Plugin 구성 아래에 저장하세요. +`oauth` 객체를 Google Meet Plugin 설정 아래에 저장하세요: ```json5 { @@ -560,39 +564,38 @@ JSON 출력에는 다음이 포함됩니다. } ``` -refresh token을 구성에 넣고 싶지 않을 때는 환경 변수를 선호하세요. 구성 값과 -환경 값이 모두 있으면, Plugin은 먼저 구성을 확인한 다음 환경 대체 값을 -확인합니다. +새로고침 토큰을 설정에 넣고 싶지 않다면 환경 변수를 선호하세요. 설정 값과 환경 +값이 모두 있으면 Plugin은 먼저 설정을 해석한 다음 환경 대체값을 사용합니다. -OAuth 동의에는 Meet 스페이스 생성, Meet 스페이스 읽기 접근 및 Meet 회의 미디어 -읽기 접근이 포함됩니다. 회의 생성 지원이 생기기 전에 인증했다면, refresh token에 -`meetings.space.created` 범위가 있도록 `openclaw googlemeet auth login --json`을 +OAuth 동의에는 Meet 공간 생성, Meet 공간 읽기 접근, Meet 회의 미디어 읽기 +접근이 포함됩니다. 회의 생성 지원이 생기기 전에 인증했다면 새로고침 토큰에 +`meetings.space.created` 범위가 포함되도록 `openclaw googlemeet auth login --json`을 다시 실행하세요. ### doctor로 OAuth 확인 -빠르고 비밀 값을 노출하지 않는 상태 확인이 필요할 때 OAuth doctor를 실행하세요. +빠르고 비밀을 출력하지 않는 상태 확인이 필요할 때 OAuth doctor를 실행하세요: ```bash openclaw googlemeet doctor --oauth --json ``` -이는 Chrome 런타임을 로드하지 않으며 연결된 Chrome Node도 필요로 하지 않습니다. -OAuth 구성이 존재하는지, refresh token으로 access token을 발급할 수 있는지 -확인합니다. JSON 보고서에는 `ok`, `configured`, `tokenSource`, `expiresAt` 및 확인 -메시지 같은 상태 필드만 포함됩니다. access token, refresh token 또는 클라이언트 -보안 비밀은 출력하지 않습니다. +이 명령은 Chrome 런타임을 로드하지 않으며 연결된 Chrome 노드가 필요하지 +않습니다. OAuth 설정이 존재하는지와 새로고침 토큰이 접근 토큰을 발급할 수 +있는지를 확인합니다. JSON 보고서에는 `ok`, `configured`, `tokenSource`, +`expiresAt` 및 확인 메시지 같은 상태 필드만 포함되며, 접근 토큰, 새로고침 +토큰 또는 클라이언트 보안 비밀은 출력하지 않습니다. 일반적인 결과: -| 검사 | 의미 | +| 검사 | 의미 | | -------------------- | --------------------------------------------------------------------------------------- | -| `oauth-config` | `oauth.clientId`와 `oauth.refreshToken`, 또는 캐시된 액세스 토큰이 있습니다. | -| `oauth-token` | 캐시된 액세스 토큰이 아직 유효하거나, 리프레시 토큰이 새 액세스 토큰을 발급했습니다. | -| `meet-spaces-get` | 선택적 `--meeting` 검사가 기존 Meet 스페이스를 확인했습니다. | -| `meet-spaces-create` | 선택적 `--create-space` 검사가 새 Meet 스페이스를 만들었습니다. | +| `oauth-config` | `oauth.clientId`와 `oauth.refreshToken`, 또는 캐시된 액세스 토큰이 있습니다. | +| `oauth-token` | 캐시된 액세스 토큰이 아직 유효하거나, 리프레시 토큰이 새 액세스 토큰을 발급했습니다. | +| `meet-spaces-get` | 선택 사항인 `--meeting` 검사가 기존 Meet 공간을 확인했습니다. | +| `meet-spaces-create` | 선택 사항인 `--create-space` 검사가 새 Meet 공간을 만들었습니다. | -Google Meet API 활성화와 `spaces.create` 범위도 증명하려면 부작용이 있는 +Google Meet API 활성화와 `spaces.create` 범위까지 증명하려면, 부작용이 있는 생성 검사를 실행하세요. ```bash @@ -600,27 +603,29 @@ openclaw googlemeet doctor --oauth --create-space --json openclaw googlemeet create --no-join --json ``` -`--create-space`는 임시 Meet URL을 만듭니다. Google Cloud 프로젝트에서 Meet API가 -활성화되어 있고, 승인된 계정에 `meetings.space.created` 범위가 있는지 확인해야 할 때 사용하세요. +`--create-space`는 일회용 Meet URL을 만듭니다. Google Cloud 프로젝트에 Meet +API가 활성화되어 있고 승인된 계정에 `meetings.space.created` 범위가 있는지 +확인해야 할 때 사용하세요. -기존 회의 스페이스에 대한 읽기 액세스를 증명하려면 다음을 실행하세요. +기존 회의 공간에 대한 읽기 액세스를 증명하려면: ```bash openclaw googlemeet doctor --oauth --meeting https://meet.google.com/abc-defg-hij --json openclaw googlemeet resolve-space --meeting https://meet.google.com/abc-defg-hij ``` -`doctor --oauth --meeting`과 `resolve-space`는 승인된 Google 계정이 액세스할 수 있는 -기존 스페이스에 대한 읽기 액세스를 증명합니다. 이 검사에서 `403`이 반환되면 -보통 Google Meet REST API가 비활성화되어 있거나, 동의한 리프레시 토큰에 필요한 -범위가 없거나, Google 계정이 해당 Meet 스페이스에 액세스할 수 없다는 뜻입니다. -리프레시 토큰 오류는 `openclaw googlemeet auth login --json`을 다시 실행하고 -새 `oauth` 블록을 저장해야 한다는 뜻입니다. +`doctor --oauth --meeting` 및 `resolve-space`는 승인된 Google 계정이 액세스할 +수 있는 기존 공간에 대한 읽기 액세스를 증명합니다. 이러한 검사에서 `403`이 +나오면 일반적으로 Google Meet REST API가 비활성화되어 있거나, 동의된 +리프레시 토큰에 필요한 범위가 없거나, Google 계정이 해당 Meet 공간에 +액세스할 수 없다는 뜻입니다. 리프레시 토큰 오류는 `openclaw googlemeet auth login +--json`을 다시 실행하고 새 `oauth` 블록을 저장하라는 뜻입니다. -브라우저 대체 경로에는 OAuth 자격 증명이 필요하지 않습니다. 이 모드에서는 Google -인증이 OpenClaw 구성에서 오지 않고, 선택한 Node에서 로그인된 Chrome 프로필에서 옵니다. +브라우저 대체 경로에는 OAuth 자격 증명이 필요하지 않습니다. 이 모드에서 +Google 인증은 OpenClaw config가 아니라 선택한 node에 로그인된 Chrome +프로필에서 가져옵니다. -다음 환경 변수를 대체값으로 사용할 수 있습니다. +이 환경 변수는 대체 값으로 허용됩니다. - `OPENCLAW_GOOGLE_MEET_CLIENT_ID` 또는 `GOOGLE_MEET_CLIENT_ID` - `OPENCLAW_GOOGLE_MEET_CLIENT_SECRET` 또는 `GOOGLE_MEET_CLIENT_SECRET` @@ -631,7 +636,7 @@ openclaw googlemeet resolve-space --meeting https://meet.google.com/abc-defg-hij - `OPENCLAW_GOOGLE_MEET_DEFAULT_MEETING` 또는 `GOOGLE_MEET_DEFAULT_MEETING` - `OPENCLAW_GOOGLE_MEET_PREVIEW_ACK` 또는 `GOOGLE_MEET_PREVIEW_ACK` -Meet URL, 코드, 또는 `spaces/{id}`를 `spaces.get`을 통해 확인합니다. +Meet URL, 코드 또는 `spaces/{id}`를 `spaces.get`을 통해 해석합니다. ```bash openclaw googlemeet resolve-space --meeting https://meet.google.com/abc-defg-hij @@ -643,7 +648,7 @@ openclaw googlemeet resolve-space --meeting https://meet.google.com/abc-defg-hij openclaw googlemeet preflight --meeting https://meet.google.com/abc-defg-hij ``` -Meet가 컨퍼런스 레코드를 만든 후 회의 아티팩트와 참석 정보를 나열하세요. +Meet가 회의 기록을 만든 후 회의 아티팩트와 참석을 나열합니다. ```bash openclaw googlemeet artifacts --meeting https://meet.google.com/abc-defg-hij @@ -651,11 +656,12 @@ openclaw googlemeet attendance --meeting https://meet.google.com/abc-defg-hij openclaw googlemeet export --meeting https://meet.google.com/abc-defg-hij --output ./meet-export ``` -`--meeting`을 사용하면 `artifacts`와 `attendance`는 기본적으로 최신 컨퍼런스 레코드를 -사용합니다. 해당 회의에 보존된 모든 레코드가 필요하면 `--all-conference-records`를 -전달하세요. +`--meeting`을 사용하면 `artifacts`와 `attendance`는 기본적으로 최신 회의 +기록을 사용합니다. 해당 회의에 대해 보존된 모든 기록을 원할 때는 +`--all-conference-records`를 전달하세요. -Meet 아티팩트를 읽기 전에 Calendar 조회로 Google Calendar에서 회의 URL을 확인할 수 있습니다. +Calendar 조회는 Meet 아티팩트를 읽기 전에 Google Calendar에서 회의 URL을 +해석할 수 있습니다. ```bash openclaw googlemeet latest --today @@ -664,14 +670,14 @@ openclaw googlemeet artifacts --event "Weekly sync" openclaw googlemeet attendance --today --format csv --output attendance.csv ``` -`--today`는 오늘의 `primary` Calendar에서 Google Meet 링크가 있는 Calendar 이벤트를 -검색합니다. 일치하는 이벤트 텍스트를 검색하려면 `--event `를 사용하고, -기본이 아닌 Calendar에는 `--calendar `를 사용하세요. Calendar 조회에는 Calendar -이벤트 읽기 전용 범위를 포함하는 새 OAuth 로그인이 필요합니다. `calendar-events`는 -일치하는 Meet 이벤트를 미리 보여 주고 `latest`, `artifacts`, `attendance`, 또는 -`export`가 선택할 이벤트를 표시합니다. +`--today`는 오늘의 `primary` 캘린더에서 Google Meet 링크가 있는 Calendar +이벤트를 검색합니다. 일치하는 이벤트 텍스트를 검색하려면 `--event `를, +기본이 아닌 캘린더에는 `--calendar `를 사용하세요. Calendar 조회에는 +Calendar 이벤트 읽기 전용 범위가 포함된 새 OAuth 로그인이 필요합니다. +`calendar-events`는 일치하는 Meet 이벤트를 미리 보여 주고 `latest`, +`artifacts`, `attendance` 또는 `export`가 선택할 이벤트를 표시합니다. -컨퍼런스 레코드 ID를 이미 알고 있다면 직접 지정하세요. +회의 기록 id를 이미 알고 있다면 직접 지정하세요. ```bash openclaw googlemeet latest --meeting https://meet.google.com/abc-defg-hij @@ -679,20 +685,21 @@ openclaw googlemeet artifacts --conference-record conferenceRecords/abc123 --jso openclaw googlemeet attendance --conference-record conferenceRecords/abc123 --json ``` -통화 후 방을 닫고 싶을 때 API로 만든 스페이스의 활성 컨퍼런스를 종료하세요. +통화 후 방을 닫고 싶을 때 API로 생성된 공간의 활성 회의를 종료합니다. ```bash openclaw googlemeet end-active-conference https://meet.google.com/abc-defg-hij ``` -이 명령은 Google Meet `spaces.endActiveConference`를 호출하며, 승인된 계정이 관리할 수 있는 -스페이스에 대해 `meetings.space.created` 범위가 있는 OAuth가 필요합니다. -OpenClaw는 Meet URL, 회의 코드, 또는 `spaces/{id}` 입력을 받아 활성 컨퍼런스를 -종료하기 전에 API 스페이스 리소스로 확인합니다. 이는 `googlemeet leave`와 별개입니다. -`leave`는 OpenClaw의 로컬/세션 참여를 중지하지만, `end-active-conference`는 -Google Meet에 해당 스페이스의 활성 컨퍼런스를 종료하도록 요청합니다. +이 명령은 Google Meet `spaces.endActiveConference`를 호출하며, 승인된 계정이 +관리할 수 있는 공간에 대해 `meetings.space.created` 범위가 있는 OAuth가 +필요합니다. OpenClaw는 Meet URL, 회의 코드 또는 `spaces/{id}` 입력을 +허용하고, 활성 회의를 종료하기 전에 이를 API 공간 리소스로 해석합니다. +이는 `googlemeet leave`와 별개입니다. `leave`는 OpenClaw의 로컬/세션 +참여를 중지하는 반면, `end-active-conference`는 Google Meet에 해당 공간의 +활성 회의를 종료하도록 요청합니다. -읽기 쉬운 보고서를 작성하세요. +읽기 쉬운 보고서를 작성합니다. ```bash openclaw googlemeet artifacts --conference-record conferenceRecords/abc123 \ @@ -707,30 +714,33 @@ openclaw googlemeet export --conference-record conferenceRecords/abc123 \ --include-doc-bodies --dry-run ``` -`artifacts`는 Google이 해당 회의에 대해 제공하는 경우 컨퍼런스 레코드 메타데이터와 -참가자, 녹화, 스크립트, 구조화된 스크립트 항목, 스마트 노트 리소스 메타데이터를 반환합니다. -큰 회의에서 항목 조회를 건너뛰려면 `--no-transcript-entries`를 사용하세요. `attendance`는 -참가자를 참가자 세션 행으로 확장하며, 최초/마지막 확인 시간, 총 세션 지속 시간, -지각/조기 퇴장 플래그, 로그인 사용자 또는 표시 이름 기준으로 병합된 중복 참가자 리소스를 -포함합니다. 원시 참가자 리소스를 별도로 유지하려면 `--no-merge-duplicates`를 전달하고, -지각 감지를 조정하려면 `--late-after-minutes`, 조기 퇴장 감지를 조정하려면 +`artifacts`는 Google이 해당 회의에 대해 노출하는 경우 회의 기록 메타데이터와 +참가자, 녹화, 스크립트, 구조화된 스크립트 항목, 스마트 노트 리소스 +메타데이터를 반환합니다. 대규모 회의에서 항목 조회를 건너뛰려면 +`--no-transcript-entries`를 사용하세요. `attendance`는 참가자를 참가자-세션 +행으로 확장하며, 최초/마지막 확인 시간, 총 세션 시간, 지각/조기 퇴장 +플래그, 로그인한 사용자 또는 표시 이름으로 병합된 중복 참가자 리소스를 +포함합니다. 원시 참가자 리소스를 따로 유지하려면 `--no-merge-duplicates`를, +지각 감지를 조정하려면 `--late-after-minutes`를, 조기 퇴장 감지를 조정하려면 `--early-before-minutes`를 전달하세요. `export`는 `summary.md`, `attendance.csv`, `transcript.md`, `artifacts.json`, -`attendance.json`, `manifest.json`이 포함된 폴더를 작성합니다. `manifest.json`은 -선택된 입력, 내보내기 옵션, 컨퍼런스 레코드, 출력 파일, 개수, 토큰 소스, 사용된 경우 -Calendar 이벤트, 그리고 부분 검색 경고를 기록합니다. 폴더 옆에 이동 가능한 아카이브도 -작성하려면 `--zip`을 전달하세요. 연결된 스크립트와 스마트 노트 Google Docs 텍스트를 -Google Drive `files.export`를 통해 내보내려면 `--include-doc-bodies`를 전달하세요. -여기에는 Drive Meet 읽기 전용 범위를 포함하는 새 OAuth 로그인이 필요합니다. -`--include-doc-bodies`가 없으면 내보내기에는 Meet 메타데이터와 구조화된 스크립트 항목만 -포함됩니다. Google이 스마트 노트 목록, 스크립트 항목, 또는 Drive 문서 본문 오류 같은 -부분 아티팩트 실패를 반환하면 전체 내보내기를 실패시키는 대신 요약과 매니페스트에 -경고가 유지됩니다. 폴더나 ZIP을 만들지 않고 같은 아티팩트/참석 데이터를 가져와 -매니페스트 JSON을 출력하려면 `--dry-run`을 사용하세요. 큰 내보내기를 작성하기 전이나 -에이전트에 개수, 선택된 레코드, 경고만 필요할 때 유용합니다. +`attendance.json`, `manifest.json`이 포함된 폴더를 작성합니다. +`manifest.json`은 선택된 입력, export 옵션, 회의 기록, 출력 파일, 개수, 토큰 +소스, 사용된 경우 Calendar 이벤트, 부분 검색 경고를 기록합니다. 폴더 옆에 +이동 가능한 아카이브도 작성하려면 `--zip`을 전달하세요. 연결된 스크립트와 +스마트 노트 Google Docs 텍스트를 Google Drive `files.export`를 통해 +내보내려면 `--include-doc-bodies`를 전달하세요. 이를 위해서는 Drive Meet 읽기 +전용 범위가 포함된 새 OAuth 로그인이 필요합니다. `--include-doc-bodies`가 +없으면 export에는 Meet 메타데이터와 구조화된 스크립트 항목만 포함됩니다. +Google이 스마트 노트 목록, 스크립트 항목 또는 Drive 문서 본문 오류 같은 +부분 아티팩트 실패를 반환하면, 전체 export를 실패시키는 대신 요약과 +manifest가 해당 경고를 유지합니다. +폴더나 ZIP을 만들지 않고 동일한 아티팩트/참석 데이터를 가져와 manifest +JSON을 출력하려면 `--dry-run`을 사용하세요. 이는 대규모 export를 작성하기 +전이나 에이전트가 개수, 선택된 기록, 경고만 필요로 할 때 유용합니다. -에이전트는 `google_meet` 도구를 통해 같은 번들을 만들 수도 있습니다. +에이전트는 `google_meet` 도구를 통해 동일한 번들을 만들 수도 있습니다. ```json { @@ -742,9 +752,10 @@ Google Drive `files.export`를 통해 내보내려면 `--include-doc-bodies`를 } ``` -내보내기 매니페스트만 반환하고 파일 쓰기를 건너뛰려면 `"dryRun": true`를 설정하세요. +export manifest만 반환하고 파일 쓰기를 건너뛰려면 `"dryRun": true`를 +설정하세요. -에이전트는 명시적인 액세스 정책으로 API 기반 방을 만들 수도 있습니다. +에이전트는 명시적 액세스 정책으로 API 기반 방을 만들 수도 있습니다. ```json { @@ -755,7 +766,7 @@ Google Drive `files.export`를 통해 내보내려면 `--include-doc-bodies`를 } ``` -또한 알려진 방의 활성 컨퍼런스를 종료할 수 있습니다. +그리고 알려진 방의 활성 회의를 종료할 수도 있습니다. ```json { @@ -764,8 +775,8 @@ Google Drive `files.export`를 통해 내보내려면 `--include-doc-bodies`를 } ``` -먼저 듣기 검증을 하려면, 회의가 유용하다고 주장하기 전에 에이전트는 `test_listen`을 -사용해야 합니다. +먼저 듣는 검증의 경우, 에이전트는 회의가 유용하다고 주장하기 전에 +`test_listen`을 사용해야 합니다. ```json { @@ -776,7 +787,7 @@ Google Drive `files.export`를 통해 내보내려면 `--include-doc-bodies`를 } ``` -실제 보존된 회의를 대상으로 보호된 라이브 스모크를 실행하세요. +실제로 보존된 회의를 대상으로 보호된 라이브 스모크를 실행하세요. ```bash OPENCLAW_LIVE_TEST=1 \ @@ -784,8 +795,8 @@ OPENCLAW_GOOGLE_MEET_LIVE_MEETING=https://meet.google.com/abc-defg-hij \ pnpm test:live -- extensions/google-meet/google-meet.live.test.ts ``` -누군가 말할 예정이고 Meet 캡션을 사용할 수 있는 회의에서 라이브 듣기 우선 브라우저 -프로브를 실행하세요. +누군가가 말하고 Meet 자막을 사용할 수 있는 회의를 대상으로 라이브 +먼저 듣는 브라우저 프로브를 실행하세요. ```bash openclaw googlemeet setup --transport chrome-node --mode transcribe @@ -795,37 +806,38 @@ openclaw googlemeet test-listen https://meet.google.com/abc-defg-hij --transport 라이브 스모크 환경: - `OPENCLAW_LIVE_TEST=1`은 보호된 라이브 테스트를 활성화합니다. -- `OPENCLAW_GOOGLE_MEET_LIVE_MEETING`은 보존된 Meet URL, 코드, 또는 +- `OPENCLAW_GOOGLE_MEET_LIVE_MEETING`은 보존된 Meet URL, 코드 또는 `spaces/{id}`를 가리킵니다. - `OPENCLAW_GOOGLE_MEET_CLIENT_ID` 또는 `GOOGLE_MEET_CLIENT_ID`는 OAuth - 클라이언트 ID를 제공합니다. + 클라이언트 id를 제공합니다. - `OPENCLAW_GOOGLE_MEET_REFRESH_TOKEN` 또는 `GOOGLE_MEET_REFRESH_TOKEN`은 리프레시 토큰을 제공합니다. - 선택 사항: `OPENCLAW_GOOGLE_MEET_CLIENT_SECRET`, `OPENCLAW_GOOGLE_MEET_ACCESS_TOKEN`, 그리고 - `OPENCLAW_GOOGLE_MEET_ACCESS_TOKEN_EXPIRES_AT`은 `OPENCLAW_` 접두사가 없는 - 같은 대체 이름을 사용합니다. + `OPENCLAW_GOOGLE_MEET_ACCESS_TOKEN_EXPIRES_AT`은 `OPENCLAW_` 접두사 없는 + 동일한 대체 이름을 사용합니다. 기본 아티팩트/참석 라이브 스모크에는 -`https://www.googleapis.com/auth/meetings.space.readonly`와 -`https://www.googleapis.com/auth/meetings.conference.media.readonly`가 필요합니다. -Calendar 조회에는 `https://www.googleapis.com/auth/calendar.events.readonly`가 필요합니다. -Drive 문서 본문 내보내기에는 +`https://www.googleapis.com/auth/meetings.space.readonly` 및 +`https://www.googleapis.com/auth/meetings.conference.media.readonly`가 +필요합니다. Calendar 조회에는 +`https://www.googleapis.com/auth/calendar.events.readonly`가 필요합니다. Drive +문서 본문 export에는 `https://www.googleapis.com/auth/drive.meet.readonly`가 필요합니다. -새 Meet 스페이스를 만드세요. +새 Meet 공간을 만듭니다. ```bash openclaw googlemeet create ``` -이 명령은 새 `meeting uri`, 소스, 참여 세션을 출력합니다. OAuth 자격 증명이 있으면 -공식 Google Meet API를 사용합니다. OAuth 자격 증명이 없으면 고정된 Chrome Node의 -로그인된 브라우저 프로필을 대체 경로로 사용합니다. 에이전트는 `action: "create"`와 함께 -`google_meet` 도구를 사용해 한 단계로 만들고 참여할 수 있습니다. URL만 만들려면 -`"join": false`를 전달하세요. +이 명령은 새 `meeting uri`, 소스, 참여 세션을 출력합니다. OAuth 자격 증명이 +있으면 공식 Google Meet API를 사용합니다. OAuth 자격 증명이 없으면 고정된 +Chrome node의 로그인된 브라우저 프로필을 대체 경로로 사용합니다. 에이전트는 +`action: "create"`와 함께 `google_meet` 도구를 사용하여 한 단계로 만들고 +참여할 수 있습니다. URL만 만들려면 `"join": false`를 전달하세요. -브라우저 대체 경로의 예시 JSON 출력: +브라우저 대체 경로의 JSON 출력 예: ```json { @@ -845,9 +857,9 @@ openclaw googlemeet create } ``` -브라우저 대체 경로가 URL을 만들기 전에 Google 로그인 또는 Meet 권한 차단에 걸리면, -Gateway 메서드는 실패한 응답을 반환하고 `google_meet` 도구는 일반 문자열 대신 -구조화된 세부 정보를 반환합니다. +브라우저 대체 경로가 URL을 만들기 전에 Google 로그인 또는 Meet 권한 차단에 +걸리면, Gateway 메서드는 실패 응답을 반환하고 `google_meet` 도구는 단순 +문자열 대신 구조화된 세부 정보를 반환합니다. ```json { @@ -865,11 +877,11 @@ Gateway 메서드는 실패한 응답을 반환하고 `google_meet` 도구는 } ``` -에이전트가 `manualActionRequired: true`를 보면 `manualActionMessage`와 브라우저 -Node/탭 컨텍스트를 보고하고, 운영자가 브라우저 단계를 완료할 때까지 새 Meet 탭을 -열지 않아야 합니다. +에이전트가 `manualActionRequired: true`를 확인하면 `manualActionMessage`와 +브라우저 node/tab 컨텍스트를 보고하고, 운영자가 브라우저 단계를 완료할 +때까지 새 Meet 탭 열기를 중지해야 합니다. -API 생성의 예시 JSON 출력: +API create의 JSON 출력 예: ```json { @@ -890,13 +902,13 @@ API 생성의 예시 JSON 출력: } ``` -Meet를 만들면 기본적으로 참여합니다. Chrome 또는 Chrome-node 전송도 브라우저를 통해 참여하려면 로그인된 Google Chrome 프로필이 필요합니다. 프로필이 로그아웃되어 있으면 OpenClaw는 `manualActionRequired: true` 또는 브라우저 폴백 오류를 보고하고, 다시 시도하기 전에 운영자에게 Google 로그인을 완료하라고 요청합니다. +Meet을 생성하면 기본적으로 참가합니다. Chrome 또는 Chrome-node 전송은 브라우저를 통해 참가하려면 여전히 로그인된 Google Chrome 프로필이 필요합니다. 프로필이 로그아웃된 상태이면 OpenClaw가 `manualActionRequired: true` 또는 브라우저 폴백 오류를 보고하고, 다시 시도하기 전에 운영자에게 Google 로그인을 완료하라고 요청합니다. -Cloud 프로젝트, OAuth 주체, 회의 참가자가 Meet 미디어 API용 Google Workspace Developer Preview Program에 등록되어 있음을 확인한 후에만 `preview.enrollmentAcknowledged: true`를 설정하세요. +Cloud 프로젝트, OAuth 주체, 회의 참가자가 Meet 미디어 API용 Google Workspace Developer Preview Program에 등록되어 있음을 확인한 뒤에만 `preview.enrollmentAcknowledged: true`를 설정하세요. ## 구성 -공통 Chrome 에이전트 경로에는 Plugin 활성화, BlackHole, SoX, 실시간 전사 제공자 키, 구성된 OpenClaw TTS 제공자만 필요합니다. OpenAI가 기본 전사 제공자입니다. 기본 에이전트 모드 전사 제공자를 변경하지 않고 `bidi` 모드에서 Google Gemini Live를 사용하려면 `realtime.voiceProvider`를 `"google"`로, `realtime.model`을 설정하세요. +공통 Chrome 에이전트 경로에는 Plugin 활성화, BlackHole, SoX, 실시간 전사 제공자 키, 구성된 OpenClaw TTS 제공자만 필요합니다. OpenAI가 기본 전사 제공자입니다. 기본 에이전트 모드 전사 제공자를 변경하지 않고 `bidi` 모드에서 Google Gemini Live를 사용하려면 `realtime.voiceProvider`를 `"google"`로 설정하고 `realtime.model`을 설정하세요. ```bash brew install blackhole-2ch sox @@ -905,7 +917,7 @@ export OPENAI_API_KEY=sk-... export GEMINI_API_KEY=... ``` -`plugins.entries.google-meet.config` 아래에 Plugin 구성을 설정하세요. +Plugin 구성을 `plugins.entries.google-meet.config` 아래에 설정하세요. ```json5 { @@ -923,31 +935,31 @@ export GEMINI_API_KEY=... 기본값: - `defaultTransport: "chrome"` -- `defaultMode: "agent"` (`"realtime"`은 `"agent"`의 레거시 호환성 별칭으로만 허용됩니다. 새 도구 호출은 `"agent"`라고 해야 합니다.) -- `chromeNode.node`: `chrome-node`의 선택적 노드 id/이름/IP +- `defaultMode: "agent"` (`"realtime"`은 `"agent"`의 레거시 호환 별칭으로만 허용됩니다. 새 도구 호출은 `"agent"`라고 해야 합니다.) +- `chromeNode.node`: `chrome-node`용 선택적 노드 ID/이름/IP - `chrome.audioBackend: "blackhole-2ch"` - `chrome.guestName: "OpenClaw Agent"`: 로그아웃된 Meet 게스트 화면에서 사용되는 이름 -- `chrome.autoJoin: true`: `chrome-node`에서 OpenClaw 브라우저 자동화를 통해 최선의 방식으로 게스트 이름을 채우고 Join Now를 클릭합니다. +- `chrome.autoJoin: true`: `chrome-node`에서 OpenClaw 브라우저 자동화를 통해 가능한 범위에서 게스트 이름을 채우고 지금 참가를 클릭합니다. - `chrome.reuseExistingTab: true`: 중복으로 열지 않고 기존 Meet 탭을 활성화합니다. -- `chrome.waitForInCallMs: 20000`: 되말하기 소개가 트리거되기 전에 Meet 탭이 통화 중이라고 보고할 때까지 기다립니다. +- `chrome.waitForInCallMs: 20000`: 대화형 인트로가 트리거되기 전에 Meet 탭이 통화 중이라고 보고할 때까지 기다립니다. - `chrome.audioFormat: "pcm16-24khz"`: 명령 쌍 오디오 형식입니다. 여전히 전화 통신 오디오를 내보내는 레거시/사용자 지정 명령 쌍에만 `"g711-ulaw-8khz"`를 사용하세요. -- `chrome.audioBufferBytes: 4096`: 생성된 Chrome 명령 쌍 오디오 명령용 SoX 처리 버퍼입니다. 이는 SoX 기본 8192바이트 버퍼의 절반으로, 사용량이 많은 호스트에서 늘릴 여지를 남기면서 기본 파이프 지연 시간을 줄입니다. SoX의 최소값보다 낮은 값은 17바이트로 고정됩니다. +- `chrome.audioBufferBytes: 4096`: 생성된 Chrome 명령 쌍 오디오 명령용 SoX 처리 버퍼입니다. 이는 SoX의 기본 8192바이트 버퍼의 절반으로, 사용량이 많은 호스트에서 값을 높일 여지를 남기면서 기본 파이프 지연 시간을 줄입니다. SoX 최소값보다 낮은 값은 17바이트로 제한됩니다. - `chrome.audioInputCommand`: CoreAudio `BlackHole 2ch`에서 읽고 `chrome.audioFormat`으로 오디오를 쓰는 SoX 명령 - `chrome.audioOutputCommand`: `chrome.audioFormat`으로 오디오를 읽고 CoreAudio `BlackHole 2ch`에 쓰는 SoX 명령 -- `chrome.bargeInInputCommand`: 어시스턴트 재생이 활성 상태인 동안 사람의 끼어들기 감지를 위해 부호 있는 16비트 리틀 엔디언 모노 PCM을 쓰는 선택적 로컬 마이크 명령입니다. 현재 이는 Gateway가 호스팅하는 `chrome` 명령 쌍 브리지에 적용됩니다. +- `chrome.bargeInInputCommand`: 어시스턴트 재생이 활성화된 동안 사람이 끼어드는 것을 감지하기 위해 부호 있는 16비트 리틀 엔디언 모노 PCM을 쓰는 선택적 로컬 마이크 명령입니다. 현재 이는 Gateway가 호스팅하는 `chrome` 명령 쌍 브리지에 적용됩니다. - `chrome.bargeInRmsThreshold: 650`: `chrome.bargeInInputCommand`에서 사람의 중단으로 간주되는 RMS 레벨 - `chrome.bargeInPeakThreshold: 2500`: `chrome.bargeInInputCommand`에서 사람의 중단으로 간주되는 피크 레벨 -- `chrome.bargeInCooldownMs: 900`: 반복되는 사람 중단 해제 사이의 최소 지연 시간 -- `mode: "agent"`: 기본 되말하기 모드입니다. 참가자 음성은 구성된 실시간 전사 제공자가 전사하고, 회의별 하위 에이전트 세션의 구성된 OpenClaw 에이전트로 전송되며, 일반 OpenClaw TTS 런타임을 통해 다시 음성으로 출력됩니다. -- `mode: "bidi"`: 폴백 직접 양방향 실시간 모델 모드입니다. 실시간 음성 제공자가 참가자 음성에 직접 응답하며, 더 깊거나 도구 기반인 답변을 위해 `openclaw_agent_consult`를 호출할 수 있습니다. -- `mode: "transcribe"`: 되말하기 브리지 없는 관찰 전용 모드입니다. +- `chrome.bargeInCooldownMs: 900`: 반복되는 사람의 중단 해제 사이의 최소 지연 시간 +- `mode: "agent"`: 기본 대화형 모드입니다. 참가자의 말은 구성된 실시간 전사 제공자가 전사하고, 회의별 하위 에이전트 세션의 구성된 OpenClaw 에이전트로 전송되며, 일반 OpenClaw TTS 런타임을 통해 음성으로 재생됩니다. +- `mode: "bidi"`: 폴백 직접 양방향 실시간 모델 모드입니다. 실시간 음성 제공자가 참가자 발화에 직접 응답하며, 더 깊은/도구 기반 답변을 위해 `openclaw_agent_consult`를 호출할 수 있습니다. +- `mode: "transcribe"`: 대화형 브리지 없는 관찰 전용 모드입니다. - `realtime.provider: "openai"`: 아래의 범위 지정 제공자 필드가 설정되지 않았을 때 사용되는 호환성 폴백입니다. -- `realtime.transcriptionProvider: "openai"`: `agent` 모드에서 실시간 전사에 사용하는 제공자 id입니다. -- `realtime.voiceProvider`: `bidi` 모드에서 직접 실시간 음성에 사용하는 제공자 id입니다. 에이전트 모드 전사는 OpenAI로 유지하면서 Gemini Live를 사용하려면 이를 `"google"`로 설정하세요. +- `realtime.transcriptionProvider: "openai"`: `agent` 모드에서 실시간 전사에 사용되는 제공자 ID입니다. +- `realtime.voiceProvider`: `bidi` 모드에서 직접 실시간 음성에 사용되는 제공자 ID입니다. 에이전트 모드 전사는 OpenAI로 유지하면서 Gemini Live를 사용하려면 이를 `"google"`로 설정하세요. - `realtime.toolPolicy: "safe-read-only"` -- `realtime.instructions`: 더 깊은 답변에는 `openclaw_agent_consult`를 사용하는 간단한 음성 답변 -- `realtime.introMessage`: 실시간 브리지가 연결될 때의 짧은 음성 준비 확인입니다. 조용히 참여하려면 이를 `""`로 설정하세요. -- `realtime.agentId`: `openclaw_agent_consult`용 선택적 OpenClaw 에이전트 id입니다. 기본값은 `main`입니다. +- `realtime.instructions`: 더 깊은 답변에는 `openclaw_agent_consult`를 사용하는 짧은 음성 응답 +- `realtime.introMessage`: 실시간 브리지가 연결될 때의 짧은 음성 준비 확인입니다. 조용히 참가하려면 `""`로 설정하세요. +- `realtime.agentId`: `openclaw_agent_consult`용 선택적 OpenClaw 에이전트 ID입니다. 기본값은 `main`입니다. 선택적 재정의: @@ -1002,7 +1014,7 @@ export GEMINI_API_KEY=... } ``` -에이전트 모드 청취와 말하기 모두에 ElevenLabs를 사용하는 구성: +에이전트 모드 듣기와 말하기 모두에 ElevenLabs 사용: ```json5 { @@ -1039,7 +1051,7 @@ export GEMINI_API_KEY=... } ``` -지속적인 Meet 음성은 `messages.tts.providers.elevenlabs.voiceId`에서 옵니다. TTS 모델 재정의가 활성화된 경우 에이전트 응답은 응답별 `[[tts:voiceId=... model=eleven_v3]]` 지시문도 사용할 수 있지만, 회의에서는 구성이 결정적인 기본값입니다. 참여 시 로그에는 `transcriptionProvider=elevenlabs`가 표시되어야 하며, 각 음성 응답은 `provider=elevenlabs model=eleven_v3 voice=`를 기록해야 합니다. +영구 Meet 음성은 `messages.tts.providers.elevenlabs.voiceId`에서 옵니다. TTS 모델 재정의가 활성화된 경우 에이전트 응답은 응답별 `[[tts:voiceId=... model=eleven_v3]]` 지시문도 사용할 수 있지만, 회의에서는 구성이 결정적 기본값입니다. 참가 시 로그에는 `transcriptionProvider=elevenlabs`가 표시되어야 하며, 각 음성 응답은 `provider=elevenlabs model=eleven_v3 voice=`를 기록해야 합니다. Twilio 전용 구성: @@ -1056,7 +1068,7 @@ Twilio 전용 구성: } ``` -`voiceCall.enabled`의 기본값은 `true`입니다. Twilio 전송에서는 실제 PSTN 통화, DTMF, 소개 인사를 Voice Call Plugin에 위임합니다. Voice Call은 실시간 미디어 스트림을 열기 전에 DTMF 시퀀스를 재생한 다음, 저장된 소개 텍스트를 초기 실시간 인사로 사용합니다. `voice-call`이 활성화되어 있지 않으면 Google Meet는 여전히 다이얼 플랜을 검증하고 기록할 수 있지만 Twilio 통화를 걸 수는 없습니다. +`voiceCall.enabled`의 기본값은 `true`입니다. Twilio 전송에서는 실제 PSTN 통화, DTMF, 인트로 인사를 Voice Call Plugin에 위임합니다. Voice Call은 실시간 미디어 스트림을 열기 전에 DTMF 시퀀스를 재생한 다음, 저장된 인트로 텍스트를 초기 실시간 인사말로 사용합니다. `voice-call`이 활성화되지 않은 경우에도 Google Meet은 다이얼 플랜을 검증하고 기록할 수 있지만 Twilio 통화를 걸 수는 없습니다. ## 도구 @@ -1071,20 +1083,20 @@ Twilio 전용 구성: } ``` -Chrome이 Gateway 호스트에서 실행될 때는 `transport: "chrome"`을 사용하세요. Chrome이 Parallels VM 같은 페어링된 노드에서 실행될 때는 `transport: "chrome-node"`를 사용하세요. 두 경우 모두 모델 제공자와 `openclaw_agent_consult`는 Gateway 호스트에서 실행되므로 모델 자격 증명은 그곳에 유지됩니다. 기본 `mode: "agent"`에서는 실시간 전사 제공자가 듣기를 처리하고, 구성된 OpenClaw 에이전트가 답변을 생성하며, 일반 OpenClaw TTS가 이를 Meet로 말합니다. 실시간 음성 모델이 직접 답변하게 하려면 `mode: "bidi"`를 사용하세요. 원시 `mode: "realtime"`은 `mode: "agent"`의 레거시 호환성 별칭으로 계속 허용되지만, 더 이상 에이전트 도구 스키마에 표시되지 않습니다. 에이전트 모드 로그에는 브리지 시작 시 해석된 전사 제공자/모델과 각 합성 응답 후의 TTS 제공자, 모델, 음성, 출력 형식, 샘플 속도가 포함됩니다. +Chrome이 Gateway 호스트에서 실행될 때는 `transport: "chrome"`을 사용하세요. Chrome이 Parallels VM 같은 페어링된 노드에서 실행될 때는 `transport: "chrome-node"`를 사용하세요. 두 경우 모두 모델 제공자와 `openclaw_agent_consult`는 Gateway 호스트에서 실행되므로 모델 자격 증명은 그곳에 유지됩니다. 기본 `mode: "agent"`에서는 실시간 전사 제공자가 듣기를 처리하고, 구성된 OpenClaw 에이전트가 답변을 생성하며, 일반 OpenClaw TTS가 이를 Meet에 말합니다. 실시간 음성 모델이 직접 응답하게 하려면 `mode: "bidi"`를 사용하세요. 원시 `mode: "realtime"`은 `mode: "agent"`의 레거시 호환 별칭으로 계속 허용되지만, 더 이상 에이전트 도구 스키마에는 표시되지 않습니다. 에이전트 모드 로그에는 브리지 시작 시 확인된 전사 제공자/모델과, 각 합성 응답 후 TTS 제공자, 모델, 음성, 출력 형식, 샘플 레이트가 포함됩니다. -활성 세션을 나열하거나 세션 ID를 검사하려면 `action: "status"`를 사용하세요. 실시간 에이전트가 즉시 말하게 하려면 `sessionId`와 `message`와 함께 `action: "speak"`를 사용하세요. 세션을 만들거나 재사용하고, 알려진 문구를 트리거하며, Chrome 호스트가 보고할 수 있을 때 `inCall` 상태를 반환하려면 `action: "test_speech"`를 사용하세요. `test_speech`는 항상 `mode: "agent"`를 강제하며, 관찰 전용 세션은 의도적으로 음성을 내보낼 수 없기 때문에 `mode: "transcribe"`로 실행하라는 요청을 받으면 실패합니다. 그 `speechOutputVerified` 결과는 이 테스트 호출 중 실시간 오디오 출력 바이트가 증가했는지를 기반으로 하므로, 이전 오디오가 있는 재사용된 세션은 새로 성공한 음성 확인으로 간주되지 않습니다. 세션을 종료됨으로 표시하려면 `action: "leave"`를 사용하세요. +활성 세션을 나열하거나 세션 ID를 검사하려면 `action: "status"`를 사용하세요. 실시간 에이전트가 즉시 말하게 하려면 `sessionId` 및 `message`와 함께 `action: "speak"`를 사용하세요. 세션을 생성하거나 재사용하고, 알려진 문구를 트리거하며, Chrome 호스트가 보고할 수 있을 때 `inCall` 상태를 반환하려면 `action: "test_speech"`를 사용하세요. `test_speech`는 항상 `mode: "agent"`를 강제하며, 관찰 전용 세션은 의도적으로 음성을 내보낼 수 없기 때문에 `mode: "transcribe"`로 실행하라는 요청을 받으면 실패합니다. 그 `speechOutputVerified` 결과는 이 테스트 호출 중 실시간 오디오 출력 바이트가 증가하는지를 기준으로 하므로, 이전 오디오가 있는 재사용 세션은 새로 성공한 음성 확인으로 간주되지 않습니다. 세션이 종료된 것으로 표시하려면 `action: "leave"`를 사용하세요. `status`에는 사용 가능한 경우 Chrome 상태가 포함됩니다. - `inCall`: Chrome이 Meet 통화 안에 있는 것으로 보입니다. -- `micMuted`: 최선의 방식으로 확인한 Meet 마이크 상태 +- `micMuted`: 가능한 범위에서 확인한 Meet 마이크 상태 - `manualActionRequired` / `manualActionReason` / `manualActionMessage`: 음성이 작동하기 전에 브라우저 프로필에 수동 로그인, Meet 호스트 승인, 권한 또는 브라우저 제어 복구가 필요합니다. -- `speechReady` / `speechBlockedReason` / `speechBlockedMessage`: 관리되는 Chrome 음성이 지금 허용되는지 여부입니다. `speechReady: false`는 OpenClaw가 소개/테스트 문구를 오디오 브리지로 보내지 않았음을 의미합니다. +- `speechReady` / `speechBlockedReason` / `speechBlockedMessage`: 관리되는 Chrome 음성이 현재 허용되는지 여부입니다. `speechReady: false`는 OpenClaw가 인트로/테스트 문구를 오디오 브리지로 보내지 않았음을 의미합니다. - `providerConnected` / `realtimeReady`: 실시간 음성 브리지 상태 - `lastInputAt` / `lastOutputAt`: 브리지에서 마지막으로 보거나 브리지로 보낸 오디오 - `audioOutputRouted` / `audioOutputDeviceLabel`: Meet 탭의 미디어 출력이 브리지에서 사용하는 BlackHole 장치로 능동적으로 라우팅되었는지 여부 -- `lastSuppressedInputAt` / `suppressedInputBytes`: 어시스턴트 재생이 활성 상태인 동안 무시된 loopback 입력 +- `lastSuppressedInputAt` / `suppressedInputBytes`: 어시스턴트 재생이 활성화된 동안 무시된 loopback 입력 ```json { @@ -1094,38 +1106,39 @@ Chrome이 Gateway 호스트에서 실행될 때는 `transport: "chrome"`을 사 } ``` -## 에이전트 및 Bidi 모드 +## 에이전트 및 bidi 모드 -Chrome `agent` 모드는 "내 에이전트가 회의에 들어와 있는" 동작에 최적화되어 있습니다. 실시간 전사 제공자가 회의 오디오를 듣고, 최종 참가자 전사는 구성된 OpenClaw 에이전트로 라우팅되며, 답변은 일반 OpenClaw TTS 런타임을 통해 음성으로 출력됩니다. 실시간 음성 모델이 직접 답변하게 하려면 `mode: "bidi"`를 설정하세요. 가까운 최종 전사 조각들은 consult 전에 병합되어 한 번의 발화 턴이 여러 개의 오래된 부분 답변을 만들지 않도록 합니다. 대기 중인 어시스턴트 오디오가 아직 재생되는 동안에는 실시간 입력도 억제되며, 에이전트 consult 전에 최근의 어시스턴트와 유사한 전사 에코가 무시되어 BlackHole loopback 때문에 에이전트가 자기 자신의 말에 답하지 않도록 합니다. +Chrome `agent` 모드는 “내 에이전트가 회의에 들어와 있는” 동작에 최적화되어 있습니다. 실시간 전사 제공자가 회의 오디오를 듣고, 최종 참가자 전사는 구성된 OpenClaw 에이전트로 라우팅되며, 답변은 일반 OpenClaw TTS 런타임을 통해 음성으로 재생됩니다. 실시간 음성 모델이 직접 응답하게 하려면 `mode: "bidi"`를 설정하세요. +가까운 최종 전사 조각은 consult 전에 병합되어, 하나의 발화 턴이 오래된 부분 답변 여러 개를 만들지 않도록 합니다. 대기 중인 어시스턴트 오디오가 아직 재생되는 동안에는 실시간 입력도 억제되며, 최근 어시스턴트와 유사한 전사 에코는 에이전트 consult 전에 무시되어 BlackHole loopback으로 인해 에이전트가 자신의 발화에 응답하지 않도록 합니다. -| 모드 | 누가 답변을 결정하는가 | 음성 출력 경로 | 사용 시점 | +| 모드 | 답변 결정 주체 | 음성 출력 경로 | 사용 시점 | | ------- | ----------------------------- | -------------------------------------- | ----------------------------------------------------- | -| `agent` | 구성된 OpenClaw 에이전트 | 일반 OpenClaw TTS 런타임 | "내 에이전트가 회의에 들어와 있는" 동작을 원할 때 | -| `bidi` | 실시간 음성 모델 | 실시간 음성 제공자 오디오 응답 | 가장 낮은 지연 시간의 대화형 음성 루프를 원할 때 | +| `agent` | 구성된 OpenClaw 에이전트 | 일반 OpenClaw TTS 런타임 | “내 에이전트가 회의에 들어와 있는” 동작을 원할 때 | +| `bidi` | 실시간 음성 모델 | 실시간 음성 제공자 오디오 응답 | 가장 낮은 지연 시간의 대화형 음성 루프를 원할 때 | `bidi` 모드에서 실시간 모델에 더 깊은 추론, 최신 정보 또는 일반 OpenClaw 도구가 필요하면 `openclaw_agent_consult`를 호출할 수 있습니다. -consult 도구는 최근 회의 트랜스크립트 컨텍스트와 함께 일반 OpenClaw 에이전트를 백그라운드에서 실행하고 간결한 음성 답변을 반환합니다. `agent` 모드에서는 OpenClaw가 해당 답변을 TTS 런타임으로 직접 전송하고, `bidi` 모드에서는 실시간 음성 모델이 consult 결과를 회의에 다시 말할 수 있습니다. Voice Call과 동일한 공유 consult 메커니즘을 사용합니다. +상담 도구는 최근 회의 transcript 컨텍스트와 함께 일반 OpenClaw agent를 내부에서 실행하고 간결한 음성 답변을 반환합니다. `agent` 모드에서는 OpenClaw가 해당 답변을 TTS 런타임으로 직접 보내며, `bidi` 모드에서는 realtime 음성 모델이 상담 결과를 회의로 다시 말할 수 있습니다. 이는 Voice Call과 동일한 공유 상담 메커니즘을 사용합니다. -기본적으로 consult는 `main` 에이전트를 대상으로 실행됩니다. Meet 레인이 전용 OpenClaw 에이전트 워크스페이스, 모델 기본값, 도구 정책, 메모리, 세션 기록을 consult해야 할 때는 `realtime.agentId`를 설정하세요. +기본적으로 상담은 `main` agent를 대상으로 실행됩니다. Meet 레인이 전용 OpenClaw agent 작업 영역, 모델 기본값, 도구 정책, memory, session history를 상담해야 하는 경우 `realtime.agentId`를 설정하세요. -에이전트 모드 consult는 회의별 `agent::subagent:google-meet:` 세션 키를 사용하므로, 후속 질문은 구성된 에이전트의 일반 에이전트 정책을 상속하면서 회의 컨텍스트를 유지합니다. +agent 모드 상담은 회의별 `agent::subagent:google-meet:` session key를 사용하므로 후속 질문은 구성된 agent의 일반 agent 정책을 상속하면서 회의 컨텍스트를 유지합니다. -`realtime.toolPolicy`는 consult 실행을 제어합니다. +`realtime.toolPolicy`는 상담 실행을 제어합니다. -- `safe-read-only`: consult 도구를 노출하고 일반 에이전트를 `read`, `web_search`, `web_fetch`, `x_search`, `memory_search`, `memory_get`으로 제한합니다. -- `owner`: consult 도구를 노출하고 일반 에이전트가 일반 에이전트 도구 정책을 사용하도록 합니다. -- `none`: 실시간 음성 모델에 consult 도구를 노출하지 않습니다. +- `safe-read-only`: 상담 도구를 노출하고 일반 agent를 `read`, `web_search`, `web_fetch`, `x_search`, `memory_search`, `memory_get`으로 제한합니다. +- `owner`: 상담 도구를 노출하고 일반 agent가 일반 agent 도구 정책을 사용하도록 허용합니다. +- `none`: realtime 음성 모델에 상담 도구를 노출하지 않습니다. -consult 세션 키는 Meet 세션별로 범위가 지정되므로, 후속 consult 호출은 같은 회의 중 이전 consult 컨텍스트를 재사용할 수 있습니다. +상담 session key는 Meet session별로 범위가 지정되므로, 후속 상담 호출은 같은 회의 중 이전 상담 컨텍스트를 재사용할 수 있습니다. -Chrome이 통화에 완전히 참가한 뒤 음성 준비 확인을 강제로 실행하려면: +Chrome이 통화에 완전히 참여한 뒤 음성 준비 확인을 강제로 실행하려면: ```bash openclaw googlemeet speak meet_... "Say exactly: I'm here and listening." ``` -전체 참가 및 발화 smoke는 다음과 같습니다. +전체 참여 및 발화 smoke를 실행하려면: ```bash openclaw googlemeet test-speech https://meet.google.com/abc-defg-hij \ @@ -1135,7 +1148,7 @@ openclaw googlemeet test-speech https://meet.google.com/abc-defg-hij \ ## 라이브 테스트 체크리스트 -무인 에이전트에 회의를 넘기기 전에 이 순서를 사용하세요. +무인 agent에 회의를 넘기기 전에 이 순서를 사용하세요. ```bash openclaw googlemeet setup @@ -1148,12 +1161,12 @@ openclaw googlemeet test-speech https://meet.google.com/abc-defg-hij \ 예상 Chrome-node 상태: - `googlemeet setup`이 모두 녹색입니다. -- Chrome-node가 기본 전송이거나 노드가 고정된 경우 `googlemeet setup`에 `chrome-node-connected`가 포함됩니다. -- `nodes status`에 선택된 노드가 연결된 것으로 표시됩니다. -- 선택된 노드가 `googlemeet.chrome`와 `browser.proxy`를 모두 광고합니다. -- Meet 탭이 통화에 참가하고 `test-speech`가 `inCall: true`와 함께 Chrome 상태를 반환합니다. +- Chrome-node가 기본 transport이거나 Node가 고정된 경우 `googlemeet setup`에 `chrome-node-connected`가 포함됩니다. +- `nodes status`에 선택한 Node가 연결된 것으로 표시됩니다. +- 선택한 Node가 `googlemeet.chrome`과 `browser.proxy`를 모두 알립니다. +- Meet 탭이 통화에 참여하고 `test-speech`가 `inCall: true`인 Chrome health를 반환합니다. -Parallels macOS VM 같은 원격 Chrome 호스트의 경우, Gateway 또는 VM을 업데이트한 뒤 가장 짧고 안전한 확인은 다음과 같습니다. +Parallels macOS VM 같은 원격 Chrome host의 경우, Gateway 또는 VM을 업데이트한 뒤 가장 짧고 안전한 확인 절차는 다음과 같습니다. ```bash openclaw googlemeet setup @@ -1164,9 +1177,9 @@ openclaw nodes invoke \ --params '{"action":"setup"}' ``` -이로써 에이전트가 실제 회의 탭을 열기 전에 Gateway Plugin이 로드되었고, VM 노드가 현재 토큰으로 연결되었으며, Meet 오디오 브리지가 사용 가능함을 증명합니다. +이는 agent가 실제 회의 탭을 열기 전에 Gateway Plugin이 로드되었고, VM Node가 현재 token으로 연결되었으며, Meet audio bridge를 사용할 수 있음을 증명합니다. -Twilio smoke의 경우 전화 접속 세부 정보를 노출하는 회의를 사용하세요. +Twilio smoke의 경우 전화 dial-in 세부 정보를 노출하는 회의를 사용하세요. ```bash openclaw googlemeet setup @@ -1179,29 +1192,29 @@ openclaw googlemeet join https://meet.google.com/abc-defg-hij \ 예상 Twilio 상태: - `googlemeet setup`에 녹색 `twilio-voice-call-plugin`, `twilio-voice-call-credentials`, `twilio-voice-call-webhook` 확인이 포함됩니다. -- Gateway를 다시 로드한 뒤 CLI에서 `voicecall`을 사용할 수 있습니다. -- 반환된 세션에 `transport: "twilio"`와 `twilio.voiceCallId`가 있습니다. -- `openclaw logs --follow`에 실시간 TwiML 전에 DTMF TwiML이 제공되고, 이후 초기 인사말이 대기열에 들어간 실시간 브리지가 표시됩니다. -- `googlemeet leave `가 위임된 음성 통화를 끊습니다. +- Gateway reload 후 CLI에서 `voicecall`을 사용할 수 있습니다. +- 반환된 session에 `transport: "twilio"`와 `twilio.voiceCallId`가 있습니다. +- `openclaw logs --follow`에 realtime TwiML 전에 DTMF TwiML이 제공되고, 이후 초기 인사말이 대기열에 들어간 realtime bridge가 표시됩니다. +- `googlemeet leave `가 위임된 음성 통화를 종료합니다. ## 문제 해결 -### 에이전트가 Google Meet 도구를 볼 수 없음 +### agent가 Google Meet 도구를 볼 수 없음 -Gateway 구성에서 Plugin이 활성화되어 있는지 확인하고 Gateway를 다시 로드하세요. +Gateway config에서 Plugin이 활성화되어 있는지 확인하고 Gateway를 reload하세요. ```bash openclaw plugins list | grep google-meet openclaw googlemeet setup ``` -방금 `plugins.entries.google-meet`를 편집했다면 Gateway를 재시작하거나 다시 로드하세요. 실행 중인 에이전트는 현재 Gateway 프로세스가 등록한 Plugin 도구만 볼 수 있습니다. +방금 `plugins.entries.google-meet`를 편집했다면 Gateway를 restart하거나 reload하세요. 실행 중인 agent는 현재 Gateway process가 등록한 Plugin 도구만 볼 수 있습니다. -macOS가 아닌 Gateway 호스트에서는 에이전트용 `google_meet` 도구가 계속 표시되지만, 로컬 Chrome talk-back 작업은 오디오 브리지에 도달하기 전에 차단됩니다. 로컬 Chrome talk-back 오디오는 현재 macOS `BlackHole 2ch`에 의존하므로, Linux 에이전트는 기본 로컬 Chrome 에이전트 경로 대신 `mode: "transcribe"`, Twilio 전화 접속 또는 macOS `chrome-node` 호스트를 사용해야 합니다. +macOS가 아닌 Gateway host에서는 agent-facing `google_meet` 도구가 계속 표시되지만, 로컬 Chrome talk-back 작업은 audio bridge에 도달하기 전에 차단됩니다. 로컬 Chrome talk-back audio는 현재 macOS `BlackHole 2ch`에 의존하므로, Linux agent는 기본 로컬 Chrome agent 경로 대신 `mode: "transcribe"`, Twilio dial-in 또는 macOS `chrome-node` host를 사용해야 합니다. -### 연결된 Google Meet 지원 노드 없음 +### 연결된 Google Meet 지원 Node가 없음 -노드 호스트에서 실행하세요. +Node host에서 실행하세요. ```bash openclaw plugins enable google-meet @@ -1210,7 +1223,7 @@ OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 \ openclaw node run --host --port 18789 --display-name parallels-macos ``` -Gateway 호스트에서 노드를 승인하고 명령을 확인하세요. +Gateway host에서 Node를 승인하고 commands를 확인하세요. ```bash openclaw devices list @@ -1218,7 +1231,7 @@ openclaw devices approve openclaw nodes status ``` -노드는 연결되어 있어야 하며 `googlemeet.chrome`와 `browser.proxy`를 나열해야 합니다. Gateway 구성은 해당 노드 명령을 허용해야 합니다. +Node가 연결되어 있어야 하며 `googlemeet.chrome`과 `browser.proxy`를 나열해야 합니다. Gateway config는 해당 Node commands를 허용해야 합니다. ```json5 { @@ -1230,7 +1243,7 @@ openclaw nodes status } ``` -`googlemeet setup`이 `chrome-node-connected`에서 실패하거나 Gateway 로그가 `gateway token mismatch`를 보고하면, 현재 Gateway 토큰으로 노드를 다시 설치하거나 재시작하세요. LAN Gateway의 경우 일반적으로 다음을 의미합니다. +`googlemeet setup`이 `chrome-node-connected`에 실패하거나 Gateway log가 `gateway token mismatch`를 보고하면 현재 Gateway token으로 Node를 다시 설치하거나 restart하세요. LAN Gateway의 경우 일반적으로 다음을 의미합니다. ```bash OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 \ @@ -1241,74 +1254,74 @@ OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1 \ --force ``` -그런 다음 노드 서비스를 다시 로드하고 다시 실행하세요. +그런 다음 Node service를 reload하고 다시 실행하세요. ```bash openclaw googlemeet setup openclaw nodes status --connected ``` -### 브라우저는 열리지만 에이전트가 참가할 수 없음 +### 브라우저는 열리지만 agent가 참여할 수 없음 -관찰 전용 참가의 경우 `googlemeet test-listen`을 실행하거나 실시간 참가의 경우 `googlemeet test-speech`를 실행한 다음 반환된 Chrome 상태를 검사하세요. 두 프로브 중 하나가 `manualActionRequired: true`를 보고하면 운영자에게 `manualActionMessage`를 보여주고 브라우저 작업이 완료될 때까지 재시도를 중단하세요. +관찰 전용 참여에는 `googlemeet test-listen`을, realtime 참여에는 `googlemeet test-speech`를 실행한 다음 반환된 Chrome health를 검사하세요. 두 probe 중 하나라도 `manualActionRequired: true`를 보고하면 operator에게 `manualActionMessage`를 보여주고 브라우저 작업이 완료될 때까지 재시도를 중단하세요. 일반적인 수동 작업: -- Chrome 프로필에 로그인합니다. -- Meet 호스트 계정에서 게스트를 승인합니다. -- Chrome의 기본 권한 프롬프트가 나타나면 Chrome 마이크/카메라 권한을 부여합니다. -- 멈춘 Meet 권한 대화 상자를 닫거나 복구합니다. +- Chrome profile에 로그인합니다. +- Meet host 계정에서 guest를 입장시킵니다. +- Chrome의 native permission prompt가 나타나면 Chrome microphone/camera 권한을 부여합니다. +- 멈춘 Meet permission dialog를 닫거나 복구합니다. -Meet에 "Do you want people to hear you in the meeting?"가 표시된다는 이유만으로 "not signed in"이라고 보고하지 마세요. 이는 Meet의 오디오 선택 중간 화면입니다. OpenClaw는 사용할 수 있을 때 브라우저 자동화를 통해 **Use microphone**을 클릭하고 실제 회의 상태를 계속 기다립니다. 생성 전용 브라우저 fallback의 경우 URL 생성에는 실시간 오디오 경로가 필요 없으므로 OpenClaw가 **Continue without microphone**을 클릭할 수 있습니다. +Meet에 "Do you want people to hear you in the meeting?"가 표시된다는 이유만으로 "not signed in"이라고 보고하지 마세요. 이는 Meet의 audio-choice interstitial입니다. OpenClaw는 가능할 때 browser automation으로 **Use microphone**을 클릭하고 실제 회의 상태를 계속 기다립니다. 생성 전용 browser fallback의 경우 URL 생성에는 realtime audio path가 필요하지 않으므로 OpenClaw가 **Continue without microphone**을 클릭할 수 있습니다. ### 회의 생성 실패 -`googlemeet create`는 OAuth 자격 증명이 구성되어 있을 때 먼저 Google Meet API `spaces.create` 엔드포인트를 사용합니다. OAuth 자격 증명이 없으면 고정된 Chrome 노드 브라우저로 fallback합니다. 확인하세요. +`googlemeet create`는 OAuth credentials가 구성된 경우 먼저 Google Meet API `spaces.create` endpoint를 사용합니다. OAuth credentials가 없으면 고정된 Chrome Node browser로 fallback합니다. 확인하세요. -- API 생성: `oauth.clientId`와 `oauth.refreshToken`이 구성되어 있거나, 일치하는 `OPENCLAW_GOOGLE_MEET_*` 환경 변수가 있어야 합니다. -- API 생성: 새로 만들기 지원이 추가된 뒤 refresh token이 발급되었어야 합니다. 오래된 토큰에는 `meetings.space.created` scope가 없을 수 있습니다. `openclaw googlemeet auth login --json`을 다시 실행하고 Plugin 구성을 업데이트하세요. -- 브라우저 fallback: `defaultTransport: "chrome-node"`와 `chromeNode.node`가 `browser.proxy` 및 `googlemeet.chrome`가 있는 연결된 노드를 가리켜야 합니다. -- 브라우저 fallback: 해당 노드의 OpenClaw Chrome 프로필이 Google에 로그인되어 있고 `https://meet.google.com/new`를 열 수 있어야 합니다. -- 브라우저 fallback: 재시도는 새 탭을 열기 전에 기존 `https://meet.google.com/new` 또는 Google 계정 프롬프트 탭을 재사용합니다. 에이전트가 시간 초과되면 다른 Meet 탭을 수동으로 열지 말고 도구 호출을 재시도하세요. -- 브라우저 fallback: 도구가 `manualActionRequired: true`를 반환하면 반환된 `browser.nodeId`, `browser.targetId`, `browserUrl`, `manualActionMessage`를 사용해 운영자를 안내하세요. 해당 작업이 완료될 때까지 루프에서 재시도하지 마세요. -- 브라우저 fallback: Meet에 "Do you want people to hear you in the meeting?"가 표시되면 탭을 열어 둡니다. OpenClaw는 브라우저 자동화를 통해 **Use microphone** 또는 생성 전용 fallback의 경우 **Continue without microphone**을 클릭하고 생성된 Meet URL을 계속 기다려야 합니다. 그럴 수 없다면 오류는 `google-login-required`가 아니라 `meet-audio-choice-required`를 언급해야 합니다. +- API 생성: `oauth.clientId`와 `oauth.refreshToken`이 구성되어 있거나, 일치하는 `OPENCLAW_GOOGLE_MEET_*` environment variables가 있어야 합니다. +- API 생성: refresh token은 create support가 추가된 후 발급되어야 합니다. 오래된 token에는 `meetings.space.created` scope가 없을 수 있습니다. `openclaw googlemeet auth login --json`을 다시 실행하고 Plugin config를 업데이트하세요. +- browser fallback: `defaultTransport: "chrome-node"`와 `chromeNode.node`가 `browser.proxy` 및 `googlemeet.chrome`이 있는 연결된 Node를 가리켜야 합니다. +- browser fallback: 해당 Node의 OpenClaw Chrome profile이 Google에 로그인되어 있고 `https://meet.google.com/new`를 열 수 있어야 합니다. +- browser fallback: 재시도는 새 탭을 열기 전에 기존 `https://meet.google.com/new` 또는 Google account prompt 탭을 재사용합니다. agent가 timeout되면 다른 Meet 탭을 수동으로 열지 말고 tool call을 재시도하세요. +- browser fallback: 도구가 `manualActionRequired: true`를 반환하면 반환된 `browser.nodeId`, `browser.targetId`, `browserUrl`, `manualActionMessage`를 사용해 operator를 안내하세요. 해당 작업이 완료될 때까지 loop로 재시도하지 마세요. +- browser fallback: Meet에 "Do you want people to hear you in the meeting?"가 표시되면 탭을 열린 상태로 두세요. OpenClaw는 browser automation을 통해 **Use microphone**을 클릭하거나, create-only fallback의 경우 **Continue without microphone**을 클릭하고 생성된 Meet URL을 계속 기다려야 합니다. 그럴 수 없다면 error는 `google-login-required`가 아니라 `meet-audio-choice-required`를 언급해야 합니다. -### 에이전트가 참가하지만 말하지 않음 +### agent가 참여하지만 말하지 않음 -실시간 경로를 확인하세요. +realtime path를 확인하세요. ```bash openclaw googlemeet setup openclaw googlemeet doctor ``` -일반 STT -> OpenClaw 에이전트 -> TTS talk-back 경로에는 `mode: "agent"`를 사용하고, 직접 실시간 음성 fallback에는 `mode: "bidi"`를 사용하세요. `mode: "transcribe"`는 의도적으로 talk-back 브리지를 시작하지 않습니다. 관찰 전용 디버깅의 경우 참가자가 말한 뒤 `openclaw googlemeet status --json `를 실행하고 `captioning`, `transcriptLines`, `lastCaptionText`를 확인하세요. `inCall`이 true인데 `transcriptLines`가 `0`에 머무르면 Meet 자막이 비활성화되어 있거나, 관찰자가 설치된 뒤 아무도 말하지 않았거나, Meet UI가 변경되었거나, 해당 회의 언어/계정에서 실시간 자막을 사용할 수 없을 수 있습니다. +일반 STT -> OpenClaw agent -> TTS talk-back path에는 `mode: "agent"`를 사용하고, direct realtime voice fallback에는 `mode: "bidi"`를 사용하세요. `mode: "transcribe"`는 의도적으로 talk-back bridge를 시작하지 않습니다. 관찰 전용 debugging의 경우 participants가 말한 뒤 `openclaw googlemeet status --json `를 실행하고 `captioning`, `transcriptLines`, `lastCaptionText`를 확인하세요. `inCall`은 true이지만 `transcriptLines`가 `0`에 머문다면 Meet captions가 비활성화되었거나, observer가 설치된 뒤 아무도 말하지 않았거나, Meet UI가 변경되었거나, 회의 언어/계정에서 live captions를 사용할 수 없을 수 있습니다. -`googlemeet test-speech`는 항상 실시간 경로를 확인하고 해당 호출에서 브리지 출력 바이트가 관찰되었는지 보고합니다. `speechOutputVerified`가 false이고 `speechOutputTimedOut`이 true이면 실시간 제공자가 발화를 수락했을 수 있지만 OpenClaw가 Chrome 오디오 브리지에 도달하는 새 출력 바이트를 보지 못한 것입니다. +`googlemeet test-speech`는 항상 realtime path를 확인하고 해당 invocation에서 bridge output bytes가 관찰되었는지 보고합니다. `speechOutputVerified`가 false이고 `speechOutputTimedOut`이 true이면 realtime provider가 utterance를 수락했을 수 있지만 OpenClaw가 새 output bytes가 Chrome audio bridge에 도달하는 것을 보지 못한 것입니다. -다음도 확인하세요. +또한 확인하세요. -- Gateway 호스트에서 `OPENAI_API_KEY` 또는 `GEMINI_API_KEY` 같은 실시간 제공자 키를 사용할 수 있습니다. -- Chrome 호스트에 `BlackHole 2ch`가 표시됩니다. -- Chrome 호스트에 `sox`가 있습니다. -- Meet 마이크와 스피커가 OpenClaw가 사용하는 가상 오디오 경로를 통해 라우팅됩니다. 로컬 Chrome 실시간 참가의 경우 `doctor`에 `meet output routed: yes`가 표시되어야 합니다. +- Gateway host에서 `OPENAI_API_KEY` 또는 `GEMINI_API_KEY` 같은 realtime provider key를 사용할 수 있습니다. +- Chrome host에서 `BlackHole 2ch`가 보입니다. +- Chrome host에 `sox`가 있습니다. +- Meet microphone 및 speaker가 OpenClaw에서 사용하는 virtual audio path를 통해 routed됩니다. 로컬 Chrome realtime joins의 경우 `doctor`에 `meet output routed: yes`가 표시되어야 합니다. -`googlemeet doctor [session-id]`는 세션, 노드, 통화 중 상태, 수동 작업 사유, 실시간 제공자 연결, `realtimeReady`, 오디오 입력/출력 활동, 마지막 오디오 타임스탬프, 바이트 카운터, 브라우저 URL을 출력합니다. 원시 JSON이 필요할 때는 `googlemeet status [session-id] --json`을 사용하세요. 토큰을 노출하지 않고 Google Meet OAuth refresh를 확인해야 할 때는 `googlemeet doctor --oauth`를 사용하고, Google Meet API 증명도 필요하면 `--meeting` 또는 `--create-space`를 추가하세요. +`googlemeet doctor [session-id]`는 session, Node, in-call state, manual action reason, realtime provider connection, `realtimeReady`, audio input/output activity, last audio timestamps, byte counters, browser URL을 출력합니다. raw JSON이 필요하면 `googlemeet status [session-id] --json`을 사용하세요. token을 노출하지 않고 Google Meet OAuth refresh를 검증해야 하면 `googlemeet doctor --oauth`를 사용하세요. Google Meet API proof도 필요하면 `--meeting` 또는 `--create-space`를 추가하세요. -에이전트가 시간 초과되었고 Meet 탭이 이미 열려 있는 것이 보이면, 다른 탭을 열지 말고 해당 탭을 검사하세요. +agent가 timeout되었고 Meet 탭이 이미 열려 있는 것이 보이면, 다른 탭을 열지 말고 해당 탭을 검사하세요. ```bash openclaw googlemeet recover-tab openclaw googlemeet recover-tab https://meet.google.com/abc-defg-hij ``` -동등한 도구 작업은 `recover_current_tab`입니다. 선택된 전송의 기존 Meet 탭에 포커스를 맞추고 검사합니다. `chrome`에서는 Gateway를 통한 로컬 브라우저 제어를 사용하고, `chrome-node`에서는 구성된 Chrome 노드를 사용합니다. 새 탭을 열거나 새 세션을 만들지 않습니다. 로그인, 승인, 권한 또는 오디오 선택 상태 같은 현재 차단 요인을 보고합니다. CLI 명령은 구성된 Gateway와 통신하므로 Gateway가 실행 중이어야 합니다. `chrome-node`도 Chrome 노드가 연결되어 있어야 합니다. +동등한 tool action은 `recover_current_tab`입니다. 선택한 transport에 대해 기존 Meet 탭에 focus하고 검사합니다. `chrome`에서는 Gateway를 통한 로컬 browser control을 사용하고, `chrome-node`에서는 구성된 Chrome Node를 사용합니다. 새 탭을 열거나 새 session을 만들지 않으며, login, admission, permissions 또는 audio-choice state 같은 현재 blocker를 보고합니다. CLI command는 구성된 Gateway와 통신하므로 Gateway가 실행 중이어야 합니다. `chrome-node`에는 Chrome Node 연결도 필요합니다. -### Twilio 설정 확인 실패 +### Twilio setup checks 실패 -`twilio-voice-call-plugin`은 `voice-call`이 허용되지 않았거나 활성화되지 않았을 때 실패합니다. 이를 `plugins.allow`에 추가하고 `plugins.entries.voice-call`을 활성화한 뒤 Gateway를 다시 로드하세요. +`voice-call`이 허용되지 않았거나 활성화되지 않은 경우 `twilio-voice-call-plugin`이 실패합니다. 이를 `plugins.allow`에 추가하고 `plugins.entries.voice-call`을 활성화한 뒤 Gateway를 reload하세요. -`twilio-voice-call-credentials`는 Twilio 백엔드에 계정 SID, 인증 토큰 또는 발신자 번호가 없을 때 실패합니다. Gateway 호스트에서 이를 설정하세요. +Twilio backend에 account SID, auth token 또는 caller number가 없으면 `twilio-voice-call-credentials`가 실패합니다. Gateway host에서 다음을 설정하세요. ```bash export TWILIO_ACCOUNT_SID=AC... @@ -1316,11 +1329,11 @@ export TWILIO_AUTH_TOKEN=... export TWILIO_FROM_NUMBER=+15550001234 ``` -`twilio-voice-call-webhook`은 `voice-call`에 공개 Webhook 노출이 없거나 `publicUrl`이 local loopback 또는 사설 네트워크 공간을 가리킬 때 실패합니다. `plugins.entries.voice-call.config.publicUrl`을 공개 제공자 URL로 설정하거나 `voice-call` 터널/Tailscale 노출을 구성하세요. +`voice-call`에 public webhook exposure가 없거나 `publicUrl`이 loopback 또는 private network space를 가리키면 `twilio-voice-call-webhook`이 실패합니다. `plugins.entries.voice-call.config.publicUrl`을 public provider URL로 설정하거나 `voice-call` tunnel/Tailscale exposure를 구성하세요. -Loopback 및 사설 URL은 통신사 콜백에 유효하지 않습니다. `publicUrl`로 `localhost`, `127.0.0.1`, `0.0.0.0`, `10.x`, `172.16.x`-`172.31.x`, `192.168.x`, `169.254.x`, `fc00::/7`, `fd00::/8`를 사용하지 마세요. +Loopback 및 private URLs는 carrier callbacks에 유효하지 않습니다. `publicUrl`로 `localhost`, `127.0.0.1`, `0.0.0.0`, `10.x`, `172.16.x`-`172.31.x`, `192.168.x`, `169.254.x`, `fc00::/7`, 또는 `fd00::/8`을 사용하지 마세요. -안정적인 공개 URL의 경우: +안정적인 public URL의 경우: ```json5 { @@ -1339,7 +1352,7 @@ Loopback 및 사설 URL은 통신사 콜백에 유효하지 않습니다. `publi } ``` -로컬 개발에서는 비공개 호스트 URL 대신 터널이나 Tailscale 노출을 사용하세요. +로컬 개발에서는 비공개 호스트 URL 대신 터널 또는 Tailscale 노출을 사용하세요. ```json5 { @@ -1357,7 +1370,7 @@ Loopback 및 사설 URL은 통신사 콜백에 유효하지 않습니다. `publi } ``` -그런 다음 Gateway를 재시작하거나 다시 로드하고 다음을 실행하세요. +그런 다음 Gateway를 다시 시작하거나 다시 로드하고 다음을 실행하세요. ```bash openclaw googlemeet setup --transport twilio @@ -1365,13 +1378,13 @@ openclaw voicecall setup openclaw voicecall smoke ``` -`voicecall smoke`는 기본적으로 준비 상태 확인 전용입니다. 특정 번호로 드라이런하려면: +`voicecall smoke`는 기본적으로 준비 상태만 확인합니다. 특정 번호로 모의 실행하려면 다음을 사용하세요. ```bash openclaw voicecall smoke --to "+15555550123" ``` -실제 아웃바운드 알림 전화를 의도적으로 걸고 싶을 때만 `--yes`를 추가하세요. +실제 발신 알림 통화를 의도적으로 걸려는 경우에만 `--yes`를 추가하세요. ```bash openclaw voicecall smoke --to "+15555550123" --yes @@ -1379,7 +1392,7 @@ openclaw voicecall smoke --to "+15555550123" --yes ### Twilio 통화가 시작되지만 회의에 들어가지 않음 -Meet 이벤트가 전화 접속 세부 정보를 노출하는지 확인하세요. 정확한 전화 접속 번호와 PIN 또는 사용자 지정 DTMF 시퀀스를 전달하세요. +Meet 이벤트가 전화 다이얼인 세부 정보를 노출하는지 확인하세요. 정확한 다이얼인 번호와 PIN 또는 사용자 지정 DTMF 시퀀스를 전달하세요. ```bash openclaw googlemeet join https://meet.google.com/abc-defg-hij \ @@ -1388,41 +1401,40 @@ openclaw googlemeet join https://meet.google.com/abc-defg-hij \ --dtmf-sequence ww123456# ``` -제공자가 PIN을 입력하기 전에 일시 중지가 필요하다면 `--dtmf-sequence`에서 앞쪽에 `w` 또는 쉼표를 사용하세요. +제공자가 PIN을 입력하기 전에 일시 중지가 필요하면 `--dtmf-sequence`에서 앞에 `w` 또는 쉼표를 사용하세요. -전화 통화는 생성되었지만 Meet 명단에 전화 접속 참가자가 표시되지 않는 경우: +전화 통화가 생성되었지만 Meet 명단에 다이얼인 참가자가 표시되지 않는 경우: -- 위임된 Twilio 통화 ID, DTMF가 대기열에 추가되었는지 여부, 인트로 인사말이 요청되었는지 여부를 확인하려면 `openclaw googlemeet doctor `를 실행하세요. +- `openclaw googlemeet doctor `를 실행하여 위임된 Twilio 통화 ID, DTMF가 대기열에 추가되었는지 여부, 소개 인사말이 요청되었는지 여부를 확인하세요. - `openclaw voicecall status --call-id `를 실행하고 통화가 아직 활성 상태인지 확인하세요. - `openclaw voicecall tail`을 실행하고 Twilio Webhook이 Gateway에 도착하는지 확인하세요. -- `openclaw logs --follow`를 실행하고 Twilio Meet 시퀀스를 찾으세요. Google Meet가 참가를 위임하고, Voice Call이 사전 연결 DTMF TwiML을 저장하고 제공하며, Voice Call이 Twilio 통화용 실시간 TwiML을 제공한 다음, Google Meet가 `voicecall.speak`로 인트로 음성을 요청합니다. -- `openclaw googlemeet setup --transport twilio`를 다시 실행하세요. 초록색 설정 확인은 필요하지만 회의 PIN 시퀀스가 올바르다는 것을 증명하지는 않습니다. -- 전화 접속 번호가 PIN과 동일한 Meet 초대 및 지역에 속하는지 확인하세요. -- Meet가 느리게 응답하거나 사전 연결 DTMF가 전송된 뒤에도 통화 기록에 PIN을 요청하는 프롬프트가 계속 표시되면 `voiceCall.dtmfDelayMs`를 기본값 12초에서 늘리세요. -- 참가자가 들어왔지만 인사말이 들리지 않는다면 `openclaw logs --follow`에서 DTMF 이후 `voicecall.speak` 요청과 미디어 스트림 TTS 재생 또는 Twilio `` 폴백을 확인하세요. 통화 기록에 여전히 "enter the meeting PIN"이 포함되어 있다면 전화 구간이 아직 Meet 회의실에 들어오지 않은 것이므로 회의 참가자는 음성을 들을 수 없습니다. +- `openclaw logs --follow`를 실행하고 Twilio Meet 시퀀스를 확인하세요. Google Meet가 참여를 위임하고, Voice Call이 사전 연결 DTMF TwiML을 저장 및 제공하며, Voice Call이 Twilio 통화용 실시간 TwiML을 제공한 다음, Google Meet가 `voicecall.speak`로 소개 음성을 요청합니다. +- `openclaw googlemeet setup --transport twilio`를 다시 실행하세요. 녹색 설정 확인은 필수이지만 회의 PIN 시퀀스가 올바르다는 것을 증명하지는 않습니다. +- 다이얼인 번호가 PIN과 동일한 Meet 초대 및 지역에 속하는지 확인하세요. +- Meet가 느리게 응답하거나 사전 연결 DTMF가 전송된 후에도 통화 기록에 PIN을 요청하는 프롬프트가 계속 표시되면 `voiceCall.dtmfDelayMs`를 기본값 12초보다 늘리세요. +- 참가자가 참여했지만 인사말이 들리지 않으면 `openclaw logs --follow`에서 DTMF 이후 `voicecall.speak` 요청과 미디어 스트림 TTS 재생 또는 Twilio `` 폴백을 확인하세요. 통화 기록에 여전히 "enter the meeting PIN"이 포함되어 있으면 전화 구간이 아직 Meet 회의실에 참여하지 않은 것이므로 회의 참가자는 음성을 들을 수 없습니다. -Webhook이 도착하지 않으면 먼저 Voice Call Plugin을 디버그하세요. 제공자는 `plugins.entries.voice-call.config.publicUrl` 또는 구성된 터널에 도달할 수 있어야 합니다. -[Voice call 문제 해결](/ko/plugins/voice-call#troubleshooting)을 참조하세요. +Webhook이 도착하지 않으면 먼저 Voice Call Plugin을 디버그하세요. 제공자가 `plugins.entries.voice-call.config.publicUrl` 또는 구성된 터널에 도달할 수 있어야 합니다. [음성 통화 문제 해결](/ko/plugins/voice-call#troubleshooting)을 참조하세요. ## 참고 -Google Meet의 공식 미디어 API는 수신 중심이므로 Meet 통화에서 말하려면 여전히 참가자 경로가 필요합니다. 이 Plugin은 그 경계를 명확하게 유지합니다. Chrome은 브라우저 참여와 로컬 오디오 라우팅을 처리하고, Twilio는 전화 접속 참여를 처리합니다. +Google Meet의 공식 미디어 API는 수신 중심이므로 Meet 통화에서 말하려면 여전히 참가자 경로가 필요합니다. 이 Plugin은 해당 경계를 명확하게 유지합니다. Chrome은 브라우저 참여와 로컬 오디오 라우팅을 처리하고, Twilio는 전화 다이얼인 참여를 처리합니다. -Chrome talk-back 모드에는 `BlackHole 2ch`와 다음 중 하나가 필요합니다. +Chrome 토크백 모드에는 `BlackHole 2ch`와 함께 다음 중 하나가 필요합니다. -- `chrome.audioInputCommand`와 `chrome.audioOutputCommand`: OpenClaw가 브리지를 소유하고, 해당 명령들과 선택한 제공자 사이에서 `chrome.audioFormat` 형식으로 오디오를 파이프합니다. 에이전트 모드는 실시간 전사와 일반 TTS를 사용하고, bidi 모드는 실시간 음성 제공자를 사용합니다. 기본 Chrome 경로는 `chrome.audioBufferBytes: 4096`을 사용하는 24 kHz PCM16입니다. 8 kHz G.711 mu-law는 레거시 명령 쌍에서도 계속 사용할 수 있습니다. -- `chrome.audioBridgeCommand`: 외부 브리지 명령이 전체 로컬 오디오 경로를 소유하며, 데몬을 시작하거나 검증한 뒤 종료해야 합니다. `agent` 모드는 TTS를 위해 명령 쌍에 직접 접근해야 하므로 이는 `bidi`에서만 유효합니다. +- `chrome.audioInputCommand`와 `chrome.audioOutputCommand`: OpenClaw가 브리지를 소유하고 해당 명령과 선택한 제공자 사이에서 `chrome.audioFormat`의 오디오를 파이프합니다. 에이전트 모드는 실시간 전사와 일반 TTS를 사용하고, bidi 모드는 실시간 음성 제공자를 사용합니다. 기본 Chrome 경로는 `chrome.audioBufferBytes: 4096`을 사용하는 24 kHz PCM16이며, 8 kHz G.711 mu-law는 레거시 명령 쌍에서 계속 사용할 수 있습니다. +- `chrome.audioBridgeCommand`: 외부 브리지 명령이 전체 로컬 오디오 경로를 소유하며 데몬을 시작하거나 검증한 뒤 종료해야 합니다. `agent` 모드는 TTS를 위해 직접 명령 쌍 접근이 필요하므로 이는 `bidi`에만 유효합니다. -에이전트 모드에서 에이전트가 `google_meet` 도구를 호출하면, 회의 컨설턴트 세션은 참가자 음성에 응답하기 전에 호출자의 현재 기록을 포크합니다. Meet 세션은 여전히 별도로 유지되므로(`agent::subagent:google-meet:`) 회의 후속 작업이 호출자 기록을 직접 변경하지 않습니다. +에이전트 모드에서 에이전트가 `google_meet` 도구를 호출하면, 회의 컨설턴트 세션은 참가자 음성에 답하기 전에 호출자의 현재 대화 기록을 포크합니다. Meet 세션은 여전히 별도로 유지되므로(`agent::subagent:google-meet:`) 회의 후속 작업이 호출자 대화 기록을 직접 변경하지 않습니다. -깨끗한 양방향 오디오를 위해 Meet 출력과 Meet 마이크를 별도의 가상 장치 또는 Loopback 스타일 가상 장치 그래프로 라우팅하세요. 하나의 공유 BlackHole 장치는 다른 참가자의 음성을 통화로 다시 에코할 수 있습니다. +깨끗한 양방향 오디오를 위해 Meet 출력과 Meet 마이크를 별도의 가상 장치 또는 Loopback 스타일의 가상 장치 그래프로 라우팅하세요. 단일 공유 BlackHole 장치는 다른 참가자의 소리를 통화로 되돌려 에코를 만들 수 있습니다. -명령 쌍 Chrome 브리지를 사용하면 `chrome.bargeInInputCommand`가 별도의 로컬 마이크를 수신하고 사람이 말하기 시작할 때 어시스턴트 재생을 지울 수 있습니다. 이렇게 하면 어시스턴트 재생 중 공유 BlackHole local loopback 입력이 일시적으로 억제되더라도 사람의 음성이 어시스턴트 출력보다 앞서 유지됩니다. `chrome.audioInputCommand` 및 `chrome.audioOutputCommand`와 마찬가지로 이는 운영자가 구성하는 로컬 명령입니다. 명시적으로 신뢰할 수 있는 명령 경로나 인수 목록을 사용하고, 신뢰할 수 없는 위치의 스크립트를 가리키지 마세요. +명령 쌍 Chrome 브리지에서는 `chrome.bargeInInputCommand`가 별도의 로컬 마이크를 듣고 사람이 말하기 시작하면 어시스턴트 재생을 지울 수 있습니다. 이렇게 하면 어시스턴트 재생 중 공유 BlackHole 루프백 입력이 일시적으로 억제되더라도 사람의 음성이 어시스턴트 출력보다 앞서 유지됩니다. `chrome.audioInputCommand` 및 `chrome.audioOutputCommand`와 마찬가지로 이는 운영자가 구성하는 로컬 명령입니다. 명시적으로 신뢰할 수 있는 명령 경로 또는 인수 목록을 사용하고, 신뢰할 수 없는 위치의 스크립트를 가리키지 마세요. -`googlemeet speak`는 Chrome 세션의 활성 talk-back 오디오 브리지를 트리거합니다. `googlemeet leave`는 해당 브리지를 중지합니다. Voice Call Plugin을 통해 위임된 Twilio 세션의 경우 `leave`는 기본 음성 통화도 끊습니다. API로 관리되는 공간의 활성 Google Meet 회의도 닫고 싶다면 `googlemeet end-active-conference`를 사용하세요. +`googlemeet speak`는 Chrome 세션의 활성 토크백 오디오 브리지를 트리거합니다. `googlemeet leave`는 해당 브리지를 중지합니다. Voice Call Plugin을 통해 위임된 Twilio 세션의 경우 `leave`는 기본 음성 통화도 끊습니다. API로 관리되는 공간의 활성 Google Meet 회의도 닫으려면 `googlemeet end-active-conference`를 사용하세요. ## 관련 항목 -- [Voice call Plugin](/ko/plugins/voice-call) -- [Talk 모드](/ko/nodes/talk) +- [Voice Call Plugin](/ko/plugins/voice-call) +- [토크 모드](/ko/nodes/talk) - [Plugin 빌드하기](/ko/plugins/building-plugins) diff --git a/docs/ko/plugins/hooks.md b/docs/ko/plugins/hooks.md index a6bf55466..257667bb4 100644 --- a/docs/ko/plugins/hooks.md +++ b/docs/ko/plugins/hooks.md @@ -1,26 +1,26 @@ --- read_when: - before_tool_call, before_agent_reply, 메시지 훅 또는 수명 주기 훅이 필요한 Plugin을 빌드하는 경우 - - Plugin의 도구 호출을 차단하거나, 다시 작성하거나, 승인을 요구해야 합니다 + - Plugin의 도구 호출을 차단하거나, 재작성하거나, 승인을 요구해야 합니다 - 내부 훅과 Plugin 훅 중에서 선택하고 있습니다 summary: 'Plugin 훅: 에이전트, 도구, 메시지, 세션 및 Gateway 수명 주기 이벤트 가로채기' title: Plugin 후크 x-i18n: - generated_at: "2026-05-06T06:34:38Z" + generated_at: "2026-05-06T17:59:18Z" model: gpt-5.5 provider: openai - source_hash: 92a149e1b343ea2d3f55855c2d02f4a9519337f0450c8a1428d52cd77ab4046a + source_hash: 3741b95bcccdff4e24b4c1f05de54649b48a6c0a2ca1dc4376475eb1823ae185 source_path: plugins/hooks.md workflow: 16 --- -Plugin 훅은 OpenClaw Plugin을 위한 인프로세스 확장 지점입니다. Plugin이 에이전트 실행, 도구 호출, 메시지 흐름, 세션 수명 주기, 하위 에이전트 라우팅, 설치 또는 Gateway 시작을 검사하거나 변경해야 할 때 사용하세요. +Plugin hooks는 OpenClaw Plugin을 위한 인프로세스 확장 지점입니다. Plugin이 에이전트 실행, 도구 호출, 메시지 흐름, 세션 수명 주기, 하위 에이전트 라우팅, 설치 또는 Gateway 시작을 검사하거나 변경해야 할 때 사용하세요. -`/new`, `/reset`, `/stop`, `agent:bootstrap`, `gateway:startup` 같은 명령 및 Gateway 이벤트에 대해 운영자가 설치하는 작은 `HOOK.md` 스크립트가 필요하다면 대신 [내부 훅](/ko/automation/hooks)을 사용하세요. +`/new`, `/reset`, `/stop`, `agent:bootstrap`, `gateway:startup` 같은 명령 및 Gateway 이벤트를 위한 작은 운영자 설치 `HOOK.md` 스크립트가 필요하다면 대신 [내부 hooks](/ko/automation/hooks)를 사용하세요. ## 빠른 시작 -Plugin 엔트리에서 `api.on(...)`으로 타입이 지정된 Plugin 훅을 등록합니다. +Plugin 엔트리에서 `api.on(...)`으로 타입이 지정된 Plugin hooks를 등록하세요. ```typescript import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry"; @@ -52,12 +52,12 @@ export default definePluginEntry({ }); ``` -훅 핸들러는 `priority` 내림차순으로 순차 실행됩니다. 우선순위가 같은 훅은 등록 순서를 유지합니다. +훅 핸들러는 내림차순 `priority`로 순차 실행됩니다. 우선순위가 같은 hooks는 등록 순서를 유지합니다. `api.on(name, handler, opts?)`는 다음을 받습니다. - `priority` - 핸들러 순서 지정(높을수록 먼저 실행). -- `timeoutMs` - 선택적 훅별 시간 예산. 설정하면 훅 러너는 예산이 지나면 해당 핸들러를 중단하고 다음 핸들러로 계속 진행합니다. 느린 설정이나 회수 작업이 호출자의 구성된 모델 제한 시간을 소모하게 두지 않습니다. 생략하면 훅 러너가 일반적으로 적용하는 기본 관찰/결정 제한 시간을 사용합니다. +- `timeoutMs` - 선택적 훅별 예산. 설정하면 훅 러너는 느린 설정 또는 회수 작업이 호출자의 구성된 모델 시간 제한을 소모하게 두는 대신, 예산이 지난 뒤 해당 핸들러를 중단하고 다음 핸들러로 계속 진행합니다. 생략하면 훅 러너가 일반적으로 적용하는 기본 관찰/결정 시간 제한을 사용합니다. 운영자는 Plugin 코드를 패치하지 않고도 훅 예산을 설정할 수 있습니다. @@ -79,62 +79,63 @@ export default definePluginEntry({ } ``` -`hooks.timeouts.`은 `hooks.timeoutMs`를 재정의하고, 이는 Plugin 작성자가 지정한 `api.on(..., { timeoutMs })` 값을 재정의합니다. 구성된 각 값은 600000밀리초 이하의 양의 정수여야 합니다. 알려진 느린 훅에는 훅별 재정의를 선호하여 한 Plugin이 모든 곳에서 더 긴 예산을 받지 않게 하세요. +`hooks.timeouts.`은 `hooks.timeoutMs`를 재정의하고, 이는 Plugin 작성자가 설정한 `api.on(..., { timeoutMs })` 값을 재정의합니다. 각 구성 값은 600000밀리초 이하의 양의 정수여야 합니다. 특정 느린 hooks가 있는 경우, 하나의 Plugin이 모든 곳에서 더 긴 예산을 받지 않도록 훅별 재정의를 선호하세요. -각 훅은 해당 핸들러를 등록한 Plugin의 확인된 구성인 `event.context.pluginConfig`를 받습니다. 현재 Plugin 옵션이 필요한 훅 결정에 사용하세요. OpenClaw는 다른 Plugin이 보는 공유 이벤트 객체를 변경하지 않고 핸들러별로 이를 주입합니다. +각 훅은 해당 핸들러를 등록한 Plugin의 해결된 구성인 `event.context.pluginConfig`를 받습니다. 현재 Plugin 옵션이 필요한 훅 결정에 사용하세요. OpenClaw는 다른 Plugin이 보는 공유 이벤트 객체를 변경하지 않고 핸들러별로 이를 주입합니다. ## 훅 카탈로그 -훅은 확장하는 표면별로 그룹화됩니다. **굵게 표시된** 이름은 결정 결과(차단, 취소, 재정의 또는 승인 요구)를 받을 수 있으며, 다른 모든 훅은 관찰 전용입니다. +Hooks는 확장하는 표면별로 그룹화됩니다. **굵게** 표시된 이름은 결정 결과(차단, 취소, 재정의 또는 승인 요구)를 받을 수 있으며, 나머지는 모두 관찰 전용입니다. **에이전트 턴** -- `before_model_resolve` - 세션 메시지가 로드되기 전에 제공자 또는 모델 재정의 -- `agent_turn_prepare` - 대기 중인 Plugin 턴 주입을 소비하고 프롬프트 훅 전에 동일 턴 컨텍스트 추가 -- `before_prompt_build` - 모델 호출 전에 동적 컨텍스트 또는 시스템 프롬프트 텍스트 추가 -- `before_agent_start` - 호환성 전용 결합 단계. 위의 두 훅을 선호하세요 -- **`before_agent_reply`** - 합성 응답 또는 침묵으로 모델 턴을 단락 처리 -- **`before_agent_finalize`** - 자연스러운 최종 답변을 검사하고 모델 패스 한 번 더 요청 -- `agent_end` - 최종 메시지, 성공 상태, 실행 시간 관찰 -- `heartbeat_prompt_contribution` - 백그라운드 모니터 및 수명 주기 Plugin을 위한 Heartbeat 전용 컨텍스트 추가 +- `before_model_resolve` - 세션 메시지를 로드하기 전에 제공자 또는 모델을 재정의 +- `agent_turn_prepare` - 대기 중인 Plugin 턴 주입을 소비하고 프롬프트 hooks 전에 같은 턴 컨텍스트를 추가 +- `before_prompt_build` - 모델 호출 전에 동적 컨텍스트 또는 시스템 프롬프트 텍스트를 추가 +- `before_agent_start` - 호환성 전용 결합 단계. 위의 두 hooks를 선호 +- **`before_agent_run`** - 모델 제출 전에 최종 프롬프트와 세션 메시지를 검사하고 선택적으로 실행을 차단 +- **`before_agent_reply`** - 합성 응답 또는 침묵으로 모델 턴을 단락 +- **`before_agent_finalize`** - 자연스러운 최종 답변을 검사하고 모델 패스를 한 번 더 요청 +- `agent_end` - 최종 메시지, 성공 상태, 실행 시간을 관찰 +- `heartbeat_prompt_contribution` - 백그라운드 모니터와 수명 주기 Plugin을 위해 heartbeat 전용 컨텍스트를 추가 **대화 관찰** -- `model_call_started` / `model_call_ended` - 프롬프트 또는 응답 내용 없이 정리된 제공자/모델 호출 메타데이터, 타이밍, 결과, 제한된 요청 ID 해시 관찰 -- `llm_input` - 제공자 입력(시스템 프롬프트, 프롬프트, 기록) 관찰 -- `llm_output` - 제공자 출력 관찰 +- `model_call_started` / `model_call_ended` - 프롬프트 또는 응답 콘텐츠 없이 정제된 제공자/모델 호출 메타데이터, 타이밍, 결과, 제한된 요청 ID 해시를 관찰 +- `llm_input` - 제공자 입력(시스템 프롬프트, 프롬프트, 기록)을 관찰 +- `llm_output` - 제공자 출력을 관찰 **도구** -- **`before_tool_call`** - 도구 매개변수 재작성, 실행 차단 또는 승인 요구 -- `after_tool_call` - 도구 결과, 오류, 실행 시간 관찰 -- **`tool_result_persist`** - 도구 결과에서 생성된 어시스턴트 메시지 재작성 -- **`before_message_write`** - 진행 중인 메시지 쓰기 검사 또는 차단(드묾) +- **`before_tool_call`** - 도구 매개변수를 다시 작성하거나, 실행을 차단하거나, 승인을 요구 +- `after_tool_call` - 도구 결과, 오류, 실행 시간을 관찰 +- **`tool_result_persist`** - 도구 결과에서 생성된 어시스턴트 메시지를 다시 작성 +- **`before_message_write`** - 진행 중인 메시지 쓰기를 검사하거나 차단(드묾) -**메시지 및 전달** +**메시지와 전달** -- **`inbound_claim`** - 에이전트 라우팅 전에 인바운드 메시지 클레임(합성 응답) -- `message_received` - 인바운드 콘텐츠, 발신자, 스레드, 메타데이터 관찰 -- **`message_sending`** - 아웃바운드 콘텐츠 재작성 또는 전달 취소 -- `message_sent` - 아웃바운드 전달 성공 또는 실패 관찰 -- **`before_dispatch`** - 채널 핸드오프 전에 아웃바운드 디스패치 검사 또는 재작성 +- **`inbound_claim`** - 에이전트 라우팅 전에 인바운드 메시지를 청구(합성 응답) +- `message_received` - 인바운드 콘텐츠, 발신자, 스레드, 메타데이터를 관찰 +- **`message_sending`** - 아웃바운드 콘텐츠를 다시 작성하거나 전달을 취소 +- `message_sent` - 아웃바운드 전달 성공 또는 실패를 관찰 +- **`before_dispatch`** - 채널 인계 전에 아웃바운드 디스패치를 검사하거나 다시 작성 - **`reply_dispatch`** - 최종 응답 디스패치 파이프라인에 참여 -**세션 및 Compaction** +**세션과 Compaction** -- `session_start` / `session_end` - 세션 수명 주기 경계 추적 -- `before_compaction` / `after_compaction` - Compaction 주기 관찰 또는 주석 추가 -- `before_reset` - 세션 재설정 이벤트(`/reset`, 프로그래밍 방식 재설정) 관찰 +- `session_start` / `session_end` - 세션 수명 주기 경계를 추적 +- `before_compaction` / `after_compaction` - Compaction 주기를 관찰하거나 주석을 추가 +- `before_reset` - 세션 재설정 이벤트를 관찰(`/reset`, 프로그래밍 방식 재설정) **하위 에이전트** -- `subagent_spawning` / `subagent_delivery_target` / `subagent_spawned` / `subagent_ended` - 하위 에이전트 라우팅 및 완료 전달 조정 +- `subagent_spawning` / `subagent_delivery_target` / `subagent_spawned` / `subagent_ended` - 하위 에이전트 라우팅과 완료 전달을 조율 **수명 주기** -- `gateway_start` / `gateway_stop` - Gateway와 함께 Plugin 소유 서비스 시작 또는 중지 -- `cron_changed` - Gateway 소유 Cron 수명 주기 변경(추가됨, 업데이트됨, 제거됨, 시작됨, 완료됨, 예약됨) 관찰 -- **`before_install`** - 스킬 또는 Plugin 설치 스캔을 검사하고 선택적으로 차단 +- `gateway_start` / `gateway_stop` - Gateway와 함께 Plugin 소유 서비스를 시작하거나 중지 +- `cron_changed` - Gateway 소유 Cron 수명 주기 변경(추가됨, 업데이트됨, 제거됨, 시작됨, 완료됨, 예약됨)을 관찰 +- **`before_install`** - skill 또는 Plugin 설치 스캔을 검사하고 선택적으로 차단 ## 도구 호출 정책 @@ -144,7 +145,7 @@ export default definePluginEntry({ - `event.params` - 선택적 `event.runId` - 선택적 `event.toolCallId` -- `ctx.agentId`, `ctx.sessionKey`, `ctx.sessionId`, `ctx.runId`, `ctx.jobId`(Cron 기반 실행에서 설정됨), 진단용 `ctx.trace` 같은 컨텍스트 필드 +- `ctx.agentId`, `ctx.sessionKey`, `ctx.sessionId`, `ctx.runId`, `ctx.jobId`(Cron 구동 실행에서 설정됨), 진단용 `ctx.trace` 같은 컨텍스트 필드 다음을 반환할 수 있습니다. @@ -169,46 +170,49 @@ type BeforeToolCallResult = { 규칙: -- `block: true`는 터미널 상태이며 더 낮은 우선순위 핸들러를 건너뜁니다. +- `block: true`는 최종 결정이며 더 낮은 우선순위의 핸들러를 건너뜁니다. - `block: false`는 결정 없음으로 처리됩니다. -- `params`는 실행할 도구 매개변수를 재작성합니다. +- `params`는 실행할 도구 매개변수를 다시 작성합니다. - `requireApproval`은 에이전트 실행을 일시 중지하고 Plugin 승인을 통해 사용자에게 요청합니다. `/approve` 명령은 exec 승인과 Plugin 승인을 모두 승인할 수 있습니다. -- 더 높은 우선순위 훅이 승인을 요청한 뒤에도 더 낮은 우선순위의 `block: true`가 여전히 차단할 수 있습니다. -- `onResolution`은 확인된 승인 결정인 `allow-once`, `allow-always`, `deny`, `timeout`, `cancelled`를 받습니다. +- 더 높은 우선순위의 훅이 승인을 요청했더라도, 더 낮은 우선순위의 `block: true`가 이후에 차단할 수 있습니다. +- `onResolution`은 해결된 승인 결정인 `allow-once`, `allow-always`, `deny`, `timeout`, `cancelled`를 받습니다. -호스트 수준 정책이 필요한 번들 Plugin은 `api.registerTrustedToolPolicy(...)`로 신뢰할 수 있는 도구 정책을 등록할 수 있습니다. 이는 일반 `before_tool_call` 훅 및 외부 Plugin 결정 전에 실행됩니다. 워크스페이스 정책, 예산 적용, 예약된 워크플로 안전성 같은 호스트 신뢰 게이트에만 사용하세요. 외부 Plugin은 일반 `before_tool_call` 훅을 사용해야 합니다. +호스트 수준 정책이 필요한 번들 Plugin은 `api.registerTrustedToolPolicy(...)`로 신뢰할 수 있는 도구 정책을 등록할 수 있습니다. 이러한 정책은 일반 `before_tool_call` hooks와 외부 Plugin 결정 전에 실행됩니다. 워크스페이스 정책, 예산 적용 또는 예약된 워크플로 안전성 같은 호스트 신뢰 게이트에만 사용하세요. 외부 Plugin은 일반 `before_tool_call` hooks를 사용해야 합니다. ### 도구 결과 지속성 -도구 결과에는 UI 렌더링, 진단, 미디어 라우팅 또는 Plugin 소유 메타데이터를 위한 구조화된 `details`가 포함될 수 있습니다. `details`를 프롬프트 콘텐츠가 아니라 런타임 메타데이터로 취급하세요. +도구 결과는 UI 렌더링, 진단, 미디어 라우팅 또는 Plugin 소유 메타데이터를 위한 구조화된 `details`를 포함할 수 있습니다. `details`를 프롬프트 콘텐츠가 아닌 런타임 메타데이터로 취급하세요. -- OpenClaw는 제공자 재생 및 Compaction 입력 전에 `toolResult.details`를 제거하여 메타데이터가 모델 컨텍스트가 되지 않게 합니다. -- 지속된 세션 항목은 제한된 `details`만 유지합니다. 너무 큰 details는 간결한 요약과 `persistedDetailsTruncated: true`로 대체됩니다. -- `tool_result_persist`와 `before_message_write`는 최종 지속성 제한 전에 실행됩니다. 훅은 반환된 `details`를 여전히 작게 유지하고, 프롬프트 관련 텍스트를 `details`에만 두지 않아야 합니다. 모델에 보이는 도구 출력은 `content`에 넣으세요. +- OpenClaw는 메타데이터가 모델 컨텍스트가 되지 않도록 제공자 재생 및 Compaction 입력 전에 `toolResult.details`를 제거합니다. +- 지속된 세션 항목은 제한된 `details`만 유지합니다. 크기가 너무 큰 details는 간결한 요약 및 `persistedDetailsTruncated: true`로 대체됩니다. +- `tool_result_persist`와 `before_message_write`는 최종 지속성 상한 전에 실행됩니다. 그래도 hooks는 반환되는 `details`를 작게 유지하고, 프롬프트 관련 텍스트를 `details`에만 두는 일을 피해야 합니다. 모델에 보이는 도구 출력은 `content`에 넣으세요. -## 프롬프트 및 모델 훅 +## 프롬프트와 모델 hooks -새 Plugin에는 단계별 훅을 사용하세요. +새 Plugin에는 단계별 hooks를 사용하세요. - `before_model_resolve`: 현재 프롬프트와 첨부 파일 메타데이터만 받습니다. `providerOverride` 또는 `modelOverride`를 반환합니다. -- `agent_turn_prepare`: 현재 프롬프트, 준비된 세션 메시지, 이 세션을 위해 비워진 정확히 한 번 실행되는 대기 중 주입을 받습니다. `prependContext` 또는 `appendContext`를 반환합니다. +- `agent_turn_prepare`: 현재 프롬프트, 준비된 세션 메시지, 이 세션을 위해 배출된 정확히 한 번만 실행되는 대기 주입을 받습니다. `prependContext` 또는 `appendContext`를 반환합니다. - `before_prompt_build`: 현재 프롬프트와 세션 메시지를 받습니다. `prependContext`, `appendContext`, `systemPrompt`, `prependSystemContext` 또는 `appendSystemContext`를 반환합니다. -- `heartbeat_prompt_contribution`: Heartbeat 턴에서만 실행되며 `prependContext` 또는 `appendContext`를 반환합니다. 사용자 시작 턴을 변경하지 않고 현재 상태를 요약해야 하는 백그라운드 모니터를 위한 것입니다. +- `heartbeat_prompt_contribution`: heartbeat 턴에서만 실행되며 `prependContext` 또는 `appendContext`를 반환합니다. 사용자 시작 턴을 변경하지 않고 현재 상태를 요약해야 하는 백그라운드 모니터를 위한 것입니다. -`before_agent_start`는 호환성을 위해 남아 있습니다. Plugin이 레거시 결합 단계에 의존하지 않도록 위의 명시적 훅을 선호하세요. +`before_agent_start`는 호환성을 위해 남아 있습니다. Plugin이 레거시 결합 단계에 의존하지 않도록 위의 명시적 hooks를 선호하세요. -`before_agent_start`와 `agent_end`는 OpenClaw가 활성 실행을 식별할 수 있을 때 `event.runId`를 포함합니다. 같은 값은 `ctx.runId`에서도 사용할 수 있습니다. Cron 기반 실행은 `ctx.jobId`(원본 Cron 작업 ID)도 노출하므로 Plugin 훅이 메트릭, 부수 효과 또는 상태의 범위를 특정 예약 작업으로 한정할 수 있습니다. +`before_agent_run`은 프롬프트 구성 후, 프롬프트 로컬 이미지 로딩 및 `llm_input` 관찰을 포함한 모든 모델 입력 전에 실행됩니다. 현재 사용자 입력을 `prompt`로 받고, 로드된 세션 기록을 `messages`로, 활성 시스템 프롬프트를 함께 받습니다. 모델이 프롬프트를 읽기 전에 실행을 중지하려면 `{ outcome: "block", reason, message? }`를 반환하세요. `reason`은 내부용이고, `message`는 사용자에게 표시되는 대체 텍스트입니다. 지원되는 결과는 `pass`와 `block`뿐이며, 지원되지 않는 결정 형태는 실패 시 차단됩니다. -채널에서 시작된 실행의 경우 `ctx.messageProvider`는 `discord` 또는 `telegram` 같은 제공자 표면이고, `ctx.channelId`는 OpenClaw가 세션 키 또는 전달 메타데이터에서 파생할 수 있을 때의 대화 대상 식별자입니다. +실행이 차단되면 OpenClaw는 대체 텍스트만 `message.content`에 저장하고 차단한 Plugin ID와 타임스탬프 같은 민감하지 않은 차단 메타데이터를 함께 저장합니다. 원래 사용자 텍스트는 transcript나 향후 컨텍스트에 유지되지 않습니다. 내부 차단 사유는 민감한 것으로 취급되어 transcript, 기록, 브로드캐스트, 로그, 진단 payload에서 제외됩니다. 관찰성은 차단자 ID, 결과, 타임스탬프 또는 안전한 범주 같은 정제된 필드를 사용해야 합니다. -`agent_end`는 관찰 훅이며 턴 이후 fire-and-forget으로 실행됩니다. 훅 러너는 30초 제한 시간을 적용하므로 멈춘 Plugin이나 임베딩 엔드포인트가 훅 프로미스를 영원히 대기 상태로 남길 수 없습니다. 제한 시간이 지나면 로그가 남고 OpenClaw는 계속 진행합니다. 다만 Plugin이 자체 중단 신호도 사용하지 않는 한 Plugin 소유 네트워크 작업을 취소하지는 않습니다. +`before_agent_start`와 `agent_end`는 OpenClaw가 활성 실행을 식별할 수 있을 때 `event.runId`를 포함합니다. 같은 값은 `ctx.runId`에서도 사용할 수 있습니다. Cron 구동 실행은 `ctx.jobId`(원본 Cron 작업 ID)도 노출하므로 Plugin hooks가 메트릭, 부작용 또는 상태를 특정 예약 작업으로 범위 지정할 수 있습니다. -원시 프롬프트, 기록, 응답, 헤더, 요청 본문 또는 제공자 요청 ID를 받아서는 안 되는 제공자 호출 원격 측정에는 `model_call_started`와 `model_call_ended`를 사용하세요. 이 훅에는 `runId`, `callId`, `provider`, `model`, 선택적 `api`/`transport`, 터미널 `durationMs`/`outcome`, OpenClaw가 제한된 제공자 요청 ID 해시를 파생할 수 있을 때의 `upstreamRequestIdHash` 같은 안정적인 메타데이터가 포함됩니다. +채널에서 시작된 실행의 경우, `ctx.messageProvider`는 `discord` 또는 `telegram` 같은 제공자 표면이고, `ctx.channelId`는 OpenClaw가 세션 키 또는 전달 메타데이터에서 도출할 수 있는 경우 대화 대상 식별자입니다. -`before_agent_finalize`는 하네스가 자연스러운 최종 어시스턴트 답변을 수락하려는 경우에만 실행됩니다. 이는 `/stop` 취소 경로가 아니며 사용자가 턴을 중단할 때 실행되지 않습니다. 최종화 전에 하네스에 모델 패스 한 번 더 요청하려면 `{ action: "revise", reason }`을 반환하고, 최종화를 강제하려면 `{ action: -"finalize", reason? }`를 반환하거나, 계속하려면 결과를 생략하세요. Codex 네이티브 `Stop` 훅은 OpenClaw `before_agent_finalize` 결정으로 중계됩니다. +`agent_end`는 관찰 훅이며 턴 이후 fire-and-forget 방식으로 실행됩니다. 훅 러너는 멈춘 Plugin 또는 임베딩 엔드포인트 때문에 훅 promise가 영원히 대기 상태로 남지 않도록 30초 시간 제한을 적용합니다. 시간 초과는 로그에 기록되고 OpenClaw는 계속 진행합니다. 단, Plugin이 자체 중단 신호도 사용하는 경우가 아니면 Plugin 소유 네트워크 작업은 취소하지 않습니다. -`action: "revise"`를 반환할 때 Plugin은 추가 모델 패스를 제한되고 재생 안전하게 만들기 위해 `retry` 메타데이터를 포함할 수 있습니다. +원시 프롬프트, 기록, 응답, 헤더, 요청 본문 또는 제공자 요청 ID를 받아서는 안 되는 제공자 호출 telemetry에는 `model_call_started`와 `model_call_ended`를 사용하세요. 이러한 hooks에는 `runId`, `callId`, `provider`, `model`, 선택적 `api`/`transport`, 종료 시점의 `durationMs`/`outcome`, 그리고 OpenClaw가 제한된 제공자 요청 ID 해시를 도출할 수 있는 경우 `upstreamRequestIdHash` 같은 안정적인 메타데이터가 포함됩니다. + +`before_agent_finalize`는 하네스가 자연스러운 최종 어시스턴트 답변을 수락하려는 경우에만 실행됩니다. 이는 `/stop` 취소 경로가 아니며 사용자가 턴을 중단할 때 실행되지 않습니다. 최종화 전에 하네스에 모델 패스를 한 번 더 요청하려면 `{ action: "revise", reason }`을 반환하고, 최종화를 강제하려면 `{ action: "finalize", reason? }`을 반환하거나, 계속 진행하려면 결과를 생략하세요. Codex 네이티브 `Stop` hooks는 OpenClaw `before_agent_finalize` 결정으로 이 훅에 전달됩니다. + +`action: "revise"`를 반환할 때, Plugin은 추가 모델 패스를 제한되고 재생 안전하게 만들기 위해 `retry` 메타데이터를 포함할 수 있습니다. ```typescript type BeforeAgentFinalizeRetry = { @@ -218,9 +222,12 @@ type BeforeAgentFinalizeRetry = { }; ``` -`instruction`은 하네스로 전송되는 수정 사유에 추가됩니다. `idempotencyKey`를 사용하면 호스트가 동등한 finalize 결정 전반에서 같은 Plugin 요청에 대한 재시도를 계산할 수 있고, `maxAttempts`는 자연스러운 최종 답변으로 계속 진행하기 전에 호스트가 허용할 추가 패스 수를 제한합니다. +`instruction`은 하네스에 전송되는 수정 사유에 추가됩니다. +`idempotencyKey`를 사용하면 호스트가 동등한 finalize 결정 전반에서 같은 Plugin 요청에 대한 재시도를 계산할 수 있으며, `maxAttempts`는 호스트가 자연스러운 최종 답변으로 계속 진행하기 전에 허용할 추가 패스 수를 제한합니다. -`llm_input`, `llm_output`, `before_agent_finalize` 또는 `agent_end`가 필요한 비번들 Plugin은 다음을 설정해야 합니다. +원시 대화 훅(`before_model_resolve`, +`before_agent_reply`, `llm_input`, `llm_output`, `before_agent_finalize`, +`agent_end`, 또는 `before_agent_run`)이 필요한 번들되지 않은 Plugin은 다음을 설정해야 합니다. ```json { @@ -236,65 +243,73 @@ type BeforeAgentFinalizeRetry = { } ``` -프롬프트 변경 훅과 지속성 있는 다음 턴 주입은 Plugin별로 `plugins.entries..hooks.allowPromptInjection=false`로 비활성화할 수 있습니다. +프롬프트를 변경하는 훅과 지속되는 다음 턴 주입은 Plugin별로 +`plugins.entries..hooks.allowPromptInjection=false`로 비활성화할 수 있습니다. -### 세션 확장 및 다음 턴 주입 +### 세션 확장과 다음 턴 주입 -Workflow Plugin은 `api.registerSessionExtension(...)`로 작은 JSON 호환 세션 상태를 유지하고 Gateway `sessions.pluginPatch` 메서드를 통해 업데이트할 수 있습니다. 세션 행은 등록된 확장 상태를 `pluginExtensions`를 통해 투영하므로, Control UI와 다른 클라이언트가 Plugin 내부를 알지 않고도 Plugin 소유 상태를 렌더링할 수 있습니다. +워크플로 Plugin은 `api.registerSessionExtension(...)`으로 작은 JSON 호환 세션 상태를 유지하고 Gateway `sessions.pluginPatch` 메서드를 통해 업데이트할 수 있습니다. 세션 행은 등록된 확장 상태를 `pluginExtensions`를 통해 투영하여 Control UI와 다른 클라이언트가 Plugin 내부 구현을 알지 않고도 Plugin 소유 상태를 렌더링할 수 있게 합니다. -Plugin이 다음 모델 턴에 정확히 한 번 도달해야 하는 지속성 컨텍스트가 필요할 때는 `api.enqueueNextTurnInjection(...)`을 사용하세요. OpenClaw는 프롬프트 훅 전에 대기 중인 주입을 비우고, 만료된 주입을 버리며, Plugin별로 `idempotencyKey`를 기준으로 중복을 제거합니다. 이는 승인 재개, 정책 요약, 백그라운드 모니터 델타, 그리고 다음 턴에서 모델에 표시되어야 하지만 영구 시스템 프롬프트 텍스트가 되어서는 안 되는 명령 이어 실행에 적합한 연결점입니다. +Plugin이 지속 컨텍스트를 다음 모델 턴에 정확히 한 번 전달해야 할 때 `api.enqueueNextTurnInjection(...)`을 사용하세요. OpenClaw는 프롬프트 훅 전에 대기 중인 주입을 비우고, 만료된 주입을 삭제하며, Plugin별로 `idempotencyKey`를 기준으로 중복 제거합니다. 이는 승인 재개, 정책 요약, 백그라운드 모니터 델타, 다음 턴에서 모델에 표시되어야 하지만 영구적인 시스템 프롬프트 텍스트가 되어서는 안 되는 명령 계속 실행에 적합한 경계입니다. -정리 의미 체계는 계약의 일부입니다. 세션 확장 정리와 런타임 수명 주기 정리 콜백은 `reset`, `delete`, `disable`, 또는 `restart`를 받습니다. 호스트는 reset/delete/disable에 대해 소유 Plugin의 영구 세션 확장 상태와 보류 중인 다음 턴 주입을 제거합니다. restart는 지속성 세션 상태를 유지하며, 정리 콜백은 Plugin이 이전 런타임 세대의 스케줄러 작업, 실행 컨텍스트, 기타 대역 외 리소스를 해제할 수 있게 합니다. +정리 의미론은 계약의 일부입니다. 세션 확장 정리와 런타임 수명 주기 정리 콜백은 `reset`, `delete`, `disable`, 또는 `restart`를 받습니다. reset/delete/disable의 경우 호스트는 소유 Plugin의 지속 세션 확장 상태와 보류 중인 다음 턴 주입을 제거합니다. restart는 지속 세션 상태를 유지하며, 정리 콜백을 통해 Plugin이 이전 런타임 세대의 스케줄러 작업, 실행 컨텍스트, 기타 대역 외 리소스를 해제할 수 있게 합니다. ## 메시지 훅 채널 수준 라우팅과 전달 정책에는 메시지 훅을 사용하세요. -- `message_received`: 인바운드 콘텐츠, 발신자, `threadId`, `messageId`, `senderId`, 선택적 실행/세션 상관관계, 메타데이터를 관찰합니다. -- `message_sending`: `content`를 다시 작성하거나 `{ cancel: true }`를 반환합니다. +- `message_received`: 인바운드 콘텐츠, 발신자, `threadId`, `messageId`, + `senderId`, 선택적 실행/세션 상관관계, 메타데이터를 관찰합니다. +- `message_sending`: `content`를 다시 쓰거나 `{ cancel: true }`를 반환합니다. - `message_sent`: 최종 성공 또는 실패를 관찰합니다. -오디오 전용 TTS 답장에서는 채널 페이로드에 보이는 텍스트/캡션이 없더라도 `content`에 숨겨진 음성 전사문이 포함될 수 있습니다. 해당 `content`를 다시 작성하면 훅에 보이는 전사문만 업데이트되며, 미디어 캡션으로 렌더링되지는 않습니다. +오디오 전용 TTS 답변의 경우 채널 페이로드에 보이는 텍스트/캡션이 없더라도 `content`에 숨겨진 음성 트랜스크립트가 포함될 수 있습니다. 해당 `content`를 다시 쓰면 훅에 표시되는 트랜스크립트만 업데이트되며, 미디어 캡션으로 렌더링되지 않습니다. -메시지 훅 컨텍스트는 사용 가능한 경우 안정적인 상관관계 필드를 노출합니다. `ctx.sessionKey`, `ctx.runId`, `ctx.messageId`, `ctx.senderId`, `ctx.trace`, `ctx.traceId`, `ctx.spanId`, `ctx.parentSpanId`, `ctx.callDepth`입니다. 레거시 메타데이터를 읽기 전에 이러한 일급 필드를 우선 사용하세요. +메시지 훅 컨텍스트는 사용 가능한 경우 안정적인 상관관계 필드를 노출합니다. +`ctx.sessionKey`, `ctx.runId`, `ctx.messageId`, `ctx.senderId`, `ctx.trace`, +`ctx.traceId`, `ctx.spanId`, `ctx.parentSpanId`, `ctx.callDepth`. 레거시 메타데이터를 읽기 전에 이러한 일급 필드를 우선 사용하세요. 채널별 메타데이터를 사용하기 전에 형식화된 `threadId` 및 `replyToId` 필드를 우선 사용하세요. 결정 규칙: -- `cancel: true`가 있는 `message_sending`은 최종 결정입니다. +- `cancel: true`가 있는 `message_sending`은 종료 결정입니다. - `cancel: false`가 있는 `message_sending`은 결정 없음으로 처리됩니다. - 다시 작성된 `content`는 이후 훅이 전달을 취소하지 않는 한 더 낮은 우선순위 훅으로 계속 전달됩니다. ## 설치 훅 -`before_install`은 Skills 및 Plugin 설치를 위한 기본 제공 스캔 후에 실행됩니다. 설치를 중단하려면 추가 발견 사항이나 `{ block: true, blockReason }`을 반환하세요. +`before_install`은 Skills 및 Plugin 설치를 위한 내장 스캔 이후 실행됩니다. +추가 발견 항목을 반환하거나 설치를 중지하려면 `{ block: true, blockReason }`을 반환하세요. -`block: true`는 최종 결정입니다. `block: false`는 결정 없음으로 처리됩니다. +`block: true`는 종료 결정입니다. `block: false`는 결정 없음으로 처리됩니다. ## Gateway 수명 주기 -Gateway 소유 상태가 필요한 Plugin 서비스에는 `gateway_start`를 사용하세요. 컨텍스트는 cron 검사와 업데이트를 위해 `ctx.config`, `ctx.workspaceDir`, `ctx.getCron?.()`를 노출합니다. 장기 실행 리소스를 정리하려면 `gateway_stop`을 사용하세요. +Gateway 소유 상태가 필요한 Plugin 서비스에는 `gateway_start`를 사용하세요. 컨텍스트는 cron 검사와 업데이트를 위해 `ctx.config`, `ctx.workspaceDir`, `ctx.getCron?.()`을 노출합니다. 장기 실행 리소스를 정리하려면 `gateway_stop`을 사용하세요. -Plugin 소유 런타임 서비스에 내부 `gateway:startup` 훅을 의존하지 마세요. +Plugin 소유 런타임 서비스에 내부 `gateway:startup` 훅에 의존하지 마세요. -`cron_changed`는 `added`, `updated`, `removed`, `started`, `finished`, `scheduled` 이유를 포괄하는 형식화된 이벤트 페이로드와 함께 Gateway 소유 cron 수명 주기 이벤트에 대해 발생합니다. 이 이벤트는 `PluginHookGatewayCronJob` 스냅샷(있는 경우 `state.nextRunAtMs`, `state.lastRunStatus`, `state.lastError` 포함)과 `not-requested` | `delivered` | `not-delivered` | `unknown` 중 하나인 `PluginHookGatewayCronDeliveryStatus`를 전달합니다. removed 이벤트도 삭제된 작업 스냅샷을 계속 전달하므로 외부 스케줄러가 상태를 조정할 수 있습니다. 외부 깨우기 스케줄러를 동기화할 때는 런타임 컨텍스트의 `ctx.getCron?.()` 및 `ctx.config`를 사용하고, 기한 확인과 실행의 진실 공급원은 OpenClaw로 유지하세요. +`cron_changed`는 `added`, `updated`, `removed`, `started`, `finished`, +`scheduled` 사유를 포함하는 형식화된 이벤트 페이로드로 gateway 소유 cron 수명 주기 이벤트에 대해 발생합니다. 이벤트는 `PluginHookGatewayCronJob` 스냅샷(있는 경우 `state.nextRunAtMs`, `state.lastRunStatus`, `state.lastError` 포함)과 `not-requested` | `delivered` | `not-delivered` | `unknown`의 `PluginHookGatewayCronDeliveryStatus`를 전달합니다. 제거된 이벤트도 삭제된 작업 스냅샷을 계속 전달하므로 외부 스케줄러가 상태를 조정할 수 있습니다. 외부 깨우기 스케줄러를 동기화할 때는 런타임 컨텍스트의 `ctx.getCron?.()` 및 `ctx.config`를 사용하고, 만료 확인과 실행의 신뢰 가능한 원천은 OpenClaw로 유지하세요. ## 예정된 지원 중단 -몇몇 훅 인접 표면은 지원 중단되었지만 아직 지원됩니다. 다음 메이저 릴리스 전에 마이그레이션하세요. +일부 훅 인접 표면은 지원 중단되었지만 아직 지원됩니다. 다음 주요 릴리스 전에 마이그레이션하세요. -- `inbound_claim` 및 `message_received` 핸들러의 **일반 텍스트 채널 봉투**. 평면 봉투 텍스트를 파싱하는 대신 `BodyForAgent`와 구조화된 사용자 컨텍스트 블록을 읽으세요. [일반 텍스트 채널 봉투 → BodyForAgent](/ko/plugins/sdk-migration#active-deprecations)를 참조하세요. -- **`before_agent_start`**는 호환성을 위해 유지됩니다. 새 Plugin은 결합된 단계 대신 `before_model_resolve`와 `before_prompt_build`를 사용해야 합니다. -- **`before_tool_call`의 `onResolution`**은 이제 자유 형식 `string` 대신 형식화된 `PluginApprovalResolution` 유니언(`allow-once` / `allow-always` / `deny` / `timeout` / `cancelled`)을 사용합니다. +- `inbound_claim` 및 `message_received` 핸들러의 **평문 채널 엔벌로프**. + 평평한 엔벌로프 텍스트를 파싱하는 대신 `BodyForAgent`와 구조화된 사용자 컨텍스트 블록을 읽으세요. [평문 채널 엔벌로프 → BodyForAgent](/ko/plugins/sdk-migration#active-deprecations)를 참고하세요. +- **`before_agent_start`**는 호환성을 위해 유지됩니다. 새 Plugin은 결합된 단계 대신 `before_model_resolve` 및 `before_prompt_build`를 사용해야 합니다. +- **`before_tool_call`의 `onResolution`**은 이제 자유 형식 `string` 대신 형식화된 `PluginApprovalResolution` 유니언(`allow-once` / `allow-always` / `deny` / + `timeout` / `cancelled`)을 사용합니다. -전체 목록(메모리 기능 등록, 제공자 thinking 프로필, 외부 인증 제공자, 제공자 탐색 형식, 작업 런타임 접근자, `command-auth` → `command-status` 이름 변경)은 [Plugin SDK 마이그레이션 → 활성 지원 중단](/ko/plugins/sdk-migration#active-deprecations)을 참조하세요. +전체 목록인 메모리 기능 등록, 공급자 사고 프로필, 외부 인증 공급자, 공급자 검색 타입, 작업 런타임 접근자, `command-auth` → `command-status` 이름 변경은 [Plugin SDK 마이그레이션 → 활성 지원 중단](/ko/plugins/sdk-migration#active-deprecations)을 참고하세요. ## 관련 항목 -- [Plugin SDK 마이그레이션](/ko/plugins/sdk-migration) - 활성 지원 중단 및 제거 일정 -- [Plugin 빌드하기](/ko/plugins/building-plugins) +- [Plugin SDK 마이그레이션](/ko/plugins/sdk-migration) - 활성 지원 중단과 제거 일정 +- [Plugin 빌드](/ko/plugins/building-plugins) - [Plugin SDK 개요](/ko/plugins/sdk-overview) - [Plugin 진입점](/ko/plugins/sdk-entrypoints) - [내부 훅](/ko/automation/hooks) -- [Plugin 아키텍처 내부 구조](/ko/plugins/architecture-internals) +- [Plugin 아키텍처 내부 구현](/ko/plugins/architecture-internals) diff --git a/docs/ko/plugins/manage-plugins.md b/docs/ko/plugins/manage-plugins.md index 1190ad37a..f77777e13 100644 --- a/docs/ko/plugins/manage-plugins.md +++ b/docs/ko/plugins/manage-plugins.md @@ -1,24 +1,24 @@ --- read_when: - - 빠른 Plugin 설치, 목록 조회, 업데이트 또는 제거 예시가 필요합니다 + - 빠른 Plugin 설치, 목록 조회, 업데이트 또는 제거 예시가 필요한 경우 - ClawHub와 npm Plugin 배포 중에서 선택하려는 경우 - Plugin 패키지를 게시하고 있습니다 sidebarTitle: Manage plugins -summary: OpenClaw Plugin 설치, 목록 조회, 제거, 업데이트 및 게시를 위한 간단한 예시 +summary: OpenClaw Plugin의 설치, 목록 조회, 제거, 업데이트 및 게시를 위한 빠른 예시 title: Plugin 관리 x-i18n: - generated_at: "2026-05-05T01:48:30Z" + generated_at: "2026-05-06T17:59:30Z" model: gpt-5.5 provider: openai - source_hash: 7fa7aa78c1ba9c83ba09bea073987ed5e037031f7c7f29307fe18934b0bd2a1c + source_hash: 265777b03434dd07caee6191765c34e17fda4c8347e0327c2f37d47f9dd7a054 source_path: plugins/manage-plugins.md workflow: 16 --- 대부분의 Plugin 워크플로는 몇 가지 명령으로 이루어집니다. 검색, 설치, Gateway 재시작, -확인, 그리고 Plugin이 더 이상 필요하지 않을 때 제거입니다. +확인, 그리고 더 이상 Plugin이 필요하지 않을 때 제거입니다. -## Plugin 목록 보기 +## Plugin 목록 ```bash openclaw plugins list @@ -27,18 +27,18 @@ openclaw plugins list --verbose openclaw plugins list --json ``` -스크립트에는 `--json`을 사용하세요. 여기에는 레지스트리 진단 정보와 Plugin 패키지가 -`dependencies` 또는 `optionalDependencies`를 선언한 경우 각 Plugin의 -정적 `dependencyStatus`가 포함됩니다. +스크립트에는 `--json`을 사용하세요. Plugin 패키지가 `dependencies` 또는 +`optionalDependencies`를 선언한 경우, 레지스트리 진단과 각 Plugin의 정적 +`dependencyStatus`가 포함됩니다. ```bash openclaw plugins list --json \ | jq '.plugins[] | {id, enabled, format, source, dependencyStatus}' ``` -`plugins list`는 콜드 인벤토리 검사입니다. OpenClaw가 설정, 매니페스트, -Plugin 레지스트리에서 무엇을 발견할 수 있는지 보여 줍니다. 이미 실행 중인 -Gateway 프로세스가 Plugin 런타임을 가져왔다는 증거는 아닙니다. +`plugins list`는 콜드 인벤토리 검사입니다. OpenClaw가 구성, 매니페스트, +Plugin 레지스트리에서 발견할 수 있는 항목을 보여주지만, 이미 실행 중인 Gateway +프로세스가 Plugin 런타임을 가져왔다는 것을 증명하지는 않습니다. ## Plugin 설치 @@ -72,8 +72,8 @@ openclaw gateway restart openclaw plugins inspect --runtime --json ``` -도구, 훅, 서비스, Gateway 메서드, Plugin 소유 CLI 명령 같은 런타임 -표면을 Plugin이 등록했다는 증거가 필요할 때는 `inspect --runtime`을 사용하세요. +도구, 훅, 서비스, Gateway 메서드, Plugin 소유 CLI 명령과 같은 런타임 표면을 +Plugin이 등록했다는 증명이 필요할 때는 `inspect --runtime`을 사용하세요. ## Plugin 업데이트 @@ -85,21 +85,21 @@ openclaw plugins update --all Plugin이 `@beta` 같은 npm dist-tag에서 설치된 경우, 이후 `update ` 호출은 기록된 해당 태그를 재사용합니다. 명시적인 npm 사양을 -전달하면 향후 업데이트를 위해 추적되는 설치 대상이 해당 사양으로 전환됩니다. +전달하면 추적되는 설치가 향후 업데이트에 해당 사양을 사용하도록 전환됩니다. ```bash openclaw plugins update @scope/openclaw-plugin@beta openclaw plugins update @scope/openclaw-plugin ``` -두 번째 명령은 이전에 정확한 버전이나 태그에 고정되어 있던 Plugin을 -레지스트리의 기본 릴리스 라인으로 되돌립니다. +두 번째 명령은 이전에 정확한 버전이나 태그로 고정된 Plugin을 레지스트리의 기본 +릴리스 라인으로 되돌립니다. -`openclaw update`가 베타 채널에서 실행되면, 기본 라인 npm 및 ClawHub -Plugin 기록은 먼저 일치하는 Plugin `@beta` 릴리스를 시도합니다. 해당 베타 -릴리스가 없으면 OpenClaw는 기록된 기본/최신 사양으로 폴백합니다. -npm Plugin의 경우, 베타 패키지가 있지만 설치 검증에 실패할 때도 OpenClaw가 -폴백합니다. 정확한 버전과 `@rc` 또는 `@beta` 같은 명시적 태그는 보존됩니다. +베타 채널에서 `openclaw update`가 실행되면, 기본 라인의 npm 및 ClawHub Plugin +레코드는 먼저 일치하는 Plugin `@beta` 릴리스를 시도합니다. 해당 베타 릴리스가 +없으면 OpenClaw는 기록된 기본/최신 사양으로 대체합니다. npm Plugin의 경우, +베타 패키지가 존재하지만 설치 검증에 실패해도 OpenClaw는 대체합니다. 정확한 버전과 +`@rc` 또는 `@beta` 같은 명시적 태그는 보존됩니다. ## Plugin 제거 @@ -110,14 +110,19 @@ openclaw plugins uninstall --keep-files openclaw gateway restart ``` -제거는 해당되는 경우 Plugin의 설정 항목, Plugin 인덱스 기록, 허용/거부 목록 -항목, 연결된 로드 경로를 제거합니다. `--keep-files`를 전달하지 않으면 -관리형 설치 디렉터리도 제거됩니다. +제거는 해당되는 경우 Plugin의 구성 항목, Plugin 인덱스 레코드, 허용/거부 목록 +항목, 연결된 로드 경로를 제거합니다. 관리형 설치 디렉터리는 `--keep-files`를 +전달하지 않는 한 제거됩니다. + +Nix 모드(`OPENCLAW_NIX_MODE=1`)에서는 Plugin 설치, 업데이트, 제거, 활성화, +비활성화 명령이 비활성화됩니다. 대신 설치의 Nix 소스에서 이러한 선택을 +관리하세요. nix-openclaw의 경우 agent 우선 +[빠른 시작](https://github.com/openclaw/nix-openclaw#quick-start)을 사용하세요. ## Plugin 게시 -외부 Plugin을 [ClawHub](https://clawhub.ai), npmjs.com 또는 둘 다에 -게시할 수 있습니다. +외부 Plugin은 [ClawHub](https://clawhub.ai), npmjs.com 또는 둘 다에 게시할 수 +있습니다. ### ClawHub에 게시 @@ -132,19 +137,19 @@ clawhub package publish your-org/your-plugin clawhub package publish your-org/your-plugin@v1.0.0 ``` -사용자는 다음 명령으로 ClawHub에서 설치합니다. +사용자는 다음으로 ClawHub에서 설치합니다. ```bash openclaw plugins install clawhub: openclaw plugins install ``` -접두사가 없는 형식은 여전히 ClawHub를 먼저 확인합니다. +축약 형식도 여전히 ClawHub를 먼저 확인합니다. ### npmjs.com에 게시 -네이티브 npm Plugin에는 Plugin 매니페스트와 `package.json` OpenClaw -엔트리포인트 메타데이터가 포함되어야 합니다. +네이티브 npm Plugin에는 Plugin 매니페스트와 `package.json` OpenClaw 엔트리포인트 +메타데이터가 포함되어야 합니다. ```json package.json { @@ -161,7 +166,7 @@ openclaw plugins install npm publish --access public ``` -사용자는 npm 전용 설치를 다음과 같이 수행합니다. +사용자는 npm 전용으로 다음과 같이 설치합니다. ```bash openclaw plugins install npm:@acme/openclaw-plugin @@ -169,22 +174,20 @@ openclaw plugins install npm:@acme/openclaw-plugin@beta openclaw plugins install npm:@acme/openclaw-plugin@1.0.0 ``` -같은 패키지가 ClawHub에서도 제공되는 경우, `npm:`은 ClawHub 조회를 건너뛰고 -npm 해석을 강제합니다. +같은 패키지가 ClawHub에서도 제공되는 경우, `npm:`은 ClawHub 조회를 건너뛰고 npm +해결을 강제합니다. ## 소스 선택 -- **ClawHub**: OpenClaw 네이티브 검색, 스캔 요약, - 버전, 설치 힌트가 필요할 때 사용합니다. -- **npmjs.com**: 이미 JavaScript 패키지를 배포하고 있거나 npm - dist-tag/비공개 레지스트리 워크플로가 필요할 때 사용합니다. -- **Git**: 브랜치, 태그, 커밋에서 직접 설치하려는 경우 사용합니다. -- **로컬 경로**: 같은 머신에서 Plugin을 개발하거나 테스트할 때 사용합니다. +- **ClawHub**: OpenClaw 네이티브 검색, 스캔 요약, 버전, 설치 힌트가 필요할 때 사용하세요. +- **npmjs.com**: 이미 JavaScript 패키지를 배포하고 있거나 npm dist-tags/비공개 레지스트리 워크플로가 필요할 때 사용하세요. +- **Git**: 브랜치, 태그, 커밋에서 직접 설치하려는 경우 사용하세요. +- **로컬 경로**: 같은 머신에서 Plugin을 개발하거나 테스트할 때 사용하세요. ## 관련 항목 - [Plugin](/ko/tools/plugin) - 개요 및 문제 해결 - [`openclaw plugins`](/ko/cli/plugins) - 전체 CLI 참조 - [ClawHub](/ko/tools/clawhub) - 게시 및 레지스트리 작업 -- [Plugin 빌드](/ko/plugins/building-plugins) - Plugin 패키지 만들기 +- [Plugin 빌드하기](/ko/plugins/building-plugins) - Plugin 패키지 만들기 - [Plugin 매니페스트](/ko/plugins/manifest) - 매니페스트 및 패키지 메타데이터 diff --git a/docs/ko/plugins/sdk-runtime.md b/docs/ko/plugins/sdk-runtime.md index b6ab2fc7d..c516a3bee 100644 --- a/docs/ko/plugins/sdk-runtime.md +++ b/docs/ko/plugins/sdk-runtime.md @@ -1,28 +1,28 @@ --- read_when: - - Plugin에서 코어 헬퍼(TTS, STT, 이미지 생성, 웹 검색, 하위 에이전트, 노드)를 호출해야 합니다 - - api.runtime가 무엇을 노출하는지 이해하려는 경우 - - Plugin 코드에서 config, 에이전트 또는 미디어 헬퍼에 접근하고 있습니다 + - Plugin에서 코어 헬퍼를 호출해야 합니다(TTS, STT, 이미지 생성, 웹 검색, 하위 에이전트, Node) + - api.runtime이 무엇을 공개하는지 이해하려는 경우 + - Plugin 코드에서 구성, 에이전트 또는 미디어 헬퍼에 접근하고 있습니다 sidebarTitle: Runtime helpers summary: api.runtime -- Plugin에서 사용할 수 있는 주입된 런타임 헬퍼 title: Plugin 런타임 헬퍼 x-i18n: - generated_at: "2026-05-04T09:37:25Z" + generated_at: "2026-05-06T17:59:37Z" model: gpt-5.5 provider: openai - source_hash: c968f30052ecba4359bdaa9b1c640c1220268933ce01ccef06bcade225b50b7d + source_hash: 2ce16325613efc07bccb8baee3fdb46eb28452b760a6c265d3a25d36bfcbcf0f source_path: plugins/sdk-runtime.md workflow: 16 --- -`api.runtime` 객체에 대한 참조입니다. 이 객체는 등록 중 모든 Plugin에 주입됩니다. 호스트 내부를 직접 가져오는 대신 이러한 헬퍼를 사용하세요. +등록 중에 모든 Plugin에 주입되는 `api.runtime` 객체에 대한 참조입니다. 호스트 내부 구현을 직접 가져오는 대신 이 헬퍼를 사용하세요. - 채널 Plugin에서 이러한 헬퍼를 맥락에 맞게 사용하는 단계별 가이드입니다. + 채널 Plugin에서 이 헬퍼를 맥락에 맞게 사용하는 단계별 가이드입니다. - - 프로바이더 Plugin에서 이러한 헬퍼를 맥락에 맞게 사용하는 단계별 가이드입니다. + + 제공자 Plugin에서 이 헬퍼를 맥락에 맞게 사용하는 단계별 가이드입니다. @@ -32,30 +32,33 @@ register(api) { } ``` -## Config 로드 및 쓰기 +## 구성 로드 및 쓰기 -활성 호출 경로에 이미 전달된 config를 우선 사용하세요. 예를 들어 등록 중에는 `api.config`, 채널/프로바이더 콜백에서는 `cfg` 인수를 사용합니다. 이렇게 하면 핫 경로에서 config를 다시 파싱하는 대신 하나의 프로세스 스냅샷이 작업 전체를 흐르게 됩니다. +활성 호출 경로에 이미 전달된 구성을 우선 사용하세요. 예를 들어 등록 중에는 `api.config`, 채널/제공자 콜백에서는 `cfg` 인수를 사용합니다. 이렇게 하면 핫 경로에서 구성을 다시 파싱하는 대신 하나의 프로세스 스냅샷이 작업 전체를 따라 흐르게 됩니다. -수명이 긴 핸들러가 현재 프로세스 스냅샷을 필요로 하고 해당 함수에 config가 전달되지 않은 경우에만 `api.runtime.config.current()`를 사용하세요. 반환된 값은 읽기 전용입니다. 편집하기 전에 복제하거나 변경 헬퍼를 사용하세요. +장기 실행 핸들러에 현재 프로세스 스냅샷이 필요하고 해당 함수에 구성이 전달되지 않은 경우에만 `api.runtime.config.current()`를 사용하세요. 반환된 값은 읽기 전용입니다. 편집하기 전에 복제하거나 변경 헬퍼를 사용하세요. -도구 팩토리는 `ctx.runtimeConfig`와 `ctx.getRuntimeConfig()`를 받습니다. 도구 정의가 생성된 뒤 config가 변경될 수 있는 경우, 수명이 긴 도구의 `execute` 콜백 안에서 getter를 사용하세요. +도구 팩터리는 `ctx.runtimeConfig`와 `ctx.getRuntimeConfig()`를 받습니다. 도구 정의가 생성된 후 구성이 변경될 수 있는 장기 실행 도구의 `execute` 콜백 안에서는 getter를 사용하세요. 변경 사항은 `api.runtime.config.mutateConfigFile(...)` 또는 `api.runtime.config.replaceConfigFile(...)`로 유지하세요. 각 쓰기는 명시적인 `afterWrite` 정책을 선택해야 합니다. -- `afterWrite: { mode: "auto" }`는 Gateway 재로드 플래너가 결정하도록 합니다. -- `afterWrite: { mode: "restart", reason: "..." }`는 작성자가 핫 리로드가 안전하지 않다고 아는 경우 깨끗한 재시작을 강제합니다. -- `afterWrite: { mode: "none", reason: "..." }`는 호출자가 후속 조치를 소유하는 경우에만 자동 재로드/재시작을 억제합니다. +- `afterWrite: { mode: "auto" }`는 Gateway 재로드 플래너가 결정하게 합니다. +- `afterWrite: { mode: "restart", reason: "..." }`는 작성자가 핫 리로드가 안전하지 않다는 것을 알고 있을 때 깔끔한 재시작을 강제합니다. +- `afterWrite: { mode: "none", reason: "..." }`는 호출자가 후속 처리를 소유하는 경우에만 자동 재로드/재시작을 억제합니다. -변경 헬퍼는 `afterWrite`와 타입이 지정된 `followUp` 요약을 반환하므로, 호출자는 재시작을 요청했는지 로그에 남기거나 테스트할 수 있습니다. 해당 재시작이 실제로 언제 일어나는지는 여전히 Gateway가 소유합니다. +변경 헬퍼는 `afterWrite`와 형식화된 `followUp` 요약을 반환하므로 호출자는 재시작을 요청했는지 로그로 남기거나 테스트할 수 있습니다. 실제로 해당 재시작이 언제 발생하는지는 여전히 Gateway가 소유합니다. -`api.runtime.config.loadConfig()`와 `api.runtime.config.writeConfigFile(...)`은 `runtime-config-load-write` 아래의 더 이상 권장되지 않는 호환성 헬퍼입니다. 런타임에서 한 번 경고하며, 마이그레이션 기간 동안 오래된 외부 Plugin을 위해 계속 사용할 수 있습니다. 번들 Plugin은 이를 사용하면 안 됩니다. Plugin 코드가 이를 호출하거나 Plugin SDK 하위 경로에서 해당 헬퍼를 가져오면 config 경계 가드가 실패합니다. +`api.runtime.config.loadConfig()`와 `api.runtime.config.writeConfigFile(...)`은 `runtime-config-load-write` 아래의 더 이상 권장되지 않는 호환성 헬퍼입니다. 런타임에서 한 번 경고하며, 마이그레이션 기간 동안 이전 외부 Plugin을 위해 계속 사용할 수 있습니다. 번들 Plugin은 이를 사용해서는 안 됩니다. Plugin 코드가 이를 호출하거나 Plugin SDK 하위 경로에서 해당 헬퍼를 가져오면 구성 경계 가드가 실패합니다. -직접 SDK 가져오기에는 넓은 -`openclaw/plugin-sdk/config-runtime` 호환성 배럴 대신 초점이 맞춰진 config 하위 경로를 사용하세요. 타입에는 `config-types`, 이미 로드된 config 어설션과 Plugin 엔트리 조회에는 `plugin-config-runtime`, 현재 프로세스 스냅샷에는 `runtime-config-snapshot`, 쓰기에는 `config-mutation`을 사용하세요. 번들 Plugin 테스트는 넓은 호환성 배럴을 모킹하는 대신 이러한 초점이 맞춰진 하위 경로를 직접 모킹해야 합니다. +직접 SDK 가져오기의 경우 넓은 +`openclaw/plugin-sdk/config-runtime` 호환성 배럴 대신 집중된 구성 하위 경로를 사용하세요. 형식에는 `config-types`, 이미 로드된 구성 어설션 및 Plugin +항목 조회에는 `plugin-config-runtime`, 현재 프로세스 스냅샷에는 +`runtime-config-snapshot`, 쓰기에는 +`config-mutation`을 사용합니다. 번들 Plugin 테스트는 넓은 호환성 배럴을 모킹하는 대신 이러한 집중된 하위 경로를 직접 모킹해야 합니다. -내부 OpenClaw 런타임 코드도 같은 방향을 따릅니다. CLI, Gateway, 또는 프로세스 경계에서 config를 한 번 로드한 뒤 그 값을 전달하세요. 성공한 변경 쓰기는 프로세스 런타임 스냅샷을 새로 고치고 내부 리비전을 증가시킵니다. 수명이 긴 캐시는 config를 로컬에서 직렬화하는 대신 런타임이 소유한 캐시 키를 기준으로 해야 합니다. 수명이 긴 런타임 모듈에는 주변 `loadConfig()` 호출에 대한 무관용 스캐너가 있습니다. 전달된 `cfg`, 요청 `context.getRuntimeConfig()`, 또는 명시적인 프로세스 경계의 `getRuntimeConfig()`를 사용하세요. +내부 OpenClaw 런타임 코드도 같은 방향을 따릅니다. CLI, Gateway 또는 프로세스 경계에서 구성을 한 번 로드한 다음 해당 값을 전달하세요. 성공한 변경 쓰기는 프로세스 런타임 스냅샷을 새로 고치고 내부 리비전을 증가시킵니다. 장기 실행 캐시는 구성을 로컬에서 직렬화하는 대신 런타임이 소유한 캐시 키를 기준으로 삼아야 합니다. 장기 실행 런타임 모듈에는 주변 `loadConfig()` 호출에 대한 무관용 스캐너가 있습니다. 전달된 `cfg`, 요청의 `context.getRuntimeConfig()`, 또는 명시적인 프로세스 경계의 `getRuntimeConfig()`를 사용하세요. -프로바이더 및 채널 실행 경로는 config 읽기 또는 편집을 위해 반환된 파일 스냅샷이 아니라 활성 런타임 config 스냅샷을 사용해야 합니다. 파일 스냅샷은 UI와 쓰기를 위해 SecretRef 마커 같은 소스 값을 보존합니다. 프로바이더 콜백에는 해석된 런타임 보기가 필요합니다. 헬퍼가 활성 소스 스냅샷 또는 활성 런타임 스냅샷 중 하나로 호출될 수 있는 경우, 자격 증명을 읽기 전에 `selectApplicableRuntimeConfig()`를 거치도록 라우팅하세요. +제공자 및 채널 실행 경로는 구성 읽기 또는 편집을 위해 반환된 파일 스냅샷이 아니라 활성 런타임 구성 스냅샷을 사용해야 합니다. 파일 스냅샷은 UI와 쓰기를 위해 SecretRef 마커 같은 원본 값을 보존합니다. 제공자 콜백에는 확인된 런타임 뷰가 필요합니다. 헬퍼가 활성 원본 스냅샷 또는 활성 런타임 스냅샷 중 하나로 호출될 수 있는 경우, 자격 증명을 읽기 전에 `selectApplicableRuntimeConfig()`를 거치도록 라우팅하세요. ## 런타임 네임스페이스 @@ -105,13 +108,13 @@ register(api) { }); ``` - `runEmbeddedAgent(...)`는 Plugin 코드에서 일반 OpenClaw 에이전트 턴을 시작하기 위한 중립 헬퍼입니다. 채널로 트리거된 응답과 동일한 프로바이더/모델 해석 및 에이전트 하네스 선택을 사용합니다. + `runEmbeddedAgent(...)`는 Plugin 코드에서 일반 OpenClaw 에이전트 턴을 시작하기 위한 중립 헬퍼입니다. 채널 트리거 응답과 동일한 제공자/모델 해석 및 에이전트 하네스 선택을 사용합니다. `runEmbeddedPiAgent(...)`는 호환성 별칭으로 남아 있습니다. - `resolveThinkingPolicy(...)`는 프로바이더/모델이 지원하는 thinking level과 선택적 기본값을 반환합니다. 프로바이더 Plugin은 thinking 훅을 통해 모델별 프로필을 소유하므로, 도구 Plugin은 프로바이더 목록을 가져오거나 중복하는 대신 이 런타임 헬퍼를 호출해야 합니다. + `resolveThinkingPolicy(...)`는 제공자/모델이 지원하는 사고 수준과 선택적 기본값을 반환합니다. 제공자 Plugin은 사고 훅을 통해 모델별 프로필을 소유하므로, 도구 Plugin은 제공자 목록을 가져오거나 복제하는 대신 이 런타임 헬퍼를 호출해야 합니다. - `normalizeThinkingLevel(...)`은 `on`, `x-high`, 또는 `extra high` 같은 사용자 텍스트를 해석된 정책과 대조하기 전에 표준 저장 level로 변환합니다. + `normalizeThinkingLevel(...)`은 `on`, `x-high`, `extra high` 같은 사용자 텍스트를 해석된 정책과 대조하기 전에 정식 저장 수준으로 변환합니다. **세션 저장소 헬퍼**는 `api.runtime.agent.session` 아래에 있습니다. @@ -125,11 +128,11 @@ register(api) { const filePath = api.runtime.agent.session.resolveSessionFilePath(cfg, sessionId); ``` - 런타임 쓰기에는 `updateSessionStore(...)` 또는 `updateSessionStoreEntry(...)`를 우선 사용하세요. 이들은 Gateway가 소유한 세션 저장소 작성자를 거치고, 동시 업데이트를 보존하며, 핫 캐시를 재사용합니다. `saveSessionStore(...)`는 호환성과 오프라인 유지관리 스타일 재작성용으로 계속 사용할 수 있습니다. + 런타임 쓰기에는 `updateSessionStore(...)` 또는 `updateSessionStoreEntry(...)`를 우선 사용하세요. 이들은 Gateway가 소유한 세션 저장소 작성기를 거치고, 동시 업데이트를 보존하며, 핫 캐시를 재사용합니다. `saveSessionStore(...)`는 호환성과 오프라인 유지보수식 재작성에 사용할 수 있도록 남아 있습니다. - 기본 모델 및 프로바이더 상수입니다. + 기본 모델 및 제공자 상수입니다. ```typescript const model = api.runtime.agent.defaults.model; // e.g. "anthropic/claude-sonnet-4-6" @@ -166,14 +169,14 @@ register(api) { ``` - 모델 재정의(`provider`/`model`)에는 config에서 `plugins.entries..subagent.allowModelOverride: true`를 통한 운영자 옵트인이 필요합니다. 신뢰할 수 없는 Plugin도 하위 에이전트를 실행할 수 있지만, 재정의 요청은 거부됩니다. + 모델 재정의(`provider`/`model`)에는 구성에서 `plugins.entries..subagent.allowModelOverride: true`를 통해 운영자의 옵트인이 필요합니다. 신뢰할 수 없는 Plugin도 하위 에이전트를 실행할 수는 있지만, 재정의 요청은 거부됩니다. - `deleteSession(...)`은 같은 Plugin이 `api.runtime.subagent.run(...)`을 통해 만든 세션을 삭제할 수 있습니다. 임의의 사용자 또는 운영자 세션을 삭제하려면 여전히 관리자 범위의 Gateway 요청이 필요합니다. + `deleteSession(...)`은 동일한 Plugin이 `api.runtime.subagent.run(...)`을 통해 생성한 세션을 삭제할 수 있습니다. 임의의 사용자 또는 운영자 세션을 삭제하려면 여전히 관리자 범위의 Gateway 요청이 필요합니다. - 연결된 Node를 나열하고 Gateway가 로드한 Plugin 코드 또는 Plugin CLI 명령에서 Node 호스트 명령을 호출합니다. Plugin이 페어링된 기기에서 로컬 작업을 소유하는 경우 사용하세요. 예를 들어 다른 Mac의 브라우저 또는 오디오 브리지가 있습니다. + 연결된 Node를 나열하고 Gateway가 로드한 Plugin 코드 또는 Plugin CLI 명령에서 Node 호스트 명령을 호출합니다. 예를 들어 다른 Mac의 브라우저 또는 오디오 브리지처럼 페어링된 장치에서 로컬 작업을 Plugin이 소유할 때 사용하세요. ```typescript const { nodes } = await api.runtime.nodes.list({ connected: true }); @@ -186,13 +189,13 @@ register(api) { }); ``` - Gateway 내부에서는 이 런타임이 인프로세스입니다. Plugin CLI 명령에서는 구성된 Gateway를 RPC로 호출하므로, `openclaw googlemeet recover-tab` 같은 명령이 터미널에서 페어링된 Node를 검사할 수 있습니다. Node 명령은 여전히 일반 Gateway Node 페어링, 명령 허용 목록, Plugin Node 호출 정책, Node 로컬 명령 처리를 거칩니다. + Gateway 내부에서는 이 런타임이 프로세스 내에서 동작합니다. Plugin CLI 명령에서는 구성된 Gateway를 RPC로 호출하므로, `openclaw googlemeet recover-tab` 같은 명령이 터미널에서 페어링된 Node를 검사할 수 있습니다. Node 명령은 여전히 일반 Gateway Node 페어링, 명령 허용 목록, Plugin Node 호출 정책, Node 로컬 명령 처리를 거칩니다. - 위험한 Node 호스트 명령을 노출하는 Plugin은 `api.registerNodeInvokePolicy(...)`로 Node 호출 정책을 등록해야 합니다. 정책은 명령 허용 목록 검사 후, 명령이 Node로 전달되기 전에 Gateway에서 실행됩니다. 따라서 직접 `node.invoke` 호출과 더 높은 수준의 Plugin 도구가 같은 강제 적용 경로를 공유합니다. + 위험한 Node 호스트 명령을 노출하는 Plugin은 `api.registerNodeInvokePolicy(...)`로 Node 호출 정책을 등록해야 합니다. 이 정책은 명령 허용 목록 확인 후, 명령이 Node로 전달되기 전에 Gateway에서 실행되므로 직접 `node.invoke` 호출과 더 높은 수준의 Plugin 도구가 같은 강제 적용 경로를 공유합니다. - Task Flow 런타임을 기존 OpenClaw 세션 키 또는 신뢰할 수 있는 도구 컨텍스트에 바인딩한 다음, 모든 호출에서 소유자를 전달하지 않고 Task Flow를 만들고 관리합니다. + Task Flow 런타임을 기존 OpenClaw 세션 키 또는 신뢰할 수 있는 도구 컨텍스트에 바인딩한 다음, 모든 호출에 소유자를 전달하지 않고 Task Flow를 만들고 관리합니다. ```typescript const taskFlow = api.runtime.tasks.managedFlows.fromToolContext(ctx); @@ -219,7 +222,7 @@ register(api) { }); ``` - 자체 바인딩 계층에서 신뢰할 수 있는 OpenClaw 세션 키를 이미 가지고 있는 경우 `bindSession({ sessionKey, requesterOrigin })`를 사용하세요. 원시 사용자 입력에서 바인딩하지 마세요. + 자체 바인딩 계층에서 신뢰할 수 있는 OpenClaw 세션 키가 이미 있는 경우 `bindSession({ sessionKey, requesterOrigin })`을 사용하세요. 원시 사용자 입력에서 바인딩하지 마세요. @@ -245,7 +248,7 @@ register(api) { }); ``` - 코어 `messages.tts` 구성과 프로바이더 선택을 사용합니다. PCM 오디오 버퍼와 샘플 레이트를 반환합니다. + 코어 `messages.tts` 구성과 제공자 선택을 사용합니다. PCM 오디오 버퍼와 샘플 레이트를 반환합니다. @@ -279,7 +282,7 @@ register(api) { }); ``` - 출력이 생성되지 않으면(예: 건너뛴 입력) `{ text: undefined }`를 반환합니다. + 출력이 생성되지 않으면(예: 입력이 건너뛰어진 경우) `{ text: undefined }`를 반환합니다. `api.runtime.stt.transcribeAudioFile(...)`는 `api.runtime.mediaUnderstanding.transcribeAudioFile(...)`의 호환성 별칭으로 유지됩니다. @@ -338,7 +341,7 @@ register(api) { - 현재 런타임 구성 스냅샷과 트랜잭션 방식의 구성 쓰기입니다. 활성 호출 경로에 이미 전달된 구성을 우선 사용하고, 핸들러가 프로세스 스냅샷을 직접 필요로 할 때만 `current()`를 사용하세요. + 현재 런타임 구성 스냅샷과 트랜잭션 구성 쓰기입니다. 활성 호출 경로에 이미 전달된 구성을 우선 사용하고, 핸들러가 프로세스 스냅샷을 직접 필요로 할 때만 `current()`를 사용하세요. ```typescript const cfg = api.runtime.config.current(); @@ -350,7 +353,7 @@ register(api) { }); ``` - `mutateConfigFile(...)` 및 `replaceConfigFile(...)`는 예를 들어 `{ mode: "restart", requiresRestart: true, reason }` 같은 `followUp` 값을 반환합니다. 이 값은 재시작 제어권을 gateway에서 빼앗지 않고 작성자의 의도를 기록합니다. + `mutateConfigFile(...)`와 `replaceConfigFile(...)`는 예를 들어 `{ mode: "restart", requiresRestart: true, reason }` 같은 `followUp` 값을 반환하며, 이는 Gateway에서 재시작 제어권을 가져오지 않고 작성자의 의도를 기록합니다. @@ -392,7 +395,7 @@ register(api) { - 모델 및 provider 인증 확인. + 모델 및 공급자 인증 확인. ```typescript const auth = await api.runtime.modelAuth.getApiKeyForModel({ model, cfg }); @@ -404,7 +407,7 @@ register(api) { - 상태 디렉터리 확인 및 SQLite 기반 키 지정 저장소. + 상태 디렉터리 확인 및 SQLite 기반 키 저장소. ```typescript const stateDir = api.runtime.state.resolveStateDir(process.env); @@ -421,7 +424,7 @@ register(api) { await store.clear(); ``` - 키 지정 저장소는 재시작 후에도 유지되며 런타임에 바인딩된 plugin id로 격리됩니다. 원자적 중복 제거 클레임에는 `registerIfAbsent(...)`를 사용하세요. 키가 없거나 만료되어 등록되면 `true`를 반환하고, 활성 값이 이미 있으면 해당 값, 생성 시간 또는 TTL을 덮어쓰지 않고 `false`를 반환합니다. 제한: 네임스페이스당 `maxEntries`, Plugin당 활성 행 1,000개, 64KB 미만의 JSON 값, 선택적 TTL 만료. + 키 저장소는 재시작 후에도 유지되며 런타임에 바인딩된 Plugin ID별로 격리됩니다. 원자적 중복 제거 클레임에는 `registerIfAbsent(...)`를 사용하세요. 키가 없거나 만료되어 등록되면 `true`를 반환하고, 값을 덮어쓰지 않은 채 이미 활성 값이 있거나 생성 시간 또는 TTL이 있으면 `false`를 반환합니다. 제한: 네임스페이스당 `maxEntries`, Plugin당 활성 행 1,000개, 64KB 미만의 JSON 값, 선택적 TTL 만료. 이 릴리스에서는 번들 Plugin만 지원됩니다. @@ -439,7 +442,7 @@ register(api) { - 채널별 런타임 헬퍼입니다(채널 Plugin이 로드된 경우 사용 가능). + 채널별 런타임 헬퍼(채널 Plugin이 로드된 경우 사용 가능). `api.runtime.channel.mentions`는 런타임 주입을 사용하는 번들 채널 Plugin을 위한 공유 인바운드 멘션 정책 표면입니다. @@ -483,10 +486,10 @@ register(api) { ## 런타임 참조 저장 -`register` 콜백 외부에서 사용하도록 런타임 참조를 저장하려면 `createPluginRuntimeStore`를 사용하세요. +`register` 콜백 외부에서 사용할 런타임 참조를 저장하려면 `createPluginRuntimeStore`를 사용하세요. - + ```typescript import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store"; import type { PluginRuntime } from "openclaw/plugin-sdk/runtime-store"; @@ -498,7 +501,7 @@ register(api) { ``` - + ```typescript export default defineChannelPluginEntry({ id: "my-plugin", @@ -509,7 +512,7 @@ register(api) { }); ``` - + ```typescript export function getRuntime() { return store.getRuntime(); // throws if not initialized @@ -524,7 +527,7 @@ register(api) { -런타임 저장소 ID에는 `pluginId`를 우선 사용하세요. 저수준 `key` 형식은 하나의 Plugin이 의도적으로 둘 이상의 런타임 슬롯을 필요로 하는 드문 경우에 사용합니다. +런타임 저장소 ID에는 `pluginId`를 우선 사용하세요. 저수준 `key` 형식은 하나의 Plugin이 의도적으로 둘 이상의 런타임 슬롯을 필요로 하는 드문 경우를 위한 것입니다. ## 기타 최상위 `api` 필드 @@ -532,7 +535,7 @@ register(api) { `api.runtime` 외에도 API 객체는 다음을 제공합니다. - Plugin id. + Plugin ID. Plugin 표시 이름. @@ -547,7 +550,7 @@ register(api) { 범위 지정 로거(`debug`, `info`, `warn`, `error`). - 현재 로드 모드입니다. `"setup-runtime"`은 전체 엔트리 전의 가벼운 시작/설정 구간입니다. + 현재 로드 모드입니다. `"setup-runtime"`은 전체 진입 이전의 경량 시작/설정 기간입니다. Plugin 루트를 기준으로 경로를 확인합니다. @@ -556,5 +559,5 @@ register(api) { ## 관련 항목 - [Plugin 내부 구조](/ko/plugins/architecture) — 기능 모델 및 레지스트리 -- [SDK 엔트리 포인트](/ko/plugins/sdk-entrypoints) — `definePluginEntry` 옵션 +- [SDK 진입점](/ko/plugins/sdk-entrypoints) — `definePluginEntry` 옵션 - [SDK 개요](/ko/plugins/sdk-overview) — 하위 경로 참조 diff --git a/docs/ko/plugins/webhooks.md b/docs/ko/plugins/webhooks.md index 5fcada260..bcb0b750c 100644 --- a/docs/ko/plugins/webhooks.md +++ b/docs/ko/plugins/webhooks.md @@ -1,33 +1,31 @@ --- read_when: - 외부 시스템에서 TaskFlows를 트리거하거나 구동하려는 경우 - - 번들로 제공되는 webhooks Plugin을 구성하고 있습니다 -summary: 'Webhook Plugin: 신뢰할 수 있는 외부 자동화를 위한 인증된 TaskFlow 인그레스' + - 번들된 Webhook Plugin을 구성하고 있습니다 +summary: 'Webhooks Plugin: 신뢰할 수 있는 외부 자동화를 위한 인증된 TaskFlow 수신 경로' title: Webhook Plugin x-i18n: - generated_at: "2026-04-30T06:45:25Z" + generated_at: "2026-05-06T17:59:35Z" model: gpt-5.5 provider: openai - source_hash: 70b195e330264af48a9e9c619bb5a0937bb15b2640edd3dd2b5517a13424e9fe + source_hash: 9d21d96f680fa24d4a53c1ed5759f800d3cfdc3336789c42c15266edd8ce9e80 source_path: plugins/webhooks.md workflow: 16 --- -# Webhooks (Plugin) +Webhooks Plugin은 외부 자동화를 OpenClaw TaskFlow에 바인딩하는 인증된 HTTP 라우트를 추가합니다. -Webhooks Plugin은 외부 자동화를 OpenClaw TaskFlows에 바인딩하는 인증된 HTTP 라우트를 추가합니다. - -Zapier, n8n, CI 작업 또는 내부 서비스 같은 신뢰할 수 있는 시스템이 먼저 사용자 지정 Plugin을 작성하지 않고도 관리형 TaskFlows를 생성하고 구동하게 하려는 경우 사용하세요. +사용자 지정 Plugin을 먼저 작성하지 않고 Zapier, n8n, CI 작업 또는 내부 서비스 같은 신뢰할 수 있는 시스템이 관리형 TaskFlow를 생성하고 구동하도록 하려는 경우 사용하세요. ## 실행 위치 -Webhooks Plugin은 Gateway 프로세스 내부에서 실행됩니다. +Webhooks Plugin은 Gateway 프로세스 안에서 실행됩니다. -Gateway가 다른 머신에서 실행 중이면 해당 Gateway 호스트에 Plugin을 설치하고 구성한 다음 Gateway를 다시 시작하세요. +Gateway가 다른 머신에서 실행되는 경우, 해당 Gateway 호스트에 Plugin을 설치하고 구성한 다음 Gateway를 재시작하세요. ## 라우트 구성 -`plugins.entries.webhooks.config` 아래에 구성을 설정합니다. +`plugins.entries.webhooks.config` 아래에 구성을 설정하세요. ```json5 { @@ -60,40 +58,40 @@ Gateway가 다른 머신에서 실행 중이면 해당 Gateway 호스트에 Plug - `enabled`: 선택 사항, 기본값은 `true` - `path`: 선택 사항, 기본값은 `/plugins/webhooks/` -- `sessionKey`: 바인딩된 TaskFlows를 소유하는 필수 세션 -- `secret`: 필수 공유 비밀 또는 SecretRef -- `controllerId`: 생성된 관리형 플로우의 선택적 컨트롤러 ID +- `sessionKey`: 바인딩된 TaskFlow를 소유하는 필수 세션 +- `secret`: 필수 공유 시크릿 또는 SecretRef +- `controllerId`: 생성된 관리형 흐름의 선택적 컨트롤러 ID - `description`: 선택적 운영자 메모 지원되는 `secret` 입력: - 일반 문자열 -- `source: "env" | "file" | "exec"`가 있는 SecretRef +- `source: "env" | "file" | "exec"`가 포함된 SecretRef -비밀 기반 라우트가 시작 시 비밀을 확인할 수 없으면, Plugin은 손상된 엔드포인트를 노출하는 대신 해당 라우트를 건너뛰고 경고를 기록합니다. +시크릿 기반 라우트가 시작 시 시크릿을 확인할 수 없으면, Plugin은 손상된 엔드포인트를 노출하는 대신 해당 라우트를 건너뛰고 경고를 기록합니다. ## 보안 모델 각 라우트는 구성된 `sessionKey`의 TaskFlow 권한으로 동작하도록 신뢰됩니다. -즉, 라우트는 해당 세션이 소유한 TaskFlows를 검사하고 변경할 수 있으므로 다음을 권장합니다. +즉 라우트가 해당 세션이 소유한 TaskFlow를 검사하고 변경할 수 있으므로, 다음을 권장합니다. -- 라우트마다 강력하고 고유한 비밀 사용 -- 인라인 일반 텍스트 비밀보다 비밀 참조 선호 +- 라우트마다 강력하고 고유한 시크릿 사용 +- 인라인 평문 시크릿보다 시크릿 참조 선호 - 워크플로에 맞는 가장 좁은 세션에 라우트 바인딩 - 필요한 특정 Webhook 경로만 노출 Plugin은 다음을 적용합니다. -- 공유 비밀 인증 -- 요청 본문 크기 및 시간 제한 보호 -- 고정 창 속도 제한 +- 공유 시크릿 인증 +- 요청 본문 크기 및 제한 시간 가드 +- 고정 윈도우 속도 제한 - 진행 중 요청 제한 -- `api.runtime.tasks.managedFlows.bindSession(...)`를 통한 소유자 바인딩 TaskFlow 접근 +- `api.runtime.tasks.managedFlows.bindSession(...)`를 통한 소유자 바인딩 TaskFlow 액세스 ## 요청 형식 -다음과 함께 `POST` 요청을 보냅니다. +다음과 함께 `POST` 요청을 보내세요. - `Content-Type: application/json` - `Authorization: Bearer ` 또는 `x-openclaw-webhook-secret: ` @@ -127,7 +125,7 @@ Plugin은 현재 다음 JSON `action` 값을 허용합니다. ### `create_flow` -라우트의 바인딩된 세션에 대한 관리형 TaskFlow를 생성합니다. +라우트에 바인딩된 세션의 관리형 TaskFlow를 생성합니다. 예시: @@ -142,7 +140,7 @@ Plugin은 현재 다음 JSON `action` 값을 허용합니다. ### `run_task` -기존 관리형 TaskFlow 내부에 관리형 하위 작업을 생성합니다. +기존 관리형 TaskFlow 안에 관리형 하위 작업을 생성합니다. 허용되는 런타임은 다음과 같습니다. @@ -190,5 +188,5 @@ Plugin은 의도적으로 Webhook 응답에서 소유자/세션 메타데이터 ## 관련 문서 - [Plugin 런타임 SDK](/ko/plugins/sdk-runtime) -- [Hook 및 Webhook 개요](/ko/automation/hooks) +- [후크와 Webhook 개요](/ko/automation/hooks) - [CLI Webhook](/ko/cli/webhooks) diff --git a/docs/ko/plugins/zalouser.md b/docs/ko/plugins/zalouser.md index af1074add..2a460e16a 100644 --- a/docs/ko/plugins/zalouser.md +++ b/docs/ko/plugins/zalouser.md @@ -2,28 +2,26 @@ read_when: - OpenClaw에서 Zalo Personal(비공식) 지원을 원합니다 - zalouser Plugin을 구성하거나 개발하고 있습니다 -summary: 'Zalo Personal Plugin: 네이티브 zca-js를 통한 QR 로그인 + 메시징 (Plugin 설치 + 채널 설정 + 도구)' -title: Zalo 개인용 Plugin +summary: 'Zalo Personal Plugin: 네이티브 zca-js를 통한 QR 로그인 + 메시징(Plugin 설치 + 채널 구성 + 도구)' +title: Zalo 개인 Plugin x-i18n: - generated_at: "2026-05-02T22:21:58Z" + generated_at: "2026-05-06T17:59:31Z" model: gpt-5.5 provider: openai - source_hash: b8bcead1a6425587a2cae40e4e817c45b9adf8afbfce6dc673065cc98353f844 + source_hash: 423325f99ddb5b39bba4c5f3aa71215edfdc092c872f92b5d2f00b6ea691246f source_path: plugins/zalouser.md workflow: 16 --- -# Zalo Personal (Plugin) - -네이티브 `zca-js`를 사용해 일반 Zalo 사용자 계정을 자동화하는 Plugin을 통해 OpenClaw에서 Zalo Personal을 지원합니다. +Zalo 개인 계정을 위한 OpenClaw 지원을 Plugin으로 제공하며, 네이티브 `zca-js`를 사용해 일반 Zalo 사용자 계정을 자동화합니다. -비공식 자동화는 계정 정지 또는 차단으로 이어질 수 있습니다. 사용에 따른 책임은 사용자에게 있습니다. +비공식 자동화는 계정 정지 또는 차단으로 이어질 수 있습니다. 본인 책임하에 사용하세요. ## 명명 -채널 id는 **개인 Zalo 사용자 계정**(비공식)을 자동화한다는 점을 명확히 하기 위해 `zalouser`입니다. 향후 공식 Zalo API 통합 가능성을 위해 `zalo`는 예약해 둡니다. +채널 ID는 `zalouser`이며, 이는 **개인 Zalo 사용자 계정**(비공식)을 자동화한다는 점을 명확히 하기 위한 것입니다. `zalo`는 향후 공식 Zalo API 통합 가능성을 위해 예약해 둡니다. ## 실행 위치 @@ -41,11 +39,12 @@ x-i18n: openclaw plugins install @openclaw/zalouser ``` -현재 공식 릴리스 태그를 따라가려면 기본 패키지를 사용하세요. 재현 가능한 설치가 필요할 때만 정확한 버전을 고정하세요. +현재 공식 릴리스 태그를 따르려면 bare 패키지를 사용하세요. 재현 가능한 설치가 필요할 때만 정확한 +버전을 고정하세요. -그런 다음 Gateway를 다시 시작하세요. +이후 Gateway를 다시 시작하세요. -### 옵션 B: 로컬 폴더에서 설치(dev) +### 옵션 B: 로컬 폴더에서 설치(개발) ```bash PLUGIN_SRC=./path/to/local/zalouser-plugin @@ -53,7 +52,7 @@ openclaw plugins install "$PLUGIN_SRC" cd "$PLUGIN_SRC" && pnpm install ``` -그런 다음 Gateway를 다시 시작하세요. +이후 Gateway를 다시 시작하세요. ## 구성 @@ -80,15 +79,15 @@ openclaw message send --channel zalouser --target --message "Hello fr openclaw directory peers list --channel zalouser --query "name" ``` -## Agent 도구 +## 에이전트 도구 도구 이름: `zalouser` 작업: `send`, `image`, `link`, `friends`, `groups`, `me`, `status` -채널 메시지 작업은 메시지 반응을 위한 `react`도 지원합니다. +채널 메시지 작업은 메시지 반응을 위해 `react`도 지원합니다. ## 관련 항목 -- [Plugin 빌드하기](/ko/plugins/building-plugins) +- [Plugin 빌드](/ko/plugins/building-plugins) - [커뮤니티 Plugin](/ko/plugins/community) diff --git a/docs/ko/providers/kilocode.md b/docs/ko/providers/kilocode.md index 797b202c2..dc856eaef 100644 --- a/docs/ko/providers/kilocode.md +++ b/docs/ko/providers/kilocode.md @@ -1,36 +1,34 @@ --- read_when: - - 여러 LLM에 사용할 하나의 API 키가 필요합니다 + - 여러 LLM에 사용할 단일 API 키가 필요합니다 - OpenClaw에서 Kilo Gateway를 통해 모델을 실행하려는 경우 -summary: Kilo Gateway의 통합 API를 사용하여 OpenClaw에서 다양한 모델에 액세스하세요 -title: Kilocode +summary: Kilo Gateway의 통합 API로 OpenClaw에서 다양한 모델에 액세스하기 +title: Kilo Gateway x-i18n: - generated_at: "2026-04-30T06:47:09Z" + generated_at: "2026-05-06T17:59:48Z" model: gpt-5.5 provider: openai - source_hash: c51012b94d4b720795356b67c8482ae7ee0b37d401689e923be0b7732d77c4aa + source_hash: 6105f5aafa0a36de2b140909e8dd21234aa8284259367a49c67d7040eaa0a93c source_path: providers/kilocode.md workflow: 16 --- -# Kilo Gateway +Kilo Gateway는 단일 엔드포인트와 API 키 뒤에서 여러 모델로 요청을 라우팅하는 **통합 API**를 제공합니다. OpenAI 호환이므로 대부분의 OpenAI SDK는 기본 URL만 변경하면 작동합니다. -Kilo Gateway는 단일 엔드포인트와 API 키 뒤에서 여러 모델로 요청을 라우팅하는 **통합 API**를 제공합니다. OpenAI 호환이므로 대부분의 OpenAI SDK는 기본 URL을 바꾸는 것만으로 작동합니다. - -| 속성 | 값 | -| ---- | ---------------------------------- | -| 제공자 | `kilocode` | -| 인증 | `KILOCODE_API_KEY` | -| API | OpenAI 호환 | +| 속성 | 값 | +| -------- | ---------------------------------- | +| Provider | `kilocode` | +| Auth | `KILOCODE_API_KEY` | +| API | OpenAI 호환 | | 기본 URL | `https://api.kilo.ai/api/gateway/` | ## 시작하기 - - [app.kilo.ai](https://app.kilo.ai)로 이동하여 로그인하거나 계정을 만든 다음, API Keys로 이동해 새 키를 생성합니다. + + [app.kilo.ai](https://app.kilo.ai)로 이동해 로그인하거나 계정을 만든 다음, API Keys로 이동하여 새 키를 생성합니다. - + ```bash openclaw onboard --auth-choice kilocode-api-key ``` @@ -42,7 +40,7 @@ Kilo Gateway는 단일 엔드포인트와 API 키 뒤에서 여러 모델로 요 ``` - + ```bash openclaw models list --provider kilocode ``` @@ -51,31 +49,38 @@ Kilo Gateway는 단일 엔드포인트와 API 키 뒤에서 여러 모델로 요 ## 기본 모델 -기본 모델은 Kilo Gateway에서 관리하는 제공자 소유의 스마트 라우팅 모델인 `kilocode/kilo/auto`입니다. +기본 모델은 Kilo Gateway가 관리하는 공급자 소유 스마트 라우팅 +모델인 `kilocode/kilo/auto`입니다. -OpenClaw는 `kilocode/kilo/auto`를 안정적인 기본 참조로 취급하지만, 해당 경로에 대해 소스 기반 작업-업스트림-모델 매핑을 게시하지는 않습니다. `kilocode/kilo/auto` 뒤의 정확한 업스트림 라우팅은 OpenClaw에 하드코딩되어 있지 않고 Kilo Gateway가 소유합니다. +OpenClaw는 `kilocode/kilo/auto`를 안정적인 기본 참조로 취급하지만, 해당 경로에 대한 +소스 기반 작업-업스트림 모델 매핑을 게시하지 않습니다. `kilocode/kilo/auto` 뒤의 정확한 +업스트림 라우팅은 OpenClaw에 하드코딩되어 있지 않고 Kilo Gateway가 소유합니다. -## 기본 제공 카탈로그 +## 내장 카탈로그 -OpenClaw는 시작 시 Kilo Gateway에서 사용 가능한 모델을 동적으로 검색합니다. 계정에서 사용할 수 있는 전체 모델 목록을 보려면 `/models kilocode`를 사용하세요. +OpenClaw는 시작 시 Kilo Gateway에서 사용 가능한 모델을 동적으로 검색합니다. 계정에서 사용 가능한 전체 모델 목록을 보려면 +`/models kilocode`를 사용하세요. -Gateway에서 사용할 수 있는 모든 모델은 `kilocode/` 접두사와 함께 사용할 수 있습니다. +Gateway에서 사용 가능한 모든 모델은 `kilocode/` 접두사와 함께 사용할 수 있습니다. | 모델 참조 | 참고 | | -------------------------------------- | ---------------------------------- | | `kilocode/kilo/auto` | 기본값 — 스마트 라우팅 | -| `kilocode/anthropic/claude-sonnet-4` | Kilo를 통한 Anthropic | -| `kilocode/openai/gpt-5.5` | Kilo를 통한 OpenAI | -| `kilocode/google/gemini-3-pro-preview` | Kilo를 통한 Google | -| ...그 외 다수 | 전체 목록은 `/models kilocode` 사용 | +| `kilocode/anthropic/claude-sonnet-4` | Kilo를 통한 Anthropic | +| `kilocode/openai/gpt-5.5` | Kilo를 통한 OpenAI | +| `kilocode/google/gemini-3-pro-preview` | Kilo를 통한 Google | +| ...그리고 더 많은 모델 | 전체 목록은 `/models kilocode` 사용 | -시작 시 OpenClaw는 `GET https://api.kilo.ai/api/gateway/models`를 조회하고 검색된 모델을 정적 대체 카탈로그보다 앞에 병합합니다. 번들된 대체 항목에는 항상 `input: ["text", "image"]`, `reasoning: true`, `contextWindow: 1000000`, `maxTokens: 128000`이 포함된 `kilocode/kilo/auto`(`Kilo Auto`)가 포함됩니다. +시작 시 OpenClaw는 `GET https://api.kilo.ai/api/gateway/models`를 쿼리하고 +검색된 모델을 정적 폴백 카탈로그보다 앞에 병합합니다. 번들된 폴백에는 항상 +`input: ["text", "image"]`, `reasoning: true`, `contextWindow: 1000000`, `maxTokens: 128000`을 포함하는 +`kilocode/kilo/auto`(`Kilo Auto`)가 포함됩니다. -## 설정 예시 +## 구성 예시 ```json5 { @@ -89,25 +94,31 @@ Gateway에서 사용할 수 있는 모든 모델은 `kilocode/` 접두사와 함 ``` - - Kilo Gateway는 소스에서 OpenRouter 호환으로 문서화되어 있으므로, 네이티브 OpenAI 요청 형태가 아니라 프록시 스타일의 OpenAI 호환 경로를 유지합니다. + + Kilo Gateway는 소스에서 OpenRouter 호환으로 문서화되어 있으므로 네이티브 OpenAI 요청 형태가 아니라 + 프록시 스타일의 OpenAI 호환 경로에 유지됩니다. - - Gemini 기반 Kilo 참조는 프록시-Gemini 경로를 유지하므로, OpenClaw는 네이티브 Gemini 재생 검증이나 부트스트랩 재작성 없이 그곳에서 Gemini 사고 서명 정제를 유지합니다. + - Gemini 기반 Kilo 참조는 프록시 Gemini 경로에 유지되므로 OpenClaw는 + 네이티브 Gemini 재생 검증이나 부트스트랩 재작성을 활성화하지 않고도 + 그곳에서 Gemini 사고 서명 정리를 유지합니다. - Kilo Gateway는 내부적으로 API 키와 함께 Bearer 토큰을 사용합니다. - - Kilo의 공유 스트림 래퍼는 제공자 앱 헤더를 추가하고 지원되는 구체 모델 참조에 대해 프록시 추론 페이로드를 정규화합니다. + + Kilo의 공유 스트림 래퍼는 공급자 앱 헤더를 추가하고 지원되는 구체적인 모델 참조에 대해 + 프록시 추론 페이로드를 정규화합니다. - `kilocode/kilo/auto` 및 기타 프록시 추론 미지원 힌트는 추론 주입을 건너뜁니다. 추론 지원이 필요하면 `kilocode/anthropic/claude-sonnet-4` 같은 구체 모델 참조를 사용하세요. + `kilocode/kilo/auto` 및 다른 프록시 추론 미지원 힌트는 추론 + 주입을 건너뜁니다. 추론 지원이 필요하면 + `kilocode/anthropic/claude-sonnet-4` 같은 구체적인 모델 참조를 사용하세요. - - - 시작 시 모델 검색에 실패하면 OpenClaw는 `kilocode/kilo/auto`가 포함된 번들 정적 카탈로그로 대체합니다. + + - 시작 시 모델 검색에 실패하면 OpenClaw는 `kilocode/kilo/auto`가 포함된 번들 정적 카탈로그로 폴백합니다. - API 키가 유효하고 Kilo 계정에서 원하는 모델이 활성화되어 있는지 확인하세요. - Gateway가 데몬으로 실행되는 경우 해당 프로세스에서 `KILOCODE_API_KEY`를 사용할 수 있는지 확인하세요(예: `~/.openclaw/.env` 또는 `env.shellEnv`를 통해). @@ -117,11 +128,11 @@ Gateway에서 사용할 수 있는 모든 모델은 `kilocode/` 접두사와 함 ## 관련 항목 - - 제공자, 모델 참조, 장애 조치 동작 선택. + + 공급자, 모델 참조, 장애 조치 동작 선택. - - 전체 OpenClaw 설정 참조입니다. + + 전체 OpenClaw 구성 참조. Kilo Gateway 대시보드, API 키, 계정 관리. diff --git a/docs/ko/providers/models.md b/docs/ko/providers/models.md index fe2778e7d..fa1fab2af 100644 --- a/docs/ko/providers/models.md +++ b/docs/ko/providers/models.md @@ -1,26 +1,23 @@ --- read_when: - - 모델 제공업체를 선택하려는 경우 - - LLM 인증 + 모델 선택을 위한 빠른 설정 예시가 필요합니다 -summary: OpenClaw가 지원하는 모델 제공자(LLM) + - 모델 제공자를 선택하려는 경우 + - LLM 인증 + 모델 선택을 위한 빠른 설정 예제가 필요한 경우 +summary: OpenClaw에서 지원하는 모델 제공자(대규모 언어 모델) title: 모델 제공자 빠른 시작 x-i18n: - generated_at: "2026-04-30T06:47:35Z" + generated_at: "2026-05-06T18:00:11Z" model: gpt-5.5 provider: openai - source_hash: 3f71f9ab34df2b545128bfeed3cab82f31b741d4a66263113068568ce6b77cd6 + source_hash: 7e95d37f3e332a9b2eb58a15dc356ad02b4cbf409926adb3faf1923825219887 source_path: providers/models.md workflow: 16 --- -# 모델 제공자 - -OpenClaw는 여러 LLM 제공자를 사용할 수 있습니다. 하나를 선택하고 인증한 다음 기본 -모델을 `provider/model`로 설정합니다. +OpenClaw는 다양한 LLM 제공업체를 사용할 수 있습니다. 하나를 선택하고 인증한 다음 기본 모델을 `provider/model`로 설정하세요. ## 빠른 시작(두 단계) -1. 제공자로 인증합니다(보통 `openclaw onboard` 사용). +1. 제공업체로 인증합니다(보통 `openclaw onboard`를 통해). 2. 기본 모델을 설정합니다. ```json5 @@ -29,24 +26,24 @@ OpenClaw는 여러 LLM 제공자를 사용할 수 있습니다. 하나를 선택 } ``` -## 지원되는 제공자(시작 세트) +## 지원되는 제공업체(시작 세트) - [Alibaba Model Studio](/ko/providers/alibaba) - [Amazon Bedrock](/ko/providers/bedrock) -- [Anthropic (API + Claude CLI)](/ko/providers/anthropic) -- [BytePlus (International)](/ko/concepts/model-providers#byteplus-international) +- [Anthropic(API + Claude CLI)](/ko/providers/anthropic) +- [BytePlus(International)](/ko/concepts/model-providers#byteplus-international) - [Chutes](/ko/providers/chutes) - [ComfyUI](/ko/providers/comfy) - [Cloudflare AI Gateway](/ko/providers/cloudflare-ai-gateway) - [DeepInfra](/ko/providers/deepinfra) - [fal](/ko/providers/fal) - [Fireworks](/ko/providers/fireworks) -- [GLM 모델](/ko/providers/glm) +- [GLM models](/ko/providers/glm) - [MiniMax](/ko/providers/minimax) - [Mistral](/ko/providers/mistral) -- [Moonshot AI (Kimi + Kimi Coding)](/ko/providers/moonshot) -- [OpenAI (API + Codex)](/ko/providers/openai) -- [OpenCode (Zen + Go)](/ko/providers/opencode) +- [Moonshot AI(Kimi + Kimi Coding)](/ko/providers/moonshot) +- [OpenAI(API + Codex)](/ko/providers/openai) +- [OpenCode(Zen + Go)](/ko/providers/opencode) - [OpenRouter](/ko/providers/openrouter) - [Qianfan](/ko/providers/qianfan) - [Qwen](/ko/providers/qwen) @@ -54,21 +51,21 @@ OpenClaw는 여러 LLM 제공자를 사용할 수 있습니다. 하나를 선택 - [StepFun](/ko/providers/stepfun) - [Synthetic](/ko/providers/synthetic) - [Vercel AI Gateway](/ko/providers/vercel-ai-gateway) -- [Venice (Venice AI)](/ko/providers/venice) +- [Venice(Venice AI)](/ko/providers/venice) - [xAI](/ko/providers/xai) - [Z.AI](/ko/providers/zai) -## 추가 번들 제공자 변형 +## 추가 번들 제공업체 변형 -- `anthropic-vertex` - Vertex 자격 증명을 사용할 수 있을 때 Google Vertex에서 Anthropic을 암시적으로 지원합니다. 별도의 온보딩 인증 선택지는 없습니다 -- `copilot-proxy` - 로컬 VS Code Copilot Proxy 브리지입니다. `openclaw onboard --auth-choice copilot-proxy`를 사용하세요 -- `google-gemini-cli` - 비공식 Gemini CLI OAuth 흐름입니다. 로컬 `gemini` 설치가 필요합니다(`brew install gemini-cli` 또는 `npm install -g @google/gemini-cli`). 기본 모델은 `google-gemini-cli/gemini-3-flash-preview`입니다. `openclaw onboard --auth-choice google-gemini-cli` 또는 `openclaw models auth login --provider google-gemini-cli --set-default`를 사용하세요 +- `anthropic-vertex` - Vertex 자격 증명을 사용할 수 있을 때 Google Vertex에서 암시적으로 Anthropic을 지원합니다. 별도의 온보딩 인증 선택지는 없습니다. +- `copilot-proxy` - 로컬 VS Code Copilot Proxy 브리지입니다. `openclaw onboard --auth-choice copilot-proxy`를 사용하세요. +- `google-gemini-cli` - 비공식 Gemini CLI OAuth 흐름입니다. 로컬 `gemini` 설치가 필요합니다(`brew install gemini-cli` 또는 `npm install -g @google/gemini-cli`). 기본 모델은 `google-gemini-cli/gemini-3-flash-preview`입니다. `openclaw onboard --auth-choice google-gemini-cli` 또는 `openclaw models auth login --provider google-gemini-cli --set-default`를 사용하세요. -전체 제공자 카탈로그(xAI, Groq, Mistral 등)와 고급 구성은 -[모델 제공자](/ko/concepts/model-providers)를 참조하세요. +전체 제공업체 카탈로그(xAI, Groq, Mistral 등)와 고급 구성은 +[모델 제공업체](/ko/concepts/model-providers)를 참조하세요. ## 관련 항목 - [모델 선택](/ko/concepts/model-providers) - [모델 장애 조치](/ko/concepts/model-failover) -- [모델 CLI](/ko/cli/models) +- [Models CLI](/ko/cli/models) diff --git a/docs/ko/reference/RELEASING.md b/docs/ko/reference/RELEASING.md index 496df11e0..5a75fab4d 100644 --- a/docs/ko/reference/RELEASING.md +++ b/docs/ko/reference/RELEASING.md @@ -1,285 +1,176 @@ --- read_when: - 공개 릴리스 채널 정의를 찾는 중 - - 릴리스 검증 또는 패키지 수락 실행 - - 버전 명명 방식과 주기 확인 -summary: 릴리스 레인, 운영자 체크리스트, 검증 박스, 버전 명명 규칙 및 주기 + - 릴리스 검증 또는 패키지 인수 실행 + - 버전 명명 방식 및 릴리스 주기 +summary: 릴리스 레인, 운영자 체크리스트, 검증 박스, 버전 명명 및 주기 title: 릴리스 정책 x-i18n: - generated_at: "2026-05-05T06:08:57Z" + generated_at: "2026-05-06T18:00:20Z" model: gpt-5.5 provider: openai - source_hash: 9980265c30c6a6571db5512749ec173cca79ac70494fd09968add793be9717a5 + source_hash: d3b9f4875496d7278ba18a8b5cb2735fb870cf32254bfc1fd819e4f233db489e source_path: reference/RELEASING.md workflow: 16 --- OpenClaw에는 세 가지 공개 릴리스 레인이 있습니다. -- stable: 기본적으로 npm `beta`에 게시되거나, 명시적으로 요청된 경우 npm `latest`에 게시되는 태그된 릴리스 -- beta: npm `beta`에 게시되는 프리릴리스 태그 -- dev: 움직이는 `main`의 최신 헤드 +- 안정: 기본적으로 npm `beta`에 게시되거나, 명시적으로 요청된 경우 npm `latest`에 게시되는 태그된 릴리스 +- 베타: npm `beta`에 게시되는 프리릴리스 태그 +- 개발: `main`의 이동하는 최신 헤드 ## 버전 이름 지정 - 안정 릴리스 버전: `YYYY.M.D` - Git 태그: `vYYYY.M.D` -- 안정 수정 릴리스 버전: `YYYY.M.D-N` +- 안정 보정 릴리스 버전: `YYYY.M.D-N` - Git 태그: `vYYYY.M.D-N` - 베타 프리릴리스 버전: `YYYY.M.D-beta.N` - Git 태그: `vYYYY.M.D-beta.N` -- 월이나 일을 0으로 채우지 마세요 +- 월 또는 일을 0으로 채우지 마세요 - `latest`는 현재 승격된 안정 npm 릴리스를 의미합니다 - `beta`는 현재 베타 설치 대상을 의미합니다 -- 안정 및 안정 수정 릴리스는 기본적으로 npm `beta`에 게시됩니다. 릴리스 운영자는 `latest`를 명시적으로 대상으로 지정하거나, 검증된 베타 빌드를 나중에 승격할 수 있습니다 +- 안정 및 안정 보정 릴리스는 기본적으로 npm `beta`에 게시됩니다. 릴리스 운영자는 `latest`를 명시적으로 대상으로 지정하거나, 검증된 베타 빌드를 나중에 승격할 수 있습니다 - 모든 안정 OpenClaw 릴리스는 npm 패키지와 macOS 앱을 함께 제공합니다. 베타 릴리스는 일반적으로 npm/패키지 경로를 먼저 검증하고 게시하며, - mac 앱 빌드/서명/공증은 명시적으로 요청되지 않는 한 안정 릴리스용으로 남겨둡니다 + mac 앱 빌드/서명/공증은 명시적으로 요청되지 않는 한 안정 릴리스용으로 예약됩니다 ## 릴리스 주기 - 릴리스는 베타 우선으로 진행됩니다 - 안정 릴리스는 최신 베타가 검증된 후에만 이어집니다 -- 유지 관리자는 일반적으로 현재 `main`에서 생성한 `release/YYYY.M.D` 브랜치에서 릴리스를 자르므로, - 릴리스 검증과 수정이 `main`의 새로운 개발을 막지 않습니다 -- 베타 태그가 푸시되었거나 게시된 뒤 수정이 필요한 경우, 유지 관리자는 기존 베타 태그를 삭제하거나 다시 만들지 않고 - 다음 `-beta.N` 태그를 자릅니다 +- 유지관리자는 일반적으로 현재 `main`에서 만든 `release/YYYY.M.D` 브랜치에서 + 릴리스를 잘라내므로, 릴리스 검증과 수정이 `main`의 새 개발을 막지 않습니다 +- 베타 태그가 푸시되었거나 게시된 뒤 수정이 필요한 경우, 유지관리자는 + 이전 베타 태그를 삭제하거나 다시 만들지 않고 다음 `-beta.N` 태그를 잘라냅니다 - 자세한 릴리스 절차, 승인, 자격 증명, 복구 참고 사항은 - 유지 관리자 전용입니다 + 유지관리자 전용입니다 ## 릴리스 운영자 체크리스트 이 체크리스트는 릴리스 흐름의 공개 형태입니다. 비공개 자격 증명, 서명, 공증, dist-tag 복구, 긴급 롤백 세부 정보는 -유지 관리자 전용 릴리스 런북에 남아 있습니다. +유지관리자 전용 릴리스 런북에 남겨 둡니다. -1. 현재 `main`에서 시작합니다. 최신 변경 사항을 가져오고, 대상 커밋이 푸시되었는지 확인하며, - 현재 `main` CI가 브랜치를 만들기에 충분히 정상인지 확인합니다. -2. 실제 커밋 기록을 바탕으로 `/changelog`로 최상단 `CHANGELOG.md` 섹션을 다시 작성하고, - 항목을 사용자 대상 내용으로 유지한 뒤 커밋하고 푸시하며, - 브랜치를 만들기 전에 한 번 더 rebase/pull합니다. +1. 현재 `main`에서 시작합니다. 최신 내용을 pull하고, 대상 커밋이 푸시되었는지 확인하며, + 현재 `main` CI가 브랜치를 만들기에 충분히 녹색인지 확인합니다. +2. 실제 커밋 기록을 바탕으로 `/changelog`를 사용해 최상단 `CHANGELOG.md` 섹션을 다시 작성하고, + 항목을 사용자 대상 내용으로 유지한 뒤 커밋하고, 푸시하고, 브랜치를 만들기 전에 한 번 더 rebase/pull합니다. 3. `src/plugins/compat/registry.ts` 및 `src/commands/doctor/shared/deprecation-compat.ts`의 릴리스 호환성 기록을 검토합니다. 업그레이드 경로가 계속 보장되는 경우에만 만료된 호환성을 제거하거나, 의도적으로 유지하는 이유를 기록합니다. -4. 현재 `main`에서 `release/YYYY.M.D`를 생성합니다. 일반 릴리스 작업을 +4. 현재 `main`에서 `release/YYYY.M.D`를 만듭니다. 일반 릴리스 작업을 `main`에서 직접 수행하지 마세요. 5. 의도한 태그에 필요한 모든 버전 위치를 올리고, `pnpm plugins:sync`를 실행하여 게시 가능한 Plugin 패키지가 릴리스 - 버전 및 호환성 메타데이터를 공유하게 한 다음, 로컬 결정적 사전 점검을 실행합니다. + 버전과 호환성 메타데이터를 공유하도록 한 다음, 로컬 결정적 프리플라이트를 실행합니다. `pnpm check:test-types`, `pnpm check:architecture`, `pnpm build && pnpm ui:build`, `pnpm plugins:sync:check`, 그리고 `pnpm release:check`. 6. `preflight_only=true`로 `OpenClaw NPM Release`를 실행합니다. 태그가 존재하기 전에는 - 전체 40자 릴리스 브랜치 SHA를 검증 전용 사전 점검에 사용할 수 있습니다. + 검증 전용 프리플라이트에 전체 40자 릴리스 브랜치 SHA를 사용할 수 있습니다. 성공한 `preflight_run_id`를 저장합니다. 7. 릴리스 브랜치, 태그 또는 전체 커밋 SHA에 대해 `Full Release Validation`으로 - 모든 프리릴리스 테스트를 시작합니다. 이는 네 가지 큰 릴리스 테스트 박스인 + 모든 프리릴리스 테스트를 시작합니다. 이것이 네 가지 큰 릴리스 테스트 박스인 Vitest, Docker, QA Lab, Package를 위한 단일 수동 진입점입니다. 8. 검증이 실패하면 릴리스 브랜치에서 수정하고, 수정을 증명하는 가장 작은 실패 - 파일, 레인, 워크플로 작업, 패키지 프로필, 제공자 또는 모델 허용 목록을 다시 실행합니다. 변경된 표면이 - 기존 증거를 무효화하는 경우에만 전체 엄브렐러를 다시 실행합니다. + 파일, 레인, 워크플로 작업, 패키지 프로필, 공급자 또는 모델 허용 목록을 다시 실행합니다. + 변경된 표면 때문에 이전 증거가 오래된 경우에만 전체 상위 워크플로를 다시 실행합니다. 9. 베타의 경우 `vYYYY.M.D-beta.N` 태그를 지정한 다음, 일치하는 - `release/YYYY.M.D` 브랜치에서 `OpenClaw Release Publish`를 실행합니다. 이 작업은 `pnpm plugins:sync:check`를 확인하고, - 모든 게시 가능한 Plugin 패키지를 npm에 먼저 게시한 뒤, 동일한 - 세트를 ClawPack npm-pack tarball로 ClawHub에 두 번째로 게시하고, 그런 다음 일치하는 dist-tag로 - 준비된 OpenClaw npm 사전 점검 아티팩트를 승격합니다. 게시 후에는 게시된 - `openclaw@YYYY.M.D-beta.N` 또는 `openclaw@beta` 패키지에 대해 게시 후 패키지 - 수락 검사를 실행합니다. 푸시되었거나 게시된 프리릴리스에 수정이 필요한 경우, - 다음으로 일치하는 프리릴리스 번호를 자릅니다. 기존 - 프리릴리스를 삭제하거나 다시 쓰지 마세요. + `release/YYYY.M.D` 브랜치에서 `OpenClaw Release Publish`를 실행합니다. 이 워크플로는 `pnpm plugins:sync:check`를 검증하고, + 게시 가능한 모든 Plugin 패키지를 npm으로, 동일한 집합을 + ClawHub로 병렬 디스패치한 다음, Plugin npm 게시가 성공하는 즉시 + 일치하는 dist-tag로 준비된 OpenClaw npm 프리플라이트 + 아티팩트를 승격합니다. + OpenClaw npm이 게시되는 동안 ClawHub 게시가 아직 실행 중일 수 있지만, + 릴리스 게시 워크플로는 두 Plugin 게시 경로와 + OpenClaw npm 게시 경로가 모두 성공적으로 완료될 때까지 끝나지 않습니다. 게시 후에는 게시된 `openclaw@YYYY.M.D-beta.N` 또는 + `openclaw@beta` 패키지에 대해 사후 게시 패키지 + 수락을 실행합니다. 푸시되었거나 게시된 프리릴리스에 수정이 필요하면, + 다음으로 일치하는 프리릴리스 번호를 잘라내세요. 이전 + 프리릴리스를 삭제하거나 다시 작성하지 마세요. 10. 안정 릴리스의 경우, 검증된 베타 또는 릴리스 후보에 필요한 - 검증 증거가 있는 경우에만 계속합니다. 안정 npm 게시도 - `OpenClaw Release Publish`를 통해 진행되며, 성공한 사전 점검 아티팩트를 - `preflight_run_id`로 재사용합니다. 안정 macOS 릴리스 준비 상태에는 + 검증 증거가 있을 때만 계속 진행합니다. 안정 npm 게시도 + `OpenClaw Release Publish`를 거치며, + `preflight_run_id`를 통해 성공한 프리플라이트 아티팩트를 재사용합니다. 안정 macOS 릴리스 준비 상태에는 패키징된 `.zip`, `.dmg`, `.dSYM.zip`, 그리고 `main`의 업데이트된 `appcast.xml`도 필요합니다. -11. 게시 후에는 npm 게시 후 검증기를 실행하고, 게시 후 채널 증거가 필요할 때 선택적 독립 실행형 - 게시된 npm Telegram E2E를 실행하며, - 필요한 경우 dist-tag 승격, 일치하는 전체 `CHANGELOG.md` 섹션의 GitHub 릴리스/프리릴리스 노트, - 그리고 릴리스 공지 단계를 진행합니다. +11. 게시 후에는 npm 사후 게시 검증기, 사후 게시 채널 증명이 필요할 때 선택적 독립 실행형 + 게시된 npm Telegram E2E, + 필요할 때 dist-tag 승격, 일치하는 전체 `CHANGELOG.md` 섹션의 GitHub 릴리스/프리릴리스 노트, + 그리고 릴리스 공지 단계를 실행합니다. -## 릴리스 사전 점검 +## 릴리스 프리플라이트 -- 릴리스 사전 점검 전에 `pnpm check:test-types`를 실행해 테스트 TypeScript가 더 빠른 로컬 `pnpm check` 게이트 밖에서도 계속 커버되도록 하세요 -- 릴리스 사전 점검 전에 `pnpm check:architecture`를 실행해 더 넓은 import - cycle 및 아키텍처 경계 검사가 더 빠른 로컬 게이트 밖에서도 녹색이 되도록 하세요 -- `pnpm release:check` 전에 `pnpm build && pnpm ui:build`를 실행해 예상되는 - `dist/*` 릴리스 아티팩트와 Control UI 번들이 pack - 검증 단계에 존재하도록 하세요 -- 루트 버전 bump 후, 태깅 전에 `pnpm plugins:sync`를 실행하세요. 이 명령은 - 배포 가능한 Plugin 패키지 버전, OpenClaw peer/API 호환성 - 메타데이터, 빌드 메타데이터, Plugin changelog stub을 core - 릴리스 버전에 맞게 업데이트합니다. `pnpm plugins:sync:check`는 변경하지 않는 릴리스 가드입니다; - 이 단계를 잊은 경우 publish workflow는 registry 변경 전에 실패합니다. -- 릴리스 승인 전에 수동 `Full Release Validation` workflow를 실행해 - 하나의 entrypoint에서 모든 사전 릴리스 test box를 시작하세요. 이 workflow는 branch, - tag 또는 full commit SHA를 받아 수동 `CI`를 dispatch하고, - install smoke, package acceptance, cross-OS - package check, QA Lab parity, Matrix 및 Telegram lane을 위해 - `OpenClaw Release Checks`를 dispatch합니다. 안정/default run은 - 포괄적인 live/E2E 및 Docker release-path soak를 - `run_release_soak=true` 뒤에 둡니다; `release_profile=full`은 soak를 강제로 켭니다. - `release_profile=full` 및 `rerun_group=all`과 함께 사용하면 release check의 - `release-package-under-test` artifact에 대해 package Telegram - E2E도 실행합니다. 동일한 - Telegram E2E가 배포된 npm 패키지도 증명해야 할 때는 publish 후 - `npm_telegram_package_spec`을 제공하세요. Package Acceptance가 - SHA로 빌드된 artifact 대신 배포된 npm 패키지에 대해 package/update matrix를 - 실행해야 할 때는 publish 후 - `package_acceptance_package_spec`을 제공하세요. - private evidence report가 Telegram E2E를 강제하지 않고 - 검증이 배포된 npm 패키지와 일치함을 증명해야 할 때는 - `evidence_package_spec`을 제공하세요. - 예: +- 릴리스 프리플라이트 전에 `pnpm check:test-types`를 실행하여 테스트 TypeScript가 더 빠른 로컬 `pnpm check` 게이트 밖에서도 계속 적용되도록 하세요 +- 릴리스 프리플라이트 전에 `pnpm check:architecture`를 실행하여 더 넓은 가져오기 순환 및 아키텍처 경계 검사가 더 빠른 로컬 게이트 밖에서도 녹색 상태가 되도록 하세요 +- `pnpm release:check` 전에 `pnpm build && pnpm ui:build`를 실행하여 pack 검증 단계에 필요한 예상 `dist/*` 릴리스 아티팩트와 Control UI 번들이 존재하도록 하세요 +- 루트 버전 범프 후, 태그 지정 전에 `pnpm plugins:sync`를 실행하세요. 이는 게시 가능한 Plugin 패키지 버전, OpenClaw 피어/API 호환성 메타데이터, 빌드 메타데이터, Plugin 변경 로그 스텁을 코어 릴리스 버전에 맞게 업데이트합니다. `pnpm plugins:sync:check`는 변경을 만들지 않는 릴리스 가드입니다. 이 단계를 잊으면 게시 워크플로가 어떤 레지스트리 변경을 하기 전에 실패합니다. +- 릴리스 승인 전에 수동 `Full Release Validation` 워크플로를 실행하여 하나의 진입점에서 모든 프리릴리스 테스트 박스를 시작하세요. 이 워크플로는 브랜치, 태그 또는 전체 커밋 SHA를 받고, 수동 `CI`를 디스패치하며, 설치 스모크, 패키지 승인, 교차 OS 패키지 검사, QA Lab 패리티, Matrix, Telegram 레인을 위한 `OpenClaw Release Checks`를 디스패치합니다. 안정/기본 실행은 철저한 라이브/E2E 및 Docker 릴리스 경로 장시간 검사를 `run_release_soak=true` 뒤에 둡니다. `release_profile=full`은 장시간 검사를 강제로 켭니다. `release_profile=full` 및 `rerun_group=all`과 함께 사용하면 릴리스 검사에서 나온 `release-package-under-test` 아티팩트를 대상으로 패키지 Telegram E2E도 실행합니다. 같은 Telegram E2E가 게시된 npm 패키지도 증명해야 한다면 게시 후 `npm_telegram_package_spec`을 제공하세요. Package Acceptance가 SHA로 빌드된 아티팩트 대신 배포된 npm 패키지를 대상으로 패키지/업데이트 매트릭스를 실행해야 한다면 게시 후 `package_acceptance_package_spec`을 제공하세요. Telegram E2E를 강제하지 않으면서 비공개 증거 보고서가 검증 대상이 게시된 npm 패키지와 일치함을 증명해야 한다면 `evidence_package_spec`을 제공하세요. 예: `gh workflow run full-release-validation.yml --ref main -f ref=release/YYYY.M.D` -- 릴리스 작업이 계속되는 동안 패키지 후보에 대한 side-channel 증명이 필요할 때는 - 수동 `Package Acceptance` workflow를 실행하세요. `openclaw@beta`, - `openclaw@latest` 또는 정확한 릴리스 버전에는 `source=npm`을 사용하세요; 현재 - `workflow_ref` harness로 신뢰할 수 있는 `package_ref` branch/tag/SHA를 pack하려면 `source=ref`를 사용하세요; 필수 - SHA-256이 있는 HTTPS tarball에는 `source=url`을 사용하세요; - 또는 다른 GitHub - Actions run에서 업로드한 tarball에는 `source=artifact`를 사용하세요. 이 workflow는 후보를 - `package-under-test`로 resolve하고, 해당 tarball에 대해 Docker E2E release scheduler를 재사용하며, - `telegram_mode=mock-openai` 또는 `telegram_mode=live-frontier`로 - 같은 tarball에 대해 Telegram QA를 실행할 수 있습니다. - 선택된 Docker lane에 `published-upgrade-survivor`가 포함되면 package - artifact가 후보가 되고 `published_upgrade_survivor_baseline`이 - 배포된 baseline을 선택합니다. `update-restart-auth`는 candidate package를 - 설치된 CLI와 package-under-test 모두로 사용하므로 - candidate update command의 managed restart path를 실행합니다. +- 릴리스 작업이 계속되는 동안 패키지 후보에 대한 사이드 채널 증거가 필요할 때 수동 `Package Acceptance` 워크플로를 실행하세요. `openclaw@beta`, `openclaw@latest` 또는 정확한 릴리스 버전에는 `source=npm`을 사용하세요. 현재 `workflow_ref` 하네스로 신뢰할 수 있는 `package_ref` 브랜치/태그/SHA를 pack하려면 `source=ref`를 사용하세요. 필수 SHA-256이 있는 HTTPS 타볼에는 `source=url`을 사용하세요. 다른 GitHub Actions 실행에서 업로드한 타볼에는 `source=artifact`를 사용하세요. 워크플로는 후보를 `package-under-test`로 해석하고, 해당 타볼에 대해 Docker E2E 릴리스 스케줄러를 재사용하며, `telegram_mode=mock-openai` 또는 `telegram_mode=live-frontier`로 같은 타볼에 대해 Telegram QA를 실행할 수 있습니다. 선택한 Docker 레인에 `published-upgrade-survivor`가 포함되면 패키지 아티팩트가 후보가 되고 `published_upgrade_survivor_baseline`이 게시된 기준선을 선택합니다. `update-restart-auth`는 후보 패키지를 설치된 CLI와 package-under-test 양쪽으로 사용하므로 후보 업데이트 명령의 관리형 재시작 경로를 실행합니다. 예: `gh workflow run package-acceptance.yml --ref main -f workflow_ref=main -f source=npm -f package_spec=openclaw@beta -f suite_profile=product -f published_upgrade_survivor_baseline=openclaw@2026.4.26 -f telegram_mode=mock-openai` - 공통 profile: - - `smoke`: install/channel/agent, gateway network 및 config reload lane - - `package`: OpenWebUI 또는 live ClawHub 없이 artifact-native package/update/restart/plugin lane - - `product`: package profile에 MCP channel, cron/subagent cleanup, - OpenAI web search 및 OpenWebUI 추가 - - `full`: OpenWebUI가 포함된 Docker release-path chunk - - `custom`: focused rerun을 위한 정확한 `docker_lanes` 선택 -- 릴리스 후보에 대한 전체 일반 CI - coverage만 필요할 때는 수동 `CI` workflow를 직접 실행하세요. 수동 CI dispatch는 changed - scoping을 우회하고 Linux Node shard, bundled-plugin shard, channel - contract, Node 22 compatibility, `check`, `check-additional`, build smoke, - docs check, Python skills, Windows, macOS, Android 및 Control UI i18n - lane을 강제로 실행합니다. + 일반 프로필: + - `smoke`: 설치/채널/에이전트, Gateway 네트워크, 구성 다시 로드 레인 + - `package`: OpenWebUI 또는 라이브 ClawHub 없는 아티팩트 네이티브 패키지/업데이트/재시작/Plugin 레인 + - `product`: 패키지 프로필에 MCP 채널, cron/서브에이전트 정리, OpenAI 웹 검색, OpenWebUI를 더한 구성 + - `full`: OpenWebUI가 포함된 Docker 릴리스 경로 청크 + - `custom`: 집중 재실행을 위한 정확한 `docker_lanes` 선택 +- 릴리스 후보에 대한 전체 일반 CI 적용 범위만 필요할 때 수동 `CI` 워크플로를 직접 실행하세요. 수동 CI 디스패치는 변경 범위 지정을 우회하고 Linux Node 샤드, 번들 Plugin 샤드, 채널 계약, Node 22 호환성, `check`, `check-additional`, 빌드 스모크, 문서 검사, Python skills, Windows, macOS, Android, Control UI i18n 레인을 강제로 실행합니다. 예: `gh workflow run ci.yml --ref release/YYYY.M.D` -- 릴리스 telemetry를 검증할 때 `pnpm qa:otel:smoke`를 실행하세요. 이 명령은 - 로컬 OTLP/HTTP receiver를 통해 QA-lab을 실행하고, Opik, Langfuse 또는 다른 외부 collector 없이 - export된 trace - span name, bounded attribute 및 content/identifier redaction을 검증합니다. -- 모든 tagged release 전에 `pnpm release:check`를 실행하세요 -- tag가 존재한 후 변경을 수행하는 publish sequence를 위해 - `OpenClaw Release Publish`를 실행하세요. - `release/YYYY.M.D`에서 dispatch하거나(main에 도달 가능한 tag를 publish할 때는 `main`), - release tag와 성공한 OpenClaw npm - `preflight_run_id`를 전달하고, 의도적으로 focused repair를 실행하는 경우가 아니라면 - default Plugin publish scope - `all-publishable`을 유지하세요. 이 workflow는 Plugin npm publish, Plugin ClawHub publish 및 OpenClaw - npm publish를 직렬화해 core package가 externalized - plugins보다 먼저 publish되지 않도록 합니다. -- Release check는 이제 별도 수동 workflow에서 실행됩니다: +- 릴리스 텔레메트리를 검증할 때 `pnpm qa:otel:smoke`를 실행하세요. 이는 로컬 OTLP/HTTP 수신기를 통해 QA-lab을 실행하고, Opik, Langfuse 또는 다른 외부 수집기를 요구하지 않고 내보낸 trace span 이름, 제한된 속성, 콘텐츠/식별자 수정 처리를 검증합니다. +- 태그가 지정된 모든 릴리스 전에 `pnpm release:check`를 실행하세요 +- 태그가 존재한 후 변경을 수행하는 게시 시퀀스에는 `OpenClaw Release Publish`를 실행하세요. `release/YYYY.M.D`에서 디스패치하세요. main에서 접근 가능한 태그를 게시할 때는 `main`에서 디스패치하고, 릴리스 태그와 성공한 OpenClaw npm `preflight_run_id`를 전달하며, 의도적으로 집중 복구를 실행하는 경우가 아니라면 기본 Plugin 게시 범위 `all-publishable`을 유지하세요. 이 워크플로는 Plugin npm 게시, Plugin ClawHub 게시, OpenClaw npm 게시를 직렬화하여 외부화된 Plugin보다 먼저 코어 패키지가 게시되지 않도록 합니다. +- 릴리스 검사는 이제 별도 수동 워크플로에서 실행됩니다: `OpenClaw Release Checks` -- `OpenClaw Release Checks`는 릴리스 승인 전에 QA Lab mock parity lane과 빠른 - live Matrix profile 및 Telegram QA lane도 실행합니다. live - lane은 `qa-live-shared` environment를 사용합니다; Telegram은 Convex CI - credential lease도 사용합니다. 전체 Matrix - transport, media 및 E2EE inventory를 병렬로 실행하려면 - `matrix_profile=all` 및 `matrix_shards=true`로 수동 `QA-Lab - All Lanes` workflow를 실행하세요. -- Cross-OS install 및 upgrade runtime validation은 public - `OpenClaw Release Checks`와 `Full Release Validation`의 일부이며, 이 둘은 - reusable workflow - `.github/workflows/openclaw-cross-os-release-checks-reusable.yml`를 직접 호출합니다 -- 이 분리는 의도된 것입니다: 실제 npm release path는 짧고 - deterministic하며 artifact-focused로 유지하고, 더 느린 live check는 자체 - lane에 둬 publish를 지연하거나 차단하지 않게 합니다 -- secret을 포함하는 release check는 `Full Release -Validation`을 통해 dispatch하거나 `main`/release workflow ref에서 dispatch해 workflow logic과 - secret이 통제되도록 해야 합니다 -- `OpenClaw Release Checks`는 resolved commit이 OpenClaw branch 또는 release tag에서 - 도달 가능하기만 하면 branch, tag 또는 full commit SHA를 받습니다 -- `OpenClaw NPM Release` validation-only preflight도 pushed tag를 요구하지 않고 - 현재 full 40-character workflow-branch commit SHA를 받습니다 -- 해당 SHA path는 validation-only이며 실제 publish로 승격할 수 없습니다 -- SHA mode에서 workflow는 package metadata check를 위해서만 - `v`을 합성합니다; 실제 publish에는 여전히 실제 release tag가 필요합니다 -- 두 workflow 모두 실제 publish 및 promotion path는 GitHub-hosted - runner에 유지하고, 변경하지 않는 validation path는 더 큰 - Blacksmith Linux runner를 사용할 수 있습니다 -- 해당 workflow는 - `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache`를 - `OPENAI_API_KEY`와 `ANTHROPIC_API_KEY` workflow secret을 모두 사용해 실행합니다 -- npm release preflight는 더 이상 별도 release check lane을 기다리지 않습니다 -- 승인 전에 `RELEASE_TAG=vYYYY.M.D node --import tsx scripts/openclaw-npm-release-check.ts` - (또는 일치하는 beta/correction tag)를 실행하세요 -- npm publish 후에는 - `node --import tsx scripts/openclaw-npm-postpublish-verify.ts YYYY.M.D` - (또는 일치하는 beta/correction version)를 실행해 fresh temp prefix에서 배포된 registry - install path를 검증하세요 -- beta publish 후에는 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@YYYY.M.D-beta.N OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci pnpm test:docker:npm-telegram-live`를 실행해 - shared leased Telegram credential - pool을 사용하여 배포된 npm 패키지에 대해 installed-package onboarding, Telegram setup 및 실제 Telegram E2E를 - 검증하세요. 로컬 maintainer one-off는 Convex var를 생략하고 세 개의 - `OPENCLAW_QA_TELEGRAM_*` env credential을 직접 전달할 수 있습니다. -- maintainer machine에서 전체 post-publish beta smoke를 실행하려면 `pnpm release:beta-smoke -- --beta betaN`를 사용하세요. 이 helper는 Parallels npm update/fresh-target validation을 실행하고, `NPM Telegram Beta E2E`를 dispatch하고, 정확한 workflow run을 poll하고, artifact를 download한 뒤 Telegram report를 출력합니다. -- Maintainer는 GitHub Actions에서 수동 `NPM Telegram Beta E2E` workflow를 통해 - 동일한 post-publish check를 실행할 수 있습니다. 이는 의도적으로 manual-only이며 - 모든 merge에서 실행되지 않습니다. -- Maintainer release automation은 이제 preflight-then-promote를 사용합니다: - - 실제 npm publish는 성공한 npm `preflight_run_id`를 통과해야 합니다 - - 실제 npm publish는 성공한 preflight run과 같은 `main` 또는 - `release/YYYY.M.D` branch에서 dispatch되어야 합니다 - - stable npm release의 기본값은 `beta`입니다 - - stable npm publish는 workflow input을 통해 명시적으로 `latest`를 target할 수 있습니다 - - token 기반 npm dist-tag mutation은 이제 보안을 위해 - `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`에 있습니다. public repo는 OIDC-only publish를 유지하는 반면 - `npm dist-tag add`에는 여전히 `NPM_TOKEN`이 필요하기 때문입니다 - - public `macOS Release`는 validation-only입니다; tag가 release branch에만 있고 - workflow가 `main`에서 dispatch되는 경우 - `public_release_branch=release/YYYY.M.D`를 설정하세요 - - 실제 private mac publish는 성공한 private mac - `preflight_run_id`와 `validate_run_id`를 통과해야 합니다 - - 실제 publish path는 artifact를 다시 build하지 않고 준비된 artifact를 promote합니다 -- `YYYY.M.D-N` 같은 stable correction release의 경우 post-publish verifier는 - `YYYY.M.D`에서 `YYYY.M.D-N`으로의 동일한 temp-prefix upgrade path도 확인해 - release correction이 이전 global install을 base stable payload에 - 조용히 남겨두지 못하게 합니다 -- npm release preflight는 tarball에 - `dist/control-ui/index.html`과 비어 있지 않은 `dist/control-ui/assets/` payload가 모두 포함되지 않으면 fail closed하여 - 빈 browser dashboard를 다시 배포하지 않도록 합니다 -- Post-publish verification은 배포된 Plugin entrypoint와 - package metadata가 설치된 registry layout에 있는지도 확인합니다. Plugin runtime payload가 누락된 상태로 - 배포되는 release는 postpublish verifier에서 실패하며 - `latest`로 promote될 수 없습니다. -- `pnpm test:install:smoke`는 candidate update tarball에 대해 npm pack `unpackedSize` budget도 강제하므로 - installer e2e가 release publish path 전에 우발적인 pack bloat를 포착합니다 -- 릴리스 작업이 CI planning, extension timing manifest 또는 - extension test matrix를 수정했다면 승인 전에 - `.github/workflows/plugin-prerelease.yml`에서 planner가 소유한 - `plugin-prerelease-extension-shard` matrix output을 재생성하고 검토해 release note가 - 오래된 CI layout을 설명하지 않게 하세요 -- Stable macOS release readiness에는 updater surface도 포함됩니다: - - GitHub release에는 packaged `.zip`, `.dmg`, `.dSYM.zip`이 포함되어야 합니다 - - `main`의 `appcast.xml`은 publish 후 새 stable zip을 가리켜야 합니다 - - packaged app은 non-debug bundle id, 비어 있지 않은 Sparkle feed - URL, 그리고 해당 release version의 canonical Sparkle build floor 이상인 `CFBundleVersion`을 - 유지해야 합니다 +- `OpenClaw Release Checks`는 릴리스 승인 전에 QA Lab mock 패리티 레인과 빠른 라이브 Matrix 프로필 및 Telegram QA 레인도 실행합니다. 라이브 레인은 `qa-live-shared` 환경을 사용합니다. Telegram은 Convex CI 자격 증명 임대도 사용합니다. 전체 Matrix 전송, 미디어, E2EE 인벤토리를 병렬로 원할 때는 `matrix_profile=all` 및 `matrix_shards=true`로 수동 `QA-Lab - All Lanes` 워크플로를 실행하세요. +- 교차 OS 설치 및 업그레이드 런타임 검증은 공개 `OpenClaw Release Checks` 및 `Full Release Validation`의 일부이며, 이들은 재사용 워크플로 `.github/workflows/openclaw-cross-os-release-checks-reusable.yml`을 직접 호출합니다 +- 이 분리는 의도된 것입니다. 실제 npm 릴리스 경로는 짧고 결정적이며 아티팩트 중심으로 유지하고, 더 느린 라이브 검사는 자체 레인에 두어 게시를 지연하거나 차단하지 않도록 합니다 +- 비밀을 포함하는 릴리스 검사는 `Full Release Validation`을 통해, 또는 `main`/릴리스 워크플로 ref에서 디스패치해야 워크플로 로직과 비밀이 통제된 상태로 유지됩니다 +- `OpenClaw Release Checks`는 해석된 커밋이 OpenClaw 브랜치 또는 릴리스 태그에서 도달 가능하다면 브랜치, 태그 또는 전체 커밋 SHA를 받습니다 +- `OpenClaw NPM Release` 검증 전용 프리플라이트도 푸시된 태그를 요구하지 않고 현재 전체 40자 워크플로 브랜치 커밋 SHA를 받습니다 +- 해당 SHA 경로는 검증 전용이며 실제 게시로 승격될 수 없습니다 +- SHA 모드에서 워크플로는 패키지 메타데이터 검사에만 `v`을 합성합니다. 실제 게시는 여전히 실제 릴리스 태그가 필요합니다 +- 두 워크플로 모두 실제 게시 및 승격 경로는 GitHub 호스팅 러너에서 유지하고, 변경을 만들지 않는 검증 경로는 더 큰 Blacksmith Linux 러너를 사용할 수 있습니다 +- 해당 워크플로는 `OPENCLAW_LIVE_TEST=1 OPENCLAW_LIVE_CACHE_TEST=1 pnpm test:live:cache`를 실행하며, `OPENAI_API_KEY` 및 `ANTHROPIC_API_KEY` 워크플로 비밀을 모두 사용합니다 +- npm 릴리스 프리플라이트는 더 이상 별도 릴리스 검사 레인을 기다리지 않습니다 +- 승인 전에 `RELEASE_TAG=vYYYY.M.D node --import tsx scripts/openclaw-npm-release-check.ts`를 실행하세요 + (또는 일치하는 beta/수정 태그) +- npm 게시 후에는 `node --import tsx scripts/openclaw-npm-postpublish-verify.ts YYYY.M.D`를 실행하여 새 임시 prefix에서 게시된 레지스트리 설치 경로를 검증하세요 + (또는 일치하는 beta/수정 버전) +- beta 게시 후에는 `OPENCLAW_NPM_TELEGRAM_PACKAGE_SPEC=openclaw@YYYY.M.D-beta.N OPENCLAW_NPM_TELEGRAM_CREDENTIAL_SOURCE=convex OPENCLAW_NPM_TELEGRAM_CREDENTIAL_ROLE=ci pnpm test:docker:npm-telegram-live`를 실행하여 공유 임대 Telegram 자격 증명 풀을 사용해 게시된 npm 패키지에 대해 설치된 패키지 온보딩, Telegram 설정, 실제 Telegram E2E를 검증하세요. 로컬 유지관리자 단발 실행은 Convex 변수를 생략하고 세 개의 `OPENCLAW_QA_TELEGRAM_*` env 자격 증명을 직접 전달할 수 있습니다. +- 유지관리자 머신에서 전체 게시 후 beta 스모크를 실행하려면 `pnpm release:beta-smoke -- --beta betaN`를 사용하세요. 이 헬퍼는 Parallels npm 업데이트/새 대상 검증을 실행하고, `NPM Telegram Beta E2E`를 디스패치하며, 정확한 워크플로 실행을 폴링하고, 아티팩트를 다운로드하고, Telegram 보고서를 출력합니다. +- 유지관리자는 GitHub Actions에서 수동 `NPM Telegram Beta E2E` 워크플로를 통해 같은 게시 후 검사를 실행할 수 있습니다. 이는 의도적으로 수동 전용이며 모든 병합마다 실행되지 않습니다. +- 유지관리자 릴리스 자동화는 이제 프리플라이트 후 승격 방식을 사용합니다: + - 실제 npm 게시는 성공한 npm `preflight_run_id`를 통과해야 합니다 + - 실제 npm 게시는 성공한 프리플라이트 실행과 같은 `main` 또는 `release/YYYY.M.D` 브랜치에서 디스패치되어야 합니다 + - 안정 npm 릴리스의 기본값은 `beta`입니다 + - 안정 npm 게시는 워크플로 입력을 통해 명시적으로 `latest`를 대상으로 지정할 수 있습니다 + - 토큰 기반 npm dist-tag 변경은 이제 보안을 위해 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml`에 있습니다. 공개 저장소는 OIDC 전용 게시를 유지하지만 `npm dist-tag add`에는 여전히 `NPM_TOKEN`이 필요하기 때문입니다 + - 공개 `macOS Release`는 검증 전용입니다. 태그가 릴리스 브랜치에만 있고 워크플로가 `main`에서 디스패치된다면 `public_release_branch=release/YYYY.M.D`를 설정하세요 + - 실제 비공개 mac 게시는 성공한 비공개 mac `preflight_run_id` 및 `validate_run_id`를 통과해야 합니다 + - 실제 게시 경로는 아티팩트를 다시 빌드하는 대신 준비된 아티팩트를 승격합니다 +- `YYYY.M.D-N` 같은 안정 수정 릴리스의 경우, 게시 후 검증기는 `YYYY.M.D`에서 `YYYY.M.D-N`으로의 동일한 임시 prefix 업그레이드 경로도 검사하여 릴리스 수정이 이전 전역 설치를 기본 안정 payload에 조용히 남겨두지 않도록 합니다 +- npm 릴리스 프리플라이트는 타볼에 `dist/control-ui/index.html`과 비어 있지 않은 `dist/control-ui/assets/` payload가 모두 포함되지 않으면 실패하도록 닫혀 있습니다. 이를 통해 빈 브라우저 대시보드를 다시 배포하지 않습니다 +- 게시 후 검증은 게시된 Plugin 진입점과 패키지 메타데이터가 설치된 레지스트리 레이아웃에 존재하는지도 확인합니다. Plugin 런타임 payload가 누락된 릴리스는 postpublish 검증기에 실패하며 `latest`로 승격될 수 없습니다. +- `pnpm test:install:smoke`는 후보 업데이트 타볼에 대해 npm pack `unpackedSize` 예산도 강제하므로, 설치 프로그램 e2e가 릴리스 게시 경로 전에 의도치 않은 pack 비대를 포착합니다 +- 릴리스 작업이 CI 계획, extension 타이밍 매니페스트 또는 extension 테스트 매트릭스를 건드렸다면 승인 전에 `.github/workflows/plugin-prerelease.yml`의 planner 소유 `plugin-prerelease-extension-shard` 매트릭스 출력을 다시 생성하고 검토하여 릴리스 노트가 오래된 CI 레이아웃을 설명하지 않도록 하세요 +- 안정 macOS 릴리스 준비 상태에는 업데이터 표면도 포함됩니다: + - GitHub 릴리스에는 패키징된 `.zip`, `.dmg`, `.dSYM.zip`이 최종적으로 포함되어야 합니다 + - 게시 후 `main`의 `appcast.xml`은 새 안정 zip을 가리켜야 합니다 + - 패키징된 앱은 디버그가 아닌 번들 id, 비어 있지 않은 Sparkle 피드 URL, 해당 릴리스 버전의 정식 Sparkle 빌드 하한 이상인 `CFBundleVersion`을 유지해야 합니다 -## Release test boxes +## 릴리스 테스트 박스 -`Full Release Validation`은 operator가 하나의 entrypoint에서 모든 사전 릴리스 test를 -시작하는 방법입니다. 빠르게 변하는 branch에서 pinned commit proof가 필요하면 -helper를 사용해 모든 child workflow가 target -SHA에 고정된 임시 branch에서 실행되도록 하세요: +`Full Release Validation`은 운영자가 하나의 진입점에서 모든 프리릴리스 테스트를 시작하는 방법입니다. 빠르게 움직이는 브랜치에서 고정 커밋 증거가 필요하면, 모든 하위 워크플로가 대상 SHA에 고정된 임시 브랜치에서 실행되도록 헬퍼를 사용하세요: ```bash pnpm ci:full-release --sha ``` -이 helper는 `release-ci/-...`를 push하고, 해당 branch에서 `ref=`로 `Full Release Validation`을 -dispatch하고, 모든 child workflow `headSha`가 -target과 일치하는지 검증한 뒤 temporary branch를 삭제합니다. 이렇게 하면 실수로 더 새로운 -`main` child run을 증명하는 일을 피할 수 있습니다. +헬퍼는 `release-ci/-...`를 푸시하고, 해당 브랜치에서 `ref=`로 `Full Release Validation`을 디스패치하며, 모든 하위 워크플로의 `headSha`가 대상과 일치하는지 검증한 다음 임시 브랜치를 삭제합니다. 이렇게 하면 실수로 더 새로운 `main` 하위 실행을 증명하는 일을 피할 수 있습니다. -Release branch 또는 tag validation의 경우 trusted `main` workflow -ref에서 실행하고 release branch 또는 tag를 `ref`로 전달하세요: +릴리스 브랜치 또는 태그 검증의 경우, 신뢰할 수 있는 `main` 워크플로 ref에서 실행하고 릴리스 브랜치 또는 태그를 `ref`로 전달하세요: ```bash gh workflow run full-release-validation.yml \ @@ -291,20 +182,49 @@ gh workflow run full-release-validation.yml \ -f evidence_package_spec=openclaw@YYYY.M.D-beta.N ``` -이 워크플로는 대상 ref를 확인하고, `target_ref=`로 수동 `CI`를 디스패치하며, `OpenClaw Release Checks`를 디스패치하고, 패키지 대상 검사용 상위 `release-package-under-test` 아티팩트를 준비하며, `release_profile=full`이고 `rerun_group=all`인 경우 또는 `npm_telegram_package_spec`이 설정된 경우 독립 실행형 패키지 Telegram E2E를 디스패치합니다. 그런 다음 `OpenClaw Release Checks`는 설치 스모크, 교차 OS 릴리스 검사, soak가 활성화된 경우 라이브/E2E Docker 릴리스 경로 커버리지, Telegram 패키지 QA가 포함된 Package Acceptance, QA Lab parity, 라이브 Matrix, 라이브 Telegram으로 팬아웃합니다. 전체 실행은 `Full Release Validation` 요약에서 `normal_ci`와 `release_checks`가 성공으로 표시될 때만 허용됩니다. full/all 모드에서는 `npm_telegram` 하위 항목도 성공해야 합니다. full/all이 아닌 경우 게시된 `npm_telegram_package_spec`이 제공되지 않았다면 건너뜁니다. 최종 검증기 요약에는 각 하위 실행의 가장 느린 작업 표가 포함되므로, 릴리스 관리자가 로그를 다운로드하지 않고도 현재 중요 경로를 확인할 수 있습니다. -전체 단계 매트릭스, 정확한 워크플로 작업 이름, stable 프로필과 full 프로필의 차이, 아티팩트, 집중 재실행 핸들은 [전체 릴리스 검증](/ko/reference/full-release-validation)을 참조하세요. -하위 워크플로는 대상 `ref`가 이전 릴리스 브랜치나 태그를 가리키더라도 `Full Release Validation`을 실행하는 신뢰된 ref, 일반적으로 `--ref main`에서 디스패치됩니다. 별도의 Full Release Validation workflow-ref 입력은 없습니다. 워크플로 실행 ref를 선택하여 신뢰된 하니스를 선택하세요. -움직이는 `main`에서 정확한 커밋 증명에 `--ref main -f ref=`를 사용하지 마세요. 원시 커밋 SHA는 워크플로 디스패치 ref가 될 수 없으므로, `pnpm ci:full-release --sha `를 사용하여 고정된 임시 브랜치를 만드세요. +이 워크플로는 대상 ref를 확인하고, `target_ref=`로 수동 `CI`를 +디스패치하며, `OpenClaw Release Checks`를 디스패치하고, 패키지 대상 검사를 위한 +상위 `release-package-under-test` 아티팩트를 준비하며, `release_profile=full`이고 +`rerun_group=all`인 경우 또는 `npm_telegram_package_spec`이 설정된 경우 독립 실행형 +패키지 Telegram E2E를 디스패치합니다. 그런 다음 `OpenClaw Release Checks`는 설치 스모크, +크로스 OS 릴리스 검사, soak가 활성화된 경우 live/E2E Docker 릴리스 경로 커버리지, +Telegram 패키지 QA가 포함된 Package Acceptance, QA Lab 패리티, live Matrix, live Telegram으로 +확장됩니다. 전체 실행은 `Full Release Validation` 요약에서 `normal_ci`와 +`release_checks`가 성공으로 표시될 때만 허용됩니다. full/all 모드에서는 `npm_telegram` +하위 항목도 성공해야 하며, full/all이 아닌 경우 게시된 `npm_telegram_package_spec`이 +제공되지 않았다면 건너뜁니다. 최종 검증자 요약에는 각 하위 실행의 가장 느린 작업 +테이블이 포함되므로, 릴리스 관리자는 로그를 다운로드하지 않고도 현재 주요 경로를 +확인할 수 있습니다. +전체 단계 매트릭스, 정확한 워크플로 작업 이름, stable과 full 프로필 차이, 아티팩트, +집중 재실행 핸들은 [전체 릴리스 검증](/ko/reference/full-release-validation)을 참고하세요. +하위 워크플로는 대상 `ref`가 이전 릴리스 브랜치나 태그를 가리키는 경우에도, +일반적으로 `--ref main`인 `Full Release Validation`을 실행하는 신뢰할 수 있는 ref에서 +디스패치됩니다. 별도의 Full Release Validation workflow-ref 입력은 없습니다. 워크플로 +실행 ref를 선택하여 신뢰할 수 있는 하네스를 선택하세요. +이동 중인 `main`에서 정확한 커밋 증거를 얻기 위해 `--ref main -f ref=`를 사용하지 +마세요. 원시 커밋 SHA는 워크플로 디스패치 ref가 될 수 없으므로, +`pnpm ci:full-release --sha `를 사용해 고정된 임시 브랜치를 생성하세요. -`release_profile`을 사용하여 라이브/provider 범위를 선택하세요. +live/provider 범위를 선택하려면 `release_profile`을 사용하세요. -- `minimum`: 가장 빠른 릴리스 핵심 OpenAI/코어 라이브 및 Docker 경로 -- `stable`: minimum에 릴리스 승인을 위한 안정 provider/backend 커버리지를 추가 -- `full`: stable에 광범위한 자문 provider/media 커버리지를 추가 +- `minimum`: 가장 빠른 릴리스 필수 OpenAI/core live 및 Docker 경로 +- `stable`: 릴리스 승인을 위한 minimum에 stable provider/backend 커버리지를 더한 범위 +- `full`: stable에 광범위한 권고 provider/media 커버리지를 더한 범위 -릴리스 차단 lane이 녹색이고 프로모션 전에 포괄적인 라이브/E2E, Docker 릴리스 경로, 제한된 게시 업그레이드 생존자 스윕을 원할 때 `stable`과 함께 `run_release_soak=true`를 사용하세요. 이 스윕은 최신 네 개의 stable 패키지와 고정된 `2026.4.23` 및 `2026.5.2` 기준선, 더 오래된 `2026.4.15` 커버리지를 포함하며, 중복 기준선을 제거하고 각 기준선을 자체 Docker runner 작업으로 샤딩합니다. `full`은 `run_release_soak=true`를 의미합니다. +릴리스 차단 lane이 녹색이고 승격 전에 포괄적인 live/E2E, Docker 릴리스 경로, 제한된 +게시 업그레이드 생존자 스윕을 원할 때는 `stable`과 함께 `run_release_soak=true`를 +사용하세요. 이 스윕은 최신 4개의 stable 패키지와 고정된 `2026.4.23`, `2026.5.2` +기준선 및 더 오래된 `2026.4.15` 커버리지를 포함하며, 중복 기준선은 제거되고 각 기준선은 +자체 Docker runner 작업으로 샤딩됩니다. `full`은 `run_release_soak=true`를 암시합니다. -`OpenClaw Release Checks`는 신뢰된 워크플로 ref를 사용해 대상 ref를 한 번 `release-package-under-test`로 확인하고, soak가 실행될 때 해당 아티팩트를 cross-OS, Package Acceptance, 릴리스 경로 Docker 검사에서 재사용합니다. 이렇게 하면 모든 패키지 대상 박스가 동일한 바이트를 사용하고 반복적인 패키지 빌드를 피할 수 있습니다. cross-OS OpenAI 설치 스모크는 repo/org 변수가 설정된 경우 `OPENCLAW_CROSS_OS_OPENAI_MODEL`을 사용하고, 그렇지 않으면 `openai/gpt-5.4`를 사용합니다. 이 lane은 가장 느린 기본 모델을 벤치마킹하는 것이 아니라 패키지 설치, 온보딩, Gateway 시작, 라이브 에이전트 한 턴을 증명하기 때문입니다. 더 넓은 라이브 provider 매트릭스는 모델별 커버리지를 위한 위치로 유지됩니다. +`OpenClaw Release Checks`는 신뢰할 수 있는 워크플로 ref를 사용해 대상 ref를 한 번 +`release-package-under-test`로 확인하고, soak가 실행될 때 cross-OS, Package Acceptance, +릴리스 경로 Docker 검사에서 해당 아티팩트를 재사용합니다. 이렇게 하면 모든 패키지 대상 +박스가 동일한 바이트를 사용하고 반복적인 패키지 빌드를 피할 수 있습니다. +크로스 OS OpenAI 설치 스모크는 repo/org 변수가 설정된 경우 `OPENCLAW_CROSS_OS_OPENAI_MODEL`을 +사용하고, 그렇지 않으면 `openai/gpt-5.4`를 사용합니다. 이 lane은 가장 느린 기본 모델을 +벤치마킹하는 것이 아니라 패키지 설치, 온보딩, Gateway 시작, live agent 한 턴을 증명하기 +때문입니다. 더 광범위한 live provider 매트릭스는 모델별 커버리지를 위한 위치로 유지됩니다. 릴리스 단계에 따라 다음 변형을 사용하세요. @@ -336,22 +256,40 @@ gh workflow run full-release-validation.yml \ -f npm_telegram_provider_mode=mock-openai ``` -집중 수정 후 첫 번째 재실행으로 전체 umbrella를 사용하지 마세요. 한 박스가 실패하면 다음 증명에는 실패한 하위 워크플로, 작업, Docker lane, 패키지 프로필, 모델 provider, 또는 QA lane을 사용하세요. 수정이 공유 릴리스 오케스트레이션을 변경했거나 이전의 전체 박스 증거를 오래된 것으로 만들었을 때만 전체 umbrella를 다시 실행하세요. umbrella의 최종 검증기는 기록된 하위 워크플로 실행 ID를 다시 검사하므로, 하위 워크플로가 성공적으로 재실행된 후에는 실패한 상위 `Verify full validation` 작업만 다시 실행하세요. +집중 수정 후 첫 재실행으로 전체 umbrella를 사용하지 마세요. 하나의 박스가 실패하면 다음 +증거에는 실패한 하위 워크플로, 작업, Docker lane, 패키지 프로필, 모델 provider 또는 QA +lane을 사용하세요. 수정이 공유 릴리스 오케스트레이션을 변경했거나 이전 all-box 증거를 +오래된 것으로 만든 경우에만 전체 umbrella를 다시 실행하세요. umbrella의 최종 검증자는 +기록된 하위 워크플로 실행 ID를 다시 확인하므로, 하위 워크플로가 성공적으로 재실행된 +후에는 실패한 상위 `Verify full validation` 작업만 재실행하세요. -제한된 복구에는 `rerun_group`을 umbrella에 전달하세요. `all`은 실제 릴리스 후보 실행이고, `ci`는 일반 CI 하위 항목만 실행하며, `plugin-prerelease`는 릴리스 전용 plugin 하위 항목만 실행하고, `release-checks`는 모든 릴리스 박스를 실행합니다. 더 좁은 릴리스 그룹은 `install-smoke`, `cross-os`, `live-e2e`, `package`, `qa`, `qa-parity`, `qa-live`, `npm-telegram`입니다. 집중 `npm-telegram` 재실행에는 `npm_telegram_package_spec`이 필요합니다. `release_profile=full`인 full/all 실행은 release-checks 패키지 아티팩트를 사용합니다. 집중 cross-OS 재실행에는 `cross_os_suite_filter=windows/packaged-upgrade` 또는 다른 OS/suite 필터를 추가할 수 있습니다. QA release-check 실패는 자문 성격입니다. QA 전용 실패는 릴리스 검증을 차단하지 않습니다. +제한된 복구에는 umbrella에 `rerun_group`을 전달하세요. `all`은 실제 릴리스 후보 실행이고, +`ci`는 일반 CI 하위 항목만 실행하며, `plugin-prerelease`는 릴리스 전용 Plugin 하위 항목만 +실행하고, `release-checks`는 모든 릴리스 박스를 실행합니다. 더 좁은 릴리스 그룹은 +`install-smoke`, `cross-os`, `live-e2e`, `package`, `qa`, `qa-parity`, `qa-live`, +`npm-telegram`입니다. 집중 `npm-telegram` 재실행에는 `npm_telegram_package_spec`이 필요합니다. +`release_profile=full`인 full/all 실행은 release-checks 패키지 아티팩트를 사용합니다. +집중 cross-OS 재실행에는 `cross_os_suite_filter=windows/packaged-upgrade` 또는 다른 +OS/suite 필터를 추가할 수 있습니다. QA release-check 실패는 권고 사항입니다. QA 전용 +실패는 릴리스 검증을 차단하지 않습니다. ### Vitest -Vitest 박스는 수동 `CI` 하위 워크플로입니다. 수동 CI는 의도적으로 변경 범위 지정을 우회하고 릴리스 후보에 대해 일반 테스트 그래프를 강제합니다. 여기에는 Linux Node shard, 번들 plugin shard, 채널 계약, Node 22 호환성, `check`, `check-additional`, 빌드 스모크, 문서 검사, Python Skills, Windows, macOS, Android, Control UI i18n이 포함됩니다. +Vitest 박스는 수동 `CI` 하위 워크플로입니다. 수동 CI는 의도적으로 변경 범위 지정을 우회하고 +릴리스 후보에 대해 일반 테스트 그래프를 강제합니다. Linux Node shard, bundled-plugin shard, +channel contract, Node 22 호환성, `check`, `check-additional`, build smoke, docs checks, +Python skills, Windows, macOS, Android, Control UI i18n이 포함됩니다. -이 박스는 "소스 트리가 전체 일반 테스트 스위트를 통과했는가?"에 답할 때 사용하세요. 릴리스 경로 제품 검증과는 다릅니다. 보관할 증거: +이 박스를 사용해 "소스 트리가 전체 일반 테스트 스위트를 통과했는가?"에 답하세요. +이는 릴리스 경로 제품 검증과 동일하지 않습니다. 보관할 증거: -- 디스패치된 `CI` 실행 URL을 보여주는 `Full Release Validation` 요약 +- 디스패치된 `CI` 실행 URL을 표시하는 `Full Release Validation` 요약 - 정확한 대상 SHA에서 녹색인 `CI` 실행 -- 회귀를 조사할 때 CI 작업의 실패한 shard 이름 또는 느린 shard 이름 +- 회귀를 조사할 때 CI 작업의 실패했거나 느린 shard 이름 - 실행에 성능 분석이 필요할 때 `.artifacts/vitest-shard-timings.json` 같은 Vitest 타이밍 아티팩트 -릴리스에 결정론적인 일반 CI가 필요하지만 Docker, QA Lab, 라이브, cross-OS, 또는 패키지 박스가 필요하지 않을 때만 수동 CI를 직접 실행하세요. +릴리스에 결정론적인 일반 CI가 필요하지만 Docker, QA Lab, live, cross-OS 또는 패키지 박스가 +필요하지 않은 경우에만 수동 CI를 직접 실행하세요. ```bash gh workflow run ci.yml --ref main -f target_ref=release/YYYY.M.D @@ -359,60 +297,91 @@ gh workflow run ci.yml --ref main -f target_ref=release/YYYY.M.D ### Docker -Docker 박스는 `openclaw-live-and-e2e-checks-reusable.yml`과 릴리스 모드 `install-smoke` 워크플로를 통해 `OpenClaw Release Checks` 안에 있습니다. 이는 소스 수준 테스트만이 아니라 패키징된 Docker 환경을 통해 릴리스 후보를 검증합니다. +Docker 박스는 `openclaw-live-and-e2e-checks-reusable.yml`을 통해 `OpenClaw Release Checks`에 +있으며, 릴리스 모드 `install-smoke` 워크플로도 포함됩니다. 이는 소스 수준 테스트만이 아니라 +패키지된 Docker 환경을 통해 릴리스 후보를 검증합니다. 릴리스 Docker 커버리지에는 다음이 포함됩니다. - 느린 Bun 전역 설치 스모크가 활성화된 전체 설치 스모크 -- 대상 SHA별 root Dockerfile 스모크 이미지 준비/재사용, QR, root/Gateway, installer/Bun 스모크 작업이 별도 install-smoke shard로 실행됨 +- 대상 SHA별 root Dockerfile 스모크 이미지 준비/재사용, QR, root/gateway, installer/Bun 스모크 작업이 별도 install-smoke shard로 실행됨 - 저장소 E2E lane -- 릴리스 경로 Docker 청크: `core`, `package-update-openai`, +- 릴리스 경로 Docker chunk: `core`, `package-update-openai`, `package-update-anthropic`, `package-update-core`, `plugins-runtime-plugins`, `plugins-runtime-services`, `plugins-runtime-install-a`, `plugins-runtime-install-b`, `plugins-runtime-install-c`, `plugins-runtime-install-d`, `plugins-runtime-install-e`, `plugins-runtime-install-f`, `plugins-runtime-install-g`, `plugins-runtime-install-h` -- 요청된 경우 `plugins-runtime-services` 청크 내부의 OpenWebUI 커버리지 -- 분할된 번들 plugin 설치/제거 lane +- 요청 시 `plugins-runtime-services` chunk 내부의 OpenWebUI 커버리지 +- 분할 bundled Plugin 설치/제거 lane `bundled-plugin-install-uninstall-0`부터 `bundled-plugin-install-uninstall-23`까지 -- 릴리스 검사가 라이브 suite를 포함할 때 라이브/E2E provider suite와 Docker 라이브 모델 커버리지 +- 릴리스 검사가 live suite를 포함할 때 live/E2E provider suite 및 Docker live 모델 커버리지 -재실행 전에 Docker 아티팩트를 사용하세요. 릴리스 경로 스케줄러는 lane 로그, `summary.json`, `failures.json`, 단계 타이밍, 스케줄러 계획 JSON, 재실행 명령이 포함된 `.artifacts/docker-tests/`를 업로드합니다. 집중 복구에는 모든 릴리스 청크를 다시 실행하는 대신 재사용 가능한 live/E2E 워크플로에서 `docker_lanes=`을 사용하세요. 생성된 재실행 명령에는 사용 가능한 경우 이전 `package_artifact_run_id`와 준비된 Docker 이미지 입력이 포함되므로, 실패한 lane이 동일한 tarball과 GHCR 이미지를 재사용할 수 있습니다. +재실행하기 전에 Docker 아티팩트를 사용하세요. 릴리스 경로 스케줄러는 lane 로그, +`summary.json`, `failures.json`, 단계 타이밍, 스케줄러 계획 JSON, 재실행 명령이 포함된 +`.artifacts/docker-tests/`를 업로드합니다. 집중 복구에는 모든 릴리스 chunk를 재실행하는 +대신 재사용 가능한 live/E2E 워크플로에서 `docker_lanes=`을 사용하세요. +생성된 재실행 명령에는 사용 가능한 경우 이전 `package_artifact_run_id`와 준비된 Docker +이미지 입력이 포함되므로, 실패한 lane은 동일한 tarball과 GHCR 이미지를 재사용할 수 있습니다. ### QA Lab -QA Lab 박스도 `OpenClaw Release Checks`의 일부입니다. 이는 Vitest 및 Docker 패키지 메커니즘과 별개인 에이전트 동작 및 채널 수준 릴리스 게이트입니다. +QA Lab 박스도 `OpenClaw Release Checks`의 일부입니다. 이는 Vitest 및 Docker 패키지 +메커니즘과 별개인 agentic 동작 및 channel 수준 릴리스 게이트입니다. 릴리스 QA Lab 커버리지에는 다음이 포함됩니다. -- 에이전트 parity pack을 사용하여 OpenAI 후보 lane을 Opus 4.6 기준선과 비교하는 mock parity lane -- `qa-live-shared` 환경을 사용하는 빠른 라이브 Matrix QA 프로필 -- Convex CI credential lease를 사용하는 라이브 Telegram QA lane -- 릴리스 telemetry에 명시적인 로컬 증명이 필요할 때 `pnpm qa:otel:smoke` +- agentic parity pack을 사용해 OpenAI 후보 lane을 Opus 4.6 기준선과 비교하는 mock parity lane +- `qa-live-shared` 환경을 사용하는 빠른 live Matrix QA 프로필 +- Convex CI 자격 증명 lease를 사용하는 live Telegram QA lane +- 릴리스 telemetry에 명시적 로컬 증거가 필요할 때 `pnpm qa:otel:smoke` -이 박스는 "릴리스가 QA 시나리오와 라이브 채널 흐름에서 올바르게 동작하는가?"에 답할 때 사용하세요. 릴리스를 승인할 때 parity, Matrix, Telegram lane의 아티팩트 URL을 보관하세요. 전체 Matrix 커버리지는 기본 릴리스 핵심 lane이 아니라 수동 sharded QA-Lab 실행으로 계속 사용할 수 있습니다. +이 박스를 사용해 "릴리스가 QA 시나리오와 live channel 흐름에서 올바르게 동작하는가?"에 +답하세요. 릴리스를 승인할 때 parity, Matrix, Telegram lane의 아티팩트 URL을 보관하세요. +전체 Matrix 커버리지는 기본 릴리스 필수 lane이 아니라 수동 샤딩 QA-Lab 실행으로 계속 사용할 +수 있습니다. -### 패키지 +### Package -패키지 박스는 설치 가능한 제품 게이트입니다. 이는 `Package Acceptance`와 resolver `scripts/resolve-openclaw-package-candidate.mjs`를 기반으로 합니다. resolver는 후보를 Docker E2E에서 소비하는 `package-under-test` tarball로 정규화하고, 패키지 inventory를 검증하며, 패키지 버전과 SHA-256을 기록하고, 워크플로 하니스 ref를 패키지 소스 ref와 분리하여 유지합니다. +Package 박스는 설치 가능한 제품 게이트입니다. 이는 `Package Acceptance`와 +`scripts/resolve-openclaw-package-candidate.mjs` resolver를 기반으로 합니다. resolver는 +후보를 Docker E2E가 소비하는 `package-under-test` tarball로 정규화하고, 패키지 inventory를 +검증하며, 패키지 버전과 SHA-256을 기록하고, 워크플로 하네스 ref를 패키지 소스 ref와 +분리된 상태로 유지합니다. 지원되는 후보 소스: -- `source=npm`: `openclaw@beta`, `openclaw@latest`, 또는 정확한 OpenClaw 릴리스 버전 -- `source=ref`: 선택된 `workflow_ref` 하니스로 신뢰된 `package_ref` 브랜치, 태그, 또는 전체 커밋 SHA를 패키징 +- `source=npm`: `openclaw@beta`, `openclaw@latest` 또는 정확한 OpenClaw 릴리스 버전 +- `source=ref`: 선택한 `workflow_ref` 하네스로 신뢰할 수 있는 `package_ref` 브랜치, 태그 또는 전체 커밋 SHA 패키징 - `source=url`: 필수 `package_sha256`이 있는 HTTPS `.tgz` 다운로드 -- `source=artifact`: 다른 GitHub Actions 실행에서 업로드한 `.tgz` 재사용 +- `source=artifact`: 다른 GitHub Actions 실행이 업로드한 `.tgz` 재사용 -`OpenClaw Release Checks`는 `source=artifact`, 준비된 릴리스 패키지 아티팩트, `suite_profile=custom`, `docker_lanes=doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor update-restart-auth plugins-offline plugin-update`, `telegram_mode=mock-openai`로 Package Acceptance를 실행합니다. Package Acceptance는 동일하게 확인된 tarball에 대해 migration, update, configured-auth update restart, 오래된 plugin 의존성 정리, offline plugin fixture, plugin update, Telegram 패키지 QA를 유지합니다. 차단 릴리스 검사는 기본 최신 게시 패키지 기준선을 사용합니다. `run_release_soak=true` 또는 `release_profile=full`은 `2026.4.23`부터 `latest`까지 npm에 게시된 모든 stable 기준선과 보고된 이슈 fixture로 확장됩니다. 이미 배포된 후보에는 `source=npm`으로 Package Acceptance를 사용하고, 게시 전 SHA 기반 로컬 npm tarball에는 `source=ref`/`source=artifact`를 사용하세요. 이는 이전에 Parallels가 필요했던 대부분의 패키지/update 커버리지를 대체하는 GitHub 네이티브 방식입니다. OS별 온보딩, installer, 플랫폼 동작에는 cross-OS 릴리스 검사가 여전히 중요하지만, 패키지/update 제품 검증에는 Package Acceptance를 우선 사용해야 합니다. +`OpenClaw Release Checks`는 `source=artifact`, 준비된 릴리스 패키지 아티팩트, +`suite_profile=custom`, +`docker_lanes=doctor-switch update-channel-switch upgrade-survivor published-upgrade-survivor update-restart-auth plugins-offline plugin-update`, +`telegram_mode=mock-openai`로 Package Acceptance를 실행합니다. Package Acceptance는 동일한 +확인된 tarball에 대해 migration, update, configured-auth update restart, stale Plugin +dependency cleanup, offline Plugin fixture, Plugin update, Telegram 패키지 QA를 유지합니다. +차단 릴리스 검사는 기본 최신 게시 패키지 기준선을 사용합니다. `run_release_soak=true` 또는 +`release_profile=full`은 `2026.4.23`부터 `latest`까지의 모든 stable npm 게시 기준선과 +보고된 이슈 fixture로 확장됩니다. 이미 출시된 후보에는 `source=npm`으로 Package Acceptance를 +사용하고, 게시 전 SHA 기반 로컬 npm tarball에는 `source=ref`/`source=artifact`를 사용하세요. +이는 이전에 Parallels가 필요했던 대부분의 패키지/update 커버리지를 대체하는 GitHub 네이티브 +대안입니다. OS별 온보딩, installer, platform 동작에는 cross-OS 릴리스 검사가 여전히 중요하지만, +패키지/update 제품 검증은 Package Acceptance를 선호해야 합니다. -업데이트와 plugin 검증을 위한 표준 체크리스트는 [업데이트와 plugin 테스트](/ko/help/testing-updates-plugins)입니다. plugin 설치/update, doctor cleanup, 또는 게시 패키지 migration 변경을 어떤 로컬, Docker, Package Acceptance, 또는 release-check lane이 증명하는지 결정할 때 사용하세요. -모든 stable `2026.4.23+` 패키지에서의 포괄적인 게시 update migration은 별도의 수동 `Update Migration` 워크플로이며, Full Release CI의 일부가 아닙니다. +update 및 Plugin 검증을 위한 표준 체크리스트는 +[업데이트 및 Plugin 테스트](/ko/help/testing-updates-plugins)입니다. Plugin 설치/update, +doctor cleanup 또는 게시 패키지 migration 변경을 증명하는 로컬, Docker, Package Acceptance +또는 release-check lane을 결정할 때 사용하세요. +모든 stable `2026.4.23+` 패키지에서의 포괄적인 게시 update migration은 별도의 수동 +`Update Migration` 워크플로이며, Full Release CI의 일부가 아닙니다. -기존 package-acceptance 관대한 처리는 의도적으로 기간이 제한되어 있습니다. `2026.4.25`까지의 패키지는 이미 npm에 게시된 메타데이터 누락에 대해 호환성 경로를 사용할 수 있습니다: tarball에 없는 비공개 QA 인벤토리 항목, 누락된 `gateway install --wrapper`, tarball에서 파생된 git fixture에 없는 패치 파일, 누락된 영구 `update.channel`, 기존 Plugin 설치 기록 위치, 누락된 marketplace 설치 기록 영구 저장, 그리고 `plugins update` 중 config 메타데이터 마이그레이션입니다. 게시된 `2026.4.26` 패키지는 이미 배포된 로컬 빌드 메타데이터 스탬프 파일에 대해 경고할 수 있습니다. 이후 패키지는 최신 패키지 계약을 충족해야 하며, 동일한 누락 사항은 릴리스 검증에서 실패합니다. +레거시 package-acceptance 완화는 의도적으로 기간이 제한되어 있습니다. `2026.4.25`까지의 패키지는 이미 npm에 게시된 메타데이터 누락에 대해 호환성 경로를 사용할 수 있습니다: tarball에 없는 비공개 QA 인벤토리 항목, 누락된 `gateway install --wrapper`, tarball에서 파생된 git fixture의 누락된 패치 파일, 누락된 영구 저장 `update.channel`, 레거시 plugin 설치 기록 위치, 누락된 marketplace 설치 기록 영구 저장, `plugins update` 중 구성 메타데이터 마이그레이션. 게시된 `2026.4.26` 패키지는 이미 배포된 로컬 빌드 메타데이터 스탬프 파일에 대해 경고할 수 있습니다. 이후 패키지는 최신 패키지 계약을 충족해야 하며, 동일한 누락 사항은 릴리스 검증 실패로 처리됩니다. -릴리스 질문이 실제 설치 가능한 패키지에 관한 것이라면 더 넓은 Package Acceptance 프로필을 사용하세요: +릴리스 질문이 실제 설치 가능한 패키지에 관한 것이라면 더 넓은 패키지 수락 프로필을 사용하세요: ```bash gh workflow run package-acceptance.yml \ @@ -426,17 +395,17 @@ gh workflow run package-acceptance.yml \ 일반적인 패키지 프로필: -- `smoke`: 빠른 패키지 설치/채널/에이전트, Gateway 네트워크, config reload 레인 -- `package`: 라이브 ClawHub 없이 install/update/restart/Plugin 패키지 계약을 확인합니다. 이것이 릴리스 체크 기본값입니다 -- `product`: `package`에 MCP 채널, cron/subagent 정리, OpenAI 웹 검색, OpenWebUI를 더합니다 +- `smoke`: 빠른 패키지 설치/채널/에이전트, Gateway 네트워크, 구성 다시 로드 레인 +- `package`: 라이브 ClawHub 없이 설치/업데이트/재시작/Plugin 패키지 계약; 릴리스 확인 기본값입니다 +- `product`: `package`에 MCP 채널, cron/하위 에이전트 정리, OpenAI 웹 검색, OpenWebUI를 추가합니다 - `full`: OpenWebUI가 포함된 Docker 릴리스 경로 청크 - `custom`: 집중 재실행을 위한 정확한 `docker_lanes` 목록 -패키지 후보 Telegram 증명을 위해 Package Acceptance에서 `telegram_mode=mock-openai` 또는 `telegram_mode=live-frontier`를 활성화하세요. 워크플로는 확인된 `package-under-test` tarball을 Telegram 레인으로 전달합니다. 독립 실행형 Telegram 워크플로는 게시 후 확인을 위해 여전히 게시된 npm 사양을 허용합니다. +패키지 후보 Telegram 증명에는 패키지 수락에서 `telegram_mode=mock-openai` 또는 `telegram_mode=live-frontier`를 활성화하세요. 워크플로는 확인된 `package-under-test` tarball을 Telegram 레인에 전달합니다. 독립형 Telegram 워크플로는 게시 후 확인을 위해 여전히 게시된 npm 사양을 허용합니다. ## 릴리스 게시 자동화 -`OpenClaw Release Publish`는 일반적인 변경을 수행하는 게시 진입점입니다. 릴리스에 필요한 순서대로 trusted-publisher 워크플로를 조율합니다: +`OpenClaw Release Publish`는 일반적인 변경을 수행하는 게시 진입점입니다. 릴리스에 필요한 순서대로 신뢰할 수 있는 게시자 워크플로를 조율합니다: 1. 릴리스 태그를 체크아웃하고 해당 커밋 SHA를 확인합니다. 2. 태그가 `main` 또는 `release/*`에서 도달 가능한지 확인합니다. @@ -445,7 +414,7 @@ gh workflow run package-acceptance.yml \ 5. 동일한 범위와 SHA로 `Plugin ClawHub Release`를 디스패치합니다. 6. 릴리스 태그, npm dist-tag, 저장된 `preflight_run_id`로 `OpenClaw NPM Release`를 디스패치합니다. -Beta 게시 예시: +베타 게시 예시: ```bash gh workflow run openclaw-release-publish.yml \ @@ -455,7 +424,7 @@ gh workflow run openclaw-release-publish.yml \ -f npm_dist_tag=beta ``` -기본 beta dist-tag로 Stable 게시: +기본 beta dist-tag로 안정 버전 게시: ```bash gh workflow run openclaw-release-publish.yml \ @@ -465,7 +434,7 @@ gh workflow run openclaw-release-publish.yml \ -f npm_dist_tag=beta ``` -`latest`로 직접 Stable 승격하는 것은 명시적으로 수행합니다: +`latest`로 직접 안정 버전을 승격하는 것은 명시적입니다: ```bash gh workflow run openclaw-release-publish.yml \ @@ -475,60 +444,60 @@ gh workflow run openclaw-release-publish.yml \ -f npm_dist_tag=latest ``` -하위 수준의 `Plugin NPM Release` 및 `Plugin ClawHub Release` 워크플로는 집중 복구 또는 재게시 작업에만 사용하세요. 선택한 Plugin 복구의 경우 `OpenClaw Release Publish`에 `plugin_publish_scope=selected` 및 `plugins=@openclaw/name`을 전달하거나, OpenClaw 패키지를 게시하면 안 되는 경우 자식 워크플로를 직접 디스패치하세요. +하위 수준의 `Plugin NPM Release` 및 `Plugin ClawHub Release` 워크플로는 집중 복구 또는 재게시 작업에만 사용하세요. 선택한 Plugin 복구의 경우 `plugin_publish_scope=selected` 및 `plugins=@openclaw/name`을 `OpenClaw Release Publish`에 전달하거나, OpenClaw 패키지를 게시하면 안 되는 경우 하위 워크플로를 직접 디스패치하세요. ## NPM 워크플로 입력 -`OpenClaw NPM Release`는 운영자가 제어하는 다음 입력을 허용합니다: +`OpenClaw NPM Release`는 다음 운영자 제어 입력을 허용합니다: -- `tag`: `v2026.4.2`, `v2026.4.2-1`, 또는 `v2026.4.2-beta.1` 같은 필수 릴리스 태그입니다. `preflight_only=true`일 때는 검증 전용 preflight를 위해 현재 전체 40자 workflow-branch 커밋 SHA도 사용할 수 있습니다 +- `tag`: `v2026.4.2`, `v2026.4.2-1`, 또는 `v2026.4.2-beta.1` 같은 필수 릴리스 태그입니다. `preflight_only=true`일 때는 검증 전용 사전 점검을 위해 현재 전체 40자 워크플로 브랜치 커밋 SHA도 사용할 수 있습니다 - `preflight_only`: 검증/빌드/패키지만 수행하려면 `true`, 실제 게시 경로에는 `false` -- `preflight_run_id`: 실제 게시 경로에서 필수입니다. 성공한 preflight 실행의 준비된 tarball을 워크플로가 재사용합니다 -- `npm_dist_tag`: 게시 경로의 npm 대상 태그입니다. 기본값은 `beta`입니다 +- `preflight_run_id`: 실제 게시 경로에서 필수이며, 워크플로가 성공한 사전 점검 실행에서 준비된 tarball을 재사용하도록 합니다 +- `npm_dist_tag`: 게시 경로의 npm 대상 태그이며, 기본값은 `beta`입니다 -`OpenClaw Release Publish`는 운영자가 제어하는 다음 입력을 허용합니다: +`OpenClaw Release Publish`는 다음 운영자 제어 입력을 허용합니다: -- `tag`: 필수 릴리스 태그입니다. 이미 존재해야 합니다 -- `preflight_run_id`: 성공한 `OpenClaw NPM Release` preflight 실행 id입니다. `publish_openclaw_npm=true`일 때 필수입니다 +- `tag`: 필수 릴리스 태그이며, 이미 존재해야 합니다 +- `preflight_run_id`: 성공한 `OpenClaw NPM Release` 사전 점검 실행 ID입니다. `publish_openclaw_npm=true`일 때 필수입니다 - `npm_dist_tag`: OpenClaw 패키지의 npm 대상 태그 - `plugin_publish_scope`: 기본값은 `all-publishable`입니다. 집중 복구 작업에만 `selected`를 사용하세요 - `plugins`: `plugin_publish_scope=selected`일 때 쉼표로 구분된 `@openclaw/*` 패키지 이름 - `publish_openclaw_npm`: 기본값은 `true`입니다. 워크플로를 Plugin 전용 복구 오케스트레이터로 사용할 때만 `false`로 설정하세요 -`OpenClaw Release Checks`는 운영자가 제어하는 다음 입력을 허용합니다: +`OpenClaw Release Checks`는 다음 운영자 제어 입력을 허용합니다: -- `ref`: 검증할 브랜치, 태그, 또는 전체 커밋 SHA입니다. secret을 포함하는 검사는 확인된 커밋이 OpenClaw 브랜치 또는 릴리스 태그에서 도달 가능해야 합니다. -- `run_release_soak`: stable/default 릴리스 체크에서 철저한 live/E2E, Docker 릴리스 경로, all-since upgrade-survivor soak를 선택합니다. `release_profile=full`이면 강제로 켜집니다. +- `ref`: 검증할 브랜치, 태그, 또는 전체 커밋 SHA입니다. 시크릿을 사용하는 확인은 확인된 커밋이 OpenClaw 브랜치 또는 릴리스 태그에서 도달 가능해야 합니다. +- `run_release_soak`: 안정/기본 릴리스 확인에서 포괄적인 라이브/E2E, Docker 릴리스 경로, 모든 버전 이후 업그레이드 생존 soak를 선택합니다. `release_profile=full`이면 강제로 켜집니다. 규칙: -- Stable 및 correction 태그는 `beta` 또는 `latest` 중 하나로 게시할 수 있습니다 -- Beta prerelease 태그는 `beta`로만 게시할 수 있습니다 -- `OpenClaw NPM Release`에서 전체 커밋 SHA 입력은 `preflight_only=true`일 때만 허용됩니다 -- `OpenClaw Release Checks`와 `Full Release Validation`은 항상 검증 전용입니다 -- 실제 게시 경로는 preflight 중 사용한 것과 동일한 `npm_dist_tag`를 사용해야 합니다. 워크플로는 게시를 계속하기 전에 해당 메타데이터를 확인합니다 +- 안정 및 수정 태그는 `beta` 또는 `latest` 중 하나에 게시할 수 있습니다 +- 베타 프리릴리스 태그는 `beta`에만 게시할 수 있습니다 +- `OpenClaw NPM Release`의 경우 전체 커밋 SHA 입력은 `preflight_only=true`일 때만 허용됩니다 +- `OpenClaw Release Checks` 및 `Full Release Validation`은 항상 검증 전용입니다 +- 실제 게시 경로는 사전 점검 중 사용한 것과 동일한 `npm_dist_tag`를 사용해야 합니다. 워크플로는 게시를 계속하기 전에 해당 메타데이터를 확인합니다 -## Stable npm 릴리스 순서 +## 안정 npm 릴리스 순서 -Stable npm 릴리스를 만들 때: +안정 npm 릴리스를 만들 때: 1. `preflight_only=true`로 `OpenClaw NPM Release`를 실행합니다 - - 태그가 존재하기 전에는 preflight 워크플로의 검증 전용 dry run에 현재 전체 workflow-branch 커밋 SHA를 사용할 수 있습니다 -2. 일반적인 beta-first 흐름에는 `npm_dist_tag=beta`를 선택하고, 의도적으로 직접 Stable 게시를 원할 때만 `latest`를 선택합니다 -3. 하나의 수동 워크플로에서 일반 CI와 live prompt cache, Docker, QA Lab, Matrix, Telegram 커버리지를 원할 때 릴리스 브랜치, 릴리스 태그, 또는 전체 커밋 SHA에서 `Full Release Validation`을 실행합니다 -4. 의도적으로 결정적인 일반 테스트 그래프만 필요하다면 릴리스 ref에서 수동 `CI` 워크플로를 실행합니다 + - 태그가 존재하기 전에는 사전 점검 워크플로의 검증 전용 dry run에 현재 전체 워크플로 브랜치 커밋 SHA를 사용할 수 있습니다 +2. 일반적인 베타 우선 흐름에는 `npm_dist_tag=beta`를 선택하고, 의도적으로 직접 안정 버전을 게시하려는 경우에만 `latest`를 선택합니다 +3. 하나의 수동 워크플로에서 일반 CI와 라이브 프롬프트 캐시, Docker, QA Lab, Matrix, Telegram 커버리지를 원할 때 릴리스 브랜치, 릴리스 태그, 또는 전체 커밋 SHA에서 `Full Release Validation`을 실행합니다 +4. 의도적으로 결정적인 일반 테스트 그래프만 필요한 경우 대신 릴리스 ref에서 수동 `CI` 워크플로를 실행합니다 5. 성공한 `preflight_run_id`를 저장합니다 -6. 동일한 `tag`, 동일한 `npm_dist_tag`, 저장된 `preflight_run_id`로 `OpenClaw Release Publish`를 실행합니다. 이 워크플로는 OpenClaw npm 패키지를 승격하기 전에 외부화된 Plugin을 npm 및 ClawHub에 게시합니다 -7. 릴리스가 `beta`에 배포된 경우, 비공개 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml` 워크플로를 사용해 해당 Stable 버전을 `beta`에서 `latest`로 승격합니다 -8. 릴리스가 의도적으로 `latest`에 직접 게시되었고 `beta`도 즉시 동일한 Stable 빌드를 따라야 한다면, 동일한 비공개 워크플로를 사용해 두 dist-tag가 모두 Stable 버전을 가리키게 하거나, 예약된 self-healing sync가 나중에 `beta`를 이동하게 두세요 +6. 동일한 `tag`, 동일한 `npm_dist_tag`, 저장된 `preflight_run_id`로 `OpenClaw Release Publish`를 실행합니다. 이 워크플로는 OpenClaw npm 패키지를 승격하기 전에 외부화된 Plugin을 npm과 ClawHub에 게시합니다 +7. 릴리스가 `beta`에 배포된 경우 비공개 `openclaw/releases-private/.github/workflows/openclaw-npm-dist-tags.yml` 워크플로를 사용하여 해당 안정 버전을 `beta`에서 `latest`로 승격합니다 +8. 릴리스가 의도적으로 `latest`에 직접 게시되었고 `beta`도 즉시 동일한 안정 빌드를 따라야 한다면 동일한 비공개 워크플로를 사용하여 두 dist-tag가 안정 버전을 가리키도록 하거나, 예약된 자가 복구 동기화가 나중에 `beta`를 이동하게 두세요 -dist-tag 변경은 여전히 `NPM_TOKEN`이 필요하므로 보안을 위해 비공개 repo에 있습니다. 공개 repo는 OIDC 전용 게시를 유지합니다. +dist-tag 변경은 여전히 `NPM_TOKEN`이 필요하므로 보안을 위해 비공개 저장소에 있습니다. 반면 공개 저장소는 OIDC 전용 게시를 유지합니다. -이렇게 하면 직접 게시 경로와 beta-first 승격 경로가 모두 문서화되고 운영자에게 보이게 유지됩니다. +이렇게 하면 직접 게시 경로와 베타 우선 승격 경로가 모두 문서화되고 운영자에게 보이게 유지됩니다. -maintainer가 로컬 npm 인증으로 fallback해야 하는 경우, 모든 1Password CLI(`op`) 명령은 전용 tmux 세션 안에서만 실행하세요. main agent shell에서 `op`를 직접 호출하지 마세요. tmux 안에 유지하면 프롬프트, 알림, OTP 처리를 관찰할 수 있고 반복되는 호스트 알림을 방지합니다. +관리자가 로컬 npm 인증으로 대체해야 하는 경우, 1Password CLI(`op`) 명령은 전용 tmux 세션 안에서만 실행하세요. 메인 에이전트 셸에서 `op`를 직접 호출하지 마세요. tmux 안에 유지하면 프롬프트, 알림, OTP 처리를 관찰할 수 있으며 반복되는 호스트 알림을 방지할 수 있습니다. -## 공개 참조 +## 공개 참고 자료 - [`.github/workflows/full-release-validation.yml`](https://github.com/openclaw/openclaw/blob/main/.github/workflows/full-release-validation.yml) - [`.github/workflows/package-acceptance.yml`](https://github.com/openclaw/openclaw/blob/main/.github/workflows/package-acceptance.yml) @@ -540,10 +509,8 @@ maintainer가 로컬 npm 인증으로 fallback해야 하는 경우, 모든 1Pass - [`scripts/package-mac-dist.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/package-mac-dist.sh) - [`scripts/make_appcast.sh`](https://github.com/openclaw/openclaw/blob/main/scripts/make_appcast.sh) -Maintainer는 실제 runbook을 위해 비공개 릴리스 문서인 -[`openclaw/maintainers/release/README.md`](https://github.com/openclaw/maintainers/blob/main/release/README.md)를 -사용합니다. +관리자는 실제 실행 절차에 비공개 릴리스 문서인 [`openclaw/maintainers/release/README.md`](https://github.com/openclaw/maintainers/blob/main/release/README.md)를 사용합니다. -## 관련 +## 관련 항목 - [릴리스 채널](/ko/install/development-channels) diff --git a/docs/ko/security/CONTRIBUTING-THREAT-MODEL.md b/docs/ko/security/CONTRIBUTING-THREAT-MODEL.md index 01f1295a6..db3706f27 100644 --- a/docs/ko/security/CONTRIBUTING-THREAT-MODEL.md +++ b/docs/ko/security/CONTRIBUTING-THREAT-MODEL.md @@ -1,21 +1,19 @@ --- read_when: - - 보안 발견 사항이나 위협 시나리오를 기여하려는 경우 + - 보안 발견 사항이나 위협 시나리오를 제공하려는 경우 - 위협 모델 검토 또는 업데이트 summary: OpenClaw 위협 모델에 기여하는 방법 title: 위협 모델에 기여하기 x-i18n: - generated_at: "2026-04-30T06:51:18Z" + generated_at: "2026-05-06T18:00:17Z" model: gpt-5.5 provider: openai - source_hash: 75cf2b408a78fce5134d24a3f115490da2dacc4ba8a1a24415425c3e4420ca55 + source_hash: a23ca088d7893180a83c02d6971bbf1c32affa724e43019fd40276eaadc52278 source_path: security/CONTRIBUTING-THREAT-MODEL.md workflow: 16 --- -# OpenClaw 위협 모델에 기여하기 - -OpenClaw를 더 안전하게 만드는 데 도움을 주셔서 감사합니다. 이 위협 모델은 계속 발전하는 문서이며, 보안 전문가가 아니어도 누구나 기여할 수 있습니다. +OpenClaw을 더 안전하게 만드는 데 도움을 주셔서 감사합니다. 이 위협 모델은 계속 발전하는 문서이며, 보안 전문가가 아니어도 누구나 기여할 수 있습니다. ## 기여 방법 @@ -26,31 +24,31 @@ OpenClaw를 더 안전하게 만드는 데 도움을 주셔서 감사합니다. **포함하면 도움이 되는 내용(필수는 아님):** - 공격 시나리오와 악용될 수 있는 방식 -- 영향을 받는 OpenClaw의 부분(CLI, Gateway, 채널, ClawHub, MCP 서버 등) -- 생각하는 심각도(낮음 / 중간 / 높음 / 치명적) +- 영향을 받는 OpenClaw 부분(CLI, Gateway, 채널, ClawHub, MCP 서버 등) +- 생각하는 심각도(낮음 / 중간 / 높음 / 심각) - 관련 연구, CVE 또는 실제 사례 링크 -ATLAS 매핑, 위협 ID, 위험 평가는 검토 중에 저희가 처리합니다. 이러한 세부 정보를 포함하고 싶다면 좋지만, 필수는 아닙니다. +검토 중에 ATLAS 매핑, 위협 ID, 위험 평가를 처리하겠습니다. 이러한 세부 정보를 포함하고 싶다면 좋지만, 필수는 아닙니다. -> **이는 실시간 취약점 신고가 아니라 위협 모델에 추가하기 위한 것입니다.** 악용 가능한 취약점을 발견했다면, 책임 있는 공개 안내는 [Trust 페이지](https://trust.openclaw.ai)를 참조하세요. +> **이는 위협 모델에 추가하기 위한 것이며, 실제 취약점을 신고하기 위한 것이 아닙니다.** 악용 가능한 취약점을 발견했다면, 책임 있는 공개 안내는 [Trust 페이지](https://trust.openclaw.ai)를 참조하세요. -### 완화책 제안하기 +### 완화 방안 제안하기 -기존 위협을 해결할 방법에 대한 아이디어가 있나요? 해당 위협을 참조하는 이슈나 PR을 여세요. 유용한 완화책은 구체적이고 실행 가능해야 합니다. 예를 들어 "Gateway에서 발신자별 10 메시지/분 속도 제한"이 "속도 제한 구현"보다 낫습니다. +기존 위협을 해결할 아이디어가 있나요? 해당 위협을 참조하는 이슈나 PR을 열어 주세요. 유용한 완화 방안은 구체적이고 실행 가능해야 합니다. 예를 들어 "Gateway에서 발신자별 10개 메시지/분 속도 제한"이 "속도 제한 구현"보다 더 좋습니다. ### 공격 체인 제안하기 -공격 체인은 여러 위협이 결합되어 현실적인 공격 시나리오가 되는 방식을 보여줍니다. 위험한 조합이 보인다면, 단계와 공격자가 이를 어떻게 연결할지 설명해 주세요. 실제로 공격이 전개되는 방식을 짧게 서술하는 것이 공식 템플릿보다 더 가치 있습니다. +공격 체인은 여러 위협이 결합되어 현실적인 공격 시나리오가 되는 방식을 보여줍니다. 위험한 조합을 발견했다면, 단계와 공격자가 이를 어떻게 연결할 수 있는지 설명해 주세요. 실제로 공격이 전개되는 방식에 대한 짧은 서술이 형식적인 템플릿보다 더 가치 있습니다. ### 기존 콘텐츠 수정 또는 개선하기 -오타, 설명 보강, 오래된 정보, 더 나은 예시 등은 이슈 없이 PR로 환영합니다. +오타, 설명 보강, 오래된 정보, 더 나은 예시 등은 이슈 없이 PR로 제출해도 됩니다. ## 사용하는 것 -### MITRE ATLAS +### MITRE ATLAS 프레임워크 -이 위협 모델은 [MITRE ATLAS](https://atlas.mitre.org/)(Adversarial Threat Landscape for AI Systems)를 기반으로 합니다. 이는 프롬프트 인젝션, 도구 오용, 에이전트 악용 같은 AI/ML 위협을 위해 특별히 설계된 프레임워크입니다. 기여하기 위해 ATLAS를 알 필요는 없습니다. 제출 내용은 검토 중에 프레임워크에 매핑합니다. +이 위협 모델은 프롬프트 인젝션, 도구 오용, 에이전트 악용과 같은 AI/ML 위협을 위해 특별히 설계된 프레임워크인 [MITRE ATLAS](https://atlas.mitre.org/)(Adversarial Threat Landscape for AI Systems)를 기반으로 합니다. 기여하기 위해 ATLAS를 알 필요는 없습니다. 제출 내용은 검토 중에 프레임워크에 매핑합니다. ### 위협 ID @@ -59,13 +57,13 @@ ATLAS 매핑, 위협 ID, 위험 평가는 검토 중에 저희가 처리합니 | 코드 | 범주 | | ------- | ------------------------------------------ | | RECON | 정찰 - 정보 수집 | -| ACCESS | 초기 접근 - 진입 확보 | +| ACCESS | 초기 접근 - 진입 권한 확보 | | EXEC | 실행 - 악성 작업 실행 | | PERSIST | 지속성 - 접근 유지 | | EVADE | 방어 회피 - 탐지 회피 | | DISC | 발견 - 환경 파악 | | EXFIL | 유출 - 데이터 탈취 | -| IMPACT | 영향 - 손상 또는 중단 | +| IMPACT | 영향 - 피해 또는 중단 | ID는 검토 중에 유지관리자가 할당합니다. 직접 선택할 필요는 없습니다. @@ -73,18 +71,18 @@ ID는 검토 중에 유지관리자가 할당합니다. 직접 선택할 필요 | 수준 | 의미 | | ------------ | ----------------------------------------------------------------- | -| **치명적** | 전체 시스템 침해 또는 높은 가능성 + 치명적 영향 | -| **높음** | 상당한 피해가 발생할 가능성이 높거나, 중간 가능성 + 치명적 영향 | -| **중간** | 보통 수준의 위험 또는 낮은 가능성 + 높은 영향 | +| **심각** | 전체 시스템 침해 또는 높은 가능성 + 심각한 영향 | +| **높음** | 상당한 피해 가능성 또는 중간 가능성 + 심각한 영향 | +| **중간** | 보통 위험 또는 낮은 가능성 + 높은 영향 | | **낮음** | 가능성이 낮고 영향이 제한적 | -위험 수준이 확실하지 않다면, 영향만 설명해 주세요. 저희가 평가하겠습니다. +위험 수준이 확실하지 않다면 영향을 설명해 주세요. 저희가 평가하겠습니다. -## 검토 절차 +## 검토 프로세스 -1. **분류** - 새 제출 내용은 48시간 이내에 검토합니다 -2. **평가** - 실현 가능성을 검증하고, ATLAS 매핑과 위협 ID를 할당하며, 위험 수준을 검증합니다 -3. **문서화** - 모든 내용이 형식에 맞고 완전한지 확인합니다 +1. **분류** - 새 제출물을 48시간 이내에 검토합니다 +2. **평가** - 실현 가능성을 확인하고, ATLAS 매핑과 위협 ID를 할당하며, 위험 수준을 검증합니다 +3. **문서화** - 모든 내용이 올바르게 형식화되고 완전한지 확인합니다 4. **병합** - 위협 모델과 시각화에 추가합니다 ## 리소스 @@ -96,15 +94,15 @@ ID는 검토 중에 유지관리자가 할당합니다. 직접 선택할 필요 ## 연락처 -- **보안 취약점:** 신고 안내는 [Trust 페이지](https://trust.openclaw.ai)를 참조하세요 -- **위협 모델 질문:** [openclaw/trust](https://github.com/openclaw/trust/issues)에 이슈를 여세요 +- **보안 취약점:** 신고 지침은 [Trust 페이지](https://trust.openclaw.ai)를 참조하세요 +- **위협 모델 질문:** [openclaw/trust](https://github.com/openclaw/trust/issues)에 이슈를 열어 주세요 - **일반 채팅:** Discord #security 채널 ## 인정 -위협 모델 기여자는 중요한 기여에 대해 위협 모델 감사의 말, 릴리스 노트, OpenClaw 보안 명예의 전당에 이름이 올라갑니다. +위협 모델 기여자는 중요한 기여에 대해 위협 모델 감사의 말, 릴리스 노트, OpenClaw 보안 명예의 전당에서 인정됩니다. -## 관련 문서 +## 관련 항목 - [위협 모델](/ko/security/THREAT-MODEL-ATLAS) - [형식 검증](/ko/security/formal-verification) diff --git a/docs/ko/security/THREAT-MODEL-ATLAS.md b/docs/ko/security/THREAT-MODEL-ATLAS.md index 0253a09cd..7d625a5eb 100644 --- a/docs/ko/security/THREAT-MODEL-ATLAS.md +++ b/docs/ko/security/THREAT-MODEL-ATLAS.md @@ -1,30 +1,28 @@ --- read_when: - - 보안 태세 또는 위협 시나리오 검토하기 + - 보안 태세 또는 위협 시나리오 검토 - 보안 기능 또는 감사 대응 작업 summary: MITRE ATLAS 프레임워크에 매핑된 OpenClaw 위협 모델 title: 위협 모델 (MITRE ATLAS) x-i18n: - generated_at: "2026-04-30T06:51:19Z" + generated_at: "2026-05-06T18:00:30Z" model: gpt-5.5 provider: openai - source_hash: d929addb829b92d650ef6caecb267fb154f6f9f7d28be7aa87851569931f5228 + source_hash: e7371231e9795cd899d727b87dfba7a5cae963f1fd1e50226e3fbb7488ef7381 source_path: security/THREAT-MODEL-ATLAS.md workflow: 16 --- -# OpenClaw 위협 모델 v1.0 - ## MITRE ATLAS 프레임워크 **버전:** 1.0-draft -**최종 업데이트:** 2026-02-04 +**마지막 업데이트:** 2026-02-04 **방법론:** MITRE ATLAS + 데이터 흐름 다이어그램 **프레임워크:** [MITRE ATLAS](https://atlas.mitre.org/) (AI 시스템을 위한 적대적 위협 환경) ### 프레임워크 출처 -이 위협 모델은 AI/ML 시스템에 대한 적대적 위협을 문서화하기 위한 업계 표준 프레임워크인 [MITRE ATLAS](https://atlas.mitre.org/)를 기반으로 구축되었습니다. ATLAS는 AI 보안 커뮤니티와 협력하여 [MITRE](https://www.mitre.org/)가 유지 관리합니다. +이 위협 모델은 AI/ML 시스템에 대한 적대적 위협을 문서화하기 위한 업계 표준 프레임워크인 [MITRE ATLAS](https://atlas.mitre.org/)를 기반으로 합니다. ATLAS는 AI 보안 커뮤니티와 협력하여 [MITRE](https://www.mitre.org/)에서 유지 관리합니다. **주요 ATLAS 리소스:** @@ -36,7 +34,7 @@ x-i18n: ### 이 위협 모델에 기여하기 -이 문서는 OpenClaw 커뮤니티가 유지 관리하는 살아 있는 문서입니다. 기여 지침은 [CONTRIBUTING-THREAT-MODEL.md](/ko/security/CONTRIBUTING-THREAT-MODEL)를 참조하세요. +이 문서는 OpenClaw 커뮤니티가 유지 관리하는 지속적으로 갱신되는 문서입니다. 기여 지침은 [CONTRIBUTING-THREAT-MODEL.md](/ko/security/CONTRIBUTING-THREAT-MODEL)를 참조하세요. - 새로운 위협 보고 - 기존 위협 업데이트 @@ -49,22 +47,22 @@ x-i18n: ### 1.1 목적 -이 위협 모델은 AI/ML 시스템을 위해 특별히 설계된 MITRE ATLAS 프레임워크를 사용하여 OpenClaw AI 에이전트 플랫폼과 ClawHub 스킬 마켓플레이스에 대한 적대적 위협을 문서화합니다. +이 위협 모델은 AI/ML 시스템을 위해 특별히 설계된 MITRE ATLAS 프레임워크를 사용하여 OpenClaw AI 에이전트 플랫폼과 ClawHub Skills 마켓플레이스에 대한 적대적 위협을 문서화합니다. ### 1.2 범위 -| 구성 요소 | 포함 여부 | 참고 사항 | +| 구성 요소 | 포함 여부 | 참고 | | ---------------------- | -------- | ------------------------------------------------ | -| OpenClaw Agent Runtime | 예 | 핵심 에이전트 실행, 도구 호출, 세션 | -| Gateway | 예 | 인증, 라우팅, 채널 통합 | -| 채널 통합 | 예 | WhatsApp, Telegram, Discord, Signal, Slack 등 | -| ClawHub 마켓플레이스 | 예 | 스킬 게시, 검토, 배포 | -| MCP 서버 | 예 | 외부 도구 제공자 | -| 사용자 기기 | 부분 | 모바일 앱, 데스크톱 클라이언트 | +| OpenClaw 에이전트 런타임 | 예 | 핵심 에이전트 실행, 도구 호출, 세션 | +| Gateway | 예 | 인증, 라우팅, 채널 통합 | +| 채널 통합 | 예 | WhatsApp, Telegram, Discord, Signal, Slack 등 | +| ClawHub 마켓플레이스 | 예 | Skill 게시, 모더레이션, 배포 | +| MCP 서버 | 예 | 외부 도구 제공자 | +| 사용자 기기 | 일부 | 모바일 앱, 데스크톱 클라이언트 | ### 1.3 범위 제외 -이 위협 모델에서 명시적으로 범위에서 제외되는 것은 없습니다. +이 위협 모델에서 명시적으로 범위에서 제외된 것은 없습니다. --- @@ -139,14 +137,14 @@ x-i18n: ### 2.2 데이터 흐름 -| 흐름 | 출처 | 대상 | 데이터 | 보호 | +| 흐름 | 출처 | 대상 | 데이터 | 보호 | | ---- | ------- | ----------- | ------------------ | -------------------- | -| F1 | 채널 | Gateway | 사용자 메시지 | TLS, AllowFrom | -| F2 | Gateway | 에이전트 | 라우팅된 메시지 | 세션 격리 | -| F3 | 에이전트 | 도구 | 도구 호출 | 정책 적용 | -| F4 | 에이전트 | 외부 | web_fetch 요청 | SSRF 차단 | -| F5 | ClawHub | 에이전트 | 스킬 코드 | 검토, 스캔 | -| F6 | 에이전트 | 채널 | 응답 | 출력 필터링 | +| F1 | 채널 | Gateway | 사용자 메시지 | TLS, AllowFrom | +| F2 | Gateway | 에이전트 | 라우팅된 메시지 | 세션 격리 | +| F3 | 에이전트 | 도구 | 도구 호출 | 정책 적용 | +| F4 | 에이전트 | 외부 | web_fetch 요청 | SSRF 차단 | +| F5 | ClawHub | 에이전트 | Skill 코드 | 모더레이션, 스캔 | +| F6 | 에이전트 | 채널 | 응답 | 출력 필터링 | --- @@ -154,29 +152,29 @@ x-i18n: ### 3.1 정찰 (AML.TA0002) -#### T-RECON-001: 에이전트 엔드포인트 발견 +#### T-RECON-001: 에이전트 엔드포인트 탐색 -| 속성 | 값 | +| 속성 | 값 | | ----------------------- | -------------------------------------------------------------------- | -| **ATLAS ID** | AML.T0006 - 능동 스캔 | -| **설명** | 공격자가 노출된 OpenClaw Gateway 엔드포인트를 스캔함 | -| **공격 벡터** | 네트워크 스캔, shodan 쿼리, DNS 열거 | -| **영향을 받는 구성 요소** | Gateway, 노출된 API 엔드포인트 | -| **현재 완화 조치** | Tailscale 인증 옵션, 기본적으로 루프백에 바인딩 | -| **잔여 위험** | 중간 - 공개 Gateway는 발견 가능 | -| **권장 사항** | 안전한 배포를 문서화하고, 발견 엔드포인트에 속도 제한 추가 | +| **ATLAS ID** | AML.T0006 - 능동 스캔 | +| **설명** | 공격자가 노출된 OpenClaw gateway 엔드포인트를 스캔함 | +| **공격 벡터** | 네트워크 스캔, shodan 쿼리, DNS 열거 | +| **영향을 받는 구성 요소** | Gateway, 노출된 API 엔드포인트 | +| **현재 완화 방안** | Tailscale 인증 옵션, 기본적으로 loopback에 바인딩 | +| **잔여 위험** | 중간 - 공개 Gateway는 발견될 수 있음 | +| **권장 사항** | 안전한 배포를 문서화하고 탐색 엔드포인트에 속도 제한 추가 | -#### T-RECON-002: 채널 통합 조사 +#### T-RECON-002: 채널 통합 프로빙 -| 속성 | 값 | +| 속성 | 값 | | ----------------------- | ------------------------------------------------------------------ | -| **ATLAS ID** | AML.T0006 - 능동 스캐닝 | -| **설명** | 공격자가 AI가 관리하는 계정을 식별하기 위해 메시징 채널을 탐색함 | -| **공격 벡터** | 테스트 메시지 전송, 응답 패턴 관찰 | -| **영향받는 구성 요소** | 모든 채널 통합 | -| **현재 완화책** | 구체적인 완화책 없음 | -| **잔여 위험** | 낮음 - 발견만으로 얻는 가치가 제한적임 | -| **권장 사항** | 응답 타이밍 무작위화를 고려 | +| **ATLAS ID** | AML.T0006 - 능동 스캐닝 | +| **Description** | 공격자가 AI 관리 계정을 식별하기 위해 메시징 채널을 탐색함 | +| **Attack Vector** | 테스트 메시지 전송, 응답 패턴 관찰 | +| **Affected Components** | 모든 채널 연동 | +| **Current Mitigations** | 특정 대응책 없음 | +| **Residual Risk** | 낮음 - 발견만으로 얻는 가치가 제한적 | +| **Recommendations** | 응답 타이밍 무작위화 고려 | --- @@ -184,39 +182,39 @@ x-i18n: #### T-ACCESS-001: 페어링 코드 가로채기 -| 속성 | 값 | +| 속성 | 값 | | ----------------------- | ------------------------------------------------------------------------------------------------------------- | -| **ATLAS ID** | AML.T0040 - AI 모델 추론 API 접근 | -| **설명** | 공격자가 페어링 유예 기간 동안 페어링 코드를 가로챔(DM 채널 페어링은 1시간, node 페어링은 5분) | -| **공격 벡터** | 숄더 서핑, 네트워크 스니핑, 사회공학 | -| **영향받는 구성 요소** | 디바이스 페어링 시스템 | -| **현재 완화책** | 1시간 만료(DM 페어링) / 5분 만료(node 페어링), 기존 채널을 통해 코드 전송 | -| **잔여 위험** | 중간 - 유예 기간이 악용될 수 있음 | -| **권장 사항** | 유예 기간 단축, 확인 단계 추가 | +| **ATLAS ID** | AML.T0040 - AI 모델 추론 API 접근 | +| **Description** | 공격자가 페어링 유예 기간(DM 채널 페어링은 1시간, Node 페어링은 5분) 동안 페어링 코드를 가로챔 | +| **Attack Vector** | 어깨너머 훔쳐보기, 네트워크 스니핑, 사회공학 | +| **Affected Components** | 기기 페어링 시스템 | +| **Current Mitigations** | 1시간 만료(DM 페어링) / 5분 만료(Node 페어링), 기존 채널을 통해 코드 전송 | +| **Residual Risk** | 중간 - 유예 기간이 악용될 수 있음 | +| **Recommendations** | 유예 기간 단축, 확인 단계 추가 | #### T-ACCESS-002: AllowFrom 스푸핑 -| 속성 | 값 | +| 속성 | 값 | | ----------------------- | ------------------------------------------------------------------------------ | -| **ATLAS ID** | AML.T0040 - AI 모델 추론 API 접근 | -| **설명** | 공격자가 채널에서 허용된 발신자 ID를 스푸핑함 | -| **공격 벡터** | 채널에 따라 다름 - 전화번호 스푸핑, 사용자 이름 사칭 | -| **영향받는 구성 요소** | 채널별 AllowFrom 검증 | -| **현재 완화책** | 채널별 ID 검증 | -| **잔여 위험** | 중간 - 일부 채널은 스푸핑에 취약함 | -| **권장 사항** | 채널별 위험 문서화, 가능한 경우 암호학적 검증 추가 | +| **ATLAS ID** | AML.T0040 - AI 모델 추론 API 접근 | +| **Description** | 공격자가 채널에서 허용된 발신자 신원을 스푸핑함 | +| **Attack Vector** | 채널에 따라 다름 - 전화번호 스푸핑, 사용자 이름 사칭 | +| **Affected Components** | 채널별 AllowFrom 검증 | +| **Current Mitigations** | 채널별 신원 확인 | +| **Residual Risk** | 중간 - 일부 채널은 스푸핑에 취약함 | +| **Recommendations** | 채널별 위험 문서화, 가능한 경우 암호학적 검증 추가 | #### T-ACCESS-003: 토큰 탈취 -| 속성 | 값 | +| 속성 | 값 | | ----------------------- | ----------------------------------------------------------- | -| **ATLAS ID** | AML.T0040 - AI 모델 추론 API 접근 | -| **설명** | 공격자가 구성 파일에서 인증 토큰을 탈취함 | -| **공격 벡터** | 멀웨어, 무단 디바이스 접근, 구성 백업 노출 | -| **영향받는 구성 요소** | ~/.openclaw/credentials/, 구성 저장소 | -| **현재 완화책** | 파일 권한 | -| **잔여 위험** | 높음 - 토큰이 일반 텍스트로 저장됨 | -| **권장 사항** | 저장 시 토큰 암호화 구현, 토큰 순환 추가 | +| **ATLAS ID** | AML.T0040 - AI 모델 추론 API 접근 | +| **Description** | 공격자가 구성 파일에서 인증 토큰을 훔침 | +| **Attack Vector** | 악성코드, 무단 기기 접근, 구성 백업 노출 | +| **Affected Components** | ~/.openclaw/credentials/, 구성 저장소 | +| **Current Mitigations** | 파일 권한 | +| **Residual Risk** | 높음 - 토큰이 평문으로 저장됨 | +| **Recommendations** | 저장 시 토큰 암호화 구현, 토큰 순환 추가 | --- @@ -224,51 +222,51 @@ x-i18n: #### T-EXEC-001: 직접 프롬프트 인젝션 -| 속성 | 값 | -| ----------------------- | ------------------------------------------------------------------------------------------ | -| **ATLAS ID** | AML.T0051.000 - LLM 프롬프트 인젝션: 직접 | -| **설명** | 공격자가 에이전트 동작을 조작하기 위해 정교하게 만든 프롬프트를 보냄 | -| **공격 벡터** | 적대적 지시가 포함된 채널 메시지 | -| **영향받는 구성 요소** | 에이전트 LLM, 모든 입력 표면 | -| **현재 완화책** | 패턴 탐지, 외부 콘텐츠 래핑 | -| **잔여 위험** | 치명적 - 탐지만 있고 차단은 없음; 정교한 공격은 우회함 | -| **권장 사항** | 다층 방어, 출력 검증, 민감한 작업에 대한 사용자 확인 구현 | +| 속성 | 값 | +| ----------------------- | ----------------------------------------------------------------------------------------- | +| **ATLAS ID** | AML.T0051.000 - LLM 프롬프트 인젝션: 직접 | +| **Description** | 공격자가 에이전트 동작을 조작하기 위해 조작된 프롬프트를 보냄 | +| **Attack Vector** | 적대적 지시가 포함된 채널 메시지 | +| **Affected Components** | 에이전트 LLM, 모든 입력 표면 | +| **Current Mitigations** | 패턴 감지, 외부 콘텐츠 래핑 | +| **Residual Risk** | 치명적 - 감지만 수행되고 차단은 없음; 정교한 공격은 우회함 | +| **Recommendations** | 다층 방어, 출력 검증, 민감한 작업에 대한 사용자 확인 구현 | #### T-EXEC-002: 간접 프롬프트 인젝션 -| 속성 | 값 | -| ----------------------- | ---------------------------------------------------------- | -| **ATLAS ID** | AML.T0051.001 - LLM 프롬프트 인젝션: 간접 | -| **설명** | 공격자가 가져온 콘텐츠에 악성 지시를 삽입함 | -| **공격 벡터** | 악성 URL, 오염된 이메일, 손상된 Webhook | -| **영향받는 구성 요소** | web_fetch, 이메일 수집, 외부 데이터 소스 | -| **현재 완화책** | XML 태그와 보안 고지를 사용한 콘텐츠 래핑 | -| **잔여 위험** | 높음 - LLM이 래퍼 지시를 무시할 수 있음 | -| **권장 사항** | 콘텐츠 정제, 분리된 실행 컨텍스트 구현 | +| 속성 | 값 | +| ----------------------- | ----------------------------------------------------------- | +| **ATLAS ID** | AML.T0051.001 - LLM 프롬프트 인젝션: 간접 | +| **Description** | 공격자가 가져온 콘텐츠에 악성 지시를 삽입함 | +| **Attack Vector** | 악성 URL, 오염된 이메일, 침해된 Webhook | +| **Affected Components** | web_fetch, 이메일 수집, 외부 데이터 소스 | +| **Current Mitigations** | XML 태그와 보안 고지로 콘텐츠 래핑 | +| **Residual Risk** | 높음 - LLM이 래퍼 지시를 무시할 수 있음 | +| **Recommendations** | 콘텐츠 정제, 별도 실행 컨텍스트 구현 | #### T-EXEC-003: 도구 인수 인젝션 -| 속성 | 값 | +| 속성 | 값 | | ----------------------- | ------------------------------------------------------------ | -| **ATLAS ID** | AML.T0051.000 - LLM 프롬프트 인젝션: 직접 | -| **설명** | 공격자가 프롬프트 인젝션을 통해 도구 인수를 조작함 | -| **공격 벡터** | 도구 매개변수 값에 영향을 주는 정교하게 만든 프롬프트 | -| **영향받는 구성 요소** | 모든 도구 호출 | -| **현재 완화책** | 위험한 명령에 대한 Exec 승인 | -| **잔여 위험** | 높음 - 사용자 판단에 의존함 | -| **권장 사항** | 인수 검증, 매개변수화된 도구 호출 구현 | +| **ATLAS ID** | AML.T0051.000 - LLM 프롬프트 인젝션: 직접 | +| **Description** | 공격자가 프롬프트 인젝션을 통해 도구 인수를 조작함 | +| **Attack Vector** | 도구 매개변수 값에 영향을 주는 조작된 프롬프트 | +| **Affected Components** | 모든 도구 호출 | +| **Current Mitigations** | 위험한 명령에 대한 Exec 승인 | +| **Residual Risk** | 높음 - 사용자 판단에 의존함 | +| **Recommendations** | 인수 검증, 매개변수화된 도구 호출 구현 | #### T-EXEC-004: Exec 승인 우회 -| 속성 | 값 | +| 속성 | 값 | | ----------------------- | ---------------------------------------------------------- | -| **ATLAS ID** | AML.T0043 - 적대적 데이터 작성 | -| **설명** | 공격자가 승인 허용 목록을 우회하는 명령을 작성함 | -| **공격 벡터** | 명령 난독화, 별칭 악용, 경로 조작 | -| **영향받는 구성 요소** | exec-approvals.ts, 명령 허용 목록 | -| **현재 완화책** | 허용 목록 + 요청 모드 | -| **잔여 위험** | 높음 - 명령 정제 없음 | -| **권장 사항** | 명령 정규화 구현, 차단 목록 확장 | +| **ATLAS ID** | AML.T0043 - 적대적 데이터 제작 | +| **Description** | 공격자가 승인 허용 목록을 우회하는 명령을 제작함 | +| **Attack Vector** | 명령 난독화, 별칭 악용, 경로 조작 | +| **Affected Components** | exec-approvals.ts, 명령 허용 목록 | +| **Current Mitigations** | 허용 목록 + ask 모드 | +| **Residual Risk** | 높음 - 명령 정규화 없음 | +| **Recommendations** | 명령 정규화 구현, 차단 목록 확장 | --- @@ -276,39 +274,39 @@ x-i18n: #### T-PERSIST-001: 악성 Skill 설치 -| 속성 | 값 | -| ----------------------- | -------------------------------------------------------------------------- | -| **ATLAS ID** | AML.T0010.001 - 공급망 침해: AI 소프트웨어 | -| **설명** | 공격자가 악성 Skill을 ClawHub에 게시함 | -| **공격 벡터** | 계정 생성, 숨겨진 악성 코드가 포함된 Skill 게시 | -| **영향받는 구성 요소** | ClawHub, Skill 로딩, 에이전트 실행 | -| **현재 완화책** | GitHub 계정 생성 기간 검증, 패턴 기반 조정 플래그 | -| **잔여 위험** | 치명적 - 샌드박싱 없음, 제한적 검토 | -| **권장 사항** | VirusTotal 통합(진행 중), Skill 샌드박싱, 커뮤니티 검토 | +| 속성 | 값 | +| ----------------------- | ------------------------------------------------------------------------ | +| **ATLAS ID** | AML.T0010.001 - 공급망 침해: AI 소프트웨어 | +| **Description** | 공격자가 ClawHub에 악성 Skill을 게시함 | +| **Attack Vector** | 계정 생성, 숨겨진 악성 코드가 포함된 Skill 게시 | +| **Affected Components** | ClawHub, Skill 로딩, 에이전트 실행 | +| **Current Mitigations** | GitHub 계정 연령 확인, 패턴 기반 조정 플래그 | +| **Residual Risk** | 치명적 - 샌드박싱 없음, 검토 제한적 | +| **Recommendations** | VirusTotal 연동(진행 중), Skill 샌드박싱, 커뮤니티 검토 | #### T-PERSIST-002: Skill 업데이트 오염 -| 속성 | 값 | -| ----------------------- | ---------------------------------------------------------------- | -| **ATLAS ID** | AML.T0010.001 - 공급망 침해: AI 소프트웨어 | -| **설명** | 공격자가 인기 Skill을 손상시키고 악성 업데이트를 푸시함 | -| **공격 벡터** | 계정 침해, Skill 소유자에 대한 사회공학 | -| **영향받는 구성 요소** | ClawHub 버전 관리, 자동 업데이트 흐름 | -| **현재 완화책** | 버전 지문 생성 | -| **잔여 위험** | 높음 - 자동 업데이트가 악성 버전을 가져올 수 있음 | -| **권장 사항** | 업데이트 서명, 롤백 기능, 버전 고정 구현 | +| 속성 | 값 | +| ----------------------- | -------------------------------------------------------------- | +| **ATLAS ID** | AML.T0010.001 - 공급망 침해: AI 소프트웨어 | +| **Description** | 공격자가 인기 Skill을 침해하고 악성 업데이트를 푸시함 | +| **Attack Vector** | 계정 침해, Skill 소유자에 대한 사회공학 | +| **Affected Components** | ClawHub 버전 관리, 자동 업데이트 흐름 | +| **Current Mitigations** | 버전 지문 | +| **Residual Risk** | 높음 - 자동 업데이트가 악성 버전을 가져올 수 있음 | +| **Recommendations** | 업데이트 서명, 롤백 기능, 버전 고정 구현 | #### T-PERSIST-003: 에이전트 구성 변조 -| 속성 | 값 | +| 속성 | 값 | | ----------------------- | --------------------------------------------------------------- | -| **ATLAS ID** | AML.T0010.002 - 공급망 침해: 데이터 | -| **설명** | 공격자가 접근을 지속하기 위해 에이전트 구성을 수정함 | -| **공격 벡터** | 구성 파일 수정, 설정 인젝션 | -| **영향받는 구성 요소** | 에이전트 구성, 도구 정책 | -| **현재 완화책** | 파일 권한 | -| **잔여 위험** | 중간 - 로컬 접근 필요 | -| **권장 사항** | 구성 무결성 검증, 구성 변경에 대한 감사 로깅 | +| **ATLAS ID** | AML.T0010.002 - 공급망 침해: 데이터 | +| **Description** | 공격자가 접근을 지속하기 위해 에이전트 구성을 수정함 | +| **Attack Vector** | 구성 파일 수정, 설정 인젝션 | +| **Affected Components** | 에이전트 구성, 도구 정책 | +| **Current Mitigations** | 파일 권한 | +| **Residual Risk** | 중간 - 로컬 접근 필요 | +| **Recommendations** | 구성 무결성 검증, 구성 변경에 대한 감사 로깅 | --- @@ -316,26 +314,26 @@ x-i18n: #### T-EVADE-001: 조정 패턴 우회 -| 속성 | 값 | -| ----------------------- | ------------------------------------------------------------------------- | -| **ATLAS ID** | AML.T0043 - 적대적 데이터 작성 | -| **설명** | 공격자가 조정 패턴을 회피하기 위해 Skill 콘텐츠를 작성함 | -| **공격 벡터** | 유니코드 동형 문자, 인코딩 기법, 동적 로딩 | -| **영향받는 구성 요소** | ClawHub moderation.ts | -| **현재 완화책** | 패턴 기반 FLAG_RULES | -| **잔여 위험** | 높음 - 단순 정규식은 쉽게 우회됨 | -| **권장 사항** | 행동 분석(VirusTotal Code Insight), AST 기반 탐지 추가 | +| 속성 | 값 | +| ----------------------- | ---------------------------------------------------------------------- | +| **ATLAS ID** | AML.T0043 - 적대적 데이터 제작 | +| **Description** | 공격자가 조정 패턴을 회피하도록 Skill 콘텐츠를 제작함 | +| **Attack Vector** | 유니코드 동형문자, 인코딩 기법, 동적 로딩 | +| **Affected Components** | ClawHub moderation.ts | +| **Current Mitigations** | 패턴 기반 FLAG_RULES | +| **Residual Risk** | 높음 - 단순 정규식은 쉽게 우회됨 | +| **Recommendations** | 동작 분석(VirusTotal Code Insight), AST 기반 감지 추가 | -#### T-EVADE-002: 콘텐츠 래퍼 이스케이프 +#### T-EVADE-002: 콘텐츠 래퍼 이탈 | 속성 | 값 | | ----------------------- | --------------------------------------------------------- | | **ATLAS ID** | AML.T0043 - 적대적 데이터 제작 | -| **설명** | 공격자가 XML 래퍼 컨텍스트를 벗어나는 콘텐츠를 제작 | -| **공격 벡터** | 태그 조작, 컨텍스트 혼동, 지침 재정의 | +| **설명** | 공격자가 XML 래퍼 컨텍스트를 벗어나는 콘텐츠를 제작함 | +| **공격 벡터** | 태그 조작, 컨텍스트 혼동, 지시문 재정의 | | **영향받는 구성 요소** | 외부 콘텐츠 래핑 | -| **현재 완화 조치** | XML 태그 + 보안 고지 | -| **잔여 위험** | 중간 - 새로운 우회 방법이 정기적으로 발견됨 | +| **현재 완화책** | XML 태그 + 보안 고지 | +| **잔여 위험** | 중간 - 새로운 우회 기법이 정기적으로 발견됨 | | **권장 사항** | 여러 래퍼 계층, 출력 측 검증 | --- @@ -344,67 +342,67 @@ x-i18n: #### T-DISC-001: 도구 열거 -| 속성 | 값 | -| ----------------------- | ----------------------------------------------------- | -| **ATLAS ID** | AML.T0040 - AI 모델 추론 API 접근 | -| **설명** | 공격자가 프롬프트를 통해 사용 가능한 도구를 열거 | -| **공격 벡터** | "어떤 도구가 있나요?" 스타일의 질의 | -| **영향받는 구성 요소** | 에이전트 도구 레지스트리 | -| **현재 완화 조치** | 특정 조치 없음 | -| **잔여 위험** | 낮음 - 도구는 일반적으로 문서화되어 있음 | -| **권장 사항** | 도구 가시성 제어 검토 | +| 속성 | 값 | +| ----------------------- | ---------------------------------------------------- | +| **ATLAS ID** | AML.T0040 - AI 모델 추론 API 접근 | +| **설명** | 공격자가 프롬프트를 통해 사용 가능한 도구를 열거함 | +| **공격 벡터** | "어떤 도구를 가지고 있나요?" 스타일의 질의 | +| **영향받는 구성 요소** | 에이전트 도구 레지스트리 | +| **현재 완화책** | 특정 없음 | +| **잔여 위험** | 낮음 - 도구는 일반적으로 문서화되어 있음 | +| **권장 사항** | 도구 가시성 제어 고려 | #### T-DISC-002: 세션 데이터 추출 -| 속성 | 값 | -| ----------------------- | ----------------------------------------------------- | -| **ATLAS ID** | AML.T0040 - AI 모델 추론 API 접근 | -| **설명** | 공격자가 세션 컨텍스트에서 민감한 데이터를 추출 | -| **공격 벡터** | "우리가 무엇을 논의했나요?" 질의, 컨텍스트 탐색 | -| **영향받는 구성 요소** | 세션 대화 기록, 컨텍스트 창 | -| **현재 완화 조치** | 발신자별 세션 격리 | -| **잔여 위험** | 중간 - 세션 내 데이터에 접근 가능 | -| **권장 사항** | 컨텍스트 내 민감 데이터 삭제 처리 구현 | +| 속성 | 값 | +| ----------------------- | ---------------------------------------------------- | +| **ATLAS ID** | AML.T0040 - AI 모델 추론 API 접근 | +| **설명** | 공격자가 세션 컨텍스트에서 민감한 데이터를 추출함 | +| **공격 벡터** | "우리가 무엇을 논의했나요?" 질의, 컨텍스트 탐색 | +| **영향받는 구성 요소** | 세션 기록, 컨텍스트 창 | +| **현재 완화책** | 발신자별 세션 격리 | +| **잔여 위험** | 중간 - 세션 내 데이터에 접근 가능 | +| **권장 사항** | 컨텍스트 내 민감한 데이터 삭제 구현 | --- ### 3.7 수집 및 유출 (AML.TA0009, AML.TA0010) -#### T-EXFIL-001: web_fetch를 통한 데이터 탈취 +#### T-EXFIL-001: web_fetch를 통한 데이터 절도 -| 속성 | 값 | -| ----------------------- | ---------------------------------------------------------------------- | -| **ATLAS ID** | AML.T0009 - 수집 | -| **설명** | 공격자가 에이전트에게 외부 URL로 전송하도록 지시하여 데이터를 유출 | -| **공격 벡터** | 에이전트가 공격자 서버로 데이터를 POST하게 하는 프롬프트 인젝션 | -| **영향받는 구성 요소** | web_fetch 도구 | -| **현재 완화 조치** | 내부 네트워크에 대한 SSRF 차단 | -| **잔여 위험** | 높음 - 외부 URL이 허용됨 | -| **권장 사항** | URL 허용 목록, 데이터 분류 인식 구현 | +| 속성 | 값 | +| ----------------------- | --------------------------------------------------------------------- | +| **ATLAS ID** | AML.T0009 - 수집 | +| **설명** | 공격자가 에이전트에게 외부 URL로 보내도록 지시하여 데이터를 유출함 | +| **공격 벡터** | 에이전트가 공격자 서버로 데이터를 POST하게 하는 프롬프트 인젝션 | +| **영향받는 구성 요소** | web_fetch 도구 | +| **현재 완화책** | 내부 네트워크에 대한 SSRF 차단 | +| **잔여 위험** | 높음 - 외부 URL 허용 | +| **권장 사항** | URL 허용 목록, 데이터 분류 인식 구현 | #### T-EXFIL-002: 무단 메시지 전송 | 속성 | 값 | | ----------------------- | ---------------------------------------------------------------- | | **ATLAS ID** | AML.T0009 - 수집 | -| **설명** | 공격자가 에이전트로 하여금 민감한 데이터가 포함된 메시지를 보내게 함 | +| **설명** | 공격자가 에이전트가 민감한 데이터를 포함한 메시지를 보내게 함 | | **공격 벡터** | 에이전트가 공격자에게 메시지를 보내게 하는 프롬프트 인젝션 | | **영향받는 구성 요소** | 메시지 도구, 채널 통합 | -| **현재 완화 조치** | 아웃바운드 메시징 게이팅 | +| **현재 완화책** | 아웃바운드 메시징 게이팅 | | **잔여 위험** | 중간 - 게이팅이 우회될 수 있음 | -| **권장 사항** | 새 수신자에 대해 명시적 확인 요구 | +| **권장 사항** | 새 수신자에 대한 명시적 확인 요구 | #### T-EXFIL-003: 자격 증명 수집 -| 속성 | 값 | -| ----------------------- | ------------------------------------------------------- | -| **ATLAS ID** | AML.T0009 - 수집 | -| **설명** | 악성 Skill이 에이전트 컨텍스트에서 자격 증명을 수집 | -| **공격 벡터** | Skill 코드가 환경 변수와 설정 파일을 읽음 | -| **영향받는 구성 요소** | Skill 실행 환경 | -| **현재 완화 조치** | Skills에 특화된 조치 없음 | -| **잔여 위험** | 치명적 - Skills가 에이전트 권한으로 실행됨 | -| **권장 사항** | Skill 샌드박싱, 자격 증명 격리 | +| 속성 | 값 | +| ----------------------- | ---------------------------------------------------------- | +| **ATLAS ID** | AML.T0009 - 수집 | +| **설명** | 악성 skill이 에이전트 컨텍스트에서 자격 증명을 수집함 | +| **공격 벡터** | Skill 코드가 환경 변수, 구성 파일을 읽음 | +| **영향받는 구성 요소** | Skill 실행 환경 | +| **현재 완화책** | Skills에 특화된 것 없음 | +| **잔여 위험** | 치명적 - Skills가 에이전트 권한으로 실행됨 | +| **권장 사항** | Skill 샌드박싱, 자격 증명 격리 | --- @@ -412,39 +410,39 @@ x-i18n: #### T-IMPACT-001: 무단 명령 실행 -| 속성 | 값 | -| ----------------------- | --------------------------------------------------- | -| **ATLAS ID** | AML.T0031 - AI 모델 무결성 약화 | -| **설명** | 공격자가 사용자 시스템에서 임의 명령을 실행 | -| **공격 벡터** | exec 승인 우회와 결합된 프롬프트 인젝션 | -| **영향받는 구성 요소** | Bash 도구, 명령 실행 | -| **현재 완화 조치** | Exec 승인, Docker 샌드박스 옵션 | -| **잔여 위험** | 치명적 - 샌드박스 없는 호스트 실행 | -| **권장 사항** | 기본값을 샌드박스로 설정, 승인 UX 개선 | +| 속성 | 값 | +| ----------------------- | -------------------------------------------------------- | +| **ATLAS ID** | AML.T0031 - AI 모델 무결성 약화 | +| **설명** | 공격자가 사용자 시스템에서 임의 명령을 실행함 | +| **공격 벡터** | exec 승인 우회와 결합된 프롬프트 인젝션 | +| **영향받는 구성 요소** | Bash 도구, 명령 실행 | +| **현재 완화책** | Exec 승인, Docker 샌드박스 옵션 | +| **잔여 위험** | 치명적 - 샌드박스 없는 호스트 실행 | +| **권장 사항** | 기본값을 샌드박스로 설정, 승인 UX 개선 | -#### T-IMPACT-002: 리소스 고갈(DoS) +#### T-IMPACT-002: 리소스 고갈 (DoS) -| 속성 | 값 | -| ----------------------- | -------------------------------------------------- | -| **ATLAS ID** | AML.T0031 - AI 모델 무결성 약화 | -| **설명** | 공격자가 API 크레딧 또는 컴퓨팅 리소스를 고갈시킴 | -| **공격 벡터** | 자동화된 메시지 폭주, 비용이 큰 도구 호출 | -| **영향받는 구성 요소** | Gateway, 에이전트 세션, API 제공자 | -| **현재 완화 조치** | 없음 | -| **잔여 위험** | 높음 - 속도 제한 없음 | -| **권장 사항** | 발신자별 속도 제한, 비용 예산 구현 | +| 속성 | 값 | +| ----------------------- | -------------------------------------------------------- | +| **ATLAS ID** | AML.T0031 - AI 모델 무결성 약화 | +| **설명** | 공격자가 API 크레딧 또는 컴퓨팅 리소스를 고갈시킴 | +| **공격 벡터** | 자동화된 메시지 플러딩, 비용이 큰 도구 호출 | +| **영향받는 구성 요소** | Gateway, 에이전트 세션, API 제공자 | +| **현재 완화책** | 없음 | +| **잔여 위험** | 높음 - 속도 제한 없음 | +| **권장 사항** | 발신자별 속도 제한, 비용 예산 구현 | #### T-IMPACT-003: 평판 손상 -| 속성 | 값 | -| ----------------------- | ------------------------------------------------------- | -| **ATLAS ID** | AML.T0031 - AI 모델 무결성 약화 | -| **설명** | 공격자가 에이전트로 하여금 유해하거나 공격적인 콘텐츠를 보내게 함 | -| **공격 벡터** | 부적절한 응답을 유발하는 프롬프트 인젝션 | -| **영향받는 구성 요소** | 출력 생성, 채널 메시징 | -| **현재 완화 조치** | LLM 제공자 콘텐츠 정책 | -| **잔여 위험** | 중간 - 제공자 필터가 완전하지 않음 | -| **권장 사항** | 출력 필터링 계층, 사용자 제어 | +| 속성 | 값 | +| ----------------------- | ------------------------------------------------------------- | +| **ATLAS ID** | AML.T0031 - AI 모델 무결성 약화 | +| **설명** | 공격자가 에이전트가 유해하거나 공격적인 콘텐츠를 보내게 함 | +| **공격 벡터** | 부적절한 응답을 유발하는 프롬프트 인젝션 | +| **영향받는 구성 요소** | 출력 생성, 채널 메시징 | +| **현재 완화책** | LLM 제공자 콘텐츠 정책 | +| **잔여 위험** | 중간 - 제공자 필터가 불완전함 | +| **권장 사항** | 출력 필터링 계층, 사용자 제어 | --- @@ -452,15 +450,15 @@ x-i18n: ### 4.1 현재 보안 제어 -| 제어 | 구현 | 효과성 | -| -------------------- | --------------------------- | ---------------------------------------------------- | -| GitHub 계정 연령 | `requireGitHubAccountAge()` | 중간 - 신규 공격자의 장벽을 높임 | -| 경로 정규화 | `sanitizePath()` | 높음 - 경로 순회를 방지 | -| 파일 형식 검증 | `isTextFile()` | 중간 - 텍스트 파일만 허용하지만 여전히 악성일 수 있음 | -| 크기 제한 | 총 50MB 번들 | 높음 - 리소스 고갈을 방지 | -| 필수 SKILL.md | 필수 readme | 낮은 보안 가치 - 정보 제공용일 뿐 | -| 패턴 모더레이션 | moderation.ts의 FLAG_RULES | 낮음 - 쉽게 우회 가능 | -| 모더레이션 상태 | `moderationStatus` 필드 | 중간 - 수동 검토 가능 | +| 제어 | 구현 | 효과성 | +| -------------------- | --------------------------- | ------------------------------------------------------------ | +| GitHub 계정 기간 | `requireGitHubAccountAge()` | 중간 - 신규 공격자의 진입 장벽을 높임 | +| 경로 정리 | `sanitizePath()` | 높음 - 경로 순회 방지 | +| 파일 유형 검증 | `isTextFile()` | 중간 - 텍스트 파일만 허용하지만 여전히 악성일 수 있음 | +| 크기 제한 | 총 50MB 번들 | 높음 - 리소스 고갈 방지 | +| 필수 SKILL.md | 필수 readme | 낮은 보안 가치 - 정보 제공용일 뿐 | +| 패턴 모더레이션 | moderation.ts의 FLAG_RULES | 낮음 - 쉽게 우회 가능 | +| 모더레이션 상태 | `moderationStatus` 필드 | 중간 - 수동 검토 가능 | ### 4.2 모더레이션 플래그 패턴 @@ -481,25 +479,25 @@ x-i18n: **제한 사항:** -- slug, displayName, summary, frontmatter, metadata, file paths만 검사 -- 실제 skill 코드 콘텐츠를 분석하지 않음 +- slug, displayName, summary, frontmatter, metadata, 파일 경로만 검사함 +- 실제 Skill 코드 콘텐츠를 분석하지 않음 - 단순 정규식은 난독화로 쉽게 우회 가능 -- 동작 분석 없음 +- 행동 분석 없음 ### 4.3 계획된 개선 사항 -| 개선 사항 | 상태 | 영향 | -| ---------------------- | ------------------------------------- | --------------------------------------------------------------------- | -| VirusTotal 통합 | 진행 중 | 높음 - Code Insight 동작 분석 | -| 커뮤니티 신고 | 부분적(`skillReports` 테이블 존재) | 중간 | -| 감사 로깅 | 부분적(`auditLogs` 테이블 존재) | 중간 | -| 배지 시스템 | 구현됨 | 중간 - `highlighted`, `official`, `deprecated`, `redactionApproved` | +| 개선 사항 | 상태 | 영향 | +| ---------------------- | ----------------------------------------- | --------------------------------------------------------------------- | +| VirusTotal 통합 | 진행 중 | 높음 - Code Insight 행동 분석 | +| 커뮤니티 신고 | 부분적 (`skillReports` 테이블 존재) | 중간 | +| 감사 로깅 | 부분적 (`auditLogs` 테이블 존재) | 중간 | +| 배지 시스템 | 구현됨 | 중간 - `highlighted`, `official`, `deprecated`, `redactionApproved` | --- ## 5. 위험 매트릭스 -### 5.1 가능성 대 영향 +### 5.1 가능성 대비 영향 | 위협 ID | 가능성 | 영향 | 위험 수준 | 우선순위 | | ------------- | ------ | -------- | ------------ | -------- | @@ -519,54 +517,54 @@ x-i18n: ### 5.2 중요 경로 공격 체인 -**공격 체인 1: Skill 기반 데이터 탈취** +**공격 체인 1: Skill 기반 데이터 절도** ``` T-PERSIST-001 → T-EVADE-001 → T-EXFIL-003 -(Publish malicious skill) → (Evade moderation) → (Harvest credentials) +(악성 skill 게시) → (모더레이션 회피) → (자격 증명 수집) ``` **공격 체인 2: 프롬프트 인젝션에서 RCE로** ``` T-EXEC-001 → T-EXEC-004 → T-IMPACT-001 -(Inject prompt) → (Bypass exec approval) → (Execute commands) +(프롬프트 주입) → (exec 승인 우회) → (명령 실행) ``` **공격 체인 3: 가져온 콘텐츠를 통한 간접 인젝션** ``` -T-EXEC-002 → T-EXFIL-001 → External exfiltration -(Poison URL content) → (Agent fetches & follows instructions) → (Data sent to attacker) +T-EXEC-002 → T-EXFIL-001 → 외부 유출 +(URL 콘텐츠 오염) → (에이전트가 가져와 지시를 따름) → (공격자에게 데이터 전송) ``` --- ## 6. 권장 사항 요약 -### 6.1 즉시(P0) +### 6.1 즉시 (P0) -| ID | 권장 사항 | 대응 대상 | +| ID | 권장 사항 | 해결 대상 | | ----- | ------------------------------------------- | -------------------------- | -| R-001 | VirusTotal 통합 완료 | T-PERSIST-001, T-EVADE-001 | -| R-002 | skill 샌드박싱 구현 | T-PERSIST-001, T-EXFIL-003 | -| R-003 | 민감한 작업에 대한 출력 검증 추가 | T-EXEC-001, T-EXEC-002 | +| R-001 | VirusTotal 통합 완료 | T-PERSIST-001, T-EVADE-001 | +| R-002 | Skill 샌드박싱 구현 | T-PERSIST-001, T-EXFIL-003 | +| R-003 | 민감한 작업에 대한 출력 검증 추가 | T-EXEC-001, T-EXEC-002 | ### 6.2 단기(P1) -| ID | 권장 사항 | 대응 대상 | -| ----- | ---------------------------------------- | ------------ | -| R-004 | 속도 제한 구현 | T-IMPACT-002 | -| R-005 | 저장 시 토큰 암호화 추가 | T-ACCESS-003 | -| R-006 | exec 승인 UX 및 검증 개선 | T-EXEC-004 | -| R-007 | web_fetch에 대한 URL 허용 목록 구현 | T-EXFIL-001 | +| ID | 권장 사항 | 해결 대상 | +| ----- | ------------------------------------------ | ------------ | +| R-004 | 속도 제한 구현 | T-IMPACT-002 | +| R-005 | 저장 시 토큰 암호화 추가 | T-ACCESS-003 | +| R-006 | exec 승인 UX 및 검증 개선 | T-EXEC-004 | +| R-007 | web_fetch에 대한 URL 허용 목록 구현 | T-EXFIL-001 | ### 6.3 중기(P2) -| ID | 권장 사항 | 대응 대상 | -| ----- | ----------------------------------------------------- | ------------- | -| R-008 | 가능한 경우 암호화된 채널 검증 추가 | T-ACCESS-002 | -| R-009 | config 무결성 검증 구현 | T-PERSIST-003 | +| ID | 권장 사항 | 해결 대상 | +| ----- | ---------------------------------------------- | ------------- | +| R-008 | 가능한 경우 암호학적 채널 검증 추가 | T-ACCESS-002 | +| R-009 | 설정 무결성 검증 구현 | T-PERSIST-003 | | R-010 | 업데이트 서명 및 버전 고정 추가 | T-PERSIST-002 | --- @@ -575,46 +573,46 @@ T-EXEC-002 → T-EXFIL-001 → External exfiltration ### 7.1 ATLAS 기법 매핑 -| ATLAS ID | 기법 이름 | OpenClaw 위협 | +| ATLAS ID | 기법 이름 | OpenClaw 위협 | | ------------- | ------------------------------ | ---------------------------------------------------------------- | -| AML.T0006 | 능동 스캔 | T-RECON-001, T-RECON-002 | -| AML.T0009 | 수집 | T-EXFIL-001, T-EXFIL-002, T-EXFIL-003 | -| AML.T0010.001 | 공급망: AI 소프트웨어 | T-PERSIST-001, T-PERSIST-002 | -| AML.T0010.002 | 공급망: 데이터 | T-PERSIST-003 | -| AML.T0031 | AI 모델 무결성 약화 | T-IMPACT-001, T-IMPACT-002, T-IMPACT-003 | -| AML.T0040 | AI 모델 추론 API 접근 | T-ACCESS-001, T-ACCESS-002, T-ACCESS-003, T-DISC-001, T-DISC-002 | -| AML.T0043 | 적대적 데이터 제작 | T-EXEC-004, T-EVADE-001, T-EVADE-002 | -| AML.T0051.000 | LLM 프롬프트 인젝션: 직접 | T-EXEC-001, T-EXEC-003 | -| AML.T0051.001 | LLM 프롬프트 인젝션: 간접 | T-EXEC-002 | +| AML.T0006 | 능동 스캔 | T-RECON-001, T-RECON-002 | +| AML.T0009 | 수집 | T-EXFIL-001, T-EXFIL-002, T-EXFIL-003 | +| AML.T0010.001 | 공급망: AI 소프트웨어 | T-PERSIST-001, T-PERSIST-002 | +| AML.T0010.002 | 공급망: 데이터 | T-PERSIST-003 | +| AML.T0031 | AI 모델 무결성 약화 | T-IMPACT-001, T-IMPACT-002, T-IMPACT-003 | +| AML.T0040 | AI 모델 추론 API 접근 | T-ACCESS-001, T-ACCESS-002, T-ACCESS-003, T-DISC-001, T-DISC-002 | +| AML.T0043 | 적대적 데이터 제작 | T-EXEC-004, T-EVADE-001, T-EVADE-002 | +| AML.T0051.000 | LLM 프롬프트 인젝션: 직접 | T-EXEC-001, T-EXEC-003 | +| AML.T0051.001 | LLM 프롬프트 인젝션: 간접 | T-EXEC-002 | ### 7.2 주요 보안 파일 -| 경로 | 목적 | 위험 수준 | +| 경로 | 목적 | 위험 수준 | | ----------------------------------- | --------------------------- | ------------ | -| `src/infra/exec-approvals.ts` | 명령 승인 로직 | **치명적** | -| `src/gateway/auth.ts` | Gateway 인증 | **치명적** | -| `src/infra/net/ssrf.ts` | SSRF 보호 | **치명적** | -| `src/security/external-content.ts` | 프롬프트 인젝션 완화 | **치명적** | -| `src/agents/sandbox/tool-policy.ts` | 도구 정책 시행 | **치명적** | -| `src/routing/resolve-route.ts` | 세션 격리 | **중간** | +| `src/infra/exec-approvals.ts` | 명령 승인 로직 | **심각** | +| `src/gateway/auth.ts` | Gateway 인증 | **심각** | +| `src/infra/net/ssrf.ts` | SSRF 보호 | **심각** | +| `src/security/external-content.ts` | 프롬프트 인젝션 완화 | **심각** | +| `src/agents/sandbox/tool-policy.ts` | 도구 정책 적용 | **심각** | +| `src/routing/resolve-route.ts` | 세션 격리 | **중간** | ### 7.3 용어집 -| 용어 | 정의 | +| 용어 | 정의 | | -------------------- | --------------------------------------------------------- | -| **ATLAS** | AI 시스템을 위한 MITRE의 적대적 위협 환경 | -| **ClawHub** | OpenClaw의 skill 마켓플레이스 | -| **Gateway** | OpenClaw의 메시지 라우팅 및 인증 계층 | +| **ATLAS** | AI 시스템을 위한 MITRE의 적대적 위협 환경 | +| **ClawHub** | OpenClaw의 Skills 마켓플레이스 | +| **Gateway** | OpenClaw의 메시지 라우팅 및 인증 계층 | | **MCP** | Model Context Protocol - 도구 제공자 인터페이스 | -| **프롬프트 인젝션** | 악의적인 지시가 입력에 삽입되는 공격 | -| **Skill** | OpenClaw 에이전트를 위한 다운로드 가능한 확장 | -| **SSRF** | 서버 측 요청 위조 | +| **프롬프트 인젝션** | 악성 지시가 입력에 삽입되는 공격 | +| **Skill** | OpenClaw 에이전트를 위한 다운로드 가능한 확장 기능 | +| **SSRF** | 서버 측 요청 위조 | --- -_이 위협 모델은 지속적으로 업데이트되는 문서입니다. 보안 문제는 security@openclaw.ai로 보고하세요._ +_이 위협 모델은 지속적으로 갱신되는 문서입니다. 보안 문제는 security@openclaw.ai로 보고하세요_ ## 관련 항목 -- [형식 검증](/ko/security/formal-verification) +- [정형 검증](/ko/security/formal-verification) - [위협 모델에 기여하기](/ko/security/CONTRIBUTING-THREAT-MODEL) diff --git a/docs/ko/security/network-proxy.md b/docs/ko/security/network-proxy.md index fa752d0a5..35b29ce82 100644 --- a/docs/ko/security/network-proxy.md +++ b/docs/ko/security/network-proxy.md @@ -2,39 +2,37 @@ read_when: - SSRF 및 DNS 리바인딩 공격에 대한 심층 방어가 필요한 경우 - OpenClaw 런타임 트래픽을 위한 외부 포워드 프록시 구성 -summary: 운영자가 관리하는 필터링 프록시를 통해 OpenClaw 런타임 HTTP 및 WebSocket 트래픽을 라우팅하는 방법 +summary: OpenClaw 런타임 HTTP 및 WebSocket 트래픽을 운영자가 관리하는 필터링 프록시를 통해 라우팅하는 방법 title: 네트워크 프록시 x-i18n: - generated_at: "2026-05-06T06:39:51Z" + generated_at: "2026-05-06T18:00:40Z" model: gpt-5.5 provider: openai - source_hash: d733c690b5f86ef62fe7a35d38fbfcd07910970bca12ca6f74fdb26c8ec4557b + source_hash: aed1cd94ce6a32cd8a3f6c7e579011992af87c1ccc40eb53efaa83b020a6792b source_path: security/network-proxy.md workflow: 16 --- -# 네트워크 프록시 +OpenClaw는 런타임 HTTP 및 WebSocket 트래픽을 운영자가 관리하는 정방향 프록시를 통해 라우팅할 수 있습니다. 이는 중앙 송신 제어, 더 강력한 SSRF 보호, 더 나은 네트워크 감사 가능성을 원하는 배포를 위한 선택적 심층 방어입니다. -OpenClaw는 런타임 HTTP 및 WebSocket 트래픽을 운영자가 관리하는 포워드 프록시를 통해 라우팅할 수 있습니다. 이는 중앙 집중식 이그레스 제어, 더 강력한 SSRF 보호, 더 나은 네트워크 감사 가능성이 필요한 배포를 위한 선택적 심층 방어입니다. - -OpenClaw는 프록시를 제공, 다운로드, 시작, 구성하거나 인증하지 않습니다. 사용자는 환경에 맞는 프록시 기술을 실행하고, OpenClaw는 일반 프로세스 로컬 HTTP 및 WebSocket 클라이언트를 이를 통해 라우팅합니다. +OpenClaw는 프록시를 제공, 다운로드, 시작, 구성 또는 인증하지 않습니다. 환경에 맞는 프록시 기술을 직접 실행하면 OpenClaw가 일반 프로세스 로컬 HTTP 및 WebSocket 클라이언트를 그 프록시를 통해 라우팅합니다. ## 프록시를 사용하는 이유 -프록시는 운영자에게 아웃바운드 HTTP 및 WebSocket 트래픽을 위한 단일 네트워크 제어 지점을 제공합니다. 이는 SSRF 강화 외의 경우에도 유용할 수 있습니다. +프록시는 운영자에게 아웃바운드 HTTP 및 WebSocket 트래픽을 위한 단일 네트워크 제어 지점을 제공합니다. 이는 SSRF 강화 외에도 유용할 수 있습니다. -- 중앙 정책: 모든 애플리케이션 HTTP 호출 지점이 네트워크 규칙을 올바르게 적용하는 데 의존하는 대신 하나의 이그레스 정책을 유지합니다. -- 연결 시점 검사: DNS 해석 이후, 프록시가 업스트림 연결을 열기 직전에 대상을 평가합니다. +- 중앙 정책: 모든 애플리케이션 HTTP 호출 지점이 네트워크 규칙을 올바르게 처리하도록 의존하는 대신 하나의 송신 정책을 유지합니다. +- 연결 시점 검사: DNS 해석 후, 프록시가 업스트림 연결을 열기 직전에 대상 위치를 평가합니다. - DNS 리바인딩 방어: 애플리케이션 수준 DNS 검사와 실제 아웃바운드 연결 사이의 간격을 줄입니다. -- 더 넓은 JavaScript 적용 범위: 일반 `fetch`, `node:http`, `node:https`, WebSocket, axios, got, node-fetch 및 유사한 클라이언트를 동일한 경로로 라우팅합니다. -- 감사 가능성: 이그레스 경계에서 허용 및 거부된 대상을 기록합니다. -- 운영 제어: OpenClaw를 다시 빌드하지 않고 대상 규칙, 네트워크 분할, 속도 제한 또는 아웃바운드 허용 목록을 적용합니다. +- 더 넓은 JavaScript 적용 범위: 일반 `fetch`, `node:http`, `node:https`, WebSocket, axios, got, node-fetch 및 유사 클라이언트를 동일한 경로로 라우팅합니다. +- 감사 가능성: 송신 경계에서 허용 및 거부된 대상 위치를 기록합니다. +- 운영 제어: OpenClaw를 다시 빌드하지 않고 대상 위치 규칙, 네트워크 세분화, 속도 제한 또는 아웃바운드 허용 목록을 적용합니다. -프록시 라우팅은 일반 HTTP 및 WebSocket 이그레스에 대한 프로세스 수준 가드레일입니다. 운영자가 지원되는 JavaScript HTTP 클라이언트를 자체 필터링 프록시를 통해 라우팅할 수 있는 실패 시 폐쇄 경로를 제공하지만, OS 수준 네트워크 샌드박스는 아니며 OpenClaw가 프록시의 대상 정책을 인증하게 만들지도 않습니다. +프록시 라우팅은 일반 HTTP 및 WebSocket 송신을 위한 프로세스 수준 가드레일입니다. 운영자가 지원되는 JavaScript HTTP 클라이언트를 자체 필터링 프록시를 통해 라우팅하는 실패 시 폐쇄 경로를 제공하지만, OS 수준 네트워크 샌드박스는 아니며 OpenClaw가 프록시의 대상 위치 정책을 인증하게 만들지도 않습니다. ## OpenClaw가 트래픽을 라우팅하는 방식 -`proxy.enabled=true`이고 프록시 URL이 구성되면 `openclaw gateway run`, `openclaw node run`, `openclaw agent --local` 같은 보호된 런타임 프로세스는 일반 HTTP 및 WebSocket 이그레스를 구성된 프록시를 통해 라우팅합니다. +`proxy.enabled=true`이고 프록시 URL이 구성된 경우, `openclaw gateway run`, `openclaw node run`, `openclaw agent --local` 같은 보호된 런타임 프로세스는 일반 HTTP 및 WebSocket 송신을 구성된 프록시를 통해 라우팅합니다. ```text OpenClaw process @@ -43,28 +41,28 @@ OpenClaw process WebSocket clients -> operator-managed filtering proxy -> public internet ``` -공개 계약은 이를 구현하는 데 사용된 내부 Node 훅이 아니라 라우팅 동작입니다. OpenClaw Gateway 제어 평면 WebSocket 클라이언트는 Gateway URL이 `localhost` 또는 `127.0.0.1`이나 `[::1]` 같은 리터럴 루프백 IP를 사용할 때 local loopback Gateway RPC 트래픽에 대해 좁은 직접 경로를 사용합니다. 이 제어 평면 경로는 운영자 프록시가 루프백 대상을 차단하더라도 루프백 Gateway에 도달할 수 있어야 합니다. 일반 런타임 HTTP 및 WebSocket 요청은 계속 구성된 프록시를 사용합니다. +공개 계약은 내부 Node 훅 구현 방식이 아니라 라우팅 동작입니다. OpenClaw Gateway 제어 평면 WebSocket 클라이언트는 Gateway URL이 `localhost` 또는 `127.0.0.1`이나 `[::1]` 같은 리터럴 루프백 IP를 사용할 때 local loopback Gateway RPC 트래픽에 대해 좁은 직접 경로를 사용합니다. 이 제어 평면 경로는 운영자 프록시가 루프백 대상 위치를 차단하더라도 루프백 Gateway에 도달할 수 있어야 합니다. 일반 런타임 HTTP 및 WebSocket 요청은 계속 구성된 프록시를 사용합니다. -내부적으로 OpenClaw는 이 기능에 두 가지 프로세스 수준 라우팅 훅을 사용합니다. +내부적으로 OpenClaw는 이 기능을 위해 두 가지 프로세스 수준 라우팅 훅을 사용합니다. - Undici 디스패처 라우팅은 `fetch`, undici 기반 클라이언트, 자체 undici 디스패처를 제공하는 전송을 처리합니다. -- `global-agent` 라우팅은 `http.request`, `https.request`, `http.get`, `https.get` 위에 계층화된 많은 라이브러리를 포함하여 Node 코어 `node:http` 및 `node:https` 호출자를 처리합니다. 관리형 프록시 모드는 명시적 Node HTTP 에이전트가 실수로 운영자 프록시를 우회하지 않도록 해당 전역 에이전트를 강제합니다. +- `global-agent` 라우팅은 `http.request`, `https.request`, `http.get`, `https.get` 위에 계층화된 많은 라이브러리를 포함해 Node 코어 `node:http` 및 `node:https` 호출자를 처리합니다. 관리형 프록시 모드는 명시적 Node HTTP 에이전트가 실수로 운영자 프록시를 우회하지 않도록 해당 전역 에이전트를 강제합니다. -일부 plugins는 프로세스 수준 라우팅이 있어도 명시적 프록시 배선이 필요한 사용자 지정 전송을 소유합니다. 예를 들어 Telegram의 Bot API 전송은 자체 HTTP/1 undici 디스패처를 사용하므로, 해당 소유자별 전송 경로에서 프로세스 프록시 env와 관리형 `OPENCLAW_PROXY_URL` 폴백을 따릅니다. +일부 Plugin은 프로세스 수준 라우팅이 있더라도 명시적 프록시 배선이 필요한 사용자 지정 전송을 소유합니다. 예를 들어 Telegram의 Bot API 전송은 자체 HTTP/1 undici 디스패처를 사용하므로 해당 소유자별 전송 경로에서 프로세스 프록시 환경과 관리형 `OPENCLAW_PROXY_URL` 대체값을 준수합니다. -프록시 URL 자체는 `http://`를 사용해야 합니다. HTTPS 대상은 여전히 HTTP `CONNECT`를 통해 프록시에서 지원됩니다. 이는 OpenClaw가 `http://127.0.0.1:3128` 같은 일반 HTTP 포워드 프록시 리스너를 기대한다는 의미일 뿐입니다. +프록시 URL 자체는 `http://`를 사용해야 합니다. HTTPS 대상 위치는 여전히 HTTP `CONNECT`를 통해 프록시에서 지원됩니다. 이는 OpenClaw가 `http://127.0.0.1:3128` 같은 일반 HTTP 정방향 프록시 리스너를 기대한다는 뜻일 뿐입니다. -프록시가 활성화되어 있는 동안 OpenClaw는 `no_proxy`, `NO_PROXY`, `GLOBAL_AGENT_NO_PROXY`를 지웁니다. 이러한 우회 목록은 대상 기반이므로, 여기에 `localhost` 또는 `127.0.0.1`이 남아 있으면 고위험 SSRF 대상이 필터링 프록시를 건너뛸 수 있습니다. +프록시가 활성화된 동안 OpenClaw는 `no_proxy`, `NO_PROXY`, `GLOBAL_AGENT_NO_PROXY`를 지웁니다. 이 우회 목록은 대상 위치 기반이므로 `localhost` 또는 `127.0.0.1`을 남겨 두면 고위험 SSRF 대상이 필터링 프록시를 건너뛸 수 있습니다. 종료 시 OpenClaw는 이전 프록시 환경을 복원하고 캐시된 프로세스 라우팅 상태를 재설정합니다. ## 관련 프록시 용어 -- `proxy.enabled` / `proxy.proxyUrl`: OpenClaw 런타임 이그레스를 위한 아웃바운드 포워드 프록시 라우팅입니다. 이 페이지는 해당 기능을 설명합니다. -- `gateway.auth.mode: "trusted-proxy"`: Gateway 접근을 위한 인바운드 ID 인식 리버스 프록시 인증입니다. [신뢰할 수 있는 프록시 인증](/ko/gateway/trusted-proxy-auth)을 참조하세요. +- `proxy.enabled` / `proxy.proxyUrl`: OpenClaw 런타임 송신을 위한 아웃바운드 정방향 프록시 라우팅입니다. 이 페이지는 이 기능을 문서화합니다. +- `gateway.auth.mode: "trusted-proxy"`: Gateway 접근을 위한 인바운드 ID 인식 역방향 프록시 인증입니다. [신뢰할 수 있는 프록시 인증](/ko/gateway/trusted-proxy-auth)을 참조하세요. - `openclaw proxy`: 개발 및 지원을 위한 로컬 디버그 프록시 및 캡처 검사기입니다. [openclaw proxy](/ko/cli/proxy)를 참조하세요. -- `tools.web.fetch.useTrustedEnvProxy`: 기본 엄격 DNS 고정 및 호스트 이름 정책은 유지하면서 운영자가 제어하는 HTTP(S) env 프록시가 DNS를 해석하도록 `web_fetch`에 옵트인합니다. [웹 가져오기](/ko/tools/web-fetch#trusted-env-proxy)를 참조하세요. -- 채널 또는 제공자별 프록시 설정: 특정 전송에 대한 소유자별 재정의입니다. 목표가 런타임 전반의 중앙 집중식 이그레스 제어라면 관리형 네트워크 프록시를 선호하세요. +- `tools.web.fetch.useTrustedEnvProxy`: 기본의 엄격한 DNS 고정 및 호스트 이름 정책은 유지하면서 운영자가 제어하는 HTTP(S) 환경 프록시가 DNS를 해석하도록 `web_fetch`에 옵트인합니다. [웹 가져오기](/ko/tools/web-fetch#trusted-env-proxy)를 참조하세요. +- 채널 또는 제공자별 프록시 설정: 특정 전송을 위한 소유자별 재정의입니다. 목표가 런타임 전체의 중앙 송신 제어라면 관리형 네트워크 프록시를 선호하세요. ## 구성 @@ -84,7 +82,7 @@ OPENCLAW_PROXY_URL=http://127.0.0.1:3128 openclaw gateway run ### Gateway 루프백 모드 -로컬 Gateway 제어 평면 클라이언트는 일반적으로 `ws://127.0.0.1:18789` 같은 루프백 WebSocket에 연결합니다. 관리형 프록시가 활성화되어 있는 동안 해당 트래픽이 어떻게 동작할지 선택하려면 `proxy.loopbackMode`를 사용하세요. +로컬 Gateway 제어 평면 클라이언트는 일반적으로 `ws://127.0.0.1:18789` 같은 루프백 WebSocket에 연결합니다. 관리형 프록시가 활성화된 동안 해당 트래픽이 어떻게 동작할지 선택하려면 `proxy.loopbackMode`를 사용하세요. ```yaml proxy: @@ -93,11 +91,11 @@ proxy: loopbackMode: gateway-only # gateway-only, proxy, or block ``` -- `gateway-only`(기본값): OpenClaw는 활성 `global-agent` `NO_PROXY` 컨트롤러에 Gateway 루프백 권한을 등록하여 로컬 Gateway WebSocket 트래픽이 직접 연결할 수 있게 합니다. 활성 Gateway URL의 호스트와 포트가 등록되므로 사용자 지정 루프백 Gateway 포트도 작동합니다. -- `proxy`: OpenClaw는 Gateway 루프백 `NO_PROXY` 권한을 등록하지 않으므로 로컬 Gateway 트래픽이 관리형 프록시를 통해 전송됩니다. 프록시가 원격인 경우, OpenClaw 호스트의 루프백 서비스를 프록시가 도달할 수 있는 호스트 이름, IP 또는 터널에 매핑하는 등의 특수 라우팅을 제공해야 합니다. 표준 원격 프록시는 `127.0.0.1` 및 `localhost`를 OpenClaw 호스트가 아니라 프록시 호스트에서 해석합니다. +- `gateway-only`(기본값): OpenClaw는 로컬 Gateway WebSocket 트래픽이 직접 연결될 수 있도록 활성 `global-agent` `NO_PROXY` 컨트롤러에 Gateway 루프백 권한을 등록합니다. 활성 Gateway URL의 호스트와 포트가 등록되므로 사용자 지정 루프백 Gateway 포트가 작동합니다. +- `proxy`: OpenClaw는 Gateway 루프백 `NO_PROXY` 권한을 등록하지 않으므로 로컬 Gateway 트래픽이 관리형 프록시를 통해 전송됩니다. 프록시가 원격인 경우 OpenClaw 호스트의 루프백 서비스에 대한 특수 라우팅을 제공해야 합니다. 예를 들면 프록시가 도달할 수 있는 호스트 이름, IP 또는 터널에 매핑하는 방식입니다. 표준 원격 프록시는 `127.0.0.1` 및 `localhost`를 OpenClaw 호스트가 아니라 프록시 호스트에서 해석합니다. - `block`: OpenClaw는 소켓을 열기 전에 루프백 Gateway 제어 평면 연결을 거부합니다. -`enabled=true`이지만 유효한 프록시 URL이 구성되어 있지 않으면 보호된 명령은 직접 네트워크 접근으로 폴백하지 않고 시작에 실패합니다. +`enabled=true`이지만 유효한 프록시 URL이 구성되지 않은 경우, 보호된 명령은 직접 네트워크 접근으로 되돌아가는 대신 시작에 실패합니다. `openclaw gateway start`로 시작되는 관리형 Gateway 서비스의 경우 URL을 구성에 저장하는 것을 선호하세요. @@ -108,9 +106,9 @@ openclaw gateway install --force openclaw gateway start ``` -환경 폴백은 포그라운드 실행에 가장 적합합니다. 설치된 서비스와 함께 사용하는 경우 `OPENCLAW_PROXY_URL`을 `$OPENCLAW_STATE_DIR/.env` 또는 `~/.openclaw/.env` 같은 서비스의 영구 환경에 넣은 다음, launchd, systemd 또는 Scheduled Tasks가 해당 값으로 Gateway를 시작하도록 서비스를 다시 설치하세요. +환경 대체값은 포그라운드 실행에 가장 적합합니다. 설치된 서비스에서 사용하는 경우 `OPENCLAW_PROXY_URL`을 `$OPENCLAW_STATE_DIR/.env` 또는 `~/.openclaw/.env` 같은 서비스의 영구 환경에 넣은 다음, launchd, systemd 또는 Scheduled Tasks가 해당 값으로 Gateway를 시작하도록 서비스를 다시 설치하세요. -`openclaw --container ...` 명령의 경우, OpenClaw는 설정되어 있으면 `OPENCLAW_PROXY_URL`을 컨테이너 대상 자식 CLI로 전달합니다. URL은 컨테이너 내부에서 도달 가능해야 합니다. `127.0.0.1`은 호스트가 아니라 컨테이너 자체를 가리킵니다. OpenClaw는 해당 안전 검사를 명시적으로 재정의하지 않는 한 컨테이너 대상 명령에 대해 루프백 프록시 URL을 거부합니다. +`openclaw --container ...` 명령의 경우, OpenClaw는 `OPENCLAW_PROXY_URL`이 설정되어 있으면 컨테이너 대상 자식 CLI로 전달합니다. URL은 컨테이너 내부에서 도달 가능해야 합니다. `127.0.0.1`은 호스트가 아니라 컨테이너 자체를 가리킵니다. OpenClaw는 안전 검사를 명시적으로 재정의하지 않는 한 컨테이너 대상 명령에 대해 루프백 프록시 URL을 거부합니다. ## 프록시 요구 사항 @@ -118,41 +116,41 @@ openclaw gateway start 프록시를 다음과 같이 구성하세요. -- 루프백 또는 신뢰할 수 있는 사설 인터페이스에만 바인딩합니다. +- 루프백 또는 신뢰할 수 있는 비공개 인터페이스에만 바인딩합니다. - OpenClaw 프로세스, 호스트, 컨테이너 또는 서비스 계정만 사용할 수 있도록 접근을 제한합니다. -- 대상을 자체적으로 해석하고 DNS 해석 이후 대상 IP를 차단합니다. +- 대상 위치를 자체적으로 해석하고 DNS 해석 후 대상 IP를 차단합니다. - 일반 HTTP 요청과 HTTPS `CONNECT` 터널 모두에 대해 연결 시점에 정책을 적용합니다. -- 루프백, 사설, 링크 로컬, 메타데이터, 멀티캐스트, 예약 또는 문서화 범위에 대한 대상 기반 우회를 거부합니다. +- 루프백, 비공개, 링크 로컬, 메타데이터, 멀티캐스트, 예약 또는 문서 범위에 대한 대상 위치 기반 우회를 거부합니다. - DNS 해석 경로를 완전히 신뢰하지 않는 한 호스트 이름 허용 목록을 피합니다. -- 요청 본문, 인증 헤더, 쿠키 또는 기타 비밀을 기록하지 않고 대상, 결정, 상태 및 이유를 기록합니다. -- 프록시 정책을 버전 관리하에 두고 보안에 민감한 구성처럼 변경 사항을 검토합니다. +- 요청 본문, 권한 부여 헤더, 쿠키 또는 기타 비밀을 기록하지 않고 대상 위치, 결정, 상태 및 이유를 기록합니다. +- 프록시 정책을 버전 관리 아래에 두고 보안에 민감한 구성처럼 변경 사항을 검토합니다. -## 권장 차단 대상 +## 권장 차단 대상 위치 -이 거부 목록을 모든 포워드 프록시, 방화벽 또는 이그레스 정책의 시작점으로 사용하세요. +모든 정방향 프록시, 방화벽 또는 송신 정책의 시작점으로 이 거부 목록을 사용하세요. -OpenClaw 애플리케이션 수준 분류기 로직은 `src/infra/net/ssrf.ts` 및 `src/shared/net/ip.ts`에 있습니다. 관련 패리티 훅은 `BLOCKED_HOSTNAMES`, `BLOCKED_IPV4_SPECIAL_USE_RANGES`, `BLOCKED_IPV6_SPECIAL_USE_RANGES`, `RFC2544_BENCHMARK_PREFIX`, 그리고 NAT64, 6to4, Teredo, ISATAP, IPv4 매핑 형식에 대한 내장 IPv4 센티널 처리입니다. 이러한 파일은 외부 프록시 정책을 유지 관리할 때 유용한 참조 자료이지만, OpenClaw는 해당 규칙을 사용자의 프록시로 자동 내보내거나 강제하지 않습니다. +OpenClaw 애플리케이션 수준 분류기 로직은 `src/infra/net/ssrf.ts` 및 `src/shared/net/ip.ts`에 있습니다. 관련 동등성 훅은 `BLOCKED_HOSTNAMES`, `BLOCKED_IPV4_SPECIAL_USE_RANGES`, `BLOCKED_IPV6_SPECIAL_USE_RANGES`, `RFC2544_BENCHMARK_PREFIX`, 그리고 NAT64, 6to4, Teredo, ISATAP 및 IPv4 매핑 형식에 대한 내장 IPv4 센티널 처리입니다. 해당 파일은 외부 프록시 정책을 유지 관리할 때 유용한 참조 자료이지만, OpenClaw는 그 규칙을 프록시로 자동 내보내거나 적용하지 않습니다. -| 범위 또는 호스트 | 차단해야 하는 이유 | +| 범위 또는 호스트 | 차단 이유 | | ------------------------------------------------------------------------------------ | ---------------------------------------------------- | | `127.0.0.0/8`, `localhost`, `localhost.localdomain` | IPv4 루프백 | | `::1/128` | IPv6 루프백 | | `0.0.0.0/8`, `::/128` | 지정되지 않은 주소 및 이 네트워크 주소 | -| `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16` | RFC1918 사설 네트워크 | +| `10.0.0.0/8`, `172.16.0.0/12`, `192.168.0.0/16` | RFC1918 비공개 네트워크 | | `169.254.0.0/16`, `fe80::/10` | 링크 로컬 주소 및 일반적인 클라우드 메타데이터 경로 | -| `169.254.169.254`, `metadata.google.internal` | 클라우드 메타데이터 서비스 | -| `100.64.0.0/10` | 캐리어급 NAT 공유 주소 공간 | +| `169.254.169.254`, `metadata.google.internal` | 클라우드 메타데이터 서비스 | +| `100.64.0.0/10` | 통신사용 NAT 공유 주소 공간 | | `198.18.0.0/15`, `2001:2::/48` | 벤치마킹 범위 | -| `192.0.0.0/24`, `192.0.2.0/24`, `198.51.100.0/24`, `203.0.113.0/24`, `2001:db8::/32` | 특수 용도 및 문서화 범위 | +| `192.0.0.0/24`, `192.0.2.0/24`, `198.51.100.0/24`, `203.0.113.0/24`, `2001:db8::/32` | 특수 용도 및 문서 범위 | | `224.0.0.0/4`, `ff00::/8` | 멀티캐스트 | | `240.0.0.0/4` | 예약된 IPv4 | -| `fc00::/7`, `fec0::/10` | IPv6 로컬/사설 범위 | +| `fc00::/7`, `fec0::/10` | IPv6 로컬/비공개 범위 | | `100::/64`, `2001:20::/28` | IPv6 폐기 및 ORCHIDv2 범위 | -| `64:ff9b::/96`, `64:ff9b:1::/48` | 내장 IPv4가 있는 NAT64 접두사 | -| `2002::/16`, `2001::/32` | 내장 IPv4가 있는 6to4 및 Teredo | +| `64:ff9b::/96`, `64:ff9b:1::/48` | 내장 IPv4가 포함된 NAT64 접두사 | +| `2002::/16`, `2001::/32` | 내장 IPv4가 포함된 6to4 및 Teredo | | `::/96`, `::ffff:0:0/96` | IPv4 호환 및 IPv4 매핑 IPv6 | -사용 중인 클라우드 제공자 또는 네트워크 플랫폼이 추가 메타데이터 호스트나 예약 범위를 문서화한 경우, 해당 항목도 추가하세요. +클라우드 제공자 또는 네트워크 플랫폼이 추가 메타데이터 호스트나 예약 범위를 문서화한 경우, 해당 항목도 추가하세요. ## 검증 @@ -162,9 +160,9 @@ OpenClaw를 실행하는 동일한 호스트, 컨테이너 또는 서비스 계 openclaw proxy validate --proxy-url http://127.0.0.1:3128 ``` -기본적으로 사용자 지정 대상이 제공되지 않으면, 이 명령은 `https://example.com/`가 성공하는지 확인하고 프록시가 도달해서는 안 되는 임시 루프백 카나리를 시작합니다. 기본 거부 검사는 프록시가 2xx가 아닌 거부 응답을 반환하거나 전송 실패로 카나리를 차단하면 통과합니다. 성공 응답이 카나리에 도달하면 실패합니다. 프록시가 활성화 및 구성되어 있지 않으면 유효성 검사는 설정 문제를 보고합니다. 설정을 변경하기 전에 일회성 사전 점검을 하려면 `--proxy-url`을 사용하세요. 배포별 기대 동작을 테스트하려면 `--allowed-url` 및 `--denied-url`을 사용하세요. 프록시를 통해 직접 APNs HTTP/2 전달이 CONNECT 터널을 열고 샌드박스 APNs 응답을 받을 수 있는지도 확인하려면 `--apns-reachable`을 추가하세요. 이 프로브는 의도적으로 유효하지 않은 제공자 토큰을 사용하므로 `403 InvalidProviderToken`이 예상되며, 이는 도달 가능으로 간주됩니다. 사용자 지정 거부 대상은 실패 시 차단됩니다. HTTP 응답이 하나라도 있으면 해당 대상이 프록시를 통해 도달 가능했다는 의미이며, 전송 오류는 OpenClaw가 프록시가 도달 가능한 원본을 차단했음을 증명할 수 없으므로 결론 불가로 보고됩니다. 유효성 검사 실패 시 이 명령은 코드 1로 종료됩니다. +기본적으로 사용자 지정 대상이 제공되지 않으면, 이 명령은 `https://example.com/`의 성공 여부를 확인하고 프록시가 도달해서는 안 되는 임시 루프백 카나리를 시작합니다. 기본 거부 확인은 프록시가 2xx가 아닌 거부 응답을 반환하거나 전송 실패로 카나리를 차단하면 통과합니다. 성공 응답이 카나리에 도달하면 실패합니다. 프록시가 활성화 및 구성되어 있지 않으면 검증은 구성 문제를 보고합니다. 구성을 변경하기 전 일회성 프리플라이트에는 `--proxy-url`을 사용하세요. 배포별 기대값을 테스트하려면 `--allowed-url` 및 `--denied-url`을 사용하세요. 프록시를 통해 직접 APNs HTTP/2 전달이 CONNECT 터널을 열고 샌드박스 APNs 응답을 받을 수 있는지도 확인하려면 `--apns-reachable`을 추가하세요. 이 프로브는 의도적으로 잘못된 공급자 토큰을 사용하므로 `403 InvalidProviderToken`이 예상되며 도달 가능으로 간주됩니다. 사용자 지정 거부 대상은 장애 시 차단됩니다. HTTP 응답이 있으면 대상에 프록시를 통해 도달할 수 있었다는 의미이며, 전송 오류는 OpenClaw가 프록시가 도달 가능한 원본을 차단했음을 증명할 수 없기 때문에 결론 불가로 보고됩니다. 검증 실패 시 명령은 코드 1로 종료됩니다. -자동화에는 `--json`을 사용하세요. JSON 출력에는 전체 결과, 적용된 프록시 설정 소스, 설정 오류, 각 대상 검사가 포함됩니다. 프록시 URL 자격 증명은 텍스트 및 JSON 출력에서 수정 처리됩니다. +자동화에는 `--json`을 사용하세요. JSON 출력에는 전체 결과, 유효 프록시 구성 소스, 구성 오류, 각 대상 확인이 포함됩니다. 프록시 URL 자격 증명은 텍스트 및 JSON 출력에서 마스킹됩니다. ```json { @@ -200,7 +198,7 @@ curl -x http://127.0.0.1:3128 http://127.0.0.1/ curl -x http://127.0.0.1:3128 http://169.254.169.254/ ``` -공개 요청은 성공해야 합니다. 루프백 및 메타데이터 요청은 프록시에 의해 차단되어야 합니다. `openclaw proxy validate`의 경우 내장 루프백 카나리가 프록시 거부와 도달 가능한 원본을 구분할 수 있습니다. 사용자 지정 `--denied-url` 검사에는 해당 카나리가 없으므로, 프록시가 별도로 검증할 수 있는 배포별 거부 신호를 노출하지 않는 한 HTTP 응답과 모호한 전송 실패를 모두 유효성 검사 실패로 처리하세요. +공개 요청은 성공해야 합니다. 루프백 및 메타데이터 요청은 프록시에 의해 차단되어야 합니다. `openclaw proxy validate`의 경우 내장 루프백 카나리가 프록시 거부와 도달 가능한 원본을 구분할 수 있습니다. 사용자 지정 `--denied-url` 확인에는 해당 카나리가 없으므로, 프록시가 별도로 검증할 수 있는 배포별 거부 신호를 노출하지 않는 한 HTTP 응답과 모호한 전송 실패를 모두 검증 실패로 취급하세요. 그런 다음 OpenClaw 프록시 라우팅을 활성화합니다. @@ -221,11 +219,11 @@ proxy: ## 제한 사항 - 프록시는 프로세스 로컬 JavaScript HTTP 및 WebSocket 클라이언트에 대한 적용 범위를 개선하지만, OS 수준 네트워크 샌드박스는 아닙니다. -- Gateway 루프백 제어 평면 트래픽은 기본적으로 `proxy.loopbackMode: "gateway-only"`를 통해 직접 로컬 우회를 사용합니다. OpenClaw는 관리되는 `global-agent` `NO_PROXY` 컨트롤러에 활성 Gateway 루프백 권한을 등록하여 이 우회를 구현합니다. 운영자는 Gateway 루프백 트래픽을 관리되는 프록시를 통해 보내려면 `proxy.loopbackMode: "proxy"`를 설정하거나, 루프백 Gateway 연결을 거부하려면 `proxy.loopbackMode: "block"`을 설정할 수 있습니다. 원격 프록시 관련 주의 사항은 [Gateway 루프백 모드](#gateway-loopback-mode)를 참조하세요. -- 원시 `net`, `tls`, `http2` 소켓, 네이티브 애드온, OpenClaw가 아닌 자식 프로세스는 프록시 환경 변수를 상속하고 준수하지 않는 한 Node 수준 프록시 라우팅을 우회할 수 있습니다. 포크된 OpenClaw 자식 CLI는 관리되는 프록시 URL 및 `proxy.loopbackMode` 상태를 상속합니다. -- IRC는 운영자가 관리하는 전달 프록시 라우팅 외부의 원시 TCP/TLS 채널입니다. 모든 송신 트래픽이 해당 전달 프록시를 거쳐야 하는 배포에서는 직접 IRC 송신이 명시적으로 승인되지 않은 한 `channels.irc.enabled=false`를 설정하세요. -- 로컬 디버그 프록시는 진단 도구이며, 관리형 프록시 모드가 활성화되어 있는 동안 프록시 요청 및 CONNECT 터널에 대한 직접 업스트림 전달은 기본적으로 비활성화됩니다. 승인된 로컬 진단에 대해서만 직접 전달을 활성화하세요. -- 사용자 로컬 WebUI 및 로컬 모델 서버는 필요할 때 운영자 프록시 정책에서 허용 목록에 추가해야 합니다. OpenClaw는 이들에 대한 일반적인 로컬 네트워크 우회를 노출하지 않습니다. -- Gateway 제어 평면 프록시 우회는 의도적으로 `localhost` 및 리터럴 루프백 IP URL로 제한됩니다. 로컬 직접 Gateway 제어 평면 연결에는 `ws://127.0.0.1:18789`, `ws://[::1]:18789` 또는 `ws://localhost:18789`를 사용하세요. 다른 호스트 이름은 일반 호스트 이름 기반 트래픽처럼 라우팅됩니다. +- Gateway 루프백 제어 플레인 트래픽은 기본적으로 `proxy.loopbackMode: "gateway-only"`를 통해 직접 로컬 우회를 사용합니다. OpenClaw는 관리되는 `global-agent` `NO_PROXY` 컨트롤러에 활성 Gateway 루프백 권한을 등록하여 해당 우회를 구현합니다. 운영자는 Gateway 루프백 트래픽을 관리 프록시를 통해 보내도록 `proxy.loopbackMode: "proxy"`를 설정하거나, 루프백 Gateway 연결을 거부하도록 `proxy.loopbackMode: "block"`을 설정할 수 있습니다. 원격 프록시 주의 사항은 [Gateway 루프백 모드](#gateway-loopback-mode)를 참조하세요. +- 원시 `net`, `tls`, `http2` 소켓, 네이티브 애드온, OpenClaw가 아닌 자식 프로세스는 프록시 환경 변수를 상속하고 준수하지 않는 한 Node 수준 프록시 라우팅을 우회할 수 있습니다. 포크된 OpenClaw 자식 CLI는 관리 프록시 URL 및 `proxy.loopbackMode` 상태를 상속합니다. +- IRC는 운영자가 관리하는 포워드 프록시 라우팅 외부의 원시 TCP/TLS 채널입니다. 모든 송신 트래픽이 해당 포워드 프록시를 통과해야 하는 배포에서는 직접 IRC 송신이 명시적으로 승인되지 않은 한 `channels.irc.enabled=false`를 설정하세요. +- 로컬 디버그 프록시는 진단 도구이며, 관리 프록시 모드가 활성화된 동안 프록시 요청 및 CONNECT 터널에 대한 직접 업스트림 포워딩은 기본적으로 비활성화됩니다. 승인된 로컬 진단에만 직접 포워딩을 활성화하세요. +- 사용자 로컬 WebUI 및 로컬 모델 서버는 필요할 때 운영자 프록시 정책에서 허용 목록에 추가해야 합니다. OpenClaw는 이를 위한 일반적인 로컬 네트워크 우회를 제공하지 않습니다. +- Gateway 제어 플레인 프록시 우회는 의도적으로 `localhost` 및 리터럴 루프백 IP URL로 제한됩니다. 로컬 직접 Gateway 제어 플레인 연결에는 `ws://127.0.0.1:18789`, `ws://[::1]:18789` 또는 `ws://localhost:18789`를 사용하세요. 다른 호스트 이름은 일반적인 호스트 이름 기반 트래픽처럼 라우팅됩니다. - OpenClaw는 프록시 정책을 검사, 테스트 또는 인증하지 않습니다. - 프록시 정책 변경은 보안에 민감한 운영 변경으로 취급하세요. diff --git a/docs/ko/tools/browser.md b/docs/ko/tools/browser.md index 3ef9dca21..94e2aef04 100644 --- a/docs/ko/tools/browser.md +++ b/docs/ko/tools/browser.md @@ -1,15 +1,15 @@ --- read_when: - 에이전트가 제어하는 브라우저 자동화 추가 - - OpenClaw가 사용자 자신의 Chrome에 간섭하는 이유 디버깅 + - OpenClaw가 사용자의 Chrome에 간섭하는 이유 디버깅하기 - macOS 앱에서 브라우저 설정 및 수명 주기 구현 summary: 통합 브라우저 제어 서비스 + 작업 명령 -title: 브라우저(OpenClaw 관리형) +title: 브라우저 (OpenClaw 관리형) x-i18n: - generated_at: "2026-05-06T06:41:11Z" + generated_at: "2026-05-06T18:00:54Z" model: gpt-5.5 provider: openai - source_hash: 3588ee1205d34df7604f1c660829c5f373b0fa76080d36c460f4ed4a08777a39 + source_hash: 1c9f79b4f8b9921724130b4793584facf1bfbe2de5fb21faa54274a4294dedd0 source_path: tools/browser.md workflow: 16 --- @@ -20,18 +20,18 @@ OpenClaw는 에이전트가 제어하는 **전용 Chrome/Brave/Edge/Chromium 프 초보자 관점: -- **에이전트 전용 별도 브라우저**라고 생각하면 됩니다. -- `openclaw` 프로필은 개인 브라우저 프로필을 건드리지 **않습니다**. +- 이를 **별도의 에이전트 전용 브라우저**로 생각하세요. +- `openclaw` 프로필은 개인 브라우저 프로필을 **건드리지 않습니다**. - 에이전트는 안전한 경로에서 **탭을 열고, 페이지를 읽고, 클릭하고, 입력**할 수 있습니다. - 내장 `user` 프로필은 Chrome MCP를 통해 실제 로그인된 Chrome 세션에 연결됩니다. ## 제공되는 기능 -- **openclaw**라는 별도 브라우저 프로필(기본적으로 주황색 강조 색상). +- 기본적으로 주황색 강조 색상을 사용하는 **openclaw**라는 별도 브라우저 프로필. - 결정적 탭 제어(목록/열기/포커스/닫기). -- 에이전트 동작(클릭/입력/드래그/선택), 스냅샷, 스크린샷, PDF. -- 브라우저 Plugin이 활성화되었을 때 에이전트에게 스냅샷, - 안정적인 탭, 오래된 참조, 수동 차단 요소 복구 루프를 알려주는 번들 `browser-automation` Skill. +- 에이전트 작업(클릭/입력/드래그/선택), 스냅샷, 스크린샷, PDF. +- 브라우저 Plugin이 활성화되어 있을 때 에이전트에게 스냅샷, + 안정적인 탭, 오래된 참조, 수동 차단 요소 복구 루프를 알려 주는 번들 `browser-automation` Skills. - 선택적 다중 프로필 지원(`openclaw`, `work`, `remote`, ...). 이 브라우저는 **일상용 브라우저가 아닙니다**. 에이전트 자동화와 검증을 위한 @@ -48,15 +48,15 @@ openclaw browser --browser-profile openclaw open https://example.com openclaw browser --browser-profile openclaw snapshot ``` -"Browser disabled"가 표시되면 구성에서 활성화하고(아래 참고) Gateway를 +"Browser disabled"가 표시되면 config에서 활성화하고(아래 참조) Gateway를 다시 시작하세요. `openclaw browser`가 아예 없거나 에이전트가 브라우저 도구를 -사용할 수 없다고 말하면 [브라우저 명령 또는 도구 누락](/ko/tools/browser#missing-browser-command-or-tool)으로 이동하세요. +사용할 수 없다고 하면 [누락된 브라우저 명령 또는 도구](/ko/tools/browser#missing-browser-command-or-tool)로 이동하세요. ## Plugin 제어 -기본 `browser` 도구는 번들 Plugin입니다. 동일한 `browser` 도구 이름을 등록하는 다른 Plugin으로 대체하려면 비활성화하세요. +기본 `browser` 도구는 번들 Plugin입니다. 같은 `browser` 도구 이름을 등록하는 다른 Plugin으로 교체하려면 비활성화하세요. ```json5 { @@ -70,14 +70,14 @@ openclaw browser --browser-profile openclaw snapshot } ``` -기본값에는 `plugins.entries.browser.enabled` **및** `browser.enabled=true`가 모두 필요합니다. Plugin만 비활성화하면 `openclaw browser` CLI, `browser.request` Gateway 메서드, 에이전트 도구, 제어 서비스가 하나의 단위로 제거됩니다. 대체 항목을 위해 `browser.*` 구성은 그대로 유지됩니다. +기본값에는 `plugins.entries.browser.enabled` **및** `browser.enabled=true`가 모두 필요합니다. Plugin만 비활성화하면 `openclaw browser` CLI, `browser.request` Gateway 메서드, 에이전트 도구, 제어 서비스가 하나의 단위로 제거됩니다. `browser.*` config는 대체 항목을 위해 그대로 유지됩니다. -브라우저 구성 변경 사항은 Plugin이 서비스를 다시 등록할 수 있도록 Gateway 재시작이 필요합니다. +브라우저 config 변경 사항은 Plugin이 서비스를 다시 등록할 수 있도록 Gateway 재시작이 필요합니다. ## 에이전트 지침 도구 프로필 참고: `tools.profile: "coding"`에는 `web_search`와 -`web_fetch`가 포함되지만 전체 `browser` 도구는 포함되지 않습니다. 에이전트나 +`web_fetch`가 포함되지만 전체 `browser` 도구는 포함되지 않습니다. 에이전트 또는 생성된 하위 에이전트가 브라우저 자동화를 사용해야 한다면 프로필 단계에서 browser를 추가하세요. @@ -97,20 +97,20 @@ openclaw browser --browser-profile openclaw snapshot 브라우저 Plugin은 두 수준의 에이전트 지침을 제공합니다. - `browser` 도구 설명에는 항상 적용되는 간결한 계약이 포함됩니다. 올바른 - 프로필을 선택하고, 참조를 같은 탭에서 유지하고, 탭 - 대상 지정에 `tabId`/레이블을 사용하고, 다단계 작업에는 브라우저 Skill을 로드합니다. -- 번들 `browser-automation` Skill에는 더 긴 운영 루프가 포함됩니다. - 먼저 상태/탭을 확인하고, 작업 탭에 레이블을 붙이고, 동작 전 스냅샷을 만들고, UI 변경 후 - 다시 스냅샷을 만들고, 오래된 참조를 한 번 복구하고, 로그인/2FA/captcha 또는 - 카메라/마이크 차단 요소는 추측하지 말고 수동 작업으로 보고합니다. + 프로필을 선택하고, 참조를 같은 탭에 유지하며, 탭 + 대상을 지정할 때 `tabId`/레이블을 사용하고, 다단계 작업에는 브라우저 Skills를 로드합니다. +- 번들 `browser-automation` Skills에는 더 긴 작업 루프가 포함됩니다. + 먼저 상태/탭을 확인하고, 작업 탭에 레이블을 지정하고, 작업 전 스냅샷을 찍고, UI 변경 후 + 다시 스냅샷을 찍고, 오래된 참조는 한 번 복구하며, 로그인/2FA/captcha 또는 + 카메라/마이크 차단 요소는 추측하지 말고 수동 조치로 보고합니다. -Plugin 번들 Skills는 Plugin이 활성화되면 에이전트의 사용 가능한 Skills에 -나열됩니다. 전체 Skill 지침은 필요할 때 로드되므로 일반적인 +Plugin 번들 Skills는 Plugin이 활성화되면 에이전트의 사용 가능한 Skills에 나열됩니다. +전체 Skills 지침은 필요할 때 로드되므로 일반적인 턴에서는 전체 토큰 비용이 들지 않습니다. -## 브라우저 명령 또는 도구 누락 +## 누락된 브라우저 명령 또는 도구 -업그레이드 후 `openclaw browser`를 알 수 없거나, `browser.request`가 없거나, 에이전트가 브라우저 도구를 사용할 수 없다고 보고하는 경우 일반적인 원인은 `browser`를 생략한 `plugins.allow` 목록이 있고 루트 `browser` 구성 블록이 없는 것입니다. 추가하세요. +업그레이드 후 `openclaw browser`를 알 수 없거나, `browser.request`가 없거나, 에이전트가 브라우저 도구를 사용할 수 없다고 보고한다면 일반적인 원인은 `browser`를 생략한 `plugins.allow` 목록이 있고 루트 `browser` config 블록이 없기 때문입니다. 다음을 추가하세요. ```json5 { @@ -120,20 +120,21 @@ Plugin 번들 Skills는 Plugin이 활성화되면 에이전트의 사용 가능 } ``` -명시적인 루트 `browser` 블록(예: `browser.enabled=true` 또는 `browser.profiles.`)은 제한적인 `plugins.allow` 아래에서도 번들 브라우저 Plugin을 활성화하며, 채널 구성 동작과 일치합니다. `plugins.entries.browser.enabled=true`와 `tools.alsoAllow: ["browser"]`만으로는 허용 목록 멤버십을 대체할 수 없습니다. `plugins.allow`를 완전히 제거해도 기본값이 복원됩니다. +예를 들어 `browser.enabled=true` 또는 `browser.profiles.` 같은 명시적 루트 `browser` 블록은 제한적인 `plugins.allow` 아래에서도 번들 브라우저 Plugin을 활성화하며, 이는 채널 config 동작과 일치합니다. `plugins.entries.browser.enabled=true`와 `tools.alsoAllow: ["browser"]`는 그 자체로 allowlist 멤버십을 대체하지 않습니다. `plugins.allow`를 완전히 제거해도 기본값이 복원됩니다. -## 프로필: `openclaw` 대 `user` +## 프로필: `openclaw` vs `user` -- `openclaw`: 관리형, 격리된 브라우저(확장 프로그램 필요 없음). +- `openclaw`: 관리되는 격리 브라우저(확장 프로그램 필요 없음). - `user`: **실제 로그인된 Chrome** 세션을 위한 내장 Chrome MCP 연결 프로필. 에이전트 브라우저 도구 호출의 경우: - 기본값: 격리된 `openclaw` 브라우저를 사용합니다. -- 기존 로그인 세션이 중요하고 사용자가 컴퓨터 앞에서 연결 프롬프트를 클릭/승인할 수 있을 때는 `profile="user"`를 선호합니다. -- 특정 브라우저 모드를 원할 때 `profile`은 명시적 재정의입니다. +- 기존 로그인 세션이 중요하고 사용자가 컴퓨터 앞에서 연결 프롬프트를 클릭/승인할 수 있을 때는 + `profile="user"`를 선호하세요. +- 특정 브라우저 모드를 원할 때는 `profile`이 명시적 재정의입니다. -관리형 모드를 기본값으로 사용하려면 `browser.defaultProfile: "openclaw"`를 설정하세요. +관리 모드를 기본값으로 사용하려면 `browser.defaultProfile: "openclaw"`를 설정하세요. ## 구성 @@ -194,34 +195,35 @@ Plugin 번들 Skills는 Plugin이 활성화되면 에이전트의 사용 가능 - + -- 제어 서비스는 `gateway.port`에서 파생된 포트의 loopback에 바인딩됩니다(기본값 `18791` = gateway + 2). `gateway.port` 또는 `OPENCLAW_GATEWAY_PORT`를 재정의하면 파생 포트가 같은 계열에서 이동합니다. -- 로컬 `openclaw` 프로필은 `cdpPort`/`cdpUrl`을 자동 할당합니다. 해당 값은 원격 CDP에만 설정하세요. 설정되지 않은 경우 `cdpUrl`은 관리형 로컬 CDP 포트로 기본 설정됩니다. -- `remoteCdpTimeoutMs`는 원격 및 `attachOnly` CDP HTTP 도달 가능성 +- 제어 서비스는 `gateway.port`에서 파생된 포트의 loopback에 바인딩됩니다(기본값 `18791` = gateway + 2). `gateway.port` 또는 `OPENCLAW_GATEWAY_PORT`를 재정의하면 파생 포트도 같은 계열에서 이동합니다. +- 로컬 `openclaw` 프로필은 `cdpPort`/`cdpUrl`을 자동 할당합니다. 이 값은 원격 CDP에만 설정하세요. `cdpUrl`은 설정되지 않은 경우 관리되는 로컬 CDP 포트를 기본값으로 사용합니다. +- `remoteCdpTimeoutMs`는 원격 및 `attachOnly` CDP HTTP 접근 가능성 확인과 탭 열기 HTTP 요청에 적용됩니다. `remoteCdpHandshakeTimeoutMs`는 해당 CDP WebSocket 핸드셰이크에 적용됩니다. - `localLaunchTimeoutMs`는 로컬에서 실행된 관리형 Chrome - 프로세스가 CDP HTTP 엔드포인트를 노출하기 위한 예산입니다. `localCdpReadyTimeoutMs`는 + 프로세스가 CDP HTTP 엔드포인트를 노출하기 위한 시간 예산입니다. `localCdpReadyTimeoutMs`는 프로세스가 발견된 후 CDP websocket 준비 상태를 위한 - 후속 예산입니다. Raspberry Pi, 저사양 VPS 또는 Chromium - 시작이 느린 오래된 하드웨어에서는 이 값을 높이세요. 값은 `120000` ms 이하의 양의 정수여야 하며, 잘못된 - 구성 값은 거부됩니다. -- 반복되는 관리형 Chrome 실행/준비 실패는 프로필별로 서킷 브레이크됩니다. - 여러 번 연속 실패한 후에는 OpenClaw가 모든 브라우저 도구 호출마다 Chromium을 생성하는 대신 새 실행 - 시도를 잠시 중단합니다. 시작 문제를 수정하거나, 브라우저가 필요하지 않으면 비활성화하거나, 복구 후 - Gateway를 다시 시작하세요. -- `actionTimeoutMs`는 호출자가 `timeoutMs`를 전달하지 않을 때 브라우저 `act` 요청의 기본 예산입니다. 클라이언트 전송은 작은 여유 시간을 추가하여 긴 대기가 HTTP 경계에서 시간 초과되지 않고 완료될 수 있게 합니다. -- `tabCleanup`은 기본 에이전트 브라우저 세션이 연 탭에 대한 최선의 정리입니다. 하위 에이전트, cron, ACP 수명 주기 정리는 세션 종료 시 명시적으로 추적된 탭을 계속 닫습니다. 기본 세션은 활성 탭을 재사용 가능하게 유지한 뒤, 유휴 상태이거나 초과된 추적 탭을 백그라운드에서 닫습니다. + 후속 시간 예산입니다. + Chromium이 느리게 시작되는 Raspberry Pi, 저사양 VPS 또는 오래된 하드웨어에서는 이 값을 늘리세요. + 값은 `120000` ms 이하의 양의 정수여야 하며, 잘못된 + config 값은 거부됩니다. +- 관리형 Chrome 실행/준비 실패가 반복되면 프로필별로 회로 차단됩니다. + 여러 번 연속 실패한 후에는 OpenClaw가 모든 브라우저 도구 호출마다 Chromium을 생성하는 대신 + 새 실행 시도를 잠시 중지합니다. 시작 문제를 해결하거나, 필요하지 않다면 브라우저를 비활성화하거나, + 복구 후 Gateway를 다시 시작하세요. +- `actionTimeoutMs`는 호출자가 `timeoutMs`를 전달하지 않을 때 브라우저 `act` 요청의 기본 시간 예산입니다. 클라이언트 전송 계층은 긴 대기가 HTTP 경계에서 시간 초과되는 대신 완료될 수 있도록 작은 여유 시간을 추가합니다. +- `tabCleanup`은 기본 에이전트 브라우저 세션에서 열린 탭에 대한 최선 노력 정리입니다. 하위 에이전트, cron, ACP 수명 주기 정리는 여전히 세션 종료 시 명시적으로 추적된 탭을 닫습니다. 기본 세션은 활성 탭을 재사용 가능하게 유지한 뒤, 백그라운드에서 유휴 상태이거나 초과된 추적 탭을 닫습니다. -- 브라우저 탐색과 탭 열기는 탐색 전에 SSRF 보호를 거치며, 이후 최종 `http(s)` URL에서 최선의 방식으로 다시 확인됩니다. +- 브라우저 탐색과 탭 열기는 탐색 전 SSRF 보호를 받으며, 이후 최종 `http(s)` URL에서도 최선 노력으로 다시 확인됩니다. - 엄격한 SSRF 모드에서는 원격 CDP 엔드포인트 검색과 `/json/version` 프로브(`cdpUrl`)도 확인됩니다. -- Gateway/제공자 `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` 환경 변수는 OpenClaw 관리 브라우저를 자동으로 프록시하지 않습니다. 관리형 Chrome은 기본적으로 직접 실행되므로 제공자 프록시 설정이 브라우저 SSRF 확인을 약화시키지 않습니다. -- 관리형 브라우저 자체를 프록시하려면 `--proxy-server=...` 또는 `--proxy-pac-url=...` 같은 명시적 Chrome 프록시 플래그를 `browser.extraArgs`를 통해 전달하세요. 엄격한 SSRF 모드는 private-network 브라우저 접근이 의도적으로 활성화되지 않은 한 명시적 브라우저 프록시 라우팅을 차단합니다. +- Gateway/프로바이더 `HTTP_PROXY`, `HTTPS_PROXY`, `ALL_PROXY`, `NO_PROXY` 환경 변수는 OpenClaw 관리 브라우저를 자동으로 프록시하지 않습니다. 관리형 Chrome은 기본적으로 직접 실행되므로 프로바이더 프록시 설정이 브라우저 SSRF 검사를 약화하지 않습니다. +- 관리 브라우저 자체를 프록시하려면 `--proxy-server=...` 또는 `--proxy-pac-url=...` 같은 명시적 Chrome 프록시 플래그를 `browser.extraArgs`를 통해 전달하세요. 엄격한 SSRF 모드는 private-network 브라우저 접근이 의도적으로 활성화되지 않는 한 명시적 브라우저 프록시 라우팅을 차단합니다. - `browser.ssrfPolicy.dangerouslyAllowPrivateNetwork`는 기본적으로 꺼져 있습니다. private-network 브라우저 접근이 의도적으로 신뢰되는 경우에만 활성화하세요. - `browser.ssrfPolicy.allowPrivateNetwork`는 레거시 별칭으로 계속 지원됩니다. @@ -229,27 +231,28 @@ Plugin 번들 Skills는 Plugin이 활성화되면 에이전트의 사용 가능 -- `attachOnly: true`는 로컬 브라우저를 절대 실행하지 않고, 이미 실행 중인 브라우저가 있을 때만 연결한다는 뜻입니다. -- `headless`는 전역으로 또는 로컬 관리형 프로필별로 설정할 수 있습니다. 프로필별 값은 `browser.headless`를 재정의하므로, 로컬에서 실행한 한 프로필은 헤드리스로 유지하고 다른 프로필은 보이는 상태로 둘 수 있습니다. -- `POST /start?headless=true` 및 `openclaw browser start --headless`는 +- `attachOnly: true`는 로컬 브라우저를 절대 실행하지 않고, 이미 실행 중인 브라우저가 있을 때만 연결한다는 의미입니다. +- `headless`는 전역으로 또는 로컬 관리형 프로필별로 설정할 수 있습니다. 프로필별 값은 `browser.headless`를 재정의하므로, 로컬에서 실행한 한 프로필은 헤드리스로 유지하면서 다른 프로필은 표시 상태로 둘 수 있습니다. +- `POST /start?headless=true`와 `openclaw browser start --headless`는 `browser.headless` 또는 프로필 구성을 다시 쓰지 않고 로컬 관리형 프로필에 대해 - 일회성 헤드리스 실행을 요청합니다. 기존 세션, attach-only, 원격 CDP 프로필은 - OpenClaw가 해당 브라우저 프로세스를 실행하지 않으므로 이 재정의를 거부합니다. + 일회성 헤드리스 실행을 요청합니다. 기존 세션, 연결 전용, 원격 CDP + 프로필은 OpenClaw가 해당 브라우저 프로세스를 실행하지 않으므로 + 이 재정의를 거부합니다. - `DISPLAY` 또는 `WAYLAND_DISPLAY`가 없는 Linux 호스트에서는 환경이나 프로필/전역 - 구성이 명시적으로 화면 표시 모드를 선택하지 않은 경우 로컬 관리형 프로필이 - 자동으로 기본 헤드리스로 설정됩니다. `openclaw browser status --json`은 + 구성이 표시 모드를 명시적으로 선택하지 않은 경우 로컬 관리형 프로필이 + 자동으로 기본 헤드리스가 됩니다. `openclaw browser status --json`은 `headlessSource`를 `env`, `profile`, `config`, `request`, `linux-display-fallback` 또는 `default`로 보고합니다. -- `OPENCLAW_BROWSER_HEADLESS=1`은 현재 프로세스의 로컬 관리형 실행을 헤드리스로 - 강제합니다. `OPENCLAW_BROWSER_HEADLESS=0`은 일반 시작에 대해 화면 표시 모드를 - 강제하며, 디스플레이 서버가 없는 Linux 호스트에서는 실행 가능한 오류를 반환합니다. - 명시적인 `start --headless` 요청은 해당 한 번의 실행에 대해서는 여전히 우선합니다. -- `executablePath`는 전역으로 또는 로컬 관리형 프로필별로 설정할 수 있습니다. 프로필별 값은 `browser.executablePath`를 재정의하므로, 서로 다른 관리형 프로필이 서로 다른 Chromium 기반 브라우저를 실행할 수 있습니다. 두 형식 모두 OS 홈 디렉터리에 대해 `~`를 허용합니다. -- `color`(최상위 및 프로필별)는 브라우저 UI에 색조를 적용해 어떤 프로필이 활성 상태인지 볼 수 있게 합니다. +- `OPENCLAW_BROWSER_HEADLESS=1`은 현재 프로세스의 로컬 관리형 실행을 헤드리스로 강제합니다. + `OPENCLAW_BROWSER_HEADLESS=0`은 일반 시작에 대해 표시 모드를 강제하고 + 디스플레이 서버가 없는 Linux 호스트에서는 조치 가능한 오류를 반환합니다. + 명시적인 `start --headless` 요청은 해당 한 번의 실행에서는 여전히 우선합니다. +- `executablePath`는 전역으로 또는 로컬 관리형 프로필별로 설정할 수 있습니다. 프로필별 값은 `browser.executablePath`를 재정의하므로 서로 다른 관리형 프로필이 서로 다른 Chromium 기반 브라우저를 실행할 수 있습니다. 두 형식 모두 OS 홈 디렉터리에 대해 `~`를 허용합니다. +- `color`(최상위 및 프로필별)는 브라우저 UI에 색조를 입혀 어떤 프로필이 활성 상태인지 확인할 수 있게 합니다. - 기본 프로필은 `openclaw`(관리형 독립 실행)입니다. 로그인된 사용자 브라우저를 사용하려면 `defaultProfile: "user"`를 사용하세요. -- 자동 감지 순서: Chromium 기반이면 시스템 기본 브라우저, 그렇지 않으면 Chrome → Brave → Edge → Chromium → Chrome Canary. +- 자동 감지 순서: Chromium 기반인 경우 시스템 기본 브라우저, 그렇지 않으면 Chrome → Brave → Edge → Chromium → Chrome Canary. - `driver: "existing-session"`은 원시 CDP 대신 Chrome DevTools MCP를 사용합니다. 해당 드라이버에는 `cdpUrl`을 설정하지 마세요. -- 기존 세션 프로필이 기본값이 아닌 Chromium 사용자 프로필(Brave, Edge 등)에 연결해야 할 때는 `browser.profiles..userDataDir`를 설정하세요. 이 경로도 OS 홈 디렉터리에 대해 `~`를 허용합니다. +- 기존 세션 프로필이 기본값이 아닌 Chromium 사용자 프로필(Brave, Edge 등)에 연결해야 할 때 `browser.profiles..userDataDir`를 설정하세요. 이 경로도 OS 홈 디렉터리에 대해 `~`를 허용합니다. @@ -257,8 +260,8 @@ Plugin 번들 Skills는 Plugin이 활성화되면 에이전트의 사용 가능 ## Brave 또는 다른 Chromium 기반 브라우저 사용 -**시스템 기본** 브라우저가 Chromium 기반(Chrome/Brave/Edge 등)인 경우, -OpenClaw는 이를 자동으로 사용합니다. 자동 감지를 재정의하려면 +**시스템 기본** 브라우저가 Chromium 기반(Chrome/Brave/Edge 등)이면 +OpenClaw가 자동으로 사용합니다. 자동 감지를 재정의하려면 `browser.executablePath`를 설정하세요. 최상위 및 프로필별 `executablePath` 값은 OS 홈 디렉터리에 대해 `~`를 허용합니다. @@ -306,58 +309,59 @@ openclaw config set browser.profiles.work.executablePath "/Applications/Google C ## 로컬 제어와 원격 제어 - **로컬 제어(기본값):** Gateway가 loopback 제어 서비스를 시작하고 로컬 브라우저를 실행할 수 있습니다. -- **원격 제어(노드 호스트):** 브라우저가 있는 머신에서 노드 호스트를 실행하면 Gateway가 브라우저 동작을 그쪽으로 프록시합니다. -- **원격 CDP:** 원격 Chromium 기반 브라우저에 연결하려면 `browser.profiles..cdpUrl`(또는 `browser.cdpUrl`)을 설정하세요. - 이 경우 OpenClaw는 로컬 브라우저를 실행하지 않습니다. -- local loopback의 외부 관리형 CDP 서비스(예: Docker에서 `127.0.0.1`로 게시된 Browserless)의 경우 - `attachOnly: true`도 설정하세요. `attachOnly`가 없는 Loopback CDP는 +- **원격 제어(Node 호스트):** 브라우저가 있는 머신에서 Node 호스트를 실행합니다. Gateway가 브라우저 작업을 그곳으로 프록시합니다. +- **원격 CDP:** 원격 Chromium 기반 브라우저에 연결하려면 + `browser.profiles..cdpUrl`(또는 `browser.cdpUrl`)을 설정합니다. 이 경우 OpenClaw는 로컬 브라우저를 실행하지 않습니다. +- loopback에서 외부 관리형 CDP 서비스(예: Docker에서 `127.0.0.1`로 게시된 Browserless)를 + 사용하는 경우 `attachOnly: true`도 설정하세요. `attachOnly`가 없는 loopback CDP는 로컬 OpenClaw 관리형 브라우저 프로필로 처리됩니다. - `headless`는 OpenClaw가 실행하는 로컬 관리형 프로필에만 영향을 줍니다. 기존 세션 또는 원격 CDP 브라우저를 다시 시작하거나 변경하지 않습니다. -- `executablePath`도 동일한 로컬 관리형 프로필 규칙을 따릅니다. 실행 중인 - 로컬 관리형 프로필에서 이를 변경하면 해당 프로필이 재시작/조정 대상으로 표시되어 +- `executablePath`도 같은 로컬 관리형 프로필 규칙을 따릅니다. 실행 중인 + 로컬 관리형 프로필에서 이를 변경하면 해당 프로필이 재시작/조정을 위해 표시되어 다음 실행에서 새 바이너리를 사용합니다. 중지 동작은 프로필 모드에 따라 다릅니다. -- 로컬 관리형 프로필: `openclaw browser stop`은 - OpenClaw가 실행한 브라우저 프로세스를 중지합니다. -- attach-only 및 원격 CDP 프로필: `openclaw browser stop`은 활성 +- 로컬 관리형 프로필: `openclaw browser stop`은 OpenClaw가 실행한 + 브라우저 프로세스를 중지합니다. +- 연결 전용 및 원격 CDP 프로필: `openclaw browser stop`은 활성 제어 세션을 닫고 Playwright/CDP 에뮬레이션 재정의(뷰포트, - 색 구성표, 로케일, 시간대, 오프라인 모드 및 유사한 상태)를 해제합니다. - OpenClaw가 실행한 브라우저 프로세스가 없더라도 그렇습니다. + 색 구성표, 로캘, 시간대, 오프라인 모드 및 유사한 상태)를 해제합니다. + OpenClaw가 브라우저 프로세스를 실행하지 않았더라도 그렇습니다. -원격 CDP URL에는 인증이 포함될 수 있습니다. +원격 CDP URL에는 인증을 포함할 수 있습니다. - 쿼리 토큰(예: `https://provider.example?token=`) - HTTP Basic 인증(예: `https://user:pass@provider.example`) OpenClaw는 `/json/*` 엔드포인트를 호출할 때와 CDP WebSocket에 연결할 때 -인증을 보존합니다. 토큰을 구성 파일에 커밋하는 대신 환경 변수나 비밀 관리자 사용을 -권장합니다. +인증을 보존합니다. 토큰을 구성 파일에 커밋하는 대신 환경 변수나 시크릿 +관리자를 사용하는 것을 권장합니다. ## Node 브라우저 프록시(무구성 기본값) -브라우저가 있는 머신에서 **노드 호스트**를 실행하면, OpenClaw가 추가 브라우저 구성 없이 -브라우저 도구 호출을 해당 노드로 자동 라우팅할 수 있습니다. -이는 원격 게이트웨이의 기본 경로입니다. +브라우저가 있는 머신에서 **Node 호스트**를 실행하면 OpenClaw가 +추가 브라우저 구성 없이도 브라우저 도구 호출을 해당 Node로 자동 라우팅할 수 있습니다. +이는 원격 Gateway의 기본 경로입니다. 참고: -- 노드 호스트는 **프록시 명령**을 통해 로컬 브라우저 제어 서버를 노출합니다. -- 프로필은 노드 자체의 `browser.profiles` 구성(로컬과 동일)에서 옵니다. -- `nodeHost.browserProxy.allowProfiles`는 선택 사항입니다. 레거시/기본 동작을 원하면 비워 두세요. 그러면 프로필 생성/삭제 라우트를 포함해 구성된 모든 프로필이 프록시를 통해 계속 접근 가능합니다. +- Node 호스트는 **프록시 명령**을 통해 로컬 브라우저 제어 서버를 노출합니다. +- 프로필은 Node 자체의 `browser.profiles` 구성에서 가져옵니다(로컬과 동일). +- `nodeHost.browserProxy.allowProfiles`는 선택 사항입니다. 레거시/기본 동작을 원하면 비워 두세요. 프로필 생성/삭제 라우트를 포함해 구성된 모든 프로필이 프록시를 통해 계속 접근 가능합니다. - `nodeHost.browserProxy.allowProfiles`를 설정하면 OpenClaw는 이를 최소 권한 경계로 처리합니다. 허용 목록에 있는 프로필만 대상으로 지정할 수 있고, 영구 프로필 생성/삭제 라우트는 프록시 표면에서 차단됩니다. - 원하지 않으면 비활성화하세요. - - 노드에서: `nodeHost.browserProxy.enabled=false` + - Node에서: `nodeHost.browserProxy.enabled=false` - Gateway에서: `gateway.nodes.browser.mode="off"` ## Browserless(호스팅 원격 CDP) -[Browserless](https://browserless.io)는 HTTPS 및 WebSocket을 통해 +[Browserless](https://browserless.io)는 HTTPS와 WebSocket을 통해 CDP 연결 URL을 노출하는 호스팅 Chromium 서비스입니다. OpenClaw는 두 형식 모두 사용할 수 있지만, -원격 브라우저 프로필의 가장 간단한 옵션은 Browserless 연결 문서의 직접 WebSocket URL입니다. +원격 브라우저 프로필의 가장 단순한 옵션은 Browserless 연결 문서의 +직접 WebSocket URL입니다. -예시: +예: ```json5 { @@ -379,15 +383,15 @@ CDP 연결 URL을 노출하는 호스팅 Chromium 서비스입니다. OpenClaw 참고: - ``를 실제 Browserless 토큰으로 바꾸세요. -- Browserless 계정과 일치하는 리전 엔드포인트를 선택하세요(해당 문서 참조). +- Browserless 계정과 일치하는 리전 엔드포인트를 선택하세요(해당 문서 참고). - Browserless가 HTTPS 기본 URL을 제공하는 경우, 직접 CDP 연결을 위해 - `wss://`로 변환하거나 HTTPS URL을 유지한 채 OpenClaw가 - `/json/version`을 검색하게 할 수 있습니다. + `wss://`로 변환하거나 HTTPS URL을 유지하고 OpenClaw가 + `/json/version`을 검색하도록 둘 수 있습니다. ### 같은 호스트의 Browserless Docker Browserless가 Docker에서 자체 호스팅되고 OpenClaw가 호스트에서 실행되는 경우, -Browserless를 외부 관리형 CDP 서비스로 취급하세요. +Browserless를 외부 관리형 CDP 서비스로 처리하세요. ```json5 { @@ -406,16 +410,16 @@ Browserless를 외부 관리형 CDP 서비스로 취급하세요. ``` `browser.profiles.browserless.cdpUrl`의 주소는 OpenClaw 프로세스에서 -접근 가능해야 합니다. Browserless도 일치하는 접근 가능한 엔드포인트를 광고해야 합니다. -Browserless `EXTERNAL`을 OpenClaw에서 접근 가능한 동일한 공개 WebSocket 기준 주소로 설정하세요. -예를 들면 `ws://127.0.0.1:3000`, `ws://browserless:3000` 또는 안정적인 비공개 Docker -네트워크 주소입니다. `/json/version`이 OpenClaw가 접근할 수 없는 주소를 가리키는 +도달 가능해야 합니다. Browserless도 일치하는 도달 가능한 엔드포인트를 광고해야 합니다. +Browserless `EXTERNAL`을 `ws://127.0.0.1:3000`, `ws://browserless:3000` 또는 안정적인 비공개 Docker +네트워크 주소와 같이 동일한 public-to-OpenClaw WebSocket 기반으로 설정하세요. +`/json/version`이 OpenClaw가 도달할 수 없는 주소를 가리키는 `webSocketDebuggerUrl`을 반환하면, CDP HTTP는 정상으로 보일 수 있지만 WebSocket 연결은 여전히 실패합니다. -loopback Browserless 프로필에 `attachOnly`를 설정하지 않은 채 두지 마세요. +loopback Browserless 프로필에는 `attachOnly`를 설정하지 않은 상태로 두지 마세요. `attachOnly`가 없으면 OpenClaw는 loopback 포트를 로컬 관리형 브라우저 -프로필로 처리하고, 해당 포트가 사용 중이지만 OpenClaw가 소유하지 않았다고 보고할 수 있습니다. +프로필로 처리하고, 포트가 사용 중이지만 OpenClaw 소유가 아니라고 보고할 수 있습니다. ## 직접 WebSocket CDP 제공자 @@ -424,8 +428,8 @@ loopback Browserless 프로필에 `attachOnly`를 설정하지 않은 채 두지 CDP URL 형태를 허용하고 올바른 연결 전략을 자동으로 선택합니다. - **HTTP(S) 검색** - `http://host[:port]` 또는 `https://host[:port]`. - OpenClaw는 `/json/version`을 호출해 WebSocket 디버거 URL을 검색한 다음 - 연결합니다. WebSocket 대체 연결은 없습니다. + OpenClaw는 WebSocket 디버거 URL을 검색하기 위해 `/json/version`을 호출한 다음 + 연결합니다. WebSocket 폴백은 없습니다. - **직접 WebSocket 엔드포인트** - `ws://host[:port]/devtools//` 또는 `/devtools/browser|page|worker|shared_worker|service_worker/` 경로가 있는 `wss://...`. OpenClaw는 WebSocket 핸드셰이크를 통해 직접 연결하고 @@ -435,17 +439,17 @@ CDP URL 형태를 허용하고 올바른 연결 전략을 자동으로 선택합 [Browserbase](https://www.browserbase.com)). OpenClaw는 먼저 HTTP `/json/version` 검색을 시도합니다(스킴을 `http`/`https`로 정규화). 검색이 `webSocketDebuggerUrl`을 반환하면 이를 사용하고, 그렇지 않으면 OpenClaw는 - 기본 루트에서 직접 WebSocket 핸드셰이크로 대체합니다. 광고된 + 기본 루트에서 직접 WebSocket 핸드셰이크로 폴백합니다. 광고된 WebSocket 엔드포인트가 CDP 핸드셰이크를 거부하지만 구성된 기본 루트가 - 이를 허용하면 OpenClaw는 해당 루트로도 대체합니다. 따라서 로컬 Chrome을 가리키는 기본 `ws://`도 - 연결될 수 있습니다. Chrome은 `/json/version`에서 얻은 특정 대상별 경로에서만 - WebSocket 업그레이드를 허용하지만, 호스팅 제공자는 검색 엔드포인트가 - Playwright CDP에 적합하지 않은 단기 URL을 광고할 때도 루트 WebSocket 엔드포인트를 - 계속 사용할 수 있습니다. + 이를 허용하면 OpenClaw는 그 루트로도 폴백합니다. 이를 통해 로컬 Chrome을 가리키는 기본 `ws://`도 + 여전히 연결할 수 있습니다. Chrome은 `/json/version`에서 가져온 특정 대상별 경로에서만 WebSocket + 업그레이드를 허용하는 반면, 호스팅 + 제공자는 검색 엔드포인트가 Playwright CDP에 적합하지 않은 단기 URL을 광고할 때도 + 루트 WebSocket 엔드포인트를 계속 사용할 수 있기 때문입니다. ### Browserbase -[Browserbase](https://www.browserbase.com)는 내장 CAPTCHA 해결, stealth mode 및 주거용 +[Browserbase](https://www.browserbase.com)는 내장 CAPTCHA 해결, 스텔스 모드, 주거용 프록시를 갖춘 헤드리스 브라우저 실행용 클라우드 플랫폼입니다. ```json5 @@ -467,74 +471,80 @@ CDP URL 형태를 허용하고 올바른 연결 전략을 자동으로 선택합 참고: -- [가입](https://www.browserbase.com/sign-up)하고 [Overview dashboard](https://www.browserbase.com/overview)에서 **API Key**를 복사하세요. +- [가입](https://www.browserbase.com/sign-up)하고 [Overview 대시보드](https://www.browserbase.com/overview)에서 + **API Key**를 복사하세요. - ``를 실제 Browserbase API 키로 바꾸세요. -- Browserbase는 WebSocket 연결 시 브라우저 세션을 자동 생성하므로, - 수동 세션 생성 단계가 필요하지 않습니다. -- 무료 티어는 동시 세션 1개와 월 1 브라우저 시간을 허용합니다. - 유료 플랜 한도는 [pricing](https://www.browserbase.com/pricing)을 참조하세요. -- 전체 API 참조, SDK 가이드 및 통합 예시는 [Browserbase docs](https://docs.browserbase.com)를 참조하세요. +- Browserbase는 WebSocket 연결 시 브라우저 세션을 자동 생성하므로 + 수동 세션 생성 단계가 필요 없습니다. +- 무료 티어는 동시 세션 1개와 월별 브라우저 1시간을 허용합니다. + 유료 플랜 제한은 [가격](https://www.browserbase.com/pricing)을 참고하세요. +- 전체 API 참조, SDK 가이드, 통합 예시는 + [Browserbase 문서](https://docs.browserbase.com)를 참고하세요. ## 보안 핵심 개념: -- 브라우저 제어는 루프백 전용입니다. 접근 흐름은 Gateway의 인증 또는 노드 페어링을 거칩니다. -- 독립 실행형 루프백 브라우저 HTTP API는 **공유 비밀 인증만** 사용합니다: +- 브라우저 제어는 loopback 전용입니다. 접근 흐름은 Gateway 인증 또는 노드 페어링을 통해 이루어집니다. +- 독립 실행형 loopback 브라우저 HTTP API는 **공유 비밀 인증만** 사용합니다: gateway 토큰 bearer 인증, `x-openclaw-password`, 또는 구성된 gateway 비밀번호를 사용하는 HTTP Basic 인증입니다. -- Tailscale Serve ID 헤더와 `gateway.auth.mode: "trusted-proxy"`는 이 - 독립 실행형 루프백 브라우저 API를 인증하지 **않습니다**. +- Tailscale Serve ID 헤더와 `gateway.auth.mode: "trusted-proxy"`는 + 이 독립 실행형 loopback 브라우저 API를 **인증하지 않습니다**. - 브라우저 제어가 활성화되어 있고 공유 비밀 인증이 구성되어 있지 않으면, OpenClaw는 - 시작 시 `gateway.auth.token`을 자동 생성하고 구성에 영구 저장합니다. -- `gateway.auth.mode`가 이미 `password`, `none`, 또는 `trusted-proxy`인 경우 - OpenClaw는 해당 토큰을 자동 생성하지 **않습니다**. -- Gateway와 모든 노드 호스트를 사설 네트워크(Tailscale)에 유지하세요. 공개 노출은 피하세요. -- 원격 CDP URL/토큰은 비밀로 취급하세요. env vars 또는 비밀 관리자를 권장합니다. + 해당 시작에만 사용되는 런타임 전용 gateway 토큰을 생성합니다. 재시작 후에도 클라이언트에 + 안정적인 비밀이 필요하면 `gateway.auth.token`, `gateway.auth.password`, `OPENCLAW_GATEWAY_TOKEN`, 또는 + `OPENCLAW_GATEWAY_PASSWORD`를 명시적으로 구성하세요. +- `gateway.auth.mode`가 이미 `password`, `none`, 또는 `trusted-proxy`인 경우 OpenClaw는 + 해당 토큰을 자동 생성하지 **않습니다**. +- Gateway와 모든 노드 호스트를 사설 네트워크(Tailscale)에 유지하고, 공개 노출을 피하세요. +- 원격 CDP URL/토큰은 비밀로 취급하세요. env vars 또는 secrets manager를 선호하세요. 원격 CDP 팁: -- 가능한 경우 암호화된 엔드포인트(HTTPS 또는 WSS)와 단기 토큰을 권장합니다. -- 장기 토큰을 구성 파일에 직접 포함하지 마세요. +- 가능한 경우 암호화된 엔드포인트(HTTPS 또는 WSS)와 수명이 짧은 토큰을 선호하세요. +- 수명이 긴 토큰을 구성 파일에 직접 포함하지 마세요. ## 프로필(다중 브라우저) -OpenClaw는 여러 이름 있는 프로필(라우팅 구성)을 지원합니다. 프로필은 다음일 수 있습니다: +OpenClaw는 여러 이름 지정 프로필(라우팅 구성)을 지원합니다. 프로필은 다음일 수 있습니다: -- **openclaw-managed**: 자체 사용자 데이터 디렉터리와 CDP 포트를 가진 전용 Chromium 기반 브라우저 인스턴스 +- **openclaw-managed**: 자체 사용자 데이터 디렉터리 + CDP 포트를 가진 전용 Chromium 기반 브라우저 인스턴스 - **remote**: 명시적 CDP URL(다른 곳에서 실행 중인 Chromium 기반 브라우저) - **existing session**: Chrome DevTools MCP 자동 연결을 통한 기존 Chrome 프로필 기본값: -- `openclaw` 프로필은 없으면 자동으로 생성됩니다. -- `user` 프로필은 Chrome MCP 기존 세션 연결을 위해 기본 제공됩니다. -- 기존 세션 프로필은 `user` 외에는 옵트인입니다. `--driver existing-session`으로 생성하세요. -- 로컬 CDP 포트는 기본적으로 **18800-18899**에서 할당됩니다. +- `openclaw` 프로필이 없으면 자동 생성됩니다. +- `user` 프로필은 Chrome MCP existing-session 연결용으로 기본 제공됩니다. +- existing-session 프로필은 `user` 외에는 옵트인입니다. `--driver existing-session`으로 생성하세요. +- local CDP 포트는 기본적으로 **18800-18899**에서 할당됩니다. - 프로필을 삭제하면 해당 로컬 데이터 디렉터리가 휴지통으로 이동합니다. -모든 제어 엔드포인트는 `?profile=`을 허용합니다. CLI는 `--browser-profile`을 사용합니다. +모든 제어 엔드포인트는 `?profile=`을 허용하며, CLI는 `--browser-profile`을 사용합니다. -## Chrome DevTools MCP를 통한 existing session +## Chrome DevTools MCP를 통한 기존 세션 -OpenClaw는 공식 Chrome DevTools MCP 서버를 통해 실행 중인 Chromium 기반 브라우저 프로필에도 -연결할 수 있습니다. 이렇게 하면 해당 브라우저 프로필에 이미 열려 있는 탭과 로그인 상태를 +OpenClaw는 공식 Chrome DevTools MCP 서버를 통해 실행 중인 Chromium 기반 브라우저 프로필에 +연결할 수도 있습니다. 이렇게 하면 해당 브라우저 프로필에 이미 열려 있는 탭과 로그인 상태를 재사용합니다. 공식 배경 및 설정 참고 자료: -- [Chrome for Developers: 브라우저 세션과 함께 Chrome DevTools MCP 사용](https://developer.chrome.com/blog/chrome-devtools-mcp-debug-your-browser-session) +- [Chrome for Developers: Use Chrome DevTools MCP with your browser session](https://developer.chrome.com/blog/chrome-devtools-mcp-debug-your-browser-session) - [Chrome DevTools MCP README](https://github.com/ChromeDevTools/chrome-devtools-mcp) 기본 제공 프로필: - `user` -선택 사항: 다른 이름, 색상, 또는 브라우저 데이터 디렉터리를 원한다면 자체 사용자 지정 기존 세션 프로필을 만드세요. +선택 사항: 다른 이름, 색상, 또는 브라우저 데이터 디렉터리를 원하면 +직접 사용자 지정 existing-session 프로필을 생성하세요. 기본 동작: -- 기본 제공 `user` 프로필은 Chrome MCP 자동 연결을 사용하며, 기본 로컬 Google Chrome 프로필을 대상으로 합니다. +- 기본 제공 `user` 프로필은 기본 local Google Chrome 프로필을 대상으로 하는 + Chrome MCP 자동 연결을 사용합니다. Brave, Edge, Chromium, 또는 기본값이 아닌 Chrome 프로필에는 `userDataDir`을 사용하세요. `~`는 OS 홈 디렉터리로 확장됩니다: @@ -556,17 +566,17 @@ Brave, Edge, Chromium, 또는 기본값이 아닌 Chrome 프로필에는 `userDa 그런 다음 일치하는 브라우저에서: -1. 원격 디버깅을 위한 해당 브라우저의 inspect 페이지를 엽니다. +1. 원격 디버깅용 해당 브라우저의 검사 페이지를 엽니다. 2. 원격 디버깅을 활성화합니다. 3. 브라우저를 계속 실행한 상태로 두고 OpenClaw가 연결할 때 연결 프롬프트를 승인합니다. -일반적인 inspect 페이지: +일반적인 검사 페이지: - Chrome: `chrome://inspect/#remote-debugging` - Brave: `brave://inspect/#remote-debugging` - Edge: `edge://inspect/#remote-debugging` -실시간 연결 스모크 테스트: +라이브 연결 smoke test: ```bash openclaw browser --browser-profile user start @@ -575,66 +585,67 @@ openclaw browser --browser-profile user tabs openclaw browser --browser-profile user snapshot --format ai ``` -성공 시 모습: +성공 상태의 예: -- `status`가 `driver: existing-session`을 표시합니다. -- `status`가 `transport: chrome-mcp`를 표시합니다. -- `status`가 `running: true`를 표시합니다. -- `tabs`가 이미 열려 있는 브라우저 탭을 나열합니다. -- `snapshot`이 선택된 실시간 탭에서 refs를 반환합니다. +- `status`에 `driver: existing-session`이 표시됩니다 +- `status`에 `transport: chrome-mcp`가 표시됩니다 +- `status`에 `running: true`가 표시됩니다 +- `tabs`에 이미 열려 있는 브라우저 탭이 나열됩니다 +- `snapshot`이 선택된 라이브 탭의 refs를 반환합니다 연결이 작동하지 않을 때 확인할 사항: -- 대상 Chromium 기반 브라우저 버전이 `144+`입니다. -- 해당 브라우저의 inspect 페이지에서 원격 디버깅이 활성화되어 있습니다. -- 브라우저가 연결 동의 프롬프트를 표시했고 사용자가 승인했습니다. -- `openclaw doctor`는 오래된 확장 기반 브라우저 구성을 마이그레이션하고 기본 자동 연결 프로필을 위해 - Chrome이 로컬에 설치되어 있는지 확인하지만, 브라우저 측 원격 디버깅을 대신 활성화할 수는 없습니다. +- 대상 Chromium 기반 브라우저 버전이 `144+`입니다 +- 해당 브라우저의 검사 페이지에서 원격 디버깅이 활성화되어 있습니다 +- 브라우저가 연결 동의 프롬프트를 표시했고 사용자가 승인했습니다 +- `openclaw doctor`는 이전 확장 기반 브라우저 구성을 마이그레이션하고 기본 자동 연결 프로필에 대해 + Chrome이 로컬에 설치되어 있는지 확인하지만, 사용자를 대신해 + 브라우저 측 원격 디버깅을 활성화할 수는 없습니다 Agent 사용: -- 사용자의 로그인된 브라우저 상태가 필요할 때 `profile="user"`를 사용하세요. +- 사용자의 로그인된 브라우저 상태가 필요하면 `profile="user"`를 사용하세요. - 사용자 지정 existing-session 프로필을 사용하는 경우 해당 명시적 프로필 이름을 전달하세요. - 사용자가 컴퓨터 앞에서 연결 프롬프트를 승인할 수 있을 때만 이 모드를 선택하세요. -- Gateway 또는 노드 호스트는 `npx chrome-devtools-mcp@latest --autoConnect`를 생성할 수 있습니다. +- Gateway 또는 노드 호스트는 `npx chrome-devtools-mcp@latest --autoConnect`를 생성할 수 있습니다 참고: -- 이 경로는 로그인된 브라우저 세션 안에서 동작할 수 있으므로 격리된 `openclaw` 프로필보다 위험이 더 높습니다. -- OpenClaw는 이 드라이버용 브라우저를 실행하지 않습니다. 연결만 합니다. -- OpenClaw는 여기서 공식 Chrome DevTools MCP `--autoConnect` 흐름을 사용합니다. `userDataDir`이 설정된 경우 - 해당 사용자 데이터 디렉터리를 대상으로 전달됩니다. -- Existing-session은 선택된 호스트에서 또는 연결된 브라우저 노드를 통해 연결할 수 있습니다. - Chrome이 다른 곳에 있고 브라우저 노드가 연결되어 있지 않다면 원격 CDP 또는 노드 호스트를 대신 사용하세요. +- 이 경로는 로그인된 브라우저 세션 안에서 동작할 수 있으므로 격리된 `openclaw` 프로필보다 위험도가 높습니다. +- OpenClaw는 이 드라이버에 대해 브라우저를 실행하지 않고 연결만 합니다. +- OpenClaw는 여기서 공식 Chrome DevTools MCP `--autoConnect` 흐름을 사용합니다. `userDataDir`이 설정되어 있으면 + 해당 사용자 데이터 디렉터리를 대상으로 하도록 그대로 전달됩니다. +- existing-session은 선택된 호스트 또는 연결된 브라우저 노드를 통해 연결할 수 있습니다. + Chrome이 다른 곳에 있고 연결된 브라우저 노드가 없으면 대신 원격 CDP 또는 노드 호스트를 사용하세요. ### 사용자 지정 Chrome MCP 실행 -기본 `npx chrome-devtools-mcp@latest` 흐름이 원하는 방식이 아닐 때(오프라인 호스트, -고정 버전, 벤더 제공 바이너리) 프로필별로 생성되는 Chrome DevTools MCP 서버를 재정의하세요: +기본 `npx chrome-devtools-mcp@latest` 흐름이 원하는 동작이 아닐 때(오프라인 호스트, +고정 버전, vendored binaries), 프로필별로 생성되는 Chrome DevTools MCP 서버를 재정의하세요: -| 필드 | 수행 작업 | +| 필드 | 수행 내용 | | ------------ | -------------------------------------------------------------------------------------------------------------------------- | -| `mcpCommand` | `npx` 대신 생성할 실행 파일입니다. 있는 그대로 해석되며, 절대 경로가 존중됩니다. | +| `mcpCommand` | `npx` 대신 생성할 실행 파일입니다. 있는 그대로 해석되며, 절대 경로가 존중됩니다. | | `mcpArgs` | `mcpCommand`에 그대로 전달되는 인수 배열입니다. 기본 `chrome-devtools-mcp@latest --autoConnect` 인수를 대체합니다. | -Existing-session 프로필에 `cdpUrl`이 설정되면 OpenClaw는 +existing-session 프로필에 `cdpUrl`이 설정되면 OpenClaw는 `--autoConnect`를 건너뛰고 엔드포인트를 Chrome MCP로 자동 전달합니다: -- `http(s)://...` → `--browserUrl `(DevTools HTTP 검색 엔드포인트). +- `http(s)://...` → `--browserUrl `(DevTools HTTP discovery 엔드포인트). - `ws(s)://...` → `--wsEndpoint `(직접 CDP WebSocket). -엔드포인트 플래그와 `userDataDir`은 함께 사용할 수 없습니다. `cdpUrl`이 설정되면, -Chrome MCP가 프로필 디렉터리를 여는 대신 엔드포인트 뒤의 실행 중인 브라우저에 연결하므로 -Chrome MCP 실행 시 `userDataDir`은 무시됩니다. +엔드포인트 플래그와 `userDataDir`은 함께 사용할 수 없습니다. `cdpUrl`이 설정되면 +Chrome MCP가 프로필 디렉터리를 여는 대신 엔드포인트 뒤의 실행 중인 브라우저에 연결하므로, +Chrome MCP 실행에서 `userDataDir`은 무시됩니다. - + -관리형 `openclaw` 프로필과 비교하면 existing-session 드라이버는 더 많은 제약이 있습니다: +관리형 `openclaw` 프로필과 비교하면 existing-session 드라이버에는 더 많은 제약이 있습니다: -- **스크린샷** - 페이지 캡처와 `--ref` 요소 캡처는 작동하지만 CSS `--element` 선택자는 작동하지 않습니다. `--full-page`는 `--ref` 또는 `--element`와 함께 사용할 수 없습니다. 페이지 또는 ref 기반 요소 스크린샷에는 Playwright가 필요하지 않습니다. -- **동작** - `click`, `type`, `hover`, `scrollIntoView`, `drag`, `select`는 스냅샷 refs가 필요합니다(CSS 선택자 불가). `click-coords`는 보이는 뷰포트 좌표를 클릭하며 스냅샷 ref가 필요하지 않습니다. `click`은 왼쪽 버튼만 지원합니다. `type`은 `slowly=true`를 지원하지 않습니다. `fill` 또는 `press`를 사용하세요. `press`는 `delayMs`를 지원하지 않습니다. `type`, `hover`, `scrollIntoView`, `drag`, `select`, `fill`, `evaluate`는 호출별 타임아웃을 지원하지 않습니다. `select`는 단일 값을 허용합니다. -- **대기 / 업로드 / 대화상자** - `wait --url`은 정확한 일치, 부분 문자열, glob 패턴을 지원합니다. `wait --load networkidle`은 지원되지 않습니다. 업로드 훅은 `ref` 또는 `inputRef`가 필요하며, 한 번에 파일 하나만 지원하고 CSS `element`는 지원하지 않습니다. 대화상자 훅은 타임아웃 재정의를 지원하지 않습니다. -- **관리형 전용 기능** - 배치 동작, PDF 내보내기, 다운로드 가로채기, `responsebody`는 여전히 관리형 브라우저 경로가 필요합니다. +- **스크린샷** - 페이지 캡처와 `--ref` 요소 캡처는 작동하지만, CSS `--element` 선택자는 작동하지 않습니다. `--full-page`는 `--ref` 또는 `--element`와 결합할 수 없습니다. 페이지 또는 ref 기반 요소 스크린샷에는 Playwright가 필요하지 않습니다. +- **동작** - `click`, `type`, `hover`, `scrollIntoView`, `drag`, `select`에는 snapshot refs가 필요합니다(CSS 선택자 없음). `click-coords`는 보이는 viewport 좌표를 클릭하며 snapshot ref가 필요하지 않습니다. `click`은 왼쪽 버튼만 지원합니다. `type`은 `slowly=true`를 지원하지 않습니다. `fill` 또는 `press`를 사용하세요. `press`는 `delayMs`를 지원하지 않습니다. `type`, `hover`, `scrollIntoView`, `drag`, `select`, `fill`, `evaluate`는 호출별 timeout을 지원하지 않습니다. `select`는 단일 값을 허용합니다. +- **대기 / 업로드 / 대화상자** - `wait --url`은 정확한 값, 부분 문자열, glob 패턴을 지원합니다. `wait --load networkidle`는 지원되지 않습니다. 업로드 hooks에는 `ref` 또는 `inputRef`가 필요하며, 한 번에 파일 하나만 가능하고 CSS `element`는 사용할 수 없습니다. 대화상자 hooks는 timeout 재정의를 지원하지 않습니다. +- **관리형 전용 기능** - batch actions, PDF export, download interception, `responsebody`는 여전히 관리형 브라우저 경로가 필요합니다. @@ -644,7 +655,8 @@ Chrome MCP 실행 시 `userDataDir`은 무시됩니다. - **전용 포트**: 개발 워크플로와의 충돌을 방지하기 위해 `9222`를 피합니다. - **결정적 탭 제어**: `tabs`는 먼저 `suggestedTargetId`를 반환한 다음 `t1` 같은 안정적인 `tabId` 핸들, 선택적 레이블, 원시 `targetId`를 반환합니다. - Agents는 `suggestedTargetId`를 재사용해야 합니다. 원시 ID는 디버깅과 호환성을 위해 계속 사용할 수 있습니다. + Agents는 `suggestedTargetId`를 재사용해야 합니다. 원시 ID는 + 디버깅 및 호환성을 위해 계속 사용할 수 있습니다. ## 브라우저 선택 @@ -660,16 +672,16 @@ Chrome MCP 실행 시 `userDataDir`은 무시됩니다. 플랫폼: -- macOS: `/Applications`와 `~/Applications`를 확인합니다. +- macOS: `/Applications` 및 `~/Applications`를 확인합니다. - Linux: `/usr/bin`, `/snap/bin`, `/opt/google`, `/opt/brave.com`, `/usr/lib/chromium`, 및 `/usr/lib/chromium-browser` 아래의 일반적인 Chrome/Brave/Edge/Chromium 위치를 확인합니다. - Windows: 일반적인 설치 위치를 확인합니다. ## 제어 API(선택 사항) -스크립팅과 디버깅을 위해 Gateway는 작은 **루프백 전용 HTTP -제어 API**와 이에 대응하는 `openclaw browser` CLI(스냅샷, refs, 대기 -강화 기능, JSON 출력, 디버그 워크플로)를 제공합니다. 전체 참고 자료는 +스크립팅 및 디버깅을 위해 Gateway는 작은 **loopback 전용 HTTP +제어 API**와 이에 맞는 `openclaw browser` CLI(snapshots, refs, wait +power-ups, JSON output, debug workflows)를 제공합니다. 전체 참고 문서는 [브라우저 제어 API](/ko/tools/browser-control)를 참조하세요. ## 문제 해결 @@ -680,22 +692,22 @@ Linux 관련 문제(특히 snap Chromium)는 WSL2 Gateway + Windows Chrome 분리 호스트 설정은 [WSL2 + Windows + 원격 Chrome CDP 문제 해결](/ko/tools/browser-wsl2-windows-remote-cdp-troubleshooting)을 참조하세요. -### CDP 시작 실패와 탐색 SSRF 차단의 차이 +### CDP 시작 실패와 탐색 SSRF 차단 -이들은 서로 다른 실패 유형이며 서로 다른 코드 경로를 가리킵니다. +이 둘은 서로 다른 실패 유형이며 서로 다른 코드 경로를 가리킵니다. -- **CDP 시작 또는 준비 상태 실패**는 OpenClaw가 브라우저 제어 플레인이 정상인지 확인할 수 없음을 의미합니다. -- **탐색 SSRF 차단**은 브라우저 제어 플레인은 정상이나 페이지 탐색 대상이 정책에 의해 거부되었음을 의미합니다. +- **CDP 시작 또는 준비 상태 실패**는 OpenClaw가 브라우저 제어 평면이 정상인지 확인할 수 없음을 의미합니다. +- **탐색 SSRF 차단**은 브라우저 제어 평면은 정상이지만 페이지 탐색 대상이 정책에 의해 거부되었음을 의미합니다. 일반적인 예: - CDP 시작 또는 준비 상태 실패: - `Chrome CDP websocket for profile "openclaw" is not reachable after start` - `Remote CDP for profile "" is not reachable at ` - - 루프백 외부 CDP 서비스가 `attachOnly: true` 없이 구성된 경우 + - loopback 외부 CDP 서비스가 `attachOnly: true` 없이 구성되어 있을 때 `Port is in use for profile "" but not by openclaw` - 탐색 SSRF 차단: - - `start`와 `tabs`는 계속 작동하지만 `open`, `navigate`, 스냅샷 또는 탭 열기 흐름이 브라우저/네트워크 정책 오류로 실패합니다. + - `open`, `navigate`, snapshot, 또는 탭 열기 흐름이 브라우저/네트워크 정책 오류로 실패하지만 `start`와 `tabs`는 계속 작동합니다 둘을 구분하려면 다음 최소 시퀀스를 사용하세요: @@ -708,42 +720,42 @@ openclaw browser --browser-profile openclaw open https://example.com 결과 해석 방법: - `start`가 `not reachable after start`로 실패하면 먼저 CDP 준비 상태를 문제 해결하세요. -- `start`는 성공하지만 `tabs`가 실패하면 제어 플레인이 여전히 비정상입니다. 이를 페이지 탐색 문제가 아니라 CDP 도달성 문제로 취급하세요. -- `start`와 `tabs`는 성공하지만 `open` 또는 `navigate`가 실패하면 브라우저 제어 플레인은 올라와 있으며 실패 원인은 탐색 정책 또는 대상 페이지에 있습니다. +- `start`는 성공하지만 `tabs`가 실패하면 제어 평면이 여전히 비정상입니다. 이를 페이지 탐색 문제가 아니라 CDP 도달 가능성 문제로 취급하세요. +- `start`와 `tabs`는 성공하지만 `open` 또는 `navigate`가 실패하면 브라우저 제어 평면은 올라와 있고 실패는 탐색 정책 또는 대상 페이지에 있습니다. - `start`, `tabs`, `open`이 모두 성공하면 기본 관리형 브라우저 제어 경로가 정상입니다. -중요한 동작 세부 정보: +중요한 동작 세부 사항: -- `browser.ssrfPolicy`를 구성하지 않은 경우에도 브라우저 구성은 기본적으로 fail-closed SSRF 정책 객체를 사용합니다. -- local loopback `openclaw` 관리형 프로필의 경우, CDP 상태 검사는 OpenClaw 자체 로컬 제어 플레인에 대한 브라우저 SSRF 도달성 적용을 의도적으로 건너뜁니다. -- 탐색 보호는 별개입니다. `start` 또는 `tabs` 결과가 성공했다고 해서 이후 `open` 또는 `navigate` 대상이 허용된다는 의미는 아닙니다. +- `browser.ssrfPolicy`를 구성하지 않아도 브라우저 구성은 기본적으로 fail-closed SSRF 정책 객체를 사용합니다. +- local loopback `openclaw` 관리형 프로필의 경우, CDP 상태 확인은 OpenClaw 자체 local 제어 평면에 대해 브라우저 SSRF 도달 가능성 강제를 의도적으로 건너뜁니다. +- 탐색 보호는 별개입니다. `start` 또는 `tabs` 결과가 성공했다고 해서 이후의 `open` 또는 `navigate` 대상이 허용된다는 뜻은 아닙니다. 보안 지침: - 기본적으로 브라우저 SSRF 정책을 완화하지 **마세요**. -- 광범위한 사설 네트워크 접근보다 `hostnameAllowlist` 또는 `allowedHostnames` 같은 좁은 호스트 예외를 권장합니다. -- `dangerouslyAllowPrivateNetwork: true`는 사설 네트워크 브라우저 접근이 필요하고 검토된, 의도적으로 신뢰된 환경에서만 사용하세요. +- 광범위한 사설 네트워크 접근보다 `hostnameAllowlist` 또는 `allowedHostnames` 같은 좁은 호스트 예외를 선호하세요. +- `dangerouslyAllowPrivateNetwork: true`는 사설 네트워크 브라우저 접근이 필요하고 검토된 의도적으로 신뢰된 환경에서만 사용하세요. ## Agent 도구 + 제어 작동 방식 -Agent는 브라우저 자동화를 위한 **도구 하나**를 받습니다: +에이전트는 브라우저 자동화를 위해 **하나의 도구**를 받습니다: - `browser` - doctor/status/start/stop/tabs/open/focus/close/snapshot/screenshot/navigate/act 매핑 방식: -- `browser snapshot`는 안정적인 UI 트리(AI 또는 ARIA)를 반환합니다. -- `browser act`는 스냅샷의 `ref` ID를 사용하여 클릭/입력/드래그/선택을 수행합니다. -- `browser screenshot`은 픽셀(전체 페이지, 요소 또는 레이블이 지정된 ref)을 캡처합니다. -- `browser doctor`는 Gateway, Plugin, 프로필, 브라우저, 탭 준비 상태를 확인합니다. -- `browser`는 다음을 허용합니다. - - `profile`: 이름이 지정된 브라우저 프로필(openclaw, chrome 또는 원격 CDP)을 선택합니다. - - `target`(`sandbox` | `host` | `node`): 브라우저가 위치한 곳을 선택합니다. - - 샌드박스 세션에서 `target: "host"`에는 `agents.defaults.sandbox.browser.allowHostControl=true`가 필요합니다. - - `target`이 생략되면 샌드박스 세션은 기본적으로 `sandbox`를 사용하고, 샌드박스가 아닌 세션은 기본적으로 `host`를 사용합니다. - - 브라우저를 사용할 수 있는 node가 연결되어 있으면, `target="host"` 또는 `target="node"`로 고정하지 않는 한 도구가 자동으로 해당 node로 라우팅할 수 있습니다. +- `browser snapshot`은 안정적인 UI 트리(AI 또는 ARIA)를 반환합니다. +- `browser act`는 snapshot `ref` ID를 사용하여 클릭/입력/드래그/선택합니다. +- `browser screenshot`은 픽셀을 캡처합니다(전체 페이지, 요소 또는 레이블이 지정된 refs). +- `browser doctor`는 Gateway, Plugin, 프로필, 브라우저 및 탭 준비 상태를 확인합니다. +- `browser`는 다음을 허용합니다: + - 명명된 브라우저 프로필(openclaw, chrome 또는 원격 CDP)을 선택하는 `profile`. + - 브라우저가 위치한 곳을 선택하는 `target`(`sandbox` | `host` | `node`). + - 샌드박스 세션에서 `target: "host"`는 `agents.defaults.sandbox.browser.allowHostControl=true`가 필요합니다. + - `target`이 생략된 경우: 샌드박스 세션은 기본적으로 `sandbox`를 사용하고, 비샌드박스 세션은 기본적으로 `host`를 사용합니다. + - 브라우저를 지원하는 노드가 연결되어 있으면, `target="host"` 또는 `target="node"`로 고정하지 않는 한 도구가 자동으로 해당 노드로 라우팅할 수 있습니다. -이렇게 하면 에이전트가 결정적으로 동작하고 취약한 선택자를 피할 수 있습니다. +이를 통해 에이전트를 결정론적으로 유지하고 깨지기 쉬운 선택자를 피할 수 있습니다. ## 관련 항목 diff --git a/docs/ko/tools/plugin.md b/docs/ko/tools/plugin.md index 08df841c7..b7d2ff8b6 100644 --- a/docs/ko/tools/plugin.md +++ b/docs/ko/tools/plugin.md @@ -1,31 +1,28 @@ --- read_when: - Plugin 설치 또는 구성 - - Plugin 검색 및 로드 규칙 이해 - - Codex/Claude 호환 Plugin 번들 작업하기 + - Plugin 검색 및 로드 규칙 이해하기 + - Codex/Claude 호환 Plugin 번들 작업 sidebarTitle: Install and Configure summary: OpenClaw Plugin 설치, 구성 및 관리 title: Plugin x-i18n: - generated_at: "2026-05-06T09:05:27Z" + generated_at: "2026-05-06T18:01:09Z" model: gpt-5.5 provider: openai - source_hash: 0d68ad3cbd040d3f973d219cf273a792f11df382f6c4ccbf80c07acb0d26c658 + source_hash: ef355ac480bce7140049f59d3d01909de2cf2fdf80ad07db62e05ee997840c81 source_path: tools/plugin.md workflow: 16 --- -Plugin은 OpenClaw에 새 기능을 확장합니다. 채널, 모델 제공자, -에이전트 하네스, 도구, Skills, 음성, 실시간 전사, 실시간 -음성, 미디어 이해, 이미지 생성, 비디오 생성, 웹 가져오기, 웹 -검색 등이 포함됩니다. 일부 Plugin은 **core**(OpenClaw와 함께 제공됨)이고, 다른 Plugin은 -**external**입니다. 대부분의 외부 Plugin은 -[ClawHub](/ko/tools/clawhub)를 통해 게시되고 검색됩니다. Npm은 직접 설치와 -마이그레이션이 완료되는 동안 임시 OpenClaw 소유 Plugin 패키지 집합에 대해 계속 지원됩니다. +Plugin은 채널, 모델 제공자, 에이전트 하네스, 도구, Skills, 음성, 실시간 전사, 실시간 +보이스, 미디어 이해, 이미지 생성, 비디오 생성, 웹 가져오기, 웹 +검색 등 새로운 기능으로 OpenClaw를 확장합니다. 일부 Plugin은 **코어**(OpenClaw와 함께 제공됨)이고, 다른 Plugin은 **외부**입니다. 대부분의 외부 Plugin은 +[ClawHub](/ko/tools/clawhub)를 통해 게시되고 검색됩니다. Npm은 직접 설치와 마이그레이션이 끝날 때까지 OpenClaw가 소유한 임시 Plugin 패키지 집합에 대해 계속 지원됩니다. ## 빠른 시작 -복사해 붙여넣을 수 있는 설치, 목록 보기, 제거, 업데이트, 게시 예시는 +설치, 목록 보기, 제거, 업데이트, 게시 예제를 복사해 붙여 넣으려면 [Plugin 관리](/ko/plugins/manage-plugins)를 참조하세요. @@ -62,21 +59,21 @@ Plugin은 OpenClaw에 새 기능을 확장합니다. 채널, 모델 제공자, openclaw gateway restart ``` - 그런 다음 구성 파일의 `plugins.entries.\.config` 아래에서 설정하세요. + 그런 다음 구성 파일의 `plugins.entries.\.config` 아래에서 설정합니다. 실행 중인 Gateway에서 소유자 전용 `/plugins enable` 및 `/plugins disable`은 Gateway 구성 리로더를 트리거합니다. Gateway는 프로세스 안에서 Plugin 런타임 - 표면을 다시 로드하며, 새 에이전트 턴은 새로 고친 레지스트리에서 - 도구 목록을 다시 빌드합니다. `/plugins install`은 Plugin 소스 코드를 변경하므로 - Gateway는 현재 프로세스가 이미 가져온 모듈을 안전하게 - 다시 로드할 수 있는 척하는 대신 재시작을 요청합니다. + 표면을 다시 로드하고, 새로운 에이전트 턴은 새로 고친 레지스트리에서 도구 목록을 + 다시 빌드합니다. `/plugins install`은 Plugin 소스 코드를 변경하므로, + Gateway는 현재 프로세스가 이미 가져온 모듈을 안전하게 다시 로드할 수 있는 척하는 대신 + 재시작을 요청합니다. - + ```bash openclaw plugins inspect --runtime --json @@ -84,9 +81,8 @@ Plugin은 OpenClaw에 새 기능을 확장합니다. 채널, 모델 제공자, openclaw --help ``` - 등록된 도구, 서비스, gateway 메서드, 훅 또는 Plugin 소유 CLI 명령을 증명해야 할 때는 - `--runtime`을 사용하세요. 일반 `inspect`는 콜드 - 매니페스트/레지스트리 검사이며, 의도적으로 Plugin 런타임 가져오기를 피합니다. + 등록된 도구, 서비스, Gateway 메서드, 훅 또는 Plugin 소유 CLI 명령을 증명해야 할 때는 `--runtime`을 사용합니다. 일반 `inspect`는 콜드 + 매니페스트/레지스트리 검사이며 의도적으로 Plugin 런타임 가져오기를 피합니다. @@ -99,79 +95,74 @@ Plugin은 OpenClaw에 새 기능을 확장합니다. 채널, 모델 제공자, /plugin enable ``` -설치 경로는 CLI와 같은 리졸버를 사용합니다. 로컬 경로/아카이브, 명시적 +설치 경로는 CLI와 동일한 해석기를 사용합니다. 로컬 경로/아카이브, 명시적 `clawhub:`, 명시적 `npm:`, 명시적 `npm-pack:`, -명시적 `git:`, 또는 npm을 통한 베어 패키지 사양입니다. +명시적 `git:`, 또는 npm을 통한 베어 패키지 명세입니다. -구성이 유효하지 않으면 설치는 일반적으로 닫힌 상태로 실패하고 +구성이 유효하지 않으면 설치는 보통 안전하게 실패하고 `openclaw doctor --fix`를 안내합니다. 유일한 복구 예외는 -`openclaw.install.allowInvalidConfigRecovery`를 옵트인한 Plugin을 위한 -좁은 번들 Plugin 재설치 경로입니다. -Gateway 시작 중에는 유효하지 않은 Plugin 구성이 다른 유효하지 않은 구성처럼 닫힌 상태로 실패합니다. -`openclaw doctor --fix`를 실행해 해당 Plugin 항목을 비활성화하고 -유효하지 않은 구성 페이로드를 제거하여 잘못된 Plugin 구성을 격리하세요. 일반 -구성 백업은 이전 값을 보존합니다. -채널 구성이 더 이상 검색할 수 없는 Plugin을 참조하지만 같은 -오래된 Plugin id가 Plugin 구성이나 설치 기록에 남아 있으면, Gateway 시작은 -모든 다른 채널을 차단하는 대신 경고를 기록하고 해당 채널을 건너뜁니다. +`openclaw.install.allowInvalidConfigRecovery`를 옵트인한 Plugin을 위한 좁은 번들 Plugin +재설치 경로입니다. +Gateway 시작 중에는 잘못된 Plugin 구성도 다른 잘못된 구성처럼 안전하게 실패합니다. +`openclaw doctor --fix`를 실행해 해당 Plugin 항목을 비활성화하고 잘못된 구성 페이로드를 제거하여 +나쁜 Plugin 구성을 격리하세요. 일반 구성 백업은 이전 값을 유지합니다. +채널 구성이 더 이상 검색할 수 없는 Plugin을 참조하지만 동일한 오래된 Plugin id가 Plugin 구성 또는 설치 기록에 남아 있으면, +Gateway 시작은 모든 다른 채널을 차단하는 대신 경고를 기록하고 해당 채널을 건너뜁니다. `openclaw doctor --fix`를 실행해 오래된 채널/Plugin 항목을 제거하세요. 오래된 Plugin 증거가 없는 알 수 없는 -채널 키는 여전히 검증에 실패하므로 오타가 계속 보입니다. -`plugins.enabled: false`가 설정되어 있으면 오래된 Plugin 참조는 비활성으로 처리됩니다. +채널 키는 여전히 검증에 실패하므로 오타가 계속 드러납니다. +`plugins.enabled: false`가 설정되어 있으면 오래된 Plugin 참조는 비활성으로 취급됩니다. Gateway 시작은 Plugin 검색/로드 작업을 건너뛰고 `openclaw doctor`는 -비활성화된 Plugin 구성을 자동 제거하는 대신 보존합니다. 오래된 Plugin id를 제거하려면 +비활성화된 Plugin 구성을 자동 제거하지 않고 보존합니다. 오래된 Plugin id를 제거하려면 doctor 정리를 실행하기 전에 Plugin을 다시 활성화하세요. -Plugin 의존성 설치는 명시적 설치/업데이트 또는 -doctor 복구 흐름 중에만 발생합니다. Gateway 시작, 구성 다시 로드, 런타임 검사는 -패키지 관리자를 실행하거나 의존성 트리를 복구하지 않습니다. 로컬 Plugin은 이미 -의존성이 설치되어 있어야 하며, npm, git, ClawHub Plugin은 -OpenClaw의 관리형 Plugin 루트 아래에 설치됩니다. npm 의존성은 OpenClaw의 관리형 npm 루트 안에서 -호이스팅될 수 있습니다. 설치/업데이트는 신뢰 전에 해당 관리형 루트를 스캔하고, -제거는 npm을 통해 npm 관리 패키지를 제거합니다. 외부 Plugin과 사용자 지정 로드 경로도 -`openclaw plugins install`을 통해 설치해야 합니다. -런타임 코드를 가져오거나 의존성을 복구하지 않고 각 -표시 Plugin의 정적 `dependencyStatus`를 보려면 `openclaw plugins list --json`을 사용하세요. +Plugin 의존성 설치는 명시적 설치/업데이트 또는 doctor 복구 흐름 중에만 발생합니다. Gateway 시작, 구성 리로드, 런타임 검사는 +패키지 관리자를 실행하거나 의존성 트리를 복구하지 않습니다. 로컬 Plugin은 +의존성이 이미 설치되어 있어야 하며, npm, git, ClawHub Plugin은 +OpenClaw의 관리형 Plugin 루트 아래에 설치됩니다. npm 의존성은 OpenClaw의 관리형 npm 루트 안에서 호이스팅될 수 있습니다. 설치/업데이트는 신뢰 전에 해당 관리형 루트를 스캔하고, +제거는 npm을 통해 npm 관리 패키지를 제거합니다. 외부 Plugin과 사용자 지정 로드 경로도 여전히 `openclaw plugins install`을 통해 설치해야 합니다. +런타임 코드를 가져오거나 의존성을 복구하지 않고 보이는 각 Plugin의 정적 `dependencyStatus`를 보려면 +`openclaw plugins list --json`을 사용하세요. 설치 시점 수명 주기는 [Plugin 의존성 해석](/ko/plugins/dependency-resolution)을 참조하세요. ### 차단된 Plugin 경로 소유권 -Plugin 진단에 -`blocked plugin candidate: suspicious ownership (... uid=1000, expected uid=0 or root)` -가 표시되고 구성 검증에서 이어서 `plugin present but blocked`가 표시되면, OpenClaw가 -이를 로드하는 프로세스와 다른 Unix 사용자가 소유한 -Plugin 파일을 발견한 것입니다. Plugin 구성을 그대로 두고, 파일 시스템 소유권을 수정하거나 -상태 디렉터리를 소유한 동일한 사용자로 OpenClaw를 실행하세요. +Plugin 진단이 +`blocked plugin candidate: suspicious ownership (... uid=1000, expected uid=0 or root)`라고 말하고 +구성 검증이 `plugin present but blocked`로 이어진다면, OpenClaw가 +이를 로드하는 프로세스와 다른 Unix 사용자가 소유한 Plugin 파일을 발견한 것입니다. +Plugin 구성은 그대로 두세요. 파일 시스템 소유권을 수정하거나 상태 디렉터리를 소유한 동일한 사용자로 +OpenClaw를 실행하세요. -Docker 설치의 경우 공식 이미지는 `node`(uid `1000`)로 실행되므로, -호스트에 바인드 마운트된 OpenClaw 구성 및 작업공간 디렉터리는 일반적으로 +Docker 설치의 경우 공식 이미지는 `node`(uid `1000`)로 실행되므로 +호스트에 바인드 마운트된 OpenClaw 구성 및 작업공간 디렉터리는 보통 uid `1000`이 소유해야 합니다. ```bash sudo chown -R 1000:1000 /path/to/openclaw-config /path/to/openclaw-workspace ``` -의도적으로 OpenClaw를 root로 실행하는 경우, 관리형 Plugin 루트를 +의도적으로 OpenClaw를 root로 실행한다면, 관리형 Plugin 루트를 대신 root 소유권으로 복구하세요. ```bash sudo chown -R root:root /path/to/openclaw-config/npm ``` -소유권을 수정한 뒤 `openclaw doctor --fix` 또는 -`openclaw plugins registry --refresh`를 다시 실행하여 영구 저장된 Plugin 레지스트리가 -복구된 파일과 일치하게 하세요. +소유권을 수정한 후에는 유지된 Plugin 레지스트리가 복구된 파일과 일치하도록 +`openclaw doctor --fix` 또는 +`openclaw plugins registry --refresh`를 다시 실행하세요. npm 설치의 경우 `latest`나 dist-tag 같은 변경 가능한 선택자는 -설치 전에 해석되고, 이후 OpenClaw의 관리형 npm 루트에서 정확히 검증된 버전으로 -고정됩니다. npm이 완료된 뒤 OpenClaw는 설치된 -`package-lock.json` 항목이 해석된 버전 및 무결성과 여전히 일치하는지 확인합니다. npm이 -다른 패키지 메타데이터를 쓰면 설치는 실패하고, 다른 Plugin 아티팩트를 -받아들이는 대신 관리형 패키지가 롤백됩니다. +설치 전에 해석된 뒤 OpenClaw의 관리형 npm 루트에서 정확히 검증된 버전으로 고정됩니다. npm이 완료된 후 OpenClaw는 설치된 +`package-lock.json` 항목이 여전히 해석된 버전 및 무결성과 일치하는지 검증합니다. npm이 다른 패키지 메타데이터를 쓰면, 다른 Plugin 아티팩트를 수락하는 대신 설치가 실패하고 관리형 패키지가 롤백됩니다. +관리형 npm 루트는 OpenClaw의 패키지 수준 npm `overrides`도 상속하므로, +패키지된 호스트를 보호하는 보안 핀이 호이스팅된 외부 +Plugin 의존성에도 적용됩니다. -소스 체크아웃은 pnpm 작업공간입니다. 번들 Plugin을 수정하기 위해 OpenClaw를 클론한 경우 -`pnpm install`을 실행하세요. 그러면 OpenClaw는 -`extensions/`에서 번들 Plugin을 로드하므로 수정 사항과 패키지 로컬 의존성이 직접 사용됩니다. -일반 npm 루트 설치는 패키징된 OpenClaw용이며, 소스 체크아웃 +소스 체크아웃은 pnpm 워크스페이스입니다. 번들 Plugin을 수정하려고 OpenClaw를 클론했다면 +`pnpm install`을 실행하세요. 그러면 OpenClaw는 `extensions/`에서 번들 Plugin을 로드하므로 +수정 사항과 패키지 로컬 의존성이 직접 사용됩니다. +일반 npm 루트 설치는 패키지된 OpenClaw용이며, 소스 체크아웃 개발용이 아닙니다. ## Plugin 유형 @@ -180,10 +171,10 @@ OpenClaw는 두 가지 Plugin 형식을 인식합니다. | 형식 | 작동 방식 | 예시 | | ---------- | ------------------------------------------------------------------ | ------------------------------------------------------ | -| **Native** | `openclaw.plugin.json` + 런타임 모듈. 프로세스 안에서 실행됨 | 공식 Plugin, 커뮤니티 npm 패키지 | -| **Bundle** | Codex/Claude/Cursor 호환 레이아웃. OpenClaw 기능으로 매핑됨 | `.codex-plugin/`, `.claude-plugin/`, `.cursor-plugin/` | +| **네이티브** | `openclaw.plugin.json` + 런타임 모듈; 프로세스 안에서 실행 | 공식 Plugin, 커뮤니티 npm 패키지 | +| **번들** | Codex/Claude/Cursor 호환 레이아웃; OpenClaw 기능에 매핑됨 | `.codex-plugin/`, `.claude-plugin/`, `.cursor-plugin/` | -둘 다 `openclaw plugins list` 아래에 표시됩니다. 번들 세부 정보는 [Plugin Bundles](/ko/plugins/bundles)를 참조하세요. +둘 다 `openclaw plugins list` 아래에 표시됩니다. 번들 세부 정보는 [Plugin 번들](/ko/plugins/bundles)을 참조하세요. 네이티브 Plugin을 작성하는 경우 [Plugin 빌드](/ko/plugins/building-plugins)와 [Plugin SDK 개요](/ko/plugins/sdk-overview)부터 시작하세요. @@ -191,25 +182,21 @@ OpenClaw는 두 가지 Plugin 형식을 인식합니다. ## 패키지 진입점 네이티브 Plugin npm 패키지는 `package.json`에 `openclaw.extensions`를 선언해야 합니다. -각 항목은 패키지 디렉터리 안에 있어야 하며 읽을 수 있는 +각 항목은 패키지 디렉터리 안에 머물러야 하며 읽을 수 있는 런타임 파일로 해석되거나, `src/index.ts`에서 `dist/index.js`처럼 추론된 빌드된 JavaScript 피어가 있는 TypeScript 소스 파일로 해석되어야 합니다. -패키징된 설치는 해당 JavaScript 런타임 출력을 포함해야 합니다. TypeScript -소스 폴백은 소스 체크아웃과 로컬 개발 경로용이며, -OpenClaw의 관리형 Plugin 루트에 설치된 npm 패키지용이 아닙니다. +패키지 설치는 해당 JavaScript 런타임 출력을 포함해야 합니다. TypeScript +소스 폴백은 소스 체크아웃과 로컬 개발 경로를 위한 것이며, +OpenClaw의 관리형 Plugin 루트에 설치된 npm 패키지를 위한 것이 아닙니다. 관리형 패키지 경고가 `requires compiled runtime output for -TypeScript entry ...`라고 표시되면, 해당 패키지는 OpenClaw가 런타임에 필요한 -JavaScript 파일 없이 게시된 것입니다. 이는 Plugin 패키징 문제이지 로컬 구성 -문제가 아닙니다. 게시자가 컴파일된 JavaScript를 다시 게시한 뒤 Plugin을 업데이트하거나 -재설치하세요. 또는 수정된 패키지를 사용할 수 있을 때까지 해당 Plugin을 비활성화/제거하세요. +TypeScript entry ...`라고 말하면, 해당 패키지는 OpenClaw가 런타임에 필요한 JavaScript 파일 없이 게시된 것입니다. 이는 Plugin 패키징 문제이지 로컬 구성 +문제가 아닙니다. 게시자가 컴파일된 JavaScript를 다시 게시한 뒤 Plugin을 업데이트하거나 다시 설치하거나, 수정된 패키지를 사용할 수 있을 때까지 해당 Plugin을 비활성화/제거하세요. -게시된 런타임 파일이 소스 항목과 같은 경로에 있지 않을 때는 `openclaw.runtimeExtensions`를 사용하세요. -존재하는 경우 `runtimeExtensions`에는 모든 `extensions` 항목마다 -정확히 하나의 항목이 있어야 합니다. 목록이 일치하지 않으면 소스 경로로 조용히 -폴백하는 대신 설치와 Plugin 검색이 실패합니다. `openclaw.setupEntry`도 -게시하는 경우 빌드된 JavaScript 피어에는 `openclaw.runtimeSetupEntry`를 사용하세요. -선언된 경우 해당 파일은 필수입니다. +게시된 런타임 파일이 소스 항목과 같은 경로에 있지 않을 때는 `openclaw.runtimeExtensions`를 사용하세요. 있으면 `runtimeExtensions`는 +모든 `extensions` 항목마다 정확히 하나의 항목을 포함해야 합니다. 목록이 일치하지 않으면 소스 경로로 조용히 폴백하는 대신 설치와 +Plugin 검색이 실패합니다. `openclaw.setupEntry`도 게시한다면 빌드된 +JavaScript 피어에 `openclaw.runtimeSetupEntry`를 사용하세요. 선언된 경우 해당 파일은 필수입니다. ```json { @@ -225,17 +212,15 @@ JavaScript 파일 없이 게시된 것입니다. 이는 Plugin 패키징 문제 ### 마이그레이션 중 OpenClaw 소유 npm 패키지 -ClawHub는 대부분 Plugin의 기본 배포 경로입니다. 현재 패키징된 -OpenClaw 릴리스는 이미 많은 공식 Plugin을 번들로 제공하므로, 일반 설정에서는 -별도의 npm 설치가 필요하지 않습니다. 모든 OpenClaw 소유 Plugin이 -ClawHub로 마이그레이션될 때까지 OpenClaw는 이전/사용자 지정 설치와 직접 npm 워크플로를 위해 -일부 `@openclaw/*` Plugin 패키지를 npm에 계속 제공합니다. +ClawHub는 대부분의 Plugin을 위한 기본 배포 경로입니다. 현재 패키지된 +OpenClaw 릴리스에는 이미 많은 공식 Plugin이 번들되어 있으므로, 일반 설정에서는 별도의 npm 설치가 필요하지 않습니다. 모든 OpenClaw 소유 Plugin이 +ClawHub로 마이그레이션될 때까지 OpenClaw는 이전/사용자 지정 설치와 직접 npm 워크플로를 위해 일부 `@openclaw/*` Plugin 패키지를 npm에 계속 제공합니다. -npm이 `@openclaw/*` Plugin 패키지를 deprecated로 보고하면, 해당 패키지 -버전은 더 오래된 외부 패키지 라인의 것입니다. 더 최신 npm 패키지가 게시될 때까지 +npm이 `@openclaw/*` Plugin 패키지를 deprecated로 보고한다면, 해당 패키지 +버전은 더 오래된 외부 패키지 계열의 것입니다. 더 새로운 npm 패키지가 게시될 때까지 현재 OpenClaw의 번들 Plugin 또는 로컬 체크아웃을 사용하세요. -| Plugin | 패키지 | 문서 | +| Plugin | 패키지 | 문서 | | --------------- | -------------------------- | ------------------------------------------ | | BlueBubbles | `@openclaw/bluebubbles` | [BlueBubbles](/ko/channels/bluebubbles) | | Discord | `@openclaw/discord` | [Discord](/ko/channels/discord) | @@ -251,7 +236,7 @@ npm이 `@openclaw/*` Plugin 패키지를 deprecated로 보고하면, 해당 패 | Zalo | `@openclaw/zalo` | [Zalo](/ko/channels/zalo) | | Zalo Personal | `@openclaw/zalouser` | [Zalo Personal](/ko/plugins/zalouser) | -### Core(OpenClaw와 함께 제공됨) +### 코어(OpenClaw와 함께 제공됨) @@ -264,10 +249,10 @@ npm이 `@openclaw/*` Plugin 패키지를 deprecated로 보고하면, 해당 패 - `memory-core` - 번들 메모리 검색(`plugins.slots.memory`를 통해 기본값) - - `memory-lancedb` - 자동 회상/캡처 기능이 있는 LanceDB 기반 장기 메모리(`plugins.slots.memory = "memory-lancedb"` 설정) + - `memory-lancedb` - 자동 회수/캡처를 지원하는 LanceDB 기반 장기 메모리(`plugins.slots.memory = "memory-lancedb"` 설정) - [Memory LanceDB](/ko/plugins/memory-lancedb)에서 OpenAI 호환 임베딩 설정, - Ollama 예시, 회수 제한, 문제 해결을 참조하세요. + OpenAI 호환 임베딩 설정, Ollama 예제, 회수 제한, 문제 해결은 + [Memory LanceDB](/ko/plugins/memory-lancedb)를 참조하세요. @@ -305,23 +290,23 @@ npm이 `@openclaw/*` Plugin 패키지를 deprecated로 보고하면, 해당 패 | `enabled` | 마스터 토글(기본값: `true`) | | `allow` | Plugin 허용 목록(선택 사항) | | `bundledDiscovery` | 번들 Plugin 검색 모드(기본값은 `allowlist`) | -| `deny` | Plugin 거부 목록(선택 사항, 거부가 우선함) | +| `deny` | Plugin 거부 목록(선택 사항, 거부가 우선) | | `load.paths` | 추가 Plugin 파일/디렉터리 | -| `slots` | 독점 슬롯 선택기(예: `memory`, `contextEngine`) | +| `slots` | 배타적 슬롯 선택기(예: `memory`, `contextEngine`) | | `entries.\` | Plugin별 토글 + 구성 | -`plugins.allow`는 배타적입니다. 비어 있지 않으면 `tools.allow`에 `"*"` 또는 특정 Plugin 소유 도구 이름이 포함되어 있더라도, 나열된 Plugin만 로드되거나 도구를 노출할 수 있습니다. 도구 허용 목록이 Plugin 도구를 참조하는 경우 소유 Plugin id를 `plugins.allow`에 추가하거나 `plugins.allow`를 제거하세요. `openclaw doctor`는 이 형태에 대해 경고합니다. +`plugins.allow`는 배타적입니다. 비어 있지 않으면 `tools.allow`에 `"*"` 또는 특정 Plugin 소유 도구 이름이 포함되어 있어도 나열된 Plugin만 로드되거나 도구를 노출할 수 있습니다. 도구 허용 목록이 Plugin 도구를 참조하는 경우 소유 Plugin ID를 `plugins.allow`에 추가하거나 `plugins.allow`를 제거하세요. `openclaw doctor`는 이 형태에 대해 경고합니다. -새 구성에서 `plugins.bundledDiscovery`의 기본값은 `"allowlist"`이므로, 제한적인 `plugins.allow` 인벤터리는 런타임 웹 검색 제공자 검색을 포함해 누락된 번들 제공자 Plugin도 차단합니다. Doctor는 이전의 제한적인 허용 목록 구성을 마이그레이션 중 `"compat"`로 표시하여, 운영자가 더 엄격한 모드를 선택하기 전까지 업그레이드가 레거시 번들 제공자 동작을 유지하도록 합니다. 빈 `plugins.allow`는 여전히 설정되지 않은/열린 상태로 처리됩니다. +새 구성에서는 `plugins.bundledDiscovery`의 기본값이 `"allowlist"`이므로, 제한적인 `plugins.allow` 인벤터리는 런타임 웹 검색 제공자 검색을 포함해 누락된 번들 제공자 Plugin도 차단합니다. Doctor는 이전의 제한적인 허용 목록 구성을 마이그레이션 중 `"compat"`으로 표시하여 운영자가 더 엄격한 모드를 선택할 때까지 업그레이드가 기존 번들 제공자 동작을 유지하도록 합니다. 비어 있는 `plugins.allow`는 여전히 설정되지 않음/열림으로 처리됩니다. -`/plugins enable` 또는 `/plugins disable`을 통해 변경한 구성은 프로세스 내 Gateway Plugin 재로드를 트리거합니다. 새 에이전트 턴은 새로 고친 Plugin 레지스트리에서 도구 목록을 다시 빌드합니다. 설치, 업데이트, 제거처럼 소스를 변경하는 작업은 이미 가져온 Plugin 모듈을 제자리에서 안전하게 교체할 수 없으므로 여전히 Gateway 프로세스를 다시 시작합니다. +`/plugins enable` 또는 `/plugins disable`을 통해 변경한 구성은 프로세스 내 Gateway Plugin 리로드를 트리거합니다. 새 에이전트 턴은 새로 고친 Plugin 레지스트리에서 도구 목록을 다시 빌드합니다. 설치, 업데이트, 제거처럼 소스를 변경하는 작업은 이미 가져온 Plugin 모듈을 제자리에서 안전하게 교체할 수 없으므로 여전히 Gateway 프로세스를 다시 시작합니다. -`openclaw plugins list`는 로컬 Plugin 레지스트리/구성 스냅샷입니다. 여기서 `enabled`인 Plugin은 저장된 레지스트리와 현재 구성이 해당 Plugin의 참여를 허용한다는 뜻입니다. 이미 실행 중인 원격 Gateway가 동일한 Plugin 코드로 재로드되거나 다시 시작되었음을 증명하지는 않습니다. 래퍼 프로세스가 있는 VPS/컨테이너 설정에서는 실제 `openclaw gateway run` 프로세스로 재시작 또는 재로드 트리거 쓰기를 보내거나, 재로드가 실패를 보고할 때 실행 중인 Gateway에 대해 `openclaw gateway restart`를 사용하세요. +`openclaw plugins list`는 로컬 Plugin 레지스트리/구성 스냅샷입니다. 거기서 `enabled` 상태인 Plugin은 영구 저장된 레지스트리와 현재 구성이 해당 Plugin의 참여를 허용한다는 뜻입니다. 이미 실행 중인 원격 Gateway가 동일한 Plugin 코드로 리로드되었거나 다시 시작되었다는 것을 증명하지는 않습니다. 래퍼 프로세스가 있는 VPS/컨테이너 설정에서는 실제 `openclaw gateway run` 프로세스에 재시작 또는 리로드를 트리거하는 쓰기를 보내거나, 리로드가 실패를 보고할 때 실행 중인 Gateway에 대해 `openclaw gateway restart`를 사용하세요. - - **비활성화됨**: Plugin은 존재하지만 활성화 규칙이 꺼 두었습니다. 구성은 보존됩니다. - - **누락됨**: 구성이 검색에서 찾지 못한 Plugin id를 참조합니다. - - **유효하지 않음**: Plugin은 존재하지만 구성이 선언된 스키마와 일치하지 않습니다. Gateway 시작은 해당 Plugin만 건너뜁니다. `openclaw doctor --fix`는 유효하지 않은 항목을 비활성화하고 구성 페이로드를 제거하여 격리할 수 있습니다. + - **비활성화됨**: Plugin은 존재하지만 활성화 규칙이 껐습니다. 구성은 보존됩니다. + - **누락됨**: 구성이 검색에서 찾지 못한 Plugin ID를 참조합니다. + - **유효하지 않음**: Plugin은 존재하지만 해당 구성이 선언된 스키마와 일치하지 않습니다. Gateway 시작은 해당 Plugin만 건너뜁니다. `openclaw doctor --fix`는 해당 항목을 비활성화하고 구성 페이로드를 제거하여 유효하지 않은 항목을 격리할 수 있습니다. @@ -331,11 +316,11 @@ OpenClaw는 다음 순서로 Plugin을 스캔합니다(첫 번째 일치가 우 - `plugins.load.paths` - 명시적 파일 또는 디렉터리 경로입니다. OpenClaw 자체 패키지 번들 Plugin 디렉터리를 다시 가리키는 경로는 무시됩니다. + `plugins.load.paths` - 명시적 파일 또는 디렉터리 경로. OpenClaw 자체 패키지 번들 Plugin 디렉터리를 다시 가리키는 경로는 무시됩니다. 오래된 별칭을 제거하려면 `openclaw doctor --fix`를 실행하세요. - + `\/.openclaw//*.ts` 및 `\/.openclaw//*/index.ts`. @@ -344,39 +329,40 @@ OpenClaw는 다음 순서로 Plugin을 스캔합니다(첫 번째 일치가 우 - OpenClaw와 함께 제공됩니다. 다수는 기본적으로 활성화됩니다(모델 제공자, 음성). - 그 외에는 명시적인 활성화가 필요합니다. + OpenClaw와 함께 제공됩니다. 많은 항목은 기본적으로 활성화됩니다(모델 제공자, 음성). + 다른 항목은 명시적 활성화가 필요합니다. -패키지 설치와 Docker 이미지는 일반적으로 컴파일된 `dist/extensions` 트리에서 번들 Plugin을 확인합니다. 번들 Plugin 소스 디렉터리가 일치하는 패키지 소스 경로 위에 bind-mounted된 경우, 예를 들어 `/app/extensions/synology-chat`, OpenClaw는 해당 마운트된 소스 디렉터리를 번들 소스 오버레이로 취급하고 패키지된 `/app/dist/extensions/synology-chat` 번들보다 먼저 검색합니다. 이렇게 하면 모든 번들 Plugin을 TypeScript 소스로 다시 전환하지 않고도 메인테이너 컨테이너 루프가 계속 작동합니다. 소스 오버레이 마운트가 있어도 패키지된 dist 번들을 강제로 사용하려면 `OPENCLAW_DISABLE_BUNDLED_SOURCE_OVERLAYS=1`을 설정하세요. +패키지 설치와 Docker 이미지는 일반적으로 컴파일된 `dist/extensions` 트리에서 번들 Plugin을 확인합니다. 예를 들어 `/app/extensions/synology-chat`처럼 번들 Plugin 소스 디렉터리가 일치하는 패키지 소스 경로 위에 bind-mounted되면, OpenClaw는 해당 마운트된 소스 디렉터리를 번들 소스 오버레이로 취급하고 패키지된 `/app/dist/extensions/synology-chat` 번들보다 먼저 검색합니다. 이렇게 하면 모든 번들 Plugin을 TypeScript 소스로 다시 전환하지 않아도 유지관리자 컨테이너 루프가 동작합니다. 소스 오버레이 마운트가 있어도 패키지된 dist 번들을 강제하려면 `OPENCLAW_DISABLE_BUNDLED_SOURCE_OVERLAYS=1`을 설정하세요. ### 활성화 규칙 -- `plugins.enabled: false`는 모든 Plugin을 비활성화하고 Plugin 검색/로드 작업을 건너뜁니다. -- `plugins.deny`는 항상 allow보다 우선합니다. -- `plugins.entries.\.enabled: false`는 해당 Plugin을 비활성화합니다. -- 워크스페이스 출처 Plugin은 **기본적으로 비활성화**됩니다(명시적으로 활성화해야 함). -- 번들 Plugin은 재정의되지 않는 한 내장된 기본 활성화 집합을 따릅니다. -- 독점 슬롯은 해당 슬롯에 대해 선택된 Plugin을 강제로 활성화할 수 있습니다. -- 일부 번들 opt-in Plugin은 제공자 모델 참조, 채널 구성 또는 하네스 런타임처럼 구성이 Plugin 소유 표면을 명명할 때 자동으로 활성화됩니다. -- 오래된 Plugin 구성은 `plugins.enabled: false`가 활성 상태인 동안 보존됩니다. 오래된 id를 제거하려면 doctor 정리를 실행하기 전에 Plugin을 다시 활성화하세요. -- OpenAI 계열 Codex 라우트는 별도의 Plugin 경계를 유지합니다. - `openai-codex/*`는 OpenAI Plugin에 속하고, 번들 Codex 앱 서버 Plugin은 `agentRuntime.id: "codex"` 또는 레거시 `codex/*` 모델 참조로 선택됩니다. +- `plugins.enabled: false`는 모든 Plugin을 비활성화하고 Plugin 검색/로드 작업을 건너뜁니다 +- `plugins.deny`는 항상 허용보다 우선합니다 +- `plugins.entries.\.enabled: false`는 해당 Plugin을 비활성화합니다 +- 작업 영역 원본 Plugin은 **기본적으로 비활성화됨**입니다(명시적으로 활성화해야 함) +- 번들 Plugin은 재정의되지 않는 한 내장 기본 활성화 집합을 따릅니다 +- 배타적 슬롯은 해당 슬롯에 선택된 Plugin을 강제로 활성화할 수 있습니다 +- 일부 번들 옵트인 Plugin은 구성이 제공자 모델 참조, 채널 구성 또는 하네스 런타임 같은 Plugin 소유 표면의 이름을 지정하면 자동으로 활성화됩니다 +- `plugins.enabled: false`가 활성화되어 있는 동안 오래된 Plugin 구성은 보존됩니다. + 오래된 ID를 제거하려면 doctor 정리를 실행하기 전에 Plugin을 다시 활성화하세요 +- OpenAI 계열 Codex 경로는 별도의 Plugin 경계를 유지합니다. + `openai-codex/*`는 OpenAI Plugin에 속하고, 번들 Codex 앱 서버 Plugin은 `agentRuntime.id: "codex"` 또는 레거시 `codex/*` 모델 참조로 선택됩니다 ## 런타임 훅 문제 해결 -Plugin이 `plugins list`에 나타나지만 `register(api)` 부수 효과 또는 훅이 실시간 채팅 트래픽에서 실행되지 않으면 먼저 다음을 확인하세요. +Plugin이 `plugins list`에 표시되지만 `register(api)` 부작용이나 훅이 실시간 채팅 트래픽에서 실행되지 않으면 먼저 다음을 확인하세요. -- `openclaw gateway status --deep --require-rpc`를 실행하고 활성 Gateway URL, 프로필, 구성 경로, 프로세스가 편집 중인 것과 일치하는지 확인하세요. -- Plugin 설치/구성/코드 변경 후 실시간 Gateway를 다시 시작하세요. 래퍼 컨테이너에서는 PID 1이 감독자일 뿐일 수 있으므로, 자식 `openclaw gateway run` 프로세스를 다시 시작하거나 시그널을 보내세요. -- 훅 등록과 진단을 확인하려면 `openclaw plugins inspect --runtime --json`을 사용하세요. `llm_input`, `llm_output`, `before_agent_finalize`, `agent_end` 같은 비번들 대화 훅에는 `plugins.entries..hooks.allowConversationAccess=true`가 필요합니다. +- `openclaw gateway status --deep --require-rpc`를 실행하고 활성 Gateway URL, 프로필, 구성 경로, 프로세스가 편집 중인 대상인지 확인하세요. +- Plugin 설치/구성/코드 변경 후 실시간 Gateway를 다시 시작하세요. 래퍼 컨테이너에서는 PID 1이 단순히 슈퍼바이저일 수 있습니다. 하위 `openclaw gateway run` 프로세스를 다시 시작하거나 신호를 보내세요. +- `openclaw plugins inspect --runtime --json`을 사용해 훅 등록과 진단을 확인하세요. `before_model_resolve`, `before_agent_reply`, `before_agent_run`, `llm_input`, `llm_output`, `before_agent_finalize`, `agent_end` 같은 비번들 대화 훅에는 `plugins.entries..hooks.allowConversationAccess=true`가 필요합니다. - 모델 전환에는 `before_model_resolve`를 선호하세요. 에이전트 턴의 모델 해석 전에 실행됩니다. `llm_output`은 모델 시도가 어시스턴트 출력을 생성한 후에만 실행됩니다. - 유효한 세션 모델을 증명하려면 `openclaw sessions` 또는 Gateway 세션/상태 표면을 사용하고, 제공자 페이로드를 디버깅할 때는 `--raw-stream --raw-stream-path `로 Gateway를 시작하세요. ### 느린 Plugin 도구 설정 -에이전트 턴이 도구를 준비하는 동안 멈춘 것처럼 보이면 trace 로깅을 활성화하고 Plugin 도구 팩터리 타이밍 줄을 확인하세요. +에이전트 턴이 도구를 준비하는 동안 멈춘 것처럼 보이면 추적 로깅을 활성화하고 Plugin 도구 팩터리 타이밍 줄을 확인하세요. ```bash openclaw config set logging.level trace @@ -389,17 +375,17 @@ openclaw logs --follow [trace:plugin-tools] factory timings ... ``` -요약에는 총 팩터리 시간과 가장 느린 Plugin 도구 팩터리가 나열되며, Plugin id, 선언된 도구 이름, 결과 형태, 도구가 선택 사항인지 여부가 포함됩니다. 단일 팩터리가 최소 1초가 걸리거나 총 Plugin 도구 팩터리 준비가 최소 5초가 걸리면 느린 줄은 경고로 승격됩니다. +요약에는 총 팩터리 시간과 가장 느린 Plugin 도구 팩터리가 나열되며, Plugin ID, 선언된 도구 이름, 결과 형태, 도구가 선택 사항인지 여부가 포함됩니다. 단일 팩터리에 최소 1초가 걸리거나 총 Plugin 도구 팩터리 준비에 최소 5초가 걸리면 느린 줄은 경고로 승격됩니다. -OpenClaw는 동일한 유효 요청 컨텍스트로 반복 해석할 때 성공한 Plugin 도구 팩터리 결과를 캐시합니다. 캐시 키에는 유효 런타임 구성, 워크스페이스, 에이전트/세션 id, 샌드박스 정책, 브라우저 설정, 전달 컨텍스트, 요청자 ID, 소유권 상태가 포함되므로, 이러한 신뢰 필드에 의존하는 팩터리는 컨텍스트가 변경되면 다시 실행됩니다. +OpenClaw는 동일한 유효 요청 컨텍스트에서 반복 해석을 위해 성공한 Plugin 도구 팩터리 결과를 캐시합니다. 캐시 키에는 유효 런타임 구성, 작업 영역, 에이전트/세션 ID, 샌드박스 정책, 브라우저 설정, 전달 컨텍스트, 요청자 ID, 소유권 상태가 포함되므로, 해당 신뢰 필드에 의존하는 팩터리는 컨텍스트가 변경될 때 다시 실행됩니다. -한 Plugin이 타이밍을 지배한다면 런타임 등록을 검사하세요. +한 Plugin이 타이밍의 대부분을 차지하면 해당 런타임 등록을 검사하세요. ```bash openclaw plugins inspect --runtime --json ``` -그런 다음 해당 Plugin을 업데이트, 재설치 또는 비활성화하세요. Plugin 작성자는 값비싼 종속성 로딩을 도구 팩터리 내부에서 수행하는 대신 도구 실행 경로 뒤로 이동해야 합니다. +그런 다음 해당 Plugin을 업데이트, 재설치 또는 비활성화하세요. Plugin 작성자는 비용이 큰 의존성 로딩을 도구 팩터리 내부에서 수행하지 말고 도구 실행 경로 뒤로 옮겨야 합니다. ### 중복 채널 또는 도구 소유권 @@ -409,24 +395,24 @@ openclaw plugins inspect --runtime --json - `channel setup already registered: ()` - `plugin tool name conflict (): ` -이는 활성화된 Plugin이 둘 이상 같은 채널, 설정 흐름 또는 도구 이름을 소유하려 한다는 뜻입니다. 가장 흔한 원인은 이제 동일한 채널 id를 제공하는 번들 Plugin 옆에 외부 채널 Plugin이 설치된 경우입니다. +이는 활성화된 Plugin이 둘 이상 같은 채널, 설정 흐름 또는 도구 이름을 소유하려 한다는 뜻입니다. 가장 흔한 원인은 이제 동일한 채널 ID를 제공하는 번들 Plugin 옆에 외부 채널 Plugin이 설치되어 있는 경우입니다. 디버그 단계: -- 활성화된 모든 Plugin과 출처를 보려면 `openclaw plugins list --enabled --verbose`를 실행하세요. +- `openclaw plugins list --enabled --verbose`를 실행해 활성화된 모든 Plugin과 원본을 확인하세요. - 의심되는 각 Plugin에 대해 `openclaw plugins inspect --runtime --json`을 실행하고 `channels`, `channelConfigs`, `tools`, 진단을 비교하세요. -- Plugin 패키지를 설치하거나 제거한 후에는 저장된 메타데이터가 현재 설치를 반영하도록 `openclaw plugins registry --refresh`를 실행하세요. +- Plugin 패키지를 설치하거나 제거한 뒤에는 영구 저장된 메타데이터가 현재 설치를 반영하도록 `openclaw plugins registry --refresh`를 실행하세요. - 설치, 레지스트리 또는 구성 변경 후 Gateway를 다시 시작하세요. 수정 옵션: -- 한 Plugin이 동일한 채널 id에 대해 다른 Plugin을 의도적으로 대체한다면, 선호되는 Plugin은 낮은 우선순위의 Plugin id로 `channelConfigs..preferOver`를 선언해야 합니다. [/plugins/manifest#replacing-another-channel-plugin](/ko/plugins/manifest#replacing-another-channel-plugin)을 참조하세요. -- 중복이 우발적이라면 `plugins.entries..enabled: false`로 한쪽을 비활성화하거나 오래된 Plugin 설치를 제거하세요. -- 두 Plugin을 모두 명시적으로 활성화한 경우 OpenClaw는 해당 요청을 유지하고 충돌을 보고합니다. 채널 소유자를 하나 선택하거나 Plugin 소유 도구의 이름을 바꿔 런타임 표면이 모호하지 않도록 하세요. +- 한 Plugin이 의도적으로 동일한 채널 ID에 대해 다른 Plugin을 대체하는 경우, 선호되는 Plugin은 더 낮은 우선순위의 Plugin ID로 `channelConfigs..preferOver`를 선언해야 합니다. [/plugins/manifest#replacing-another-channel-plugin](/ko/plugins/manifest#replacing-another-channel-plugin)을 참조하세요. +- 중복이 우발적인 경우 `plugins.entries..enabled: false`로 한쪽을 비활성화하거나 오래된 Plugin 설치를 제거하세요. +- 두 Plugin을 모두 명시적으로 활성화한 경우 OpenClaw는 해당 요청을 유지하고 충돌을 보고합니다. 런타임 표면이 모호하지 않도록 채널의 소유자를 하나 선택하거나 Plugin 소유 도구의 이름을 변경하세요. -## Plugin 슬롯(독점 카테고리) +## Plugin 슬롯(배타적 범주) -일부 카테고리는 독점적입니다(한 번에 하나만 활성화됨). +일부 범주는 배타적입니다(한 번에 하나만 활성화). ```json5 { @@ -442,7 +428,7 @@ openclaw plugins inspect --runtime --json | 슬롯 | 제어 대상 | 기본값 | | --------------- | --------------------- | ------------------- | | `memory` | 활성 메모리 Plugin | `memory-core` | -| `contextEngine` | 활성 컨텍스트 엔진 | `legacy` (내장) | +| `contextEngine` | 활성 컨텍스트 엔진 | `legacy`(내장) | ## CLI 참조 @@ -492,75 +478,81 @@ openclaw plugins enable openclaw plugins disable ``` -번들 Plugin은 OpenClaw와 함께 제공됩니다. 다수는 기본적으로 활성화되어 있습니다(예: +번들 Plugin은 OpenClaw와 함께 제공됩니다. 많은 번들 Plugin이 기본적으로 활성화됩니다(예: 번들 모델 제공자, 번들 음성 제공자, 번들 브라우저 Plugin). 다른 번들 Plugin은 여전히 `openclaw plugins enable `가 필요합니다. -`--force`는 기존에 설치된 Plugin 또는 훅 팩을 제자리에서 덮어씁니다. 추적되는 npm -Plugin의 일반적인 업그레이드에는 `openclaw plugins update `를 사용하세요. -관리되는 설치 대상에 복사하지 않고 소스 경로를 재사용하는 `--link`와 함께 사용하는 것은 -지원되지 않습니다. +`--force`는 기존에 설치된 Plugin 또는 hook pack을 그 자리에서 덮어씁니다. 추적되는 npm +Plugin의 일반 업그레이드에는 `openclaw plugins update `를 사용하세요. +소스 경로를 관리형 설치 대상 위에 복사하는 대신 재사용하는 `--link`와 함께 사용할 수 없습니다. -`plugins.allow`가 이미 설정되어 있으면, `openclaw plugins install`은 설치된 -Plugin ID를 해당 허용 목록에 추가한 뒤 활성화합니다. 같은 Plugin ID가 -`plugins.deny`에 있으면, 명시적 설치가 재시작 후 즉시 로드될 수 있도록 설치 과정에서 해당 -오래된 거부 항목을 제거합니다. +`plugins.allow`가 이미 설정되어 있으면, `openclaw plugins install`은 +설치된 Plugin id를 활성화하기 전에 해당 허용 목록에 추가합니다. 같은 Plugin id가 +`plugins.deny`에 있으면, 명시적으로 설치한 항목을 재시작 후 즉시 로드할 수 있도록 install이 +그 오래된 거부 항목을 제거합니다. -OpenClaw는 Plugin 인벤토리, 기여 소유권, 시작 계획을 위한 콜드 읽기 모델로 지속되는 로컬 -Plugin 레지스트리를 유지합니다. 설치, 업데이트, 제거, 활성화, 비활성화 흐름은 Plugin -상태를 변경한 뒤 해당 레지스트리를 새로 고칩니다. 동일한 `plugins/installs.json` 파일은 -최상위 `installRecords`에 영구 설치 메타데이터를, `plugins`에 재구축 가능한 매니페스트 -메타데이터를 보관합니다. 레지스트리가 없거나, 오래되었거나, 유효하지 않으면 -`openclaw plugins registry --refresh`가 Plugin 런타임 모듈을 로드하지 않고 설치 기록, -구성 정책, 매니페스트/패키지 메타데이터에서 매니페스트 뷰를 다시 구축합니다. -`openclaw plugins update `는 추적되는 설치에 적용됩니다. dist-tag 또는 -정확한 버전이 포함된 npm 패키지 spec을 전달하면 패키지 이름을 추적되는 Plugin 기록으로 다시 -해석하고 향후 업데이트를 위해 새 spec을 기록합니다. 버전 없이 패키지 이름을 전달하면 정확히 -고정된 설치를 레지스트리의 기본 릴리스 라인으로 되돌립니다. 설치된 npm Plugin이 이미 해석된 -버전 및 기록된 아티팩트 식별자와 일치하면 OpenClaw는 다운로드, 재설치, 구성 재작성 없이 -업데이트를 건너뜁니다. -`openclaw update`가 베타 채널에서 실행될 때 기본 라인 npm 및 ClawHub -Plugin 기록은 먼저 `@beta`를 시도하고, Plugin 베타 릴리스가 없으면 기본/latest로 -폴백합니다. 정확한 버전과 명시적 태그는 고정된 상태로 유지됩니다. +OpenClaw는 Plugin 인벤토리, 기여 소유권, 시작 계획을 위한 콜드 읽기 모델로 +영구 로컬 Plugin 레지스트리를 유지합니다. install, update, +uninstall, enable, disable 흐름은 Plugin 상태를 변경한 뒤 해당 레지스트리를 새로 고칩니다. +동일한 `plugins/installs.json` 파일은 최상위 `installRecords`에 내구성 있는 설치 메타데이터를, +`plugins`에 재빌드 가능한 manifest 메타데이터를 보관합니다. 레지스트리가 없거나 오래되었거나 +유효하지 않으면, `openclaw plugins registry +--refresh`가 Plugin 런타임 모듈을 로드하지 않고 설치 기록, config 정책, +manifest/package 메타데이터에서 manifest 뷰를 다시 빌드합니다. -`--pin`은 npm 전용입니다. 마켓플레이스 설치는 npm spec 대신 마켓플레이스 소스 메타데이터를 -유지하므로 `--marketplace`와 함께 사용할 수 없습니다. +Nix 모드(`OPENCLAW_NIX_MODE=1`)에서는 Plugin 수명 주기 변경 명령이 비활성화됩니다. +대신 설치용 Nix 소스를 통해 Plugin 패키지 선택과 config를 관리하세요. nix-openclaw의 경우 agent 우선 +[빠른 시작](https://github.com/openclaw/nix-openclaw#quick-start)부터 시작하세요. +`openclaw plugins update `는 추적되는 설치에 적용됩니다. dist-tag 또는 정확한 버전이 있는 +npm 패키지 spec을 전달하면 패키지 이름을 추적되는 Plugin 레코드로 다시 해석하고, 향후 업데이트를 위해 +새 spec을 기록합니다. 버전 없이 패키지 이름을 전달하면 정확히 고정된 설치가 레지스트리의 기본 릴리스 라인으로 +되돌아갑니다. 설치된 npm Plugin이 이미 해석된 버전 및 기록된 artifact identity와 일치하면, +OpenClaw는 다운로드, 재설치, config 재작성 없이 업데이트를 건너뜁니다. +`openclaw update`가 beta 채널에서 실행되면, 기본 라인의 npm 및 ClawHub +Plugin 레코드는 먼저 `@beta`를 시도하고 Plugin beta 릴리스가 없으면 default/latest로 대체합니다. +정확한 버전과 명시적 태그는 고정된 상태로 유지됩니다. -`--dangerously-force-unsafe-install`은 내장 위험 코드 스캐너의 오탐에 대비한 비상 -우회 옵션입니다. Plugin 설치 및 Plugin 업데이트가 내장 `critical` 발견 항목을 지나 -계속되도록 허용하지만, Plugin `before_install` 정책 차단이나 스캔 실패 차단은 여전히 -우회하지 않습니다. 설치 스캔은 패키지된 테스트 목이 차단되지 않도록 `tests/`, +`--pin`은 npm 전용입니다. `--marketplace`와 함께 사용할 수 없습니다. marketplace 설치는 +npm spec 대신 marketplace 소스 메타데이터를 영구 저장하기 때문입니다. + +`--dangerously-force-unsafe-install`은 내장 위험 코드 스캐너의 오탐을 위한 비상 우회 옵션입니다. +Plugin 설치와 Plugin 업데이트가 내장 `critical` 발견 항목을 지나 계속 진행되도록 허용하지만, +Plugin `before_install` 정책 차단이나 스캔 실패 차단을 우회하지는 않습니다. +설치 스캔은 패키지된 테스트 mock 때문에 차단되는 일을 피하기 위해 `tests/`, `__tests__/`, `*.test.*`, `*.spec.*` 같은 일반적인 테스트 파일과 디렉터리를 무시합니다. -선언된 Plugin 런타임 진입점은 이러한 이름 중 하나를 사용하더라도 여전히 스캔됩니다. +선언된 Plugin 런타임 진입점은 이러한 이름 중 하나를 사용하더라도 계속 스캔됩니다. -이 CLI 플래그는 Plugin 설치/업데이트 흐름에만 적용됩니다. Gateway 기반 Skills -의존성 설치는 대신 일치하는 `dangerouslyForceUnsafeInstall` 요청 재정의를 사용하며, -`openclaw skills install`은 별도의 ClawHub Skills 다운로드/설치 흐름으로 유지됩니다. +이 CLI 플래그는 Plugin install/update 흐름에만 적용됩니다. Gateway 기반 skill +의존성 설치는 대신 일치하는 `dangerouslyForceUnsafeInstall` 요청 +override를 사용하며, `openclaw skills install`은 별도의 ClawHub +skill 다운로드/설치 흐름으로 유지됩니다. -ClawHub에 게시한 Plugin이 스캔으로 인해 숨겨지거나 차단된 경우, ClawHub 대시보드를 열거나 -`clawhub package rescan `을 실행해 ClawHub가 다시 확인하도록 요청하세요. -`--dangerously-force-unsafe-install`은 자신의 머신에서 이루어지는 설치에만 영향을 줍니다. -ClawHub에 Plugin 재스캔을 요청하거나 차단된 릴리스를 공개 상태로 만들지는 않습니다. +ClawHub에 게시한 Plugin이 스캔 때문에 숨겨졌거나 차단된 경우, +ClawHub 대시보드를 열거나 `clawhub package rescan `을 실행하여 ClawHub에 다시 확인하도록 요청하세요. +`--dangerously-force-unsafe-install`은 자신의 머신에서의 설치에만 영향을 줍니다. +ClawHub에 Plugin을 다시 스캔하도록 요청하거나 차단된 릴리스를 공개로 만들지는 않습니다. -호환 번들은 동일한 Plugin 목록/검사/활성화/비활성화 흐름에 참여합니다. 현재 런타임 지원에는 -번들 Skills, Claude 명령 Skills, Claude `settings.json` 기본값, Claude `.lsp.json` -및 매니페스트에서 선언한 `lspServers` 기본값, Cursor 명령 Skills, 호환되는 Codex 훅 +호환 번들은 동일한 Plugin list/inspect/enable/disable 흐름에 참여합니다. +현재 런타임 지원에는 번들 Skills, Claude command-skills, +Claude `settings.json` 기본값, Claude `.lsp.json` 및 manifest로 선언된 +`lspServers` 기본값, Cursor command-skills, 호환 Codex hook 디렉터리가 포함됩니다. -`openclaw plugins inspect `는 번들 기반 Plugin에 대해 감지된 번들 기능과 지원되거나 -지원되지 않는 MCP 및 LSP 서버 항목도 보고합니다. +`openclaw plugins inspect `는 감지된 번들 기능과 번들 기반 Plugin에 대한 +지원 또는 미지원 MCP 및 LSP 서버 항목도 보고합니다. -마켓플레이스 소스는 `~/.claude/plugins/known_marketplaces.json`의 Claude 알려진 -마켓플레이스 이름, 로컬 마켓플레이스 루트 또는 `marketplace.json` 경로, `owner/repo` 같은 -GitHub 축약형, GitHub 저장소 URL, 또는 git URL일 수 있습니다. 원격 마켓플레이스의 경우 -Plugin 항목은 복제된 마켓플레이스 저장소 안에 머물러야 하며 상대 경로 소스만 사용해야 합니다. +Marketplace 소스는 `~/.claude/plugins/known_marketplaces.json`의 Claude 알려진 marketplace 이름, +로컬 marketplace 루트 또는 `marketplace.json` 경로, +`owner/repo` 같은 GitHub 축약형, GitHub repo +URL, 또는 git URL일 수 있습니다. 원격 marketplace의 경우 Plugin 항목은 +클론된 marketplace repo 내부에 있어야 하며 상대 경로 소스만 사용해야 합니다. -전체 세부 정보는 [`openclaw plugins` CLI 참조](/ko/cli/plugins)를 참고하세요. +전체 세부 정보는 [`openclaw plugins` CLI 참조](/ko/cli/plugins)를 참조하세요. ## Plugin API 개요 -네이티브 Plugin은 `register(api)`를 노출하는 진입 객체를 내보냅니다. 오래된 -Plugin은 레거시 별칭으로 여전히 `activate(api)`를 사용할 수 있지만, 새 Plugin은 +네이티브 Plugin은 `register(api)`를 노출하는 entry 객체를 export합니다. 이전 +Plugin은 여전히 레거시 별칭으로 `activate(api)`를 사용할 수 있지만, 새 Plugin은 `register`를 사용해야 합니다. ```typescript @@ -581,66 +573,68 @@ export default definePluginEntry({ }); ``` -OpenClaw는 Plugin 활성화 중 진입 객체를 로드하고 `register(api)`를 호출합니다. -로더는 오래된 Plugin을 위해 여전히 `activate(api)`로 폴백하지만, 번들 Plugin과 새 외부 -Plugin은 `register`를 공개 계약으로 간주해야 합니다. +OpenClaw는 Plugin 활성화 중 entry 객체를 로드하고 `register(api)`를 호출합니다. +로더는 이전 Plugin을 위해 여전히 `activate(api)`로 대체하지만, +번들 Plugin과 새 외부 Plugin은 `register`를 공개 contract로 취급해야 합니다. -`api.registrationMode`는 Plugin에 진입점이 로드되는 이유를 알려줍니다. +`api.registrationMode`는 entry가 로드되는 이유를 Plugin에 알려줍니다. | 모드 | 의미 | | --------------- | -------------------------------------------------------------------------------------------------------------------------------- | -| `full` | 런타임 활성화입니다. 도구, 훅, 서비스, 명령, 라우트 및 기타 라이브 부수 효과를 등록합니다. | -| `discovery` | 읽기 전용 기능 탐색입니다. 제공자와 메타데이터를 등록합니다. 신뢰된 Plugin 진입 코드가 로드될 수 있지만 라이브 부수 효과는 건너뜁니다. | -| `setup-only` | 경량 설정 진입점을 통한 채널 설정 메타데이터 로드입니다. | -| `setup-runtime` | 런타임 진입점도 필요한 채널 설정 로드입니다. | -| `cli-metadata` | CLI 명령 메타데이터 수집 전용입니다. | +| `full` | 런타임 활성화. tools, hooks, services, commands, routes 및 기타 live side effects를 등록합니다. | +| `discovery` | 읽기 전용 기능 discovery. providers와 metadata를 등록합니다. 신뢰할 수 있는 Plugin entry code가 로드될 수 있지만 live side effects는 건너뜁니다. | +| `setup-only` | 경량 setup entry를 통한 Channel setup metadata 로딩. | +| `setup-runtime` | runtime entry도 필요한 Channel setup 로딩. | +| `cli-metadata` | CLI command metadata 수집만 수행합니다. | -소켓, 데이터베이스, 백그라운드 워커 또는 장기 실행 클라이언트를 여는 Plugin 진입점은 이러한 -부수 효과를 `api.registrationMode === "full"`로 보호해야 합니다. 탐색 로드는 활성화 로드와 -별도로 캐시되며 실행 중인 Gateway 레지스트리를 대체하지 않습니다. 탐색은 비활성화 방식이지만, -가져오기 없는 방식은 아닙니다. OpenClaw는 스냅샷을 만들기 위해 신뢰된 Plugin 진입점 또는 -채널 Plugin 모듈을 평가할 수 있습니다. 모듈 최상위 수준은 가볍고 부수 효과가 없게 유지하고, -네트워크 클라이언트, 서브프로세스, 리스너, 자격 증명 읽기, 서비스 시작은 전체 런타임 경로 뒤로 -이동하세요. +소켓, 데이터베이스, background workers 또는 오래 유지되는 +clients를 여는 Plugin entry는 이러한 side effect를 `api.registrationMode === "full"`로 보호해야 합니다. +Discovery 로드는 활성화 로드와 별도로 캐시되며 실행 중인 Gateway 레지스트리를 대체하지 않습니다. +Discovery는 비활성화이지만 import-free는 아닙니다. +OpenClaw는 snapshot을 빌드하기 위해 신뢰할 수 있는 Plugin entry 또는 channel Plugin module을 평가할 수 있습니다. +module top level은 가볍고 side-effect-free로 유지하고, +network clients, subprocesses, listeners, credential reads, service startup은 +full-runtime 경로 뒤로 옮기세요. -일반적인 등록 메서드: +일반적인 registration methods: | 메서드 | 등록하는 항목 | | --------------------------------------- | --------------------------- | | `registerProvider` | 모델 제공자(LLM) | -| `registerChannel` | 채팅 채널 | +| `registerChannel` | 채팅 Channel | | `registerTool` | 에이전트 도구 | -| `registerHook` / `on(...)` | 수명 주기 훅 | -| `registerSpeechProvider` | 텍스트 음성 변환 / STT | -| `registerRealtimeTranscriptionProvider` | 스트리밍 STT | -| `registerRealtimeVoiceProvider` | 양방향 실시간 음성 | +| `registerHook` / `on(...)` | 수명 주기 hooks | +| `registerSpeechProvider` | Text-to-speech / STT | +| `registerRealtimeTranscriptionProvider` | Streaming STT | +| `registerRealtimeVoiceProvider` | Duplex realtime voice | | `registerMediaUnderstandingProvider` | 이미지/오디오 분석 | | `registerImageGenerationProvider` | 이미지 생성 | | `registerMusicGenerationProvider` | 음악 생성 | | `registerVideoGenerationProvider` | 비디오 생성 | -| `registerWebFetchProvider` | 웹 가져오기 / 스크레이프 제공자 | -| `registerWebSearchProvider` | 웹 검색 | -| `registerHttpRoute` | HTTP 엔드포인트 | -| `registerCommand` / `registerCli` | CLI 명령 | -| `registerContextEngine` | 컨텍스트 엔진 | -| `registerService` | 백그라운드 서비스 | +| `registerWebFetchProvider` | Web fetch / scrape provider | +| `registerWebSearchProvider` | Web search | +| `registerHttpRoute` | HTTP endpoint | +| `registerCommand` / `registerCli` | CLI commands | +| `registerContextEngine` | Context engine | +| `registerService` | Background service | -타입 지정 수명 주기 훅의 훅 가드 동작: +typed lifecycle hooks의 hook guard 동작: -- `before_tool_call`: `{ block: true }`는 종결 조건입니다. 더 낮은 우선순위의 핸들러는 건너뜁니다. -- `before_tool_call`: `{ block: false }`는 아무 작업도 하지 않으며 이전 차단을 해제하지 않습니다. -- `before_install`: `{ block: true }`는 종결 조건입니다. 더 낮은 우선순위의 핸들러는 건너뜁니다. -- `before_install`: `{ block: false }`는 아무 작업도 하지 않으며 이전 차단을 해제하지 않습니다. -- `message_sending`: `{ cancel: true }`는 종결 조건입니다. 더 낮은 우선순위의 핸들러는 건너뜁니다. -- `message_sending`: `{ cancel: false }`는 아무 작업도 하지 않으며 이전 취소를 해제하지 않습니다. +- `before_tool_call`: `{ block: true }`는 terminal입니다. 우선순위가 낮은 handlers는 건너뜁니다. +- `before_tool_call`: `{ block: false }`는 no-op이며 이전 block을 해제하지 않습니다. +- `before_install`: `{ block: true }`는 terminal입니다. 우선순위가 낮은 handlers는 건너뜁니다. +- `before_install`: `{ block: false }`는 no-op이며 이전 block을 해제하지 않습니다. +- `message_sending`: `{ cancel: true }`는 terminal입니다. 우선순위가 낮은 handlers는 건너뜁니다. +- `message_sending`: `{ cancel: false }`는 no-op이며 이전 cancel을 해제하지 않습니다. -네이티브 Codex 앱 서버는 Codex 네이티브 도구 이벤트를 이 훅 표면으로 다시 브리지합니다. -Plugin은 `before_tool_call`을 통해 네이티브 Codex 도구를 차단하고, `after_tool_call`을 -통해 결과를 관찰하며, Codex `PermissionRequest` 승인에 참여할 수 있습니다. 브리지는 아직 -Codex 네이티브 도구 인수를 재작성하지 않습니다. 정확한 Codex 런타임 지원 경계는 -[Codex 하네스 v1 지원 계약](/ko/plugins/codex-harness#v1-support-contract)에 있습니다. +네이티브 Codex 앱 서버 실행은 Codex 네이티브 도구 이벤트를 이 +후크 표면으로 다시 브리지합니다. Plugin은 `before_tool_call`을 통해 네이티브 Codex 도구를 차단하고, +`after_tool_call`을 통해 결과를 관찰하며, Codex +`PermissionRequest` 승인에 참여할 수 있습니다. 브리지는 아직 Codex 네이티브 도구 +인수를 다시 작성하지 않습니다. 정확한 Codex 런타임 지원 경계는 +[Codex 하니스 v1 지원 계약](/ko/plugins/codex-harness#v1-support-contract)에 있습니다. -전체 타입 지정 훅 동작은 [SDK 개요](/ko/plugins/sdk-overview#hook-decision-semantics)를 참고하세요. +전체 타입 지정 후크 동작은 [SDK 개요](/ko/plugins/sdk-overview#hook-decision-semantics)를 참조하세요. ## 관련 @@ -649,4 +643,4 @@ Codex 네이티브 도구 인수를 재작성하지 않습니다. 정확한 Code - [Plugin 매니페스트](/ko/plugins/manifest) - 매니페스트 스키마 - [도구 등록하기](/ko/plugins/building-plugins#registering-agent-tools) - Plugin에 에이전트 도구 추가하기 - [Plugin 내부 구조](/ko/plugins/architecture) - 기능 모델 및 로드 파이프라인 -- [커뮤니티 Plugin](/ko/plugins/community) - 타사 목록 +- [커뮤니티 Plugin](/ko/plugins/community) - 서드 파티 목록 diff --git a/docs/ko/tools/web-fetch.md b/docs/ko/tools/web-fetch.md index 98b79a18d..41f25ab09 100644 --- a/docs/ko/tools/web-fetch.md +++ b/docs/ko/tools/web-fetch.md @@ -4,26 +4,26 @@ read_when: - web_fetch 또는 해당 Firecrawl 폴백을 구성해야 합니다 - web_fetch 제한과 캐싱을 이해하려는 경우 sidebarTitle: Web Fetch -summary: web_fetch 도구 -- 읽기 가능한 콘텐츠 추출 기능이 있는 HTTP 가져오기 +summary: web_fetch 도구 -- 가독성 있는 콘텐츠 추출을 지원하는 HTTP 가져오기 title: 웹 가져오기 x-i18n: - generated_at: "2026-05-04T02:26:25Z" + generated_at: "2026-05-06T18:01:09Z" model: gpt-5.5 provider: openai - source_hash: c8c3efbf4a640b2fd69cc9532dcb06a873a6830a2e8a85ab7510ab38207c8670 + source_hash: 337174898861db217bf0db052d8e8749989c295e89c73d9d5a6911f6335ba03d source_path: tools/web-fetch.md workflow: 16 --- `web_fetch` 도구는 일반 HTTP GET을 수행하고 읽을 수 있는 콘텐츠를 추출합니다 -(HTML을 markdown 또는 텍스트로 변환). JavaScript는 **실행하지 않습니다**. +(HTML을 markdown 또는 text로 변환). JavaScript는 실행하지 **않습니다**. -JS 의존도가 높은 사이트나 로그인으로 보호된 페이지에는 대신 +JS가 많은 사이트나 로그인으로 보호된 페이지에는 대신 [웹 브라우저](/ko/tools/browser)를 사용하세요. ## 빠른 시작 -`web_fetch`는 **기본적으로 활성화되어 있습니다** -- 설정이 필요하지 않습니다. 에이전트가 +`web_fetch`는 **기본적으로 활성화되어 있습니다** -- 설정이 필요 없습니다. 에이전트가 즉시 호출할 수 있습니다. ```javascript @@ -37,11 +37,11 @@ await web_fetch({ url: "https://example.com/article" }); -주요 콘텐츠 추출 후의 출력 형식입니다. +주요 콘텐츠 추출 후 출력 형식입니다. -출력을 이 문자 수로 잘라냅니다. +출력을 지정한 문자 수로 잘라냅니다. ## 작동 방식 @@ -59,8 +59,8 @@ await web_fetch({ url: "https://example.com/article" }); Firecrawl API를 통해 다시 시도합니다. - 동일한 URL을 반복해서 가져오는 일을 줄이기 위해 결과를 15분 동안 - 캐시합니다(설정 가능). + 동일한 URL의 반복 가져오기를 줄이기 위해 결과를 15분 동안(설정 가능) + 캐시합니다. @@ -92,10 +92,10 @@ await web_fetch({ url: "https://example.com/article" }); } ``` -## Firecrawl 대체 경로 +## Firecrawl 폴백 Readability 추출이 실패하면 `web_fetch`는 봇 우회와 더 나은 추출을 위해 -[Firecrawl](/ko/tools/firecrawl)로 대체할 수 있습니다. +[Firecrawl](/ko/tools/firecrawl)로 폴백할 수 있습니다. ```json5 { @@ -126,59 +126,59 @@ Readability 추출이 실패하면 `web_fetch`는 봇 우회와 더 나은 추 ``` `plugins.entries.firecrawl.config.webFetch.apiKey`는 SecretRef 객체를 지원합니다. -기존 `tools.web.fetch.firecrawl.*` 설정은 `openclaw doctor --fix`로 자동 마이그레이션됩니다. +레거시 `tools.web.fetch.firecrawl.*` 설정은 `openclaw doctor --fix`로 자동 마이그레이션됩니다. Firecrawl이 활성화되어 있고 해당 SecretRef가 확인되지 않았으며 - `FIRECRAWL_API_KEY` env 대체값도 없으면 gateway 시작이 빠르게 실패합니다. + `FIRECRAWL_API_KEY` env 폴백도 없으면 Gateway 시작이 빠르게 실패합니다. - Firecrawl `baseUrl` 재정의는 제한됩니다. 호스팅 트래픽은 + Firecrawl `baseUrl` 재정의는 제한되어 있습니다. 호스팅 트래픽은 `https://api.firecrawl.dev`를 사용하며, 자체 호스팅 재정의는 비공개 또는 - 내부 엔드포인트를 대상으로 해야 하고, `http://`는 해당 비공개 대상에만 허용됩니다. + 내부 엔드포인트를 대상으로 해야 하고 `http://`는 이러한 비공개 대상에만 허용됩니다. 현재 런타임 동작: -- `tools.web.fetch.provider`는 가져오기 대체 공급자를 명시적으로 선택합니다. +- `tools.web.fetch.provider`는 가져오기 폴백 제공자를 명시적으로 선택합니다. - `provider`가 생략되면 OpenClaw는 사용 가능한 자격 증명에서 준비된 첫 번째 web-fetch - 공급자를 자동 감지합니다. 샌드박스가 적용되지 않은 `web_fetch`는 - `contracts.webFetchProviders`를 선언하고 런타임에 일치하는 공급자를 등록하는 - 설치된 plugins를 사용할 수 있습니다. 현재 번들 공급자는 Firecrawl입니다. -- 샌드박스 적용 `web_fetch` 호출은 번들 공급자로만 제한됩니다. -- Readability가 비활성화되어 있으면 `web_fetch`는 선택된 공급자 대체 경로로 - 바로 건너뜁니다. 사용 가능한 공급자가 없으면 닫힌 상태로 실패합니다. + 제공자를 자동 감지합니다. 샌드박스가 아닌 `web_fetch`는 + `contracts.webFetchProviders`를 선언하고 런타임에 일치하는 제공자를 등록하는 + 설치된 plugins를 사용할 수 있습니다. 현재 번들 제공자는 Firecrawl입니다. +- 샌드박스 처리된 `web_fetch` 호출은 번들 제공자로 제한됩니다. +- Readability가 비활성화되어 있으면 `web_fetch`는 선택된 + 제공자 폴백으로 바로 건너뜁니다. 사용 가능한 제공자가 없으면 닫힌 상태로 실패합니다. -## 신뢰할 수 있는 Env 프록시 +## 신뢰할 수 있는 env 프록시 -배포 환경에서 `web_fetch`가 신뢰할 수 있는 아웃바운드 HTTP(S) 프록시를 -거쳐야 하는 경우 `tools.web.fetch.useTrustedEnvProxy: true`를 설정하세요. +배포에서 `web_fetch`가 신뢰할 수 있는 아웃바운드 HTTP(S) 프록시를 거쳐야 한다면 +`tools.web.fetch.useTrustedEnvProxy: true`를 설정하세요. -이 모드에서도 OpenClaw는 요청을 보내기 전에 호스트 이름 기반 SSRF 검사를 -적용하지만, 로컬 DNS 고정 대신 프록시가 DNS를 확인하도록 허용합니다. 프록시가 -운영자에 의해 제어되고 DNS 확인 후 아웃바운드 정책을 적용하는 경우에만 활성화하세요. +이 모드에서도 OpenClaw는 요청을 보내기 전에 호스트 이름 기반 SSRF 검사를 적용하지만, +로컬 DNS 고정을 수행하는 대신 프록시가 DNS를 확인하도록 합니다. 프록시가 운영자가 +제어하며 DNS 확인 후 아웃바운드 정책을 적용하는 경우에만 활성화하세요. - HTTP(S) 프록시 env var가 설정되어 있지 않거나 대상 호스트가 + HTTP(S) 프록시 env 변수가 설정되어 있지 않거나 대상 호스트가 `NO_PROXY`로 제외된 경우, `web_fetch`는 로컬 DNS 고정이 있는 일반 엄격 경로로 - 대체됩니다. + 폴백합니다. -## 제한 및 안전 +## 제한 및 안전성 -- `maxChars`는 `tools.web.fetch.maxCharsCap`으로 제한됩니다 -- 응답 본문은 파싱 전에 `maxResponseBytes`로 제한됩니다. 크기가 초과된 +- `maxChars`는 `tools.web.fetch.maxCharsCap`로 제한됩니다 +- 응답 본문은 파싱 전에 `maxResponseBytes`로 제한되며, 너무 큰 응답은 경고와 함께 잘립니다 - 비공개/내부 호스트 이름은 차단됩니다 -- `tools.web.fetch.ssrfPolicy.allowRfc2544BenchmarkRange` 및 - `tools.web.fetch.ssrfPolicy.allowIpv6UniqueLocalRange`는 신뢰할 수 있는 - 가짜 IP 프록시 스택을 위한 좁은 opt-in입니다. 프록시가 해당 합성 범위를 - 소유하고 자체 대상 정책을 적용하는 경우가 아니면 설정하지 마세요 +- `tools.web.fetch.ssrfPolicy.allowRfc2544BenchmarkRange`와 + `tools.web.fetch.ssrfPolicy.allowIpv6UniqueLocalRange`는 신뢰할 수 있는 가짜 IP + 프록시 스택을 위한 좁은 옵트인입니다. 프록시가 해당 합성 범위를 소유하고 + 자체 대상 정책을 적용하지 않는 한 설정하지 마세요 - 리디렉션은 확인되며 `maxRedirects`로 제한됩니다 -- `useTrustedEnvProxy`는 명시적 opt-in이며 DNS 확인 후에도 아웃바운드 정책을 +- `useTrustedEnvProxy`는 명시적 옵트인이며, DNS 확인 후에도 아웃바운드 정책을 적용하는 운영자 제어 프록시에만 활성화해야 합니다 -- `web_fetch`는 최선형 방식입니다 -- 일부 사이트에는 [웹 브라우저](/ko/tools/browser)가 필요합니다 +- `web_fetch`는 최선 노력 방식입니다 -- 일부 사이트에는 [웹 브라우저](/ko/tools/browser)가 필요합니다 ## 도구 프로필 @@ -195,6 +195,6 @@ Readability 추출이 실패하면 `web_fetch`는 봇 우회와 더 나은 추 ## 관련 항목 -- [웹 검색](/ko/tools/web) -- 여러 공급자로 웹 검색 -- [웹 브라우저](/ko/tools/browser) -- JS 의존도가 높은 사이트를 위한 전체 브라우저 자동화 -- [Firecrawl](/ko/tools/firecrawl) -- Firecrawl 검색 및 스크래핑 도구 +- [웹 검색](/ko/tools/web) -- 여러 제공자로 웹 검색 +- [웹 브라우저](/ko/tools/browser) -- JS가 많은 사이트를 위한 전체 브라우저 자동화 +- [Firecrawl](/ko/tools/firecrawl) -- Firecrawl 검색 및 스크레이핑 도구