chore(i18n): refresh ko translations
This commit is contained in:
parent
7a3577b126
commit
fec11739bd
@ -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 엔드포인트로 다시 전달할 수 있습니다.
|
||||
|
||||
## 빠른 시작
|
||||
|
||||
<Steps>
|
||||
<Step title="일회성 알림 추가">
|
||||
<Step title="일회성 리마인더 추가">
|
||||
```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:<jobId>` 세션의 추적된 브라우저 탭/프로세스를 최선의 노력으로 닫아, 분리된 브라우저 자동화가 고아 프로세스를 남기지 않도록 합니다.
|
||||
- 격리된 Cron 실행은 오래된 확인 응답도 방지합니다. 첫 결과가 단순한 중간 상태 업데이트(`on it`, `pulling everything together` 및 유사한 힌트)이고 최종 답변을 담당하는 하위 서브에이전트 실행이 더 이상 없다면, OpenClaw는 전달 전에 실제 결과를 한 번 다시 요청합니다.
|
||||
- 격리된 Cron 실행은 임베디드 실행의 구조화된 실행 거부 메타데이터를 우선 사용한 다음, `SYSTEM_RUN_DENIED`와 `INVALID_REQUEST` 같은 알려진 최종 요약/출력 마커로 폴백하므로, 차단된 명령이 성공한 실행으로 보고되지 않습니다.
|
||||
- 격리된 Cron 실행은 응답 페이로드가 생성되지 않아도 실행 수준의 에이전트 실패를 작업 오류로 취급하므로, 모델/제공자 실패는 오류 카운터를 증가시키고 작업을 성공으로 지우는 대신 실패 알림을 트리거합니다.
|
||||
- 격리된 에이전트 턴 작업이 `timeoutSeconds`에 도달하면 Cron은 기본 에이전트 실행을 중단하고 짧은 정리 시간을 제공합니다. 실행이 비워지지 않으면 Gateway 소유 정리가 Cron이 타임아웃을 기록하기 전에 해당 실행의 세션 소유권을 강제로 지워, 대기 중인 채팅 작업이 오래된 처리 세션 뒤에 남지 않도록 합니다.
|
||||
- 격리된 Cron 실행은 실행이 완료되면 해당 `cron:<jobId>` 세션의 추적된 브라우저 탭/프로세스를 최선의 방식으로 닫으므로, 분리된 브라우저 자동화가 고아 프로세스를 남기지 않습니다.
|
||||
- 좁은 범위의 Cron 자체 정리 권한을 받은 격리된 Cron 실행은 여전히 스케줄러 상태와 현재 작업에 대한 자체 필터링된 목록을 읽을 수 있으므로, 상태/Heartbeat 확인은 더 넓은 Cron 변경 접근 권한을 얻지 않고도 자체 스케줄을 검사할 수 있습니다.
|
||||
- 격리된 Cron 실행은 오래된 확인 응답도 방지합니다. 첫 번째 결과가 중간 상태 업데이트(`on it`, `pulling everything together` 및 유사한 힌트)일 뿐이고 최종 답변을 아직 담당하는 하위 서브에이전트 실행이 없다면, OpenClaw는 전달 전에 실제 결과를 한 번 다시 요청합니다.
|
||||
- 격리된 Cron 실행은 임베디드 실행의 구조화된 실행 거부 메타데이터를 우선 사용한 다음, `SYSTEM_RUN_DENIED` 및 `INVALID_REQUEST` 같은 알려진 최종 요약/출력 마커로 폴백하므로, 차단된 명령이 성공한 실행으로 보고되지 않습니다.
|
||||
- 격리된 Cron 실행은 응답 페이로드가 생성되지 않은 경우에도 실행 수준의 에이전트 실패를 작업 오류로 처리하므로, 모델/프로바이더 실패는 작업을 성공으로 지우는 대신 오류 카운터를 증가시키고 실패 알림을 트리거합니다.
|
||||
- 격리된 에이전트 턴 작업이 `timeoutSeconds`에 도달하면 Cron은 기본 에이전트 실행을 중단하고 짧은 정리 창을 제공합니다. 실행이 비워지지 않으면 Gateway 소유 정리가 Cron이 타임아웃을 기록하기 전에 해당 실행의 세션 소유권을 강제로 지우므로, 대기 중인 채팅 작업이 오래된 처리 세션 뒤에 남지 않습니다.
|
||||
|
||||
<a id="maintenance"></a>
|
||||
|
||||
<Note>
|
||||
Cron의 작업 조정은 먼저 런타임 소유이고, 그다음은 내구성 있는 기록 기반입니다. 활성 Cron 작업은 오래된 하위 세션 행이 아직 존재하더라도 Cron 런타임이 해당 작업을 실행 중으로 추적하는 동안 계속 활성 상태로 유지됩니다. 런타임이 작업 소유를 중지하고 5분 유예 시간이 만료되면, 유지 관리가 일치하는 `cron:<jobId>:<startedAt>` 실행의 영구 실행 로그와 작업 상태를 확인합니다. 해당 내구성 있는 기록에 종료 결과가 있으면 작업 원장이 그 기록에서 확정되고, 그렇지 않으면 Gateway 소유 유지 관리가 작업을 `lost`로 표시할 수 있습니다. 오프라인 CLI 감사는 내구성 있는 기록에서 복구할 수 있지만, 자체적으로 비어 있는 인프로세스 활성 작업 집합을 Gateway 소유 Cron 실행이 사라졌다는 증거로 취급하지 않습니다.
|
||||
Cron의 작업 조정은 먼저 런타임 소유이고, 그다음으로 내구성 있는 기록 기반입니다. 활성 Cron 작업은 오래된 자식 세션 행이 여전히 존재하더라도 Cron 런타임이 해당 작업을 실행 중으로 계속 추적하는 동안 라이브 상태로 유지됩니다. 런타임이 작업 소유를 중지하고 5분 유예 시간이 만료되면, 유지 관리 검사는 일치하는 `cron:<jobId>:<startedAt>` 실행에 대해 영구 저장된 실행 로그와 작업 상태를 확인합니다. 해당 내구성 있는 기록이 종료 결과를 보여주면 작업 원장이 그 결과로 마무리됩니다. 그렇지 않으면 Gateway 소유 유지 관리가 작업을 `lost`로 표시할 수 있습니다. 오프라인 CLI 감사는 내구성 있는 기록에서 복구할 수 있지만, 자체의 비어 있는 인프로세스 활성 작업 집합을 Gateway 소유 Cron 실행이 사라졌다는 증거로 취급하지 않습니다.
|
||||
</Note>
|
||||
|
||||
## 스케줄 유형
|
||||
@ -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:<jobId>` | 보고서, 백그라운드 작업 |
|
||||
| 메인 세션 | `main` | 다음 Heartbeat 턴 | 리마인더, 시스템 이벤트 |
|
||||
| 격리 | `isolated` | 전용 `cron:<jobId>` | 보고서, 백그라운드 작업 |
|
||||
| 현재 세션 | `current` | 생성 시점에 바인딩됨 | 컨텍스트 인식 반복 작업 |
|
||||
| 사용자 지정 세션 | `session:custom-id` | 영구 이름 지정 세션 | 기록을 기반으로 쌓아 가는 워크플로 |
|
||||
| 사용자 지정 세션 | `session:custom-id` | 영구 명명 세션 | 기록을 기반으로 이어지는 워크플로 |
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="기본 세션과 격리 세션, 사용자 지정 세션">
|
||||
**기본 세션** 작업은 시스템 이벤트를 큐에 넣고 선택적으로 Heartbeat를 깨웁니다(`--wake now` 또는 `--wake next-heartbeat`). 이러한 시스템 이벤트는 대상 세션의 일일/유휴 재설정 최신성을 연장하지 않습니다. **격리된** 작업은 새 세션으로 전용 에이전트 턴을 실행합니다. **사용자 지정 세션**(`session:xxx`)은 실행 간 컨텍스트를 영구 유지하여 이전 요약을 기반으로 쌓아 가는 일일 스탠드업 같은 워크플로를 가능하게 합니다.
|
||||
<Accordion title="메인 세션과 격리 및 사용자 지정 비교">
|
||||
**메인 세션** 작업은 시스템 이벤트를 큐에 넣고 선택적으로 Heartbeat를 깨웁니다(`--wake now` 또는 `--wake next-heartbeat`). 이러한 시스템 이벤트는 대상 세션의 일일/유휴 재설정 신선도를 연장하지 않습니다. **격리** 작업은 새로운 세션에서 전용 에이전트 턴을 실행합니다. **사용자 지정 세션**(`session:xxx`)은 실행 간 컨텍스트를 유지하여 이전 요약을 기반으로 하는 일일 스탠드업 같은 워크플로를 가능하게 합니다.
|
||||
</Accordion>
|
||||
<Accordion title="격리된 작업에서 '새 세션'의 의미">
|
||||
격리된 작업에서 "새 세션"은 각 실행마다 새로운 트랜스크립트/세션 ID를 의미합니다. OpenClaw는 thinking/fast/verbose 설정, 레이블, 명시적으로 사용자가 선택한 모델/인증 재정의 같은 안전한 기본 설정을 가져올 수 있지만, 이전 Cron 행의 주변 대화 컨텍스트는 상속하지 않습니다. 여기에는 채널/그룹 라우팅, 전송 또는 큐 정책, 승격, 출처, ACP 런타임 바인딩이 포함됩니다. 반복 작업이 의도적으로 동일한 대화 컨텍스트를 기반으로 해야 한다면 `current` 또는 `session:<id>`를 사용하세요.
|
||||
<Accordion title="격리 작업에서 '새 세션'의 의미">
|
||||
격리 작업에서 "새 세션"은 각 실행마다 새 트랜스크립트/세션 ID를 의미합니다. OpenClaw는 thinking/fast/verbose 설정, 레이블, 명시적으로 사용자가 선택한 모델/인증 오버라이드 같은 안전한 선호 설정을 유지할 수 있지만, 이전 Cron 행의 주변 대화 컨텍스트인 채널/그룹 라우팅, 전송 또는 큐 정책, 권한 상승, 출처 또는 ACP 런타임 바인딩은 상속하지 않습니다. 반복 작업이 의도적으로 동일한 대화 컨텍스트를 기반으로 이어져야 하는 경우 `current` 또는 `session:<id>`를 사용하세요.
|
||||
</Accordion>
|
||||
<Accordion title="런타임 정리">
|
||||
격리된 작업의 경우 런타임 해체에는 이제 해당 Cron 세션에 대한 최선의 브라우저 정리가 포함됩니다. 정리 실패는 무시되므로 실제 Cron 결과가 여전히 우선합니다.
|
||||
격리 작업의 경우 런타임 종료에는 이제 해당 Cron 세션에 대한 최선의 브라우저 정리가 포함됩니다. 실제 Cron 결과가 우선되도록 정리 실패는 무시됩니다.
|
||||
|
||||
격리된 Cron 실행은 공유 런타임 정리 경로를 통해 작업을 위해 생성된 번들 MCP 런타임 인스턴스도 모두 폐기합니다. 이는 기본 세션 및 사용자 지정 세션 MCP 클라이언트를 해체하는 방식과 일치하므로, 격리된 Cron 작업은 실행 간에 stdio 하위 프로세스나 오래 지속되는 MCP 연결을 누수하지 않습니다.
|
||||
격리된 Cron 실행은 공유 런타임 정리 경로를 통해 작업에 대해 생성된 번들 MCP 런타임 인스턴스도 모두 폐기합니다. 이는 메인 세션 및 사용자 지정 세션 MCP 클라이언트가 종료되는 방식과 일치하므로, 격리된 Cron 작업은 실행 간 stdio 자식 프로세스나 장기 실행 MCP 연결을 누수하지 않습니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="서브에이전트 및 Discord 전달">
|
||||
격리된 Cron 실행이 서브에이전트를 오케스트레이션할 때, 전달도 오래된 부모 중간 텍스트보다 최종 하위 출력을 선호합니다. 하위 실행이 아직 실행 중이면 OpenClaw는 해당 부분적인 부모 업데이트를 알리는 대신 억제합니다.
|
||||
격리된 Cron 실행이 서브에이전트를 오케스트레이션할 때, 전달은 오래된 부모 중간 텍스트보다 최종 하위 출력도 우선합니다. 하위 항목이 아직 실행 중이면 OpenClaw는 해당 부분적인 부모 업데이트를 알리는 대신 억제합니다.
|
||||
|
||||
텍스트 전용 Discord 알림 대상의 경우, OpenClaw는 스트리밍/중간 텍스트 페이로드와 최종 답변을 모두 재생하는 대신 표준 최종 어시스턴트 텍스트를 한 번 보냅니다. 미디어 및 구조화된 Discord 페이로드는 첨부 파일과 구성 요소가 누락되지 않도록 여전히 별도 페이로드로 전달됩니다.
|
||||
텍스트 전용 Discord 알림 대상의 경우 OpenClaw는 스트리밍/중간 텍스트 페이로드와 최종 답변을 모두 재생하는 대신 표준 최종 어시스턴트 텍스트를 한 번 전송합니다. 미디어 및 구조화된 Discord 페이로드는 첨부 파일과 컴포넌트가 누락되지 않도록 여전히 별도 페이로드로 전달됩니다.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
### 격리된 작업의 페이로드 옵션
|
||||
### 격리 작업의 페이로드 옵션
|
||||
|
||||
<ParamField path="--message" type="string" required>
|
||||
프롬프트 텍스트(격리된 작업에 필요).
|
||||
프롬프트 텍스트(격리에는 필수).
|
||||
</ParamField>
|
||||
<ParamField path="--model" type="string">
|
||||
모델 재정의입니다. 작업에 선택된 허용 모델을 사용합니다.
|
||||
모델 오버라이드입니다. 작업에 선택된 허용 모델을 사용합니다.
|
||||
</ParamField>
|
||||
<ParamField path="--thinking" type="string">
|
||||
Thinking 수준 재정의입니다.
|
||||
사고 수준 오버라이드입니다.
|
||||
</ParamField>
|
||||
<ParamField path="--light-context" type="boolean">
|
||||
워크스페이스 부트스트랩 파일 주입을 건너뜁니다.
|
||||
@ -138,48 +139,48 @@ Cron 표현식은 [croner](https://github.com/Hexagon/croner)로 파싱됩니다
|
||||
작업이 사용할 수 있는 도구를 제한합니다. 예: `--tools exec,read`.
|
||||
</ParamField>
|
||||
|
||||
`--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:<id>`, `user:<id>`)를 사용해야 합니다. Matrix 방 ID는 대소문자를 구분합니다. Matrix의 정확한 방 ID 또는 `room:!room:server` 형식을 사용하세요.
|
||||
`--announce --channel telegram --to "-1001234567890"`를 사용해 채널로 전달합니다. Telegram 포럼 주제의 경우 `-1001234567890:topic:123`을 사용합니다. 직접 RPC/config 호출자는 `delivery.threadId`를 문자열 또는 숫자로 전달할 수도 있습니다. Slack/Discord/Mattermost 대상은 명시적 접두사(`channel:<id>`, `user:<id>`)를 사용해야 합니다. 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:<id>`, `user:<id>`, `imessage:<handle>`, `sms:<number>` 같은 대상 종류 및 서비스 접두사는 provider 선택자가 아니라 채널 소유 대상 구문으로 유지됩니다.
|
||||
공지 전달에서 `channel: "last"`를 사용하거나 `channel`을 생략하면, `telegram:123` 같은 공급자 접두사가 붙은 대상이 cron이 세션 기록 또는 구성된 단일 채널로 폴백하기 전에 채널을 선택할 수 있습니다. 로드된 Plugin이 알리는 접두사만 공급자 선택자입니다. `delivery.channel`이 명시적이면 대상 접두사는 같은 공급자를 이름으로 지정해야 합니다. 예를 들어 `channel: "whatsapp"`와 `to: "telegram:123"` 조합은 WhatsApp이 Telegram ID를 전화번호로 해석하게 두지 않고 거부됩니다. `channel:<id>`, `user:<id>`, `imessage:<handle>`, `sms:<number>` 같은 대상 종류 및 서비스 접두사는 공급자 선택자가 아니라 채널 소유 대상 구문으로 유지됩니다.
|
||||
|
||||
격리된 작업의 경우 채팅 전달은 공유됩니다. 채팅 경로를 사용할 수 있으면 작업이 `--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 <token>`(권장)
|
||||
- `Authorization: Bearer <token>` (권장)
|
||||
- `x-openclaw-token: <token>`
|
||||
|
||||
쿼리 문자열 토큰은 거부됩니다.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="POST /hooks/wake">
|
||||
기본 세션에 대한 시스템 이벤트를 대기열에 넣습니다.
|
||||
기본 세션에 시스템 이벤트를 큐에 넣습니다.
|
||||
|
||||
```bash
|
||||
curl -X POST http://127.0.0.1:18789/hooks/wake \
|
||||
@ -278,43 +279,43 @@ Gateway는 외부 트리거를 위한 HTTP Webhook 엔드포인트를 노출할
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Mapped hooks (POST /hooks/<name>)">
|
||||
사용자 지정 hook 이름은 config의 `hooks.mappings`를 통해 해석됩니다. Mapping은 임의의 payload를 템플릿이나 코드 변환으로 `wake` 또는 `agent` 동작으로 변환할 수 있습니다.
|
||||
사용자 지정 훅 이름은 config의 `hooks.mappings`를 통해 해석됩니다. 매핑은 템플릿 또는 코드 변환으로 임의의 페이로드를 `wake` 또는 `agent` 액션으로 변환할 수 있습니다.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
<Warning>
|
||||
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`도 설정하세요.
|
||||
- 훅 페이로드는 기본적으로 안전 경계로 래핑됩니다.
|
||||
|
||||
</Warning>
|
||||
|
||||
## Gmail PubSub 통합
|
||||
|
||||
Google PubSub를 통해 Gmail 받은편지함 트리거를 OpenClaw에 연결합니다.
|
||||
Google PubSub을 통해 Gmail 받은편지함 트리거를 OpenClaw에 연결합니다.
|
||||
|
||||
<Note>
|
||||
**필수 조건:** `gcloud` CLI, `gog`(gogcli), OpenClaw hooks 활성화, 공개 HTTPS 엔드포인트용 Tailscale.
|
||||
**필수 조건:** `gcloud` CLI, `gog`(gogcli), 활성화된 OpenClaw 훅, 공용 HTTPS 엔드포인트용 Tailscale.
|
||||
</Note>
|
||||
|
||||
### 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회 설정
|
||||
|
||||
<Steps>
|
||||
<Step title="Select the GCP project">
|
||||
@ -391,11 +392,11 @@ openclaw cron edit <jobId> --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`은 조용한 추가 재시도 대상으로 에이전트 기본값까지 폴스루하지 않습니다.
|
||||
|
||||
</Note>
|
||||
|
||||
@ -419,29 +420,29 @@ openclaw cron edit <jobId> --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`.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Retry behavior">
|
||||
**일회성 retry**: 일시적 오류(rate limit, overload, network, server error)는 exponential backoff로 최대 3회 retry합니다. 영구 오류는 즉시 비활성화됩니다.
|
||||
**일회성 재시도**: 일시적 오류(속도 제한, 과부하, 네트워크, 서버 오류)는 지수 백오프로 최대 3회 재시도됩니다. 영구 오류는 즉시 비활성화됩니다.
|
||||
|
||||
**반복 retry**: retry 사이에 exponential backoff(30초에서 60분)를 적용합니다. Backoff는 다음 성공 실행 이후 reset됩니다.
|
||||
**반복 재시도**: 재시도 사이에는 지수 백오프(30초~60분)가 적용됩니다. 백오프는 다음 성공 실행 이후 초기화됩니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Maintenance">
|
||||
`cron.sessionRetention`(기본값 `24h`)은 격리된 실행 세션 항목을 정리합니다. `cron.runLog.maxBytes` / `cron.runLog.keepLines`는 run-log 파일을 자동 정리합니다.
|
||||
`cron.sessionRetention`(기본값 `24h`)은 격리된 실행 세션 항목을 정리합니다. `cron.runLog.maxBytes` / `cron.runLog.keepLines`는 실행 로그 파일을 자동으로 정리합니다.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 문제 해결
|
||||
|
||||
### 명령 ladder
|
||||
### 명령 단계
|
||||
|
||||
```bash
|
||||
openclaw status
|
||||
@ -458,23 +459,23 @@ openclaw doctor
|
||||
<Accordion title="Cron not firing">
|
||||
- `cron.enabled`와 `OPENCLAW_SKIP_CRON` env var를 확인하세요.
|
||||
- Gateway가 계속 실행 중인지 확인하세요.
|
||||
- `cron` schedule의 경우 timezone(`--tz`)과 host timezone을 비교해 확인하세요.
|
||||
- run output의 `reason: not-due`는 manual run이 `openclaw cron run <jobId> --due`로 확인되었고 작업이 아직 due 상태가 아니었음을 의미합니다.
|
||||
- `cron` 일정의 경우 시간대(`--tz`)와 호스트 시간대를 확인하세요.
|
||||
- 실행 출력의 `reason: not-due`는 수동 실행이 `openclaw cron run <jobId> --due`로 확인되었고 작업의 기한이 아직 되지 않았다는 뜻입니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Cron이 실행되었지만 전달되지 않음">
|
||||
- 전달 모드 `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"`와 이전 채팅, 또는 명시적 채널/대상).
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Cron 또는 Heartbeat가 /new-style 롤오버를 막는 것처럼 보임">
|
||||
- 일일 및 유휴 초기화 최신성은 `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`이 없는 레거시 유휴 행은 복구된 시작 시간을 유휴 기준선으로 사용합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="시간대 주의 사항">
|
||||
@ -489,5 +490,5 @@ openclaw doctor
|
||||
|
||||
- [자동화 및 작업](/ko/automation) — 모든 자동화 메커니즘 한눈에 보기
|
||||
- [백그라운드 작업](/ko/automation/tasks) — Cron 실행을 위한 작업 원장
|
||||
- [Heartbeat](/ko/gateway/heartbeat) — 주기적인 기본 세션 턴
|
||||
- [Heartbeat](/ko/gateway/heartbeat) — 주기적인 메인 세션 턴
|
||||
- [시간대](/ko/concepts/timezone) — 시간대 구성
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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
|
||||
```
|
||||
|
||||
<Note>
|
||||
Teams CLI는 현재 프리뷰 상태입니다. 명령과 플래그는 릴리스마다 변경될 수 있습니다.
|
||||
Teams CLI는 현재 프리뷰 상태입니다. 명령과 플래그는 릴리스 간에 변경될 수 있습니다.
|
||||
</Note>
|
||||
|
||||
**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
|
||||
```
|
||||
|
||||
<Note>
|
||||
Teams는 devtunnels로 인증할 수 없으므로 `--allow-anonymous`가 필요합니다. 각 수신 봇 요청은 여전히 Teams SDK에 의해 자동으로 검증됩니다.
|
||||
Teams는 devtunnels로 인증할 수 없으므로 `--allow-anonymous`가 필요합니다. 들어오는 각 봇 요청은 여전히 Teams SDK가 자동으로 검증합니다.
|
||||
</Note>
|
||||
|
||||
대안: `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 <teamsAppId> --install-link
|
||||
```
|
||||
|
||||
**6. 모든 것이 작동하는지 확인**
|
||||
**6. 모든 것이 작동하는지 확인하기**
|
||||
|
||||
```bash
|
||||
teams app doctor <teamsAppId>
|
||||
```
|
||||
|
||||
이 명령은 봇 등록, AAD 앱 구성, 매니페스트 유효성, SSO 설정 전반에 대해 진단을 실행합니다.
|
||||
이 명령은 봇 등록, AAD 앱 구성, 매니페스트 유효성, SSO 설정 전반의 진단을 실행합니다.
|
||||
|
||||
프로덕션 배포에서는 클라이언트 암호 대신 [페더레이션 인증](/ko/channels/msteams#federated-authentication-certificate-plus-managed-identity)(인증서 또는 관리 ID)을 사용하는 것을 고려하세요.
|
||||
프로덕션 배포에서는 클라이언트 시크릿 대신 [페더레이션 인증](/ko/channels/msteams#federated-authentication-certificate-plus-managed-identity)(인증서 또는 관리 ID)을 사용하는 것을 고려하세요.
|
||||
|
||||
<Note>
|
||||
그룹 채팅은 기본적으로 차단됩니다(`channels.msteams.groupPolicy: "allowlist"`). 그룹 답장을 허용하려면 `channels.msteams.groupAllowFrom`을 설정하거나, 모든 구성원(멘션 게이트 적용)을 허용하려면 `groupPolicy: "open"`을 사용하세요.
|
||||
@ -130,14 +130,14 @@ teams app doctor <teamsAppId>
|
||||
## 목표
|
||||
|
||||
- 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 <teamsAppId>
|
||||
**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 <teamsAppId>
|
||||
}
|
||||
```
|
||||
|
||||
**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 <teamsAppId>
|
||||
<details>
|
||||
<summary><strong>수동 설정(Teams CLI 없이)</strong></summary>
|
||||
|
||||
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** |
|
||||
|
||||
<Warning>
|
||||
새 멀티 테넌트 봇 생성은 2025-07-31 이후 사용 중단되었습니다. 새 봇에는 **Single Tenant**를 사용하세요.
|
||||
</Warning>
|
||||
|
||||
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 = <App ID>`인 `bot` 항목을 포함합니다.
|
||||
- `botId = <App ID>`가 포함된 `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 채널이 자동으로 시작됩니다.
|
||||
|
||||
</details>
|
||||
|
||||
@ -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=<client-id>`(사용자 할당에만 해당)
|
||||
- `MSTEAMS_MANAGED_IDENTITY_CLIENT_ID=<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: "<APP_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 <teamsAppId> --endpoint "https://<new-url>/api/messages"
|
||||
@ -461,64 +461,64 @@ teams app update <teamsAppId> --endpoint "https://<new-url>/api/messages"
|
||||
teams app doctor <teamsAppId>
|
||||
```
|
||||
|
||||
한 번에 bot 등록, AAD 앱, 매니페스트, SSO 구성을 검사합니다.
|
||||
Bot 등록, AAD 앱, 매니페스트, SSO 구성을 한 번에 확인합니다.
|
||||
|
||||
**테스트 메시지 보내기:**
|
||||
|
||||
1. Teams 앱을 설치합니다(`teams app get <id> --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["<user_id>"].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 <teamsAppId> ChannelMessage.Read.Group --type Application
|
||||
|
||||
## Teams 매니페스트 예시(수정됨)
|
||||
|
||||
필수 필드가 포함된 최소한의 유효한 예시입니다. ID와 URL을 교체하세요.
|
||||
필수 필드가 포함된 최소한의 유효한 예시입니다. ID와 URL을 바꾸세요.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -596,7 +596,7 @@ teams app manifest upload manifest.json <teamsAppId>
|
||||
# Version is auto-bumped if content changed
|
||||
```
|
||||
|
||||
업데이트 후 새 권한이 적용되도록 각 팀에서 앱을 다시 설치하고, 캐시된 앱 메타데이터를 지우기 위해 Teams를 **완전히 종료한 뒤 다시 실행**합니다(창만 닫는 것이 아님).
|
||||
업데이트 후 새 권한을 적용하려면 각 팀에 앱을 다시 설치하고, 캐시된 앱 메타데이터를 지우기 위해 Teams를 **완전히 종료한 뒤 다시 실행**하세요(창만 닫는 것이 아님).
|
||||
|
||||
<details>
|
||||
<summary>수동 매니페스트 업데이트(CLI 없이)</summary>
|
||||
@ -605,14 +605,14 @@ teams app manifest upload manifest.json <teamsAppId>
|
||||
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에서 → 앱 → 앱 관리 → 사용자 지정 앱 업로드
|
||||
|
||||
</details>
|
||||
|
||||
## 기능: RSC만 사용 vs Graph
|
||||
## 기능: RSC 전용 vs Graph
|
||||
|
||||
### **Teams RSC만** 사용하는 경우(앱 설치됨, Graph API 권한 없음)
|
||||
### **Teams RSC 전용** 사용 시(앱 설치됨, Graph API 권한 없음)
|
||||
|
||||
작동함:
|
||||
|
||||
@ -624,28 +624,28 @@ teams app manifest upload manifest.json <teamsAppId>
|
||||
|
||||
- 채널/그룹 **이미지 또는 파일 콘텐츠**(페이로드에는 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 <teamsAppId>
|
||||
- `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.<teamId>.replyStyle`: 팀별 재정의입니다.
|
||||
- `channels.msteams.teams.<teamId>.requireMention`: 팀별 재정의입니다.
|
||||
- `channels.msteams.teams.<teamId>.tools`: 채널 재정의가 없을 때 사용되는 기본 팀별 도구 정책 재정의(`allow`/`deny`/`alsoAllow`)입니다.
|
||||
@ -704,38 +704,38 @@ Teams Markdown은 Slack이나 Discord보다 더 제한적입니다:
|
||||
- `channels.msteams.teams.<teamId>.channels.<conversationId>.tools`: 채널별 도구 정책 재정의(`allow`/`deny`/`alsoAllow`)입니다.
|
||||
- `channels.msteams.teams.<teamId>.channels.<conversationId>.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:<agentId>:<mainKey>`).
|
||||
- 다이렉트 메시지는 기본 세션을 공유합니다(`agent:<agentId>:<mainKey>`).
|
||||
- 채널/그룹 메시지는 대화 ID를 사용합니다:
|
||||
- `agent:<agentId>:msteams:channel:<conversationId>`
|
||||
- `agent:<agentId>:msteams:group:<conversationId>`
|
||||
|
||||
## 답장 스타일: 스레드와 게시물 비교
|
||||
## 응답 스타일: 스레드와 게시물
|
||||
|
||||
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:<id> ...`
|
||||
- 투표는 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:<aad-object-id>` | `user:40a1a0ed-4ff2-4164-a219-55518990c197` |
|
||||
| 사용자(이름 기준) | `user:<display-name>` | `user:John Smith`(Graph API 필요) |
|
||||
| 그룹/채널 | `conversation:<conversation-id>` | `conversation:19:abc123...@thread.tacv2` |
|
||||
| 그룹/채널(원시) | `<conversation-id>` | `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.
|
||||
```
|
||||
|
||||
<Note>
|
||||
`user:` 접두사가 없으면 이름은 기본적으로 그룹 또는 팀 해석에 사용됩니다. 표시 이름으로 사람을 대상으로 지정할 때는 항상 `user:`를 사용하세요.
|
||||
`user:` 접두사가 없으면 이름은 기본적으로 그룹 또는 팀 확인 대상으로 처리됩니다. 표시 이름으로 사람을 대상으로 지정할 때는 항상 `user:`를 사용하세요.
|
||||
</Note>
|
||||
|
||||
## 사전 메시징
|
||||
|
||||
- 사전 메시지는 사용자가 상호작용한 **후에만** 가능합니다. 해당 시점에 대화 참조를 저장하기 때문입니다.
|
||||
- 사전 메시지는 사용자가 상호작용한 **후에만** 가능합니다. 그 시점에 대화 참조를 저장하기 때문입니다.
|
||||
- `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) - 접근 모델 및 강화
|
||||
|
||||
@ -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 <CODE>
|
||||
```
|
||||
|
||||
아직 명령 소유자가 구성되어 있지 않으면, 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:<name>`으로 참조됩니다:
|
||||
정적 그룹은 `type: "message.senders"`를 사용하며, 채널 허용 목록에서
|
||||
`accessGroup:<name>`으로 참조됩니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -81,71 +81,71 @@ openclaw pairing approve telegram <CODE>
|
||||
}
|
||||
```
|
||||
|
||||
액세스 그룹은 여기에서 자세히 설명합니다: [액세스 그룹](/ko/channels/access-groups)
|
||||
접근 그룹은 여기에서 자세히 설명합니다: [접근 그룹](/ko/channels/access-groups)
|
||||
|
||||
### 상태가 저장되는 위치
|
||||
|
||||
`~/.openclaw/credentials/` 아래에 저장됩니다:
|
||||
`~/.openclaw/credentials/` 아래에 저장됩니다.
|
||||
|
||||
- 대기 중인 요청: `<channel>-pairing.json`
|
||||
- 승인된 허용 목록 저장소:
|
||||
- 기본 계정: `<channel>-allowFrom.json`
|
||||
- 기본이 아닌 계정: `<channel>-<accountId>-allowFrom.json`
|
||||
|
||||
계정 범위 지정 동작:
|
||||
계정 범위 동작:
|
||||
|
||||
- 기본이 아닌 계정은 범위가 지정된 허용 목록 파일만 읽고 씁니다.
|
||||
- 기본 계정은 채널 범위의 범위 미지정 허용 목록 파일을 사용합니다.
|
||||
- 기본이 아닌 계정은 해당 범위의 허용 목록 파일만 읽고 씁니다.
|
||||
- 기본 계정은 채널 범위의 범위 지정 없는 허용 목록 파일을 사용합니다.
|
||||
|
||||
이를 민감한 정보로 취급하세요(어시스턴트 접근을 제어합니다).
|
||||
이 항목들은 민감한 정보로 취급하세요(어시스턴트 접근을 제어합니다).
|
||||
|
||||
<Note>
|
||||
페어링 허용 목록 저장소는 DM 접근용입니다. 그룹 권한 부여는 별도입니다.
|
||||
DM 페어링 코드를 승인해도 해당 발신자가 자동으로 그룹
|
||||
명령을 실행하거나 그룹에서 봇을 제어할 수 있게 되지는 않습니다. 첫 소유자 부트스트랩은
|
||||
DM 페어링 코드를 승인해도 해당 발신자가 그룹
|
||||
명령을 실행하거나 그룹에서 봇을 제어할 수 있도록 자동 허용되지는 않습니다. 첫 소유자 부트스트랩은
|
||||
`commands.ownerAllowFrom`의 별도 구성 상태이며, 그룹 채팅 전달은 여전히
|
||||
채널의 그룹 허용 목록을 따릅니다(예: 채널에 따라 `groupAllowFrom`, `groups`, 또는 그룹별
|
||||
혹은 토픽별 재정의).
|
||||
채널의 그룹 허용 목록(예: 채널에 따라 `groupAllowFrom`, `groups`, 그룹별
|
||||
또는 주제별 재정의)을 따릅니다.
|
||||
</Note>
|
||||
|
||||
## 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 <requestId>
|
||||
openclaw devices reject <requestId>
|
||||
```
|
||||
|
||||
승인하는 페어링된 기기 세션이 페어링 전용 범위로 열려 있어 명시적 승인이
|
||||
거부되면, CLI는 동일한 요청을 `operator.admin`으로 다시 시도합니다.
|
||||
이를 통해 기존의 관리자 권한이 가능한 페어링된 기기가 `devices/paired.json`을
|
||||
직접 편집하지 않고도 새 Control UI/브라우저 페어링을 복구할 수 있습니다.
|
||||
Gateway는 여전히 다시 시도된 연결을 검증합니다. `operator.admin`으로 인증할 수 없는
|
||||
토큰은 계속 차단됩니다.
|
||||
승인하는 페어링된 기기 세션이 페어링 전용 범위로 열렸기 때문에 명시적 승인이 거부되면,
|
||||
CLI는 동일한 요청을 `operator.admin`으로 재시도합니다. 이를 통해 기존의 관리자 권한이 있는 페어링된 기기는
|
||||
`devices/paired.json`을 직접 편집하지 않고도 새 Control UI/브라우저 페어링을 복구할 수 있습니다.
|
||||
Gateway는 여전히 재시도된 연결을 검증합니다. `operator.admin`으로 인증할 수 없는 토큰은
|
||||
계속 차단됩니다.
|
||||
|
||||
동일한 기기가 다른 인증 세부 정보(예: 다른 역할/범위/공개 키)로 다시 시도하면,
|
||||
이전 대기 요청은 대체되고 새 `requestId`가 생성됩니다.
|
||||
동일한 기기가 다른 인증 세부 정보(예: 다른
|
||||
역할/범위/공개 키)로 재시도하면 이전 대기 요청은 대체되고 새
|
||||
`requestId`가 생성됩니다.
|
||||
|
||||
<Note>
|
||||
이미 페어링된 기기가 조용히 더 넓은 접근 권한을 얻지는 않습니다. 더 많은 범위나 더 넓은 역할을 요청하며 다시 연결하면, OpenClaw는 기존 승인을 그대로 유지하고 새로운 대기 중 업그레이드 요청을 생성합니다. 승인하기 전에 `openclaw devices list`를 사용하여 현재 승인된 접근 권한과 새로 요청된 접근 권한을 비교하세요.
|
||||
이미 페어링된 기기가 조용히 더 넓은 접근 권한을 얻지는 않습니다. 더 많은 범위나 더 넓은 역할을 요청하며 다시 연결하면, OpenClaw는 기존 승인을 그대로 유지하고 새 대기 중 업그레이드 요청을 생성합니다. 승인하기 전에 `openclaw devices list`를 사용하여 현재 승인된 접근 권한과 새로 요청된 접근 권한을 비교하세요.
|
||||
</Note>
|
||||
|
||||
### 선택 사항: 신뢰할 수 있는 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)
|
||||
|
||||
@ -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도 지원됩니다.
|
||||
|
||||
<CardGroup cols={3}>
|
||||
<Card title="Pairing" icon="link" href="/ko/channels/pairing">
|
||||
Slack DM은 기본적으로 페어링 모드를 사용합니다.
|
||||
</Card>
|
||||
<Card title="Slash commands" icon="terminal" href="/ko/tools/slash-commands">
|
||||
네이티브 명령 동작과 명령 카탈로그입니다.
|
||||
네이티브 명령 동작 및 명령 카탈로그입니다.
|
||||
</Card>
|
||||
<Card title="Channel troubleshooting" icon="wrench" href="/ko/channels/troubleshooting">
|
||||
채널 간 진단 및 복구 플레이북입니다.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
## 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의 요청별로 수행됨 |
|
||||
|
||||
<Note>
|
||||
단일 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을 종료하는 경우에 적합합니다.
|
||||
</Note>
|
||||
|
||||
## 빠른 설정
|
||||
@ -54,7 +54,7 @@ DM과 채널에서 Slack 앱 통합을 통해 프로덕션에 바로 사용할
|
||||
<Tab title="Socket Mode (default)">
|
||||
<Steps>
|
||||
<Step title="Create a new Slack app">
|
||||
[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**.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
@ -188,13 +188,13 @@ DM과 채널에서 Slack 앱 통합을 통해 프로덕션에 바로 사용할
|
||||
</CodeGroup>
|
||||
|
||||
<Note>
|
||||
**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)를 참조하세요.
|
||||
</Note>
|
||||
|
||||
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을 복사합니다.
|
||||
|
||||
</Step>
|
||||
|
||||
@ -244,7 +244,7 @@ openclaw gateway
|
||||
<Tab title="HTTP Request URLs">
|
||||
<Steps>
|
||||
<Step title="Create a new Slack app">
|
||||
[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**.
|
||||
|
||||
<CodeGroup>
|
||||
|
||||
@ -327,7 +327,7 @@ openclaw gateway
|
||||
}
|
||||
```
|
||||
|
||||
```json Minimal
|
||||
```json 최소
|
||||
{
|
||||
"display_information": {
|
||||
"name": "OpenClaw",
|
||||
@ -390,21 +390,21 @@ openclaw gateway
|
||||
</CodeGroup>
|
||||
|
||||
<Note>
|
||||
**권장**은 번들 Slack Plugin의 전체 기능 세트와 일치합니다. **최소**는 제한적인 워크스페이스를 위해 파일, 반응, 핀, 그룹 DM(`mpim:*`), `emoji:read`, `usergroups:read`를 제외합니다. 범위별 근거는 [매니페스트 및 범위 체크리스트](#manifest-and-scope-checklist)를 참조하세요.
|
||||
**권장**은 번들 Slack Plugin의 전체 기능 세트와 일치합니다. **최소**는 제한적인 워크스페이스를 위해 파일, 반응, 핀, 그룹 DM(`mpim:*`), `emoji:read`, `usergroups:read`를 제외합니다. 범위별 근거는 [매니페스트 및 범위 체크리스트](#manifest-and-scope-checklist)를 참고하세요.
|
||||
</Note>
|
||||
|
||||
<Info>
|
||||
세 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 모드에서 조용히 아무 작업도 하지 않습니다.
|
||||
</Info>
|
||||
|
||||
Slack이 앱을 만든 후:
|
||||
|
||||
- **Basic Information → App Credentials**: 요청 검증에 사용할 **Signing Secret**을 복사합니다.
|
||||
- **Install App → Install to Workspace**: `xoxb-...` Bot User OAuth Token을 복사합니다.
|
||||
- **기본 정보 → 앱 자격 증명**: 요청 검증에 사용할 **Signing Secret**을 복사합니다.
|
||||
- **앱 설치 → 워크스페이스에 설치**: `xoxb-...` Bot User OAuth Token을 복사합니다.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Configure OpenClaw">
|
||||
<Step title="OpenClaw 구성">
|
||||
|
||||
권장 SecretRef 설정:
|
||||
|
||||
@ -429,14 +429,14 @@ openclaw config patch --file ./slack.http.patch.json5
|
||||
```
|
||||
|
||||
<Note>
|
||||
다중 계정 HTTP에는 고유한 Webhook 경로 사용
|
||||
다중 계정 HTTP에는 고유한 Webhook 경로를 사용하세요
|
||||
|
||||
등록이 충돌하지 않도록 각 계정에 서로 다른 `webhookPath`(기본값 `/slack/events`)를 지정하세요.
|
||||
각 계정에 서로 다른 `webhookPath`(기본값 `/slack/events`)를 지정하여 등록이 충돌하지 않도록 합니다.
|
||||
</Note>
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Start gateway">
|
||||
<Step title="Gateway 시작">
|
||||
|
||||
```bash
|
||||
openclaw gateway
|
||||
@ -448,9 +448,9 @@ openclaw gateway
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## 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에 대해 계속 활성화됩니다.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Optional native slash commands">
|
||||
<Accordion title="선택적 네이티브 슬래시 명령">
|
||||
|
||||
여러 [네이티브 슬래시 명령](#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)의 하위 집합으로 바꾸세요.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Socket Mode (default)">
|
||||
<Tab title="Socket Mode(기본값)">
|
||||
|
||||
```json
|
||||
{
|
||||
@ -731,7 +731,7 @@ Slack 웹소켓 pong/서버 ping 제한 시간을 기록하는 Socket Mode 워
|
||||
|
||||
</Tab>
|
||||
<Tab title="HTTP Request URLs">
|
||||
위 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 워
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="선택적 작성자 표시 범위(쓰기 작업)">
|
||||
발신 메시지가 기본 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`입니다.
|
||||
|
||||
<Tip>
|
||||
작업/디렉터리 읽기의 경우 사용자 토큰이 구성되어 있으면 우선될 수 있습니다. 쓰기의 경우 봇 토큰이 계속 우선됩니다. 사용자 토큰 쓰기는 `userTokenReadOnly: false`이고 봇 토큰을 사용할 수 없을 때만 허용됩니다.
|
||||
작업/디렉터리 읽기의 경우 사용자 토큰이 구성되어 있으면 선호될 수 있습니다. 쓰기의 경우 봇 토큰이 계속 선호됩니다. 사용자 토큰 쓰기는 `userTokenReadOnly: false`이고 봇 토큰을 사용할 수 없을 때만 허용됩니다.
|
||||
</Tip>
|
||||
|
||||
## 작업 및 게이트
|
||||
|
||||
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 <code>`를 사용합니다.
|
||||
DM에서 페어링은 `openclaw pairing approve slack <code>`를 사용합니다.
|
||||
|
||||
</Tab>
|
||||
|
||||
@ -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`가 필요합니다.
|
||||
|
||||
<Warning>
|
||||
이름 기반 키(`#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.*`로 제어됩니다.
|
||||
</Tab>
|
||||
|
||||
<Tab title="멘션 및 채널 사용자">
|
||||
채널 메시지는 기본적으로 멘션으로 제어됩니다.
|
||||
채널 메시지는 기본적으로 멘션 게이트가 적용됩니다.
|
||||
|
||||
멘션 소스:
|
||||
|
||||
- 명시적 앱 멘션(`<@botId>`)
|
||||
- 봇 사용자가 해당 사용자 그룹의 구성원일 때의 Slack 사용자 그룹 멘션(`<!subteam^S...>`); `usergroups:read` 필요
|
||||
- 멘션 정규식 패턴(`agents.list[].groupChat.mentionPatterns`, 대체값 `messages.groupChat.mentionPatterns`)
|
||||
- 암시적 봇 답글 스레드 동작(`thread.requireExplicitMention`이 `true`일 때 비활성화됨)
|
||||
- Slack 사용자 그룹 멘션(`<!subteam^S...>`): 봇 사용자가 해당 사용자 그룹의 멤버인 경우, `usergroups:read` 필요
|
||||
- 멘션 정규식 패턴(`agents.list[].groupChat.mentionPatterns`, 폴백 `messages.groupChat.mentionPatterns`)
|
||||
- 암시적 봇에게 답장한 스레드 동작(`thread.requireExplicitMention`이 `true`일 때 비활성화됨)
|
||||
|
||||
채널별 제어(`channels.slack.channels.<id>`; 이름은 시작 시 확인 또는 `dangerouslyAllowNameMatching`을 통해서만):
|
||||
채널별 제어(`channels.slack.channels.<id>`; 이름은 시작 시 해석 또는 `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는 봇이 작성한 방 메시지를 삭제합니다.
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## 스레딩, 세션 및 답글 태그
|
||||
## 스레딩, 세션 및 답장 태그
|
||||
|
||||
- DM은 `direct`로, 채널은 `channel`로, MPIM은 `group`으로 라우팅됩니다.
|
||||
- Slack 라우트 바인딩은 원시 피어 ID와 `channel:C12345678`, `user:U12345678`, `<@U12345678>` 같은 Slack 대상 형식을 허용합니다.
|
||||
- 기본 `session.dmScope=main`에서는 Slack DM이 에이전트 기본 세션으로 합쳐집니다.
|
||||
- 채널 세션: `agent:<agentId>:slack:channel:<channelId>`.
|
||||
- 스레드 답글은 해당되는 경우 스레드 세션 접미사(`:thread:<threadTs>`)를 만들 수 있습니다.
|
||||
- `channels.slack.thread.historyScope` 기본값은 `thread`입니다. `thread.inheritParent` 기본값은 `false`입니다.
|
||||
- `channels.slack.thread.initialHistoryLimit`은 새 스레드 세션이 시작될 때 가져올 기존 스레드 메시지 수를 제어합니다(기본값 `20`; 비활성화하려면 `0` 설정).
|
||||
- `channels.slack.thread.requireExplicitMention`(기본값 `false`): `true`이면 암시적 스레드 멘션을 억제하여, 봇이 이미 해당 스레드에 참여했더라도 스레드 안에서 명시적 `@bot` 멘션에만 응답하게 합니다. 이 설정이 없으면 봇이 참여한 스레드의 답글은 `requireMention` 게이트를 우회합니다.
|
||||
- 스레드 답장은 적용 가능한 경우 스레드 세션 접미사(`:thread:<threadTs>`)를 만들 수 있습니다.
|
||||
- `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:<id>]]`
|
||||
|
||||
<Note>
|
||||
`replyToMode="off"`는 명시적 `[[reply_to_*]]` 태그를 포함하여 Slack의 **모든** 답글 스레딩을 비활성화합니다. 이는 `"off"` 모드에서도 명시적 태그가 계속 적용되는 Telegram과 다릅니다. Slack 스레드는 채널에서 메시지를 숨기지만, Telegram 답글은 인라인으로 계속 표시됩니다.
|
||||
`replyToMode="off"`는 명시적 `[[reply_to_*]]` 태그를 포함하여 Slack의 **모든** 답장 스레딩을 비활성화합니다. 이는 `"off"` 모드에서도 명시적 태그를 계속 준수하는 Telegram과 다릅니다. Slack 스레드는 메시지를 채널에서 숨기지만, Telegram 답장은 인라인으로 계속 표시됩니다.
|
||||
</Note>
|
||||
|
||||
## 확인 반응
|
||||
|
||||
`ackReaction`은 OpenClaw가 인바운드 메시지를 처리하는 동안 확인 이모지를 보냅니다.
|
||||
|
||||
해결 순서:
|
||||
해석 순서:
|
||||
|
||||
- `channels.slack.accounts.<accountId>.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"`).
|
||||
- 반응은 최선형 방식이며, 답장 또는 실패 경로가 완료된 뒤 정리가 자동으로 시도됩니다.
|
||||
|
||||
## 미디어, 청킹 및 전달
|
||||
## 미디어, 청킹, 전달
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="인바운드 첨부 파일">
|
||||
Slack 파일 첨부는 Slack이 호스팅하는 비공개 URL(토큰 인증 요청 흐름)에서 다운로드되며, 가져오기에 성공하고 크기 제한이 허용하면 미디어 저장소에 기록됩니다. 파일 자리표시자는 Slack `fileId`를 포함하므로 에이전트가 `download-file`로 원본 파일을 가져올 수 있습니다.
|
||||
<Accordion title="Inbound attachments">
|
||||
Slack 파일 첨부는 Slack이 호스팅하는 비공개 URL(토큰 인증 요청 흐름)에서 다운로드되며, 가져오기에 성공하고 크기 제한이 허용되면 미디어 저장소에 기록됩니다. 파일 자리 표시자에는 Slack `fileId`가 포함되어 에이전트가 `download-file`로 원본 파일을 가져올 수 있습니다.
|
||||
|
||||
다운로드에는 제한된 유휴 및 전체 타임아웃이 사용됩니다. Slack 파일 가져오기가 멈추거나 실패하면 OpenClaw는 메시지 처리를 계속하고 파일 자리표시자로 대체합니다.
|
||||
다운로드에는 제한된 유휴 시간 제한과 전체 시간 제한이 사용됩니다. Slack 파일 검색이 멈추거나 실패하면 OpenClaw는 메시지 처리를 계속하고 파일 자리 표시자로 대체합니다.
|
||||
|
||||
런타임 인바운드 크기 상한은 `channels.slack.mediaMaxMb`로 재정의하지 않는 한 기본값이 `20MB`입니다.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="아웃바운드 텍스트 및 파일">
|
||||
- 텍스트 청크는 `channels.slack.textChunkLimit`를 사용합니다(기본값 4000)
|
||||
- `channels.slack.chunkMode="newline"`은 단락 우선 분할을 활성화합니다
|
||||
- 파일 전송은 Slack 업로드 API를 사용하며 스레드 답글(`thread_ts`)을 포함할 수 있습니다
|
||||
- 아웃바운드 미디어 상한은 구성된 경우 `channels.slack.mediaMaxMb`를 따르고, 그렇지 않으면 채널 전송은 미디어 파이프라인의 MIME 종류 기본값을 사용합니다
|
||||
<Accordion title="Outbound text and files">
|
||||
- 텍스트 청크는 `channels.slack.textChunkLimit`(기본값 4000)을 사용합니다
|
||||
- `channels.slack.chunkMode="newline"`은 문단 우선 분할을 활성화합니다
|
||||
- 파일 전송은 Slack 업로드 API를 사용하며 스레드 답장(`thread_ts`)을 포함할 수 있습니다
|
||||
- 아웃바운드 미디어 상한은 구성된 경우 `channels.slack.mediaMaxMb`를 따르며, 그렇지 않으면 채널 전송은 미디어 파이프라인의 MIME 종류 기본값을 사용합니다
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="전달 대상">
|
||||
<Accordion title="Delivery targets">
|
||||
선호되는 명시적 대상:
|
||||
|
||||
- DM에는 `user:<id>`
|
||||
- 채널에는 `channel:<id>`
|
||||
|
||||
텍스트/블록 전용 Slack DM은 사용자 ID에 직접 게시할 수 있습니다. 파일 업로드와 스레드 전송은 해당 경로에 구체적인 대화 ID가 필요하므로 먼저 Slack 대화 API를 통해 DM을 엽니다.
|
||||
텍스트/블록 전용 Slack DM은 사용자 ID로 직접 게시할 수 있습니다. 파일 업로드와 스레드 전송은 구체적인 대화 ID가 필요하므로 먼저 Slack 대화 API를 통해 DM을 엽니다.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 명령 및 슬래시 동작
|
||||
## 명령과 슬래시 동작
|
||||
|
||||
슬래시 명령은 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:<agentId>:slack:slash:<userId>` 같은 격리된 키를 사용하며, 여전히 `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).
|
||||
|
||||
<Accordion title="주요 Slack 필드">
|
||||
<Accordion title="High-signal Slack fields">
|
||||
|
||||
- 모드/인증: `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"`이고 하나 이상의
|
||||
## 문제 해결
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="채널에서 답글이 없음">
|
||||
<Accordion title="No replies in channels">
|
||||
순서대로 확인하세요.
|
||||
|
||||
- `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
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="DM 메시지가 무시됨">
|
||||
<Accordion title="DM messages ignored">
|
||||
확인하세요.
|
||||
|
||||
- `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
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Socket 모드가 연결되지 않음">
|
||||
Slack 앱 설정에서 봇 + 앱 토큰 및 Socket Mode 활성화를 검증하세요.
|
||||
<Accordion title="Socket mode not connecting">
|
||||
Slack 앱 설정에서 봇 + 앱 토큰과 Socket Mode 활성화를 검증하세요.
|
||||
|
||||
`openclaw channels status --probe --json`에 `botTokenStatus` 또는
|
||||
`appTokenStatus: "configured_unavailable"`가 표시되면 Slack 계정은
|
||||
구성되었지만 현재 런타임이 SecretRef 기반 값을 확인하지 못한 것입니다.
|
||||
구성되어 있지만 현재 런타임이 SecretRef 기반 값을 확인할 수 없었다는 뜻입니다.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="HTTP 모드가 이벤트를 수신하지 않음">
|
||||
검증하세요.
|
||||
<Accordion title="HTTP mode not receiving events">
|
||||
검증 항목:
|
||||
|
||||
- 서명 시크릿
|
||||
- Webhook 경로
|
||||
@ -1298,106 +1296,106 @@ openclaw pairing list slack
|
||||
- HTTP 계정별 고유한 `webhookPath`
|
||||
|
||||
계정 스냅샷에 `signingSecretStatus: "configured_unavailable"`가 표시되면
|
||||
HTTP 계정은 구성되었지만 현재 런타임이 SecretRef 기반 서명 시크릿을
|
||||
확인하지 못한 것입니다.
|
||||
HTTP 계정은 구성되어 있지만 현재 런타임이 SecretRef 기반 서명 시크릿을
|
||||
확인할 수 없었다는 뜻입니다.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="네이티브/슬래시 명령이 실행되지 않음">
|
||||
의도한 것이 무엇인지 확인하세요.
|
||||
<Accordion title="Native/slash commands not firing">
|
||||
의도한 방식이 무엇인지 확인하세요.
|
||||
|
||||
- Slack에 등록된 일치하는 슬래시 명령이 있는 네이티브 명령 모드(`channels.slack.commands.native: true`)
|
||||
- 또는 단일 슬래시 명령 모드(`channels.slack.slashCommand.enabled: true`)
|
||||
- Slack에 등록된 일치하는 슬래시 명령과 함께 네이티브 명령 모드(`channels.slack.commands.native: true`)를 사용
|
||||
- 또는 단일 슬래시 명령 모드(`channels.slack.slashCommand.enabled: true`)를 사용
|
||||
|
||||
`commands.useAccessGroups`와 채널/사용자 허용 목록도 확인하세요.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 첨부 파일 비전 참조
|
||||
## 첨부 비전 참조
|
||||
|
||||
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)
|
||||
|
||||
## 관련 항목
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="페어링" icon="link" href="/ko/channels/pairing">
|
||||
<Card title="Pairing" icon="link" href="/ko/channels/pairing">
|
||||
Slack 사용자를 Gateway에 페어링합니다.
|
||||
</Card>
|
||||
<Card title="그룹" icon="users" href="/ko/channels/groups">
|
||||
채널 및 그룹 DM 동작.
|
||||
<Card title="Groups" icon="users" href="/ko/channels/groups">
|
||||
채널 및 그룹 DM 동작입니다.
|
||||
</Card>
|
||||
<Card title="채널 라우팅" icon="route" href="/ko/channels/channel-routing">
|
||||
수신 메시지를 에이전트로 라우팅합니다.
|
||||
<Card title="Channel routing" icon="route" href="/ko/channels/channel-routing">
|
||||
인바운드 메시지를 에이전트로 라우팅합니다.
|
||||
</Card>
|
||||
<Card title="보안" icon="shield" href="/ko/gateway/security">
|
||||
위협 모델 및 강화.
|
||||
<Card title="Security" icon="shield" href="/ko/gateway/security">
|
||||
위협 모델과 강화입니다.
|
||||
</Card>
|
||||
<Card title="구성" icon="sliders" href="/ko/gateway/configuration">
|
||||
구성 레이아웃 및 우선순위.
|
||||
<Card title="Configuration" icon="sliders" href="/ko/gateway/configuration">
|
||||
구성 레이아웃과 우선순위입니다.
|
||||
</Card>
|
||||
<Card title="슬래시 명령" icon="terminal" href="/ko/tools/slash-commands">
|
||||
명령 카탈로그 및 동작.
|
||||
<Card title="Slash commands" icon="terminal" href="/ko/tools/slash-commands">
|
||||
명령 카탈로그와 동작입니다.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@ -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 계정**을 자동화합니다.
|
||||
|
||||
<Warning>
|
||||
이는 비공식 통합이며 계정 정지 또는 차단으로 이어질 수 있습니다. 본인 책임하에 사용하세요.
|
||||
@ -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 <code>`
|
||||
|
||||
## 그룹 접근(선택 사항)
|
||||
## 그룹 액세스(선택 사항)
|
||||
|
||||
- 기본값: `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.<group>.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) — 액세스 모델 및 강화
|
||||
|
||||
@ -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`와 동일).
|
||||
|
||||
<Note>
|
||||
`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.<name>.config` 아래에 값을 설정하세요.
|
||||
</Note>
|
||||
|
||||
## 루트 옵션
|
||||
|
||||
<ParamField path="--section <section>" type="string">
|
||||
하위 명령 없이 `openclaw config`를 실행할 때 반복 지정 가능한 안내 설정 섹션 필터입니다.
|
||||
하위 명령 없이 `openclaw config`를 실행할 때 반복해서 지정할 수 있는 안내식 설정 섹션 필터입니다.
|
||||
</ParamField>
|
||||
|
||||
지원되는 안내 섹션: `workspace`, `model`, `web`, `gateway`, `daemon`, `channels`, `plugins`, `skills`, `health`.
|
||||
@ -50,17 +54,17 @@ openclaw config validate --json
|
||||
`openclaw.json`용으로 생성된 JSON 스키마를 JSON으로 stdout에 출력합니다.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="포함되는 내용">
|
||||
<Accordion title="포함 내용">
|
||||
- 현재 루트 구성 스키마와 편집기 도구용 루트 `$schema` 문자열 필드.
|
||||
- Control UI에서 사용하는 필드 `title` 및 `description` 문서 메타데이터.
|
||||
- 중첩 객체, 와일드카드(`*`), 배열 항목(`[]`) 노드는 일치하는 필드 문서가 있으면 동일한 `title` / `description` 메타데이터를 상속합니다.
|
||||
- `anyOf` / `oneOf` / `allOf` 분기도 일치하는 필드 문서가 있으면 동일한 문서 메타데이터를 상속합니다.
|
||||
- 런타임 매니페스트를 로드할 수 있을 때 최선의 라이브 Plugin + 채널 스키마 메타데이터.
|
||||
- 현재 구성이 유효하지 않아도 깔끔한 대체 스키마.
|
||||
- 일치하는 필드 문서가 있으면 중첩 객체, 와일드카드(`*`), 배열 항목(`[]`) 노드가 동일한 `title` / `description` 메타데이터를 상속합니다.
|
||||
- 일치하는 필드 문서가 있으면 `anyOf` / `oneOf` / `allOf` 분기도 동일한 문서 메타데이터를 상속합니다.
|
||||
- 런타임 매니페스트를 로드할 수 있을 때 최선의 실시간 Plugin + 채널 스키마 메타데이터.
|
||||
- 현재 구성이 유효하지 않은 경우에도 깔끔한 대체 스키마.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="관련 런타임 RPC">
|
||||
`config.schema.lookup`은 얕은 스키마 노드(`title`, `description`, `type`, `enum`, `const`, 공통 경계), 일치하는 UI 힌트 메타데이터, 즉시 하위 요약을 포함해 정규화된 구성 경로 하나를 반환합니다. Control UI 또는 사용자 지정 클라이언트에서 경로 범위 드릴다운에 사용하세요.
|
||||
`config.schema.lookup`은 얕은 스키마 노드(`title`, `description`, `type`, `enum`, `const`, 공통 범위), 일치하는 UI 힌트 메타데이터, 즉시 하위 요약과 함께 정규화된 구성 경로 하나를 반환합니다. Control UI 또는 사용자 지정 클라이언트에서 경로 범위 드릴다운에 사용하세요.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
@ -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 <path> --json`은 터미널 형식의 텍스트 대신 원시 값을 JSON으로 출력합니다.
|
||||
|
||||
<Note>
|
||||
객체 할당은 기본적으로 대상 경로를 대체합니다. `agents.defaults.models`, `models.providers`, `models.providers.<id>.models`, `plugins.entries`, `auth.profiles`처럼 사용자가 추가한 항목을 흔히 보관하는 보호된 맵/목록 경로는 `--replace`를 전달하지 않으면 기존 항목을 제거하는 대체를 거부합니다.
|
||||
객체 할당은 기본적으로 대상 경로를 교체합니다. `agents.defaults.models`, `models.providers`, `models.providers.<id>.models`, `plugins.entries`, `auth.profiles`처럼 사용자가 추가한 항목을 흔히 보관하는 보호된 맵/목록 경로는 `--replace`를 전달하지 않는 한 기존 항목을 제거하는 교체를 거부합니다.
|
||||
</Note>
|
||||
|
||||
해당 맵에 항목을 추가할 때는 `--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)을 참고하세요.
|
||||
</Warning>
|
||||
|
||||
배치 파싱은 항상 배치 페이로드(`--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 <path>`를 사용하세요.
|
||||
객체나 배열 하나가 재귀적으로 패치되는 대신 제공한 값과 정확히 같아져야 할 때는 `--replace-path <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.<alias>`를 사용해야
|
||||
- `--provider-timeout-ms <ms>` (`file`, `exec`)
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Env 공급자(--provider-source env)">
|
||||
<Accordion title="Env provider (--provider-source env)">
|
||||
- `--provider-allowlist <ENV_VAR>` (반복 가능)
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="File 공급자(--provider-source file)">
|
||||
<Accordion title="File provider (--provider-source file)">
|
||||
- `--provider-path <path>` (필수)
|
||||
- `--provider-mode <singleValue|json>`
|
||||
- `--provider-max-bytes <bytes>`
|
||||
- `--provider-allow-insecure-path`
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Exec 공급자(--provider-source exec)">
|
||||
<Accordion title="Exec provider (--provider-source exec)">
|
||||
- `--provider-command <path>` (필수)
|
||||
- `--provider-arg <arg>` (반복 가능)
|
||||
- `--provider-no-output-timeout-ms <ms>`
|
||||
@ -277,7 +281,7 @@ Provider 빌더 대상은 경로로 `secrets.providers.<alias>`를 사용해야
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
강화된 exec 공급자 예시:
|
||||
강화된 exec provider 예시:
|
||||
|
||||
```bash
|
||||
openclaw config set secrets.providers.vault \
|
||||
@ -319,25 +323,25 @@ openclaw config set channels.discord.token \
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Dry-run 동작">
|
||||
- 빌더 모드: 변경된 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` 없이 사용하면 오류가 발생합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="--dry-run --json 필드">
|
||||
`--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`일 때의 구조화된 스키마/해결 가능성 실패
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
@ -412,11 +416,11 @@ openclaw config set channels.discord.token \
|
||||
</Tabs>
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="dry-run이 실패하는 경우">
|
||||
- `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 <n> exec SecretRef resolvability check(s)`: dry-run이 exec ref를 건너뛰었습니다. exec resolvability 검증이 필요하면 `--allow-exec`로 다시 실행하세요.
|
||||
<Accordion title="드라이런이 실패하는 경우">
|
||||
- `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 <n> exec SecretRef resolvability check(s)`: 드라이런이 exec 참조를 건너뛰었습니다. exec 해결 가능성 검증이 필요하면 `--allow-exec`로 다시 실행하세요.
|
||||
- 배치 모드에서는 실패한 항목을 수정하고 쓰기 전에 `--dry-run`을 다시 실행하세요.
|
||||
|
||||
</Accordion>
|
||||
@ -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.*`로 그 옆에 저장합니다.
|
||||
|
||||
<Warning>
|
||||
active config 경로는 일반 파일이어야 합니다. symlink된 `openclaw.json` 레이아웃은 쓰기에 지원되지 않습니다. 대신 `OPENCLAW_CONFIG_PATH`를 사용해 실제 파일을 직접 가리키세요.
|
||||
활성 구성 경로는 일반 파일이어야 합니다. 심볼릭 링크된 `openclaw.json` 레이아웃은 쓰기에 지원되지 않습니다. 대신 `OPENCLAW_CONFIG_PATH`를 사용해 실제 파일을 직접 가리키세요.
|
||||
</Warning>
|
||||
|
||||
작은 편집에는 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를 사용해 같은 터미널에서 각 변경 사항을 검증하는 동안 내장 에이전트가 활성 구성을 문서와 비교하도록 할 수 있습니다.
|
||||
|
||||
<Note>
|
||||
검증이 이미 실패하고 있다면 `openclaw configure` 또는 `openclaw doctor --fix`로 시작하세요. `openclaw chat`은 invalid-config guard를 우회하지 않습니다.
|
||||
검증이 이미 실패하고 있다면 `openclaw configure` 또는 `openclaw doctor --fix`부터 시작하세요. `openclaw chat`은 유효하지 않은 구성 보호를 우회하지 않습니다.
|
||||
</Note>
|
||||
|
||||
```bash
|
||||
openclaw chat
|
||||
```
|
||||
|
||||
그런 다음 TUI 내부에서 실행합니다.
|
||||
그런 다음 TUI 안에서:
|
||||
|
||||
```text
|
||||
!openclaw config file
|
||||
@ -487,21 +491,21 @@ openclaw chat
|
||||
일반적인 복구 루프:
|
||||
|
||||
<Steps>
|
||||
<Step title="docs와 비교">
|
||||
agent에게 현재 config를 관련 docs 페이지와 비교하고 가장 작은 수정 사항을 제안하도록 요청하세요.
|
||||
<Step title="문서와 비교">
|
||||
에이전트에게 현재 구성을 관련 문서 페이지와 비교하고 가장 작은 수정 사항을 제안하도록 요청하세요.
|
||||
</Step>
|
||||
<Step title="대상 편집 적용">
|
||||
`openclaw config set` 또는 `openclaw configure`로 대상 편집을 적용하세요.
|
||||
<Step title="대상 지정 편집 적용">
|
||||
`openclaw config set` 또는 `openclaw configure`로 대상 지정 편집을 적용하세요.
|
||||
</Step>
|
||||
<Step title="다시 검증">
|
||||
각 변경 후 `openclaw config validate`를 다시 실행하세요.
|
||||
</Step>
|
||||
<Step title="런타임 문제는 doctor 사용">
|
||||
검증은 통과하지만 runtime이 여전히 정상적이지 않다면, migration 및 복구 도움을 위해 `openclaw doctor` 또는 `openclaw doctor --fix`를 실행하세요.
|
||||
<Step title="런타임 문제에는 doctor 사용">
|
||||
검증은 통과하지만 런타임이 여전히 정상적이지 않다면 마이그레이션 및 복구 도움말을 위해 `openclaw doctor` 또는 `openclaw doctor --fix`를 실행하세요.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## 관련 항목
|
||||
## 관련
|
||||
|
||||
- [CLI 참조](/ko/cli)
|
||||
- [Configuration](/ko/gateway/configuration)
|
||||
- [구성](/ko/gateway/configuration)
|
||||
|
||||
@ -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:<id>` 및 `channel:<id>`
|
||||
- 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
|
||||
|
||||
@ -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.<timestamp>`로 보관하려면 대화형 확인이 필요합니다. `--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.<id>` 항목을 비활성화하고 잘못된 `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.<timestamp>`로 아카이브하려면 대화형 확인이 필요합니다. `--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.<id>` 항목을 비활성화하고 잘못된 `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.<provider>`로 자동 마이그레이션합니다.
|
||||
- 반복적인 `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.<skill>.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.<provider>`로 자동 마이그레이션합니다.
|
||||
- 반복되는 `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.<skill>.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)
|
||||
|
||||
@ -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 <name>
|
||||
```
|
||||
|
||||
구성(기본값은 `~/.openclaw/openclaw.json`)에 추가하여 특정 훅을 활성화합니다.
|
||||
구성(기본값: `~/.openclaw/openclaw.json`)에 특정 훅을 추가하여 활성화합니다.
|
||||
|
||||
**참고:** 워크스페이스 훅은 여기 또는 구성에서 활성화하기 전까지 기본적으로 비활성화됩니다. Plugin이 관리하는 훅은 `openclaw hooks list`에 `plugin:<id>`로 표시되며 여기서는 활성화/비활성화할 수 없습니다. 대신 Plugin을 활성화/비활성화하세요.
|
||||
**참고:** 워크스페이스 훅은 여기 또는 구성에서 활성화할 때까지 기본적으로 비활성화되어 있습니다. Plugin이 관리하는 훅은 `openclaw hooks list`에 `plugin:<id>`로 표시되며 여기서 활성화/비활성화할 수 없습니다. 대신 해당 Plugin을 활성화/비활성화하세요.
|
||||
|
||||
**인수:**
|
||||
|
||||
@ -157,15 +157,16 @@ openclaw hooks enable session-memory
|
||||
|
||||
**수행 작업:**
|
||||
|
||||
- 훅이 존재하고 적격인지 확인
|
||||
- 구성에서 `hooks.internal.entries.<name>.enabled = true`로 업데이트
|
||||
- 훅이 존재하고 적격한지 확인
|
||||
- 구성에서 `hooks.internal.entries.<name>.enabled = true` 업데이트
|
||||
- 구성을 디스크에 저장
|
||||
|
||||
훅이 `<workspace>/hooks/`에서 온 경우, Gateway가 이를 로드하려면 이 옵트인 단계가 필요합니다.
|
||||
훅이 `<workspace>/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 <path> # 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/<id>`로 복사
|
||||
- 설치된 훅을 `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 <id>
|
||||
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`
|
||||
|
||||
|
||||
@ -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 <id>`: 단일 에이전트로 범위를 제한합니다. 이 옵션이 없으면 이러한 명령은 구성된 각 에이전트에 대해 실행됩니다. 에이전트 목록이 구성되어 있지 않으면 기본 에이전트로 대체됩니다.
|
||||
- `--verbose`: 프로브 및 인덱싱 중 자세한 로그를 출력합니다.
|
||||
- `--agent <id>`: 단일 에이전트로 범위를 제한합니다. 지정하지 않으면 이러한 명령은 구성된 각 에이전트에 대해 실행됩니다. 에이전트 목록이 구성되어 있지 않으면 기본 에이전트로 대체됩니다.
|
||||
- `--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 <id>`: 단일 에이전트로 범위를 제한합니다(기본값: 기본 에이전트).
|
||||
- `--max-results <n>`: 반환되는 결과 수를 제한합니다.
|
||||
- `--min-score <n>`: 낮은 점수의 일치를 필터링합니다.
|
||||
- `--json`: JSON 결과를 인쇄합니다.
|
||||
- `--json`: JSON 결과를 표시합니다.
|
||||
|
||||
`memory promote`:
|
||||
|
||||
단기 메모리 promotion을 미리 보고 적용합니다.
|
||||
단기 메모리 승격을 미리 보고 적용합니다.
|
||||
|
||||
```bash
|
||||
openclaw memory promote [--apply] [--limit <n>] [--include-promoted]
|
||||
```
|
||||
|
||||
- `--apply` -- promotion을 `MEMORY.md`에 씁니다(기본값: 미리 보기만).
|
||||
- `--apply` -- 승격 항목을 `MEMORY.md`에 씁니다(기본값: 미리 보기만).
|
||||
- `--limit <n>` -- 표시할 후보 수를 제한합니다.
|
||||
- `--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 <id>`: 단일 에이전트로 범위를 제한합니다(기본값: 기본 에이전트).
|
||||
- `--limit <n>`: 반환/적용할 최대 후보 수입니다.
|
||||
- `--min-score <n>`: 최소 가중 promotion 점수입니다.
|
||||
- `--min-recall-count <n>`: 후보에 필요한 최소 recall 횟수입니다.
|
||||
- `--min-score <n>`: 최소 가중 승격 점수입니다.
|
||||
- `--min-recall-count <n>`: 후보에 필요한 최소 회상 수입니다.
|
||||
- `--min-unique-queries <n>`: 후보에 필요한 최소 고유 쿼리 수입니다.
|
||||
- `--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 <selector> [--agent <id>] [--include-promoted] [--json]
|
||||
@ -115,43 +115,43 @@ openclaw memory promote-explain <selector> [--agent <id>] [--include-promoted] [
|
||||
|
||||
- `<selector>`: 조회할 후보 키, 경로 조각 또는 스니펫 조각입니다.
|
||||
- `--agent <id>`: 단일 에이전트로 범위를 제한합니다(기본값: 기본 에이전트).
|
||||
- `--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 <id>] [--include-promoted] [--json]
|
||||
```
|
||||
|
||||
- `--agent <id>`: 단일 에이전트로 범위를 제한합니다(기본값: 기본 에이전트).
|
||||
- `--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/<phase>/YYYY-MM-DD.md`에 기록됩니다.
|
||||
- 순위 지정은 recall 빈도, 검색 관련성, 쿼리 다양성, 시간적 최신성, 날짜 간 통합, 파생 개념 풍부도라는 가중 신호를 사용합니다.
|
||||
- Promotion은 `MEMORY.md`에 쓰기 전에 라이브 일일 노트를 다시 읽으므로, 편집되거나 삭제된 단기 스니펫은 오래된 recall-store 스냅샷에서 promoted되지 않습니다.
|
||||
- 예약 및 수동 `memory promote` 실행은 CLI 임계값 오버라이드를 전달하지 않는 한 동일한 deep 단계 기본값을 공유합니다.
|
||||
- 자동 실행은 구성된 메모리 워크스페이스 전체로 fan out됩니다.
|
||||
- 사람이 읽을 수 있는 단계 출력과 일기 항목은 `DREAMS.md`(또는 기존 `dreams.md`)에 작성되며, 선택적으로 단계별 보고서가 `memory/dreaming/<phase>/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 <file-or-dir> --grounded`는 아무것도 쓰지 않고 과거 일일 노트에서 근거 기반 `What Happened`, `Reflections`, `Possible Lasting Updates`를 미리 봅니다.
|
||||
- `memory rem-backfill --path <file-or-dir>`는 UI 검토를 위해 되돌릴 수 있는 근거 기반 일기 항목을 `DREAMS.md`에 씁니다.
|
||||
- `memory rem-backfill --path <file-or-dir> --stage-short-term`은 근거 기반 지속 후보도 라이브 단기 promotion 저장소에 시드하여 일반 deep 단계가 순위를 매길 수 있게 합니다.
|
||||
- `memory rem-backfill --rollback`은 이전에 쓴 근거 기반 일기 항목을 제거하고, `memory rem-backfill --rollback-short-term`은 이전에 스테이징한 근거 기반 단기 후보를 제거합니다.
|
||||
- 전체 단계 설명 및 구성 참조는 [Dreaming](/ko/concepts/dreaming)을 참조하세요.
|
||||
- `memory rem-backfill --path <file-or-dir> --stage-short-term`는 일반 deep 단계가 순위를 매길 수 있도록 근거 기반 지속 후보를 라이브 단기 승격 저장소에도 시드합니다.
|
||||
- `memory rem-backfill --rollback`은 이전에 작성된 근거 기반 일기 항목을 제거하고, `memory rem-backfill --rollback-short-term`은 이전에 스테이징된 근거 기반 단기 후보를 제거합니다.
|
||||
- 전체 단계 설명과 구성 참조는 [Dreaming](/ko/concepts/dreaming)을 참조하세요.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
|
||||
@ -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 <gateway-host> --port 18789
|
||||
- `--port <port>`: Gateway WebSocket 포트(기본값: `18789`)
|
||||
- `--tls`: Gateway 연결에 TLS 사용
|
||||
- `--tls-fingerprint <sha256>`: 예상 TLS 인증서 지문(sha256)
|
||||
- `--node-id <id>`: node id 재정의(pairing 토큰 삭제)
|
||||
- `--display-name <name>`: node 표시 이름 재정의
|
||||
- `--node-id <id>`: Node ID 재정의(페어링 토큰 지움)
|
||||
- `--display-name <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 <gateway-host> --port 18789
|
||||
@ -89,10 +91,10 @@ openclaw node install --host <gateway-host> --port 18789
|
||||
- `--port <port>`: Gateway WebSocket 포트(기본값: `18789`)
|
||||
- `--tls`: Gateway 연결에 TLS 사용
|
||||
- `--tls-fingerprint <sha256>`: 예상 TLS 인증서 지문(sha256)
|
||||
- `--node-id <id>`: node id 재정의(pairing 토큰 삭제)
|
||||
- `--display-name <name>`: node 표시 이름 재정의
|
||||
- `--node-id <id>`: Node ID 재정의(페어링 토큰 지움)
|
||||
- `--display-name <name>`: Node 표시 이름 재정의
|
||||
- `--runtime <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 <requestId>
|
||||
```
|
||||
|
||||
엄격하게 제어되는 node 네트워크에서는 Gateway 운영자가 신뢰된 CIDR에서의 최초 node pairing 자동 승인을 명시적으로 opt-in할 수 있습니다:
|
||||
엄격하게 제어되는 Node 네트워크에서는 Gateway 운영자가 신뢰할 수 있는 CIDR에서 처음 발생하는 Node 페어링을 자동 승인하도록 명시적으로 옵트인할 수 있습니다.
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -134,23 +136,23 @@ openclaw devices approve <requestId>
|
||||
}
|
||||
```
|
||||
|
||||
이는 기본적으로 비활성화되어 있습니다. 요청된 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 <id|name|ip>`(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)
|
||||
|
||||
@ -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 <duration>`을 사용합니다(예: `24h`, `7d`).
|
||||
오래된 Gateway 소유 노드 페어링 레코드를 삭제하려면 `nodes remove --node <id|name|ip>`를 사용합니다.
|
||||
`nodes list`는 보류 중/페어링된 항목 테이블을 출력합니다. 페어링된 행에는 가장 최근 연결 경과 시간(Last Connect)이 포함됩니다.
|
||||
현재 연결된 Node만 표시하려면 `--connected`를 사용하세요. 특정 기간(예: `24h`, `7d`) 내에
|
||||
연결된 Node로 필터링하려면 `--last-connected <duration>`를 사용하세요.
|
||||
오래된 Gateway 소유 Node 페어링 레코드를 삭제하려면 `nodes remove --node <id|name|ip>`를 사용하세요.
|
||||
|
||||
승인 참고 사항:
|
||||
|
||||
- `openclaw nodes pending`에는 페어링 범위만 필요합니다.
|
||||
- `gateway.nodes.pairing.autoApproveCidrs`는 명시적으로 신뢰된 최초 `role: node` 기기 페어링에 대해서만
|
||||
보류 단계를 건너뛸 수 있습니다. 기본적으로 꺼져 있으며
|
||||
업그레이드를 승인하지 않습니다.
|
||||
- `gateway.nodes.pairing.autoApproveCidrs`는
|
||||
명시적으로 신뢰된 최초 `role: node` 디바이스 페어링에 대해서만 보류 단계를 건너뛸 수 있습니다. 기본적으로 꺼져 있으며
|
||||
업그레이드는 승인하지 않습니다.
|
||||
- `openclaw nodes approve <requestId>`는 보류 중인 요청에서 추가 범위 요구 사항을
|
||||
상속합니다.
|
||||
상속합니다:
|
||||
- 명령 없는 요청: 페어링만
|
||||
- 실행이 아닌 노드 명령: 페어링 + 쓰기
|
||||
- exec가 아닌 Node 명령: 페어링 + 쓰기
|
||||
- `system.run` / `system.run.prepare` / `system.which`: 페어링 + 관리자
|
||||
|
||||
## 호출
|
||||
@ -69,15 +69,15 @@ openclaw nodes invoke --node <id|name|ip> --command <command> --params <json>
|
||||
호출 플래그:
|
||||
|
||||
- `--params <json>`: JSON 객체 문자열(기본값 `{}`).
|
||||
- `--invoke-timeout <ms>`: 노드 호출 제한 시간(기본값 `15000`).
|
||||
- `--invoke-timeout <ms>`: Node 호출 제한 시간(기본값 `15000`).
|
||||
- `--idempotency-key <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)
|
||||
|
||||
@ -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 <code> --notify
|
||||
|
||||
- `[channel]`: 위치 인수 채널 ID
|
||||
- `--channel <channel>`: 명시적 채널 ID
|
||||
- `--account <accountId>`: 다중 계정 채널의 계정 ID
|
||||
- `--json`: 기계 판독 가능 출력
|
||||
- `--account <accountId>`: 다중 계정 채널용 계정 ID
|
||||
- `--json`: 기계가 읽을 수 있는 출력
|
||||
|
||||
참고:
|
||||
|
||||
- 페어링 가능 채널이 여러 개 구성된 경우 위치 인수로든 `--channel`로든 채널을 제공해야 합니다.
|
||||
- 채널 ID가 유효하기만 하면 확장 채널도 허용됩니다.
|
||||
- 페어링을 지원하는 채널이 여러 개 구성된 경우, 위치 인수로 또는 `--channel`을 사용해 채널을 제공해야 합니다.
|
||||
- 채널 ID가 유효하면 확장 채널도 허용됩니다.
|
||||
|
||||
## `pairing approve`
|
||||
|
||||
@ -56,27 +56,27 @@ openclaw pairing approve --channel telegram --account work <code> --notify
|
||||
|
||||
- `openclaw pairing approve <channel> <code>`
|
||||
- `openclaw pairing approve --channel <channel> <code>`
|
||||
- 정확히 하나의 페어링 가능 채널만 구성된 경우 `openclaw pairing approve <code>`
|
||||
- 페어링을 지원하는 채널이 정확히 하나만 구성된 경우 `openclaw pairing approve <code>`
|
||||
|
||||
옵션:
|
||||
|
||||
- `--channel <channel>`: 명시적 채널 ID
|
||||
- `--account <accountId>`: 다중 계정 채널의 계정 ID
|
||||
- `--notify`: 같은 채널에서 요청자에게 확인 메시지를 다시 보냅니다.
|
||||
- `--account <accountId>`: 다중 계정 채널용 계정 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 <channel>`로 전달합니다.
|
||||
- `pairing list`는 다중 계정 채널에 대해 `--account <accountId>`를 지원합니다.
|
||||
- 채널 입력: 위치 인수로 전달하거나(`pairing list telegram`) `--channel <channel>`을 사용합니다.
|
||||
- `pairing list`는 다중 계정 채널용 `--account <accountId>`를 지원합니다.
|
||||
- `pairing approve`는 `--account <accountId>`와 `--notify`를 지원합니다.
|
||||
- 페어링 가능 채널이 하나만 구성된 경우 `pairing approve <code>`가 허용됩니다.
|
||||
- 이 부트스트랩이 생기기 전에 발신자를 승인했다면 `openclaw doctor`를 실행하세요. 명령 소유자가 구성되지 않은 경우 경고하고, 이를 수정하기 위한 `openclaw config set commands.ownerAllowFrom ...` 명령을 보여 줍니다.
|
||||
- 페어링을 지원하는 채널이 하나만 구성된 경우 `pairing approve <code>`가 허용됩니다.
|
||||
- 이 부트스트랩이 생기기 전에 발신자를 승인했다면 `openclaw doctor`를 실행하세요. 명령 소유자가 구성되지 않았을 때 경고하고 이를 수정할 `openclaw config set commands.ownerAllowFrom ...` 명령을 표시합니다.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
|
||||
@ -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, 훅 팩, 호환 번들을 관리합니다.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Plugin 시스템" href="/ko/tools/plugin">
|
||||
Plugin 설치, 활성화, 문제 해결을 위한 최종 사용자 가이드입니다.
|
||||
Plugin 설치, 활성화 및 문제 해결을 위한 최종 사용자 가이드입니다.
|
||||
</Card>
|
||||
<Card title="Plugin 관리" href="/ko/plugins/manage-plugins">
|
||||
설치, 목록 보기, 업데이트, 제거, 게시에 대한 빠른 예시입니다.
|
||||
설치, 목록 표시, 업데이트, 제거 및 게시를 위한 빠른 예시입니다.
|
||||
</Card>
|
||||
<Card title="Plugin 번들" href="/ko/plugins/bundles">
|
||||
번들 호환성 모델입니다.
|
||||
@ -62,14 +62,18 @@ openclaw plugins marketplace list <marketplace>
|
||||
openclaw plugins marketplace list <marketplace> --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)을 참조하세요.
|
||||
|
||||
<Note>
|
||||
번들된 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)을 사용하세요.
|
||||
</Note>
|
||||
|
||||
네이티브 OpenClaw Plugin은 인라인 JSON Schema(`configSchema`, 비어 있더라도 포함)와 함께 `openclaw.plugin.json`을 제공해야 합니다. 호환 번들은 대신 자체 번들 매니페스트를 사용합니다.
|
||||
<Note>
|
||||
번들 Plugin은 OpenClaw와 함께 제공됩니다. 일부는 기본적으로 활성화되어 있으며(예: 번들 모델 공급자, 번들 음성 공급자, 번들 브라우저 Plugin), 나머지는 `plugins enable`이 필요합니다.
|
||||
|
||||
네이티브 OpenClaw Plugin은 인라인 JSON Schema(`configSchema`, 비어 있더라도)를 포함한 `openclaw.plugin.json`을 제공해야 합니다. 호환 번들은 대신 자체 번들 매니페스트를 사용합니다.
|
||||
|
||||
`plugins list`는 `Format: openclaw` 또는 `Format: bundle`을 표시합니다. 자세한 목록/정보 출력에는 번들 하위 유형(`codex`, `claude`, 또는 `cursor`)과 감지된 번들 기능도 표시됩니다.
|
||||
</Note>
|
||||
@ -94,84 +98,86 @@ openclaw plugins install <plugin> --marketplace https://github.com/<owner>/<repo
|
||||
```
|
||||
|
||||
<Warning>
|
||||
단순 패키지 이름은 출시 전환 기간 동안 기본적으로 npm에서 설치됩니다. ClawHub에는 `clawhub:<package>`를 사용하세요. Plugin 설치를 코드 실행처럼 다루세요. 고정된 버전을 사용하는 것을 권장합니다.
|
||||
출시 전환 기간에는 단순 패키지 이름이 기본적으로 npm에서 설치됩니다. ClawHub에는 `clawhub:<package>`를 사용하세요. Plugin 설치를 코드 실행처럼 취급하세요. 고정된 버전을 선호하세요.
|
||||
</Warning>
|
||||
|
||||
`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`를 사용하세요.
|
||||
|
||||
<Note>
|
||||
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`로 대체합니다.
|
||||
</Note>
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="구성 include 및 잘못된 구성 복구">
|
||||
`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 복구 경로입니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="--force와 재설치 및 업데이트">
|
||||
`--force`는 기존 설치 대상을 재사용하고 이미 설치된 Plugin 또는 훅 팩을 제자리에서 덮어씁니다. 새 로컬 경로, 아카이브, ClawHub 패키지 또는 npm 아티팩트에서 같은 ID를 의도적으로 다시 설치할 때 사용하세요. 이미 추적 중인 npm Plugin의 일반 업그레이드에는 `openclaw plugins update <id-or-npm-spec>`를 사용하는 것이 좋습니다.
|
||||
<Accordion title="--force 및 재설치와 업데이트 비교">
|
||||
`--force`는 기존 설치 대상을 재사용하고 이미 설치된 Plugin 또는 훅 팩을 제자리에서 덮어씁니다. 새 로컬 경로, 아카이브, ClawHub 패키지 또는 npm 아티팩트에서 같은 ID를 의도적으로 재설치할 때 사용하세요. 이미 추적 중인 npm Plugin의 일반 업그레이드에는 `openclaw plugins update <id-or-npm-spec>`를 선호하세요.
|
||||
|
||||
이미 설치된 Plugin ID에 대해 `plugins install`을 실행하면 OpenClaw가 중지하고 일반 업그레이드에는 `plugins update <id-or-npm-spec>`를, 현재 설치를 다른 소스로 정말 덮어쓰려는 경우에는 `plugins install <package> --force`를 사용하라고 안내합니다.
|
||||
이미 설치된 Plugin ID에 대해 `plugins install`을 실행하면 OpenClaw가 중지되고 일반 업그레이드에는 `plugins update <id-or-npm-spec>`를, 다른 소스에서 현재 설치를 정말로 덮어쓰려는 경우에는 `plugins install <package> --force`를 안내합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="--pin 범위">
|
||||
`--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`와 함께 지원되지 않습니다.
|
||||
</Accordion>
|
||||
<Accordion title="--dangerously-force-unsafe-install">
|
||||
`--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)의 게시자 단계를 사용하세요.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="훅 팩 및 npm spec">
|
||||
`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:<package>`를 사용하세요. 단순 패키지 spec도 출시 전환 기간 동안 npm에서 직접 설치됩니다.
|
||||
npm 해석을 명시하려면 `npm:<package>`를 사용하세요. 출시 전환 기간에는 단순 패키지 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`)을 사용하세요.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Git 저장소">
|
||||
git 저장소에서 직접 설치하려면 `git:<repo>`를 사용하세요. 지원되는 형식에는 `git:github.com/owner/repo`, `git:owner/repo`, 전체 `https://`, `ssh://`, `git://`, `file://`, 및 `git@host:owner/repo.git` 클론 URL이 포함됩니다. 설치 전에 브랜치, 태그 또는 커밋을 체크아웃하려면 `@<ref>` 또는 `#<ref>`를 추가하세요.
|
||||
<Accordion title="Git 리포지토리">
|
||||
git 리포지토리에서 직접 설치하려면 `git:<repo>`를 사용하세요. 지원되는 형식에는 `git:github.com/owner/repo`, `git:owner/repo`, 전체 `https://`, `ssh://`, `git://`, `file://`, `git@host:owner/repo.git` 클론 URL이 포함됩니다. 설치 전에 브랜치, 태그 또는 커밋을 체크아웃하려면 `@<ref>` 또는 `#<ref>`를 추가하세요.
|
||||
|
||||
Git 설치는 임시 디렉터리에 클론하고, 요청된 ref가 있으면 체크아웃한 다음, 일반 Plugin 디렉터리 설치 프로그램을 사용합니다. 즉 매니페스트 검증, 위험 코드 스캔, 패키지 관리자 설치 작업, 설치 기록이 npm 설치처럼 동작합니다. 기록된 git 설치에는 소스 URL/ref와 해석된 커밋이 포함되므로 `openclaw plugins update`가 나중에 소스를 다시 해석할 수 있습니다.
|
||||
Git 설치는 임시 디렉터리에 클론하고, 요청된 ref가 있으면 체크아웃한 다음, 일반 Plugin 디렉터리 설치 프로그램을 사용합니다. 즉 매니페스트 검증, 위험 코드 스캔, 패키지 관리자 설치 작업 및 설치 기록이 npm 설치처럼 동작합니다. 기록된 git 설치에는 소스 URL/ref와 해석된 커밋이 포함되므로 `openclaw plugins update`가 나중에 소스를 다시 해석할 수 있습니다.
|
||||
|
||||
git에서 설치한 후에는 `openclaw plugins inspect <id> --runtime --json`을 사용하여 gateway 메서드 및 CLI 명령 같은 런타임 등록을 확인하세요. Plugin이 `api.registerCli`로 CLI 루트를 등록했다면, 예를 들어 `openclaw demo-plugin ping`처럼 OpenClaw 루트 CLI를 통해 해당 명령을 직접 실행하세요.
|
||||
git에서 설치한 후 `openclaw plugins inspect <id> --runtime --json`을 사용하여 Gateway 메서드 및 CLI 명령 같은 런타임 등록을 확인하세요. Plugin이 `api.registerCli`로 CLI 루트를 등록한 경우, 예를 들어 `openclaw demo-plugin ping`처럼 OpenClaw 루트 CLI를 통해 해당 명령을 직접 실행하세요.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="아카이브">
|
||||
지원되는 아카이브: `.zip`, `.tgz`, `.tar.gz`, `.tar`. 네이티브 OpenClaw Plugin 아카이브는 추출된 Plugin 루트에 유효한 `openclaw.plugin.json`을 포함해야 합니다. `package.json`만 포함한 아카이브는 OpenClaw가 설치 기록을 쓰기 전에 거부됩니다.
|
||||
|
||||
파일이 npm-pack tarball이고, 레지스트리 설치에서 사용하는 것과 동일한 관리형 npm 루트 설치 경로를 테스트하려면 `npm-pack:<path.tgz>`를 사용하세요. 여기에는 `package-lock.json` 검증, hoisted 종속성 스캔, npm 설치 기록이 포함됩니다. 일반 아카이브 경로는 여전히 Plugin 확장 루트 아래에 로컬 아카이브로 설치됩니다.
|
||||
파일이 npm-pack tarball이고 레지스트리 설치에 사용되는 것과 동일한 관리형 npm 루트 설치 경로를 테스트하려면
|
||||
`npm-pack:<path.tgz>`를 사용하세요. 여기에는 `package-lock.json` 검증, 호이스팅된 종속성 스캔 및
|
||||
npm 설치 기록이 포함됩니다. 일반 아카이브 경로는 여전히 Plugin 확장 루트 아래에 로컬 아카이브로 설치됩니다.
|
||||
|
||||
Claude marketplace 설치도 지원됩니다.
|
||||
Claude 마켓플레이스 설치도 지원됩니다.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
ClawHub 설치는 명시적 `clawhub:<package>` locator를 사용합니다.
|
||||
ClawHub 설치는 명시적 `clawhub:<package>` 로케이터를 사용합니다.
|
||||
|
||||
```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 <marketplace-name>
|
||||
openclaw plugins install <plugin-name>@<marketplace-name>
|
||||
```
|
||||
|
||||
marketplace 소스를 명시적으로 전달하려면 `--marketplace`를 사용하세요.
|
||||
Marketplace 소스를 명시적으로 전달하려면 `--marketplace`를 사용하세요.
|
||||
|
||||
```bash
|
||||
openclaw plugins install <plugin-name> --marketplace <marketplace-name>
|
||||
@ -206,16 +212,16 @@ openclaw plugins install <plugin-name> --marketplace ./my-marketplace
|
||||
```
|
||||
|
||||
<Tabs>
|
||||
<Tab title="Marketplace sources">
|
||||
- `~/.claude/plugins/known_marketplaces.json`에 있는 Claude 알려진 마켓플레이스 이름
|
||||
- 로컬 마켓플레이스 루트 또는 `marketplace.json` 경로
|
||||
- `owner/repo` 같은 GitHub 저장소 축약형
|
||||
<Tab title="Marketplace 소스">
|
||||
- `~/.claude/plugins/known_marketplaces.json`의 Claude 알려진 Marketplace 이름
|
||||
- 로컬 Marketplace 루트 또는 `marketplace.json` 경로
|
||||
- `owner/repo` 같은 GitHub 저장소 약식 표기
|
||||
- `https://github.com/owner/repo` 같은 GitHub 저장소 URL
|
||||
- git URL
|
||||
|
||||
</Tab>
|
||||
<Tab title="Remote marketplace rules">
|
||||
GitHub 또는 git에서 로드된 원격 마켓플레이스의 경우 Plugin 항목은 복제된 마켓플레이스 저장소 안에 있어야 합니다. OpenClaw는 해당 저장소의 상대 경로 소스를 허용하고, 원격 매니페스트의 HTTP(S), 절대 경로, git, GitHub 및 기타 비경로 Plugin 소스를 거부합니다.
|
||||
<Tab title="원격 Marketplace 규칙">
|
||||
GitHub 또는 git에서 로드되는 원격 Marketplace의 경우, Plugin 항목은 복제된 Marketplace 저장소 안에 있어야 합니다. OpenClaw는 해당 저장소의 상대 경로 소스를 허용하고, 원격 매니페스트의 HTTP(S), 절대 경로, git, GitHub 및 기타 경로가 아닌 Plugin 소스를 거부합니다.
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
@ -227,7 +233,7 @@ openclaw plugins install <plugin-name> --marketplace ./my-marketplace
|
||||
- Cursor 호환 번들(`.cursor-plugin/plugin.json`)
|
||||
|
||||
<Note>
|
||||
호환 번들은 일반 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에 표시되지만 아직 런타임 실행에 연결되어 있지는 않습니다.
|
||||
</Note>
|
||||
|
||||
### 목록
|
||||
@ -246,45 +252,45 @@ openclaw plugins search <query> --json
|
||||
활성화된 Plugin만 표시합니다.
|
||||
</ParamField>
|
||||
<ParamField path="--verbose" type="boolean">
|
||||
표 보기에서 Plugin별 소스/출처/버전/활성화 메타데이터 상세 줄로 전환합니다.
|
||||
표 보기에서 Plugin별 소스/출처/버전/활성화 메타데이터가 포함된 상세 줄로 전환합니다.
|
||||
</ParamField>
|
||||
<ParamField path="--json" type="boolean">
|
||||
기계가 읽을 수 있는 인벤터리와 레지스트리 진단 및 패키지 의존성 설치 상태입니다.
|
||||
레지스트리 진단 및 패키지 의존성 설치 상태가 포함된 기계 판독 가능 인벤토리입니다.
|
||||
</ParamField>
|
||||
|
||||
<Note>
|
||||
`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하거나, 패키지 관리자를 실행하거나, 누락된 의존성을 복구하지 않습니다.
|
||||
</Note>
|
||||
|
||||
`plugins search`는 원격 ClawHub 카탈로그 조회입니다. 로컬 상태를 검사하거나, 구성을 변경하거나, 패키지를 설치하거나, Plugin 런타임 코드를 로드하지 않습니다. 검색 결과에는 ClawHub 패키지 이름, 패밀리, 채널, 버전, 요약 및 `openclaw plugins install clawhub:<package>` 같은 설치 힌트가 포함됩니다.
|
||||
`plugins search`는 원격 ClawHub 카탈로그 조회입니다. 로컬 상태를 검사하거나, config를 변경하거나, 패키지를 설치하거나, Plugin 런타임 코드를 로드하지 않습니다. 검색 결과에는 ClawHub 패키지 이름, family, channel, version, summary 및 `openclaw plugins install clawhub:<package>` 같은 설치 힌트가 포함됩니다.
|
||||
|
||||
패키징된 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 <id> --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.<id>.hooks.allowConversationAccess=true`가 필요합니다.
|
||||
- `openclaw plugins inspect <id> --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.<id>.hooks.allowConversationAccess=true`가 필요합니다.
|
||||
|
||||
로컬 디렉터리 복사를 피하려면 `--link`를 사용하세요(`plugins.load.paths`에 추가됨).
|
||||
로컬 디렉터리를 복사하지 않으려면 `--link`를 사용하세요(`plugins.load.paths`에 추가됨).
|
||||
|
||||
```bash
|
||||
openclaw plugins install -l ./my-plugin
|
||||
```
|
||||
|
||||
<Note>
|
||||
링크된 설치는 관리되는 설치 대상 위에 복사하는 대신 소스 경로를 재사용하므로 `--force`는 `--link`와 함께 지원되지 않습니다.
|
||||
연결된 설치는 관리형 설치 대상 위에 복사하는 대신 소스 경로를 재사용하므로 `--force`는 `--link`와 함께 지원되지 않습니다.
|
||||
|
||||
npm 설치에서 `--pin`을 사용하면 기본 동작은 고정하지 않은 상태로 유지하면서, 해석된 정확한 spec(`name@version`)을 관리되는 Plugin 인덱스에 저장합니다.
|
||||
npm 설치에서 `--pin`을 사용하면 기본 동작은 고정하지 않은 상태로 유지하면서, 해결된 정확한 사양(`name@version`)을 관리형 Plugin 인덱스에 저장합니다.
|
||||
</Note>
|
||||
|
||||
### 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 <id> --dry-run
|
||||
openclaw plugins uninstall <id> --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`로 재설정됩니다.
|
||||
|
||||
<Note>
|
||||
`--keep-config`는 `--keep-files`의 사용 중단된 별칭으로 지원됩니다.
|
||||
`--keep-config`는 `--keep-files`의 사용 중단된 alias로 지원됩니다.
|
||||
</Note>
|
||||
|
||||
### 업데이트
|
||||
@ -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 설치에 적용됩니다.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Resolving plugin id vs npm spec">
|
||||
Plugin id를 전달하면 OpenClaw는 해당 Plugin에 기록된 설치 spec을 재사용합니다. 즉, 이전에 저장된 `@beta` 같은 dist-tag와 정확히 고정된 버전은 이후 `update <id>` 실행에서도 계속 사용됩니다.
|
||||
<Accordion title="Plugin id와 npm spec 해석">
|
||||
Plugin id를 전달하면 OpenClaw는 해당 Plugin에 대해 기록된 설치 사양을 재사용합니다. 즉 이전에 저장된 `@beta` 같은 dist-tag와 정확히 고정된 버전은 이후 `update <id>` 실행에서도 계속 사용됩니다.
|
||||
|
||||
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이 정확한 버전에 고정되어 있었고 이를 레지스트리의 기본 릴리스 라인으로 되돌리고 싶을 때 사용하세요.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Beta channel updates">
|
||||
`openclaw plugins update`는 새 spec을 전달하지 않는 한 추적된 Plugin spec을 재사용합니다. `openclaw update`는 추가로 활성 OpenClaw 업데이트 채널을 알고 있습니다. 베타 채널에서는 기본 라인 npm 및 ClawHub Plugin 레코드가 먼저 `@beta`를 시도한 다음, Plugin 베타 릴리스가 없으면 기록된 default/latest spec으로 폴백합니다. 정확한 버전과 명시적 태그는 해당 선택자에 고정된 상태를 유지합니다.
|
||||
<Accordion title="Beta 채널 업데이트">
|
||||
`openclaw plugins update`는 새 사양을 전달하지 않는 한 추적 중인 Plugin 사양을 재사용합니다. `openclaw update`는 추가로 활성 OpenClaw 업데이트 채널을 알고 있습니다. beta 채널에서는 기본 라인의 npm 및 ClawHub Plugin 기록이 먼저 `@beta`를 시도한 뒤, Plugin beta 릴리스가 없으면 기록된 default/latest 사양으로 fallback합니다. 정확한 버전과 명시적 태그는 해당 선택자에 고정된 상태로 유지됩니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Version checks and integrity drift">
|
||||
라이브 npm 업데이트 전에 OpenClaw는 설치된 패키지 버전을 npm 레지스트리 메타데이터와 비교합니다. 설치된 버전과 기록된 아티팩트 식별자가 이미 해석된 대상과 일치하면 다운로드, 재설치 또는 `openclaw.json` 재작성 없이 업데이트를 건너뜁니다.
|
||||
<Accordion title="버전 확인 및 무결성 drift">
|
||||
라이브 npm 업데이트 전에 OpenClaw는 설치된 패키지 버전을 npm 레지스트리 메타데이터와 비교합니다. 설치된 버전과 기록된 아티팩트 식별자가 이미 해결된 대상과 일치하면 다운로드, 재설치 또는 `openclaw.json` 재작성 없이 업데이트를 건너뜁니다.
|
||||
|
||||
저장된 무결성 해시가 있고 가져온 아티팩트 해시가 변경되면 OpenClaw는 이를 npm 아티팩트 드리프트로 처리합니다. 대화형 `openclaw plugins update` 명령은 예상 해시와 실제 해시를 출력하고 계속하기 전에 확인을 요청합니다. 비대화형 업데이트 헬퍼는 호출자가 명시적 계속 정책을 제공하지 않는 한 닫힌 상태로 실패합니다.
|
||||
저장된 무결성 해시가 있고 가져온 아티팩트 해시가 변경되면 OpenClaw는 이를 npm 아티팩트 drift로 처리합니다. 대화형 `openclaw plugins update` 명령은 예상 해시와 실제 해시를 출력하고 계속 진행하기 전에 확인을 요청합니다. 비대화형 업데이트 helper는 호출자가 명시적 계속 진행 정책을 제공하지 않는 한 fail closed로 실패합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="--dangerously-force-unsafe-install on update">
|
||||
`--dangerously-force-unsafe-install`는 Plugin 업데이트 중 내장 위험 코드 스캔의 오탐에 대한 비상 우회로 `plugins update`에서도 사용할 수 있습니다. 그래도 Plugin `before_install` 정책 차단이나 스캔 실패 차단은 우회하지 않으며, hook-pack 업데이트가 아니라 Plugin 업데이트에만 적용됩니다.
|
||||
<Accordion title="업데이트의 --dangerously-force-unsafe-install">
|
||||
`--dangerously-force-unsafe-install`은 Plugin 업데이트 중 내장 위험 코드 scan의 false positive에 대한 break-glass override로 `plugins update`에서도 사용할 수 있습니다. 그래도 Plugin `before_install` 정책 차단이나 scan 실패 차단을 우회하지 않으며, hook-pack 업데이트가 아니라 Plugin 업데이트에만 적용됩니다.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
@ -344,34 +350,34 @@ openclaw plugins inspect <id> --runtime
|
||||
openclaw plugins inspect <id> --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 <command> ...`로 실행하세요. 예를 들어 `demo-git`을 등록하는 Plugin은 `openclaw demo-git ping`으로 확인할 수 있습니다.
|
||||
Plugin 소유 CLI 명령은 루트 `openclaw` command group으로 설치됩니다. `inspect --runtime`이 `cliCommands` 아래에 명령을 표시한 뒤에는 `openclaw <command> ...`로 실행하세요. 예를 들어 `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)를 참조하세요.
|
||||
|
||||
<Note>
|
||||
`--json` 플래그는 스크립팅과 감사에 적합한 기계가 읽을 수 있는 보고서를 출력합니다. `inspect --all`은 shape, capability 종류, 호환성 알림, 번들 기능, 훅 요약 열이 포함된 전체 플릿 표를 렌더링합니다. `info`는 `inspect`의 별칭입니다.
|
||||
`--json` 플래그는 스크립팅과 감사에 적합한 기계 판독 가능 보고서를 출력합니다. `inspect --all`은 형태, 기능 종류, 호환성 알림, 번들 기능, 훅 요약 열을 포함한 전체 플릿 표를 렌더링합니다. `info`는 `inspect`의 별칭입니다.
|
||||
</Note>
|
||||
|
||||
### Doctor
|
||||
### 진단
|
||||
|
||||
```bash
|
||||
openclaw plugins doctor
|
||||
```
|
||||
|
||||
`doctor`는 Plugin 로드 오류, 매니페스트/검색 진단 및 호환성 알림을 보고합니다. 모든 것이 깨끗하면 `No plugin issues detected.`를 출력합니다.
|
||||
`doctor`는 Plugin 로드 오류, 매니페스트/디스커버리 진단, 호환성 알림을 보고합니다. 모든 것이 정상이면 `No plugin issues detected.`를 출력합니다.
|
||||
|
||||
구성된 Plugin이 디스크에 있지만 로더의 경로 안전성 검사에 의해 차단된 경우, 구성 검증은 Plugin 항목을 유지하고 `present but blocked`로 보고합니다. `plugins.entries.<id>` 또는 `plugins.allow` 구성을 제거하는 대신, 경로 소유권이나 world-writable 권한 같은 앞선 차단된 Plugin 진단을 수정하세요.
|
||||
구성된 Plugin이 디스크에 있지만 로더의 경로 안전성 검사에 의해 차단된 경우, 구성 검증은 Plugin 항목을 유지하고 이를 `present but blocked`로 보고합니다. `plugins.entries.<id>` 또는 `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는 해당 오래된 패키지를 제거하고 레지스트리를 다시 빌드하여 시작 시 번들 매니페스트 기준으로 검증되도록 합니다.
|
||||
|
||||
<Warning>
|
||||
`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 폴백은 마이그레이션이 배포되는 동안의 긴급 시작 복구용으로만 사용하세요.
|
||||
</Warning>
|
||||
|
||||
### 마켓플레이스
|
||||
@ -398,9 +404,9 @@ openclaw plugins marketplace list <source>
|
||||
openclaw plugins marketplace list <source> --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)
|
||||
|
||||
@ -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 제거 또는 다시 작성
|
||||
|
||||
## 관련 항목
|
||||
|
||||
|
||||
@ -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`과 에이전트 작업 공간을 초기화합니다.
|
||||
|
||||
<Note>
|
||||
`openclaw setup`은 변경 가능한 구성 설치용입니다. Nix 모드(`OPENCLAW_NIX_MODE=1`)에서는 구성 파일이 Nix에서 관리되므로 OpenClaw가 설정 쓰기를 거부합니다. 에이전트는 공식 [nix-openclaw 빠른 시작](https://github.com/openclaw/nix-openclaw#quick-start) 또는 다른 Nix 패키지에 해당하는 소스 구성을 사용해야 합니다.
|
||||
</Note>
|
||||
|
||||
관련 항목:
|
||||
|
||||
- 시작하기: [시작하기](/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 <dir>`: 에이전트 작업 영역 디렉터리(`agents.defaults.workspace`로 저장됨)
|
||||
- `--workspace <dir>`: 에이전트 작업 공간 디렉터리(`agents.defaults.workspace`로 저장됨)
|
||||
- `--wizard`: 온보딩 실행
|
||||
- `--non-interactive`: 프롬프트 없이 온보딩 실행
|
||||
- `--mode <local|remote>`: 온보딩 모드
|
||||
@ -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)을 사용하세요.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
@ -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 <stable|beta|dev>`: 업데이트 채널을 설정합니다(git + npm, config에 유지됨).
|
||||
- `--tag <dist-tag|version|spec>`: 이번 업데이트에만 패키지 대상을 재정의합니다. 패키지 설치의 경우 `main`은 `github:openclaw/openclaw#main`에 매핑됩니다.
|
||||
- `--dry-run`: config 쓰기, 설치, plugins 동기화 또는 재시작 없이 계획된 업데이트 작업(채널/태그/대상/재시작 흐름)을 미리 봅니다.
|
||||
- `--json`: 손상되었거나 로드할 수 없는 관리형 plugins가 core 업데이트 성공 후 복구를 필요로 할 때의
|
||||
`postUpdate.plugins.warnings`와, 업데이트 후 Plugin 동기화 중 npm Plugin 아티팩트 드리프트가 감지될 때의
|
||||
`postUpdate.plugins.integrityDrifts`를 포함하여, 기계가 읽을 수 있는 `UpdateRunResult` JSON을 출력합니다.
|
||||
- `--timeout <seconds>`: 단계별 제한 시간(기본값은 1800초).
|
||||
- `--no-restart`: 업데이트가 성공한 뒤 Gateway 서비스를 다시 시작하지 않습니다. Gateway를 다시 시작하는 패키지 관리자 업데이트는 명령이 성공하기 전에 다시 시작된 서비스가 예상 업데이트 버전을 보고하는지 확인합니다.
|
||||
- `--channel <stable|beta|dev>`: 업데이트 채널을 설정합니다(git + npm, 구성에 유지됨).
|
||||
- `--tag <dist-tag|version|spec>`: 이 업데이트에 한해 패키지 대상을 재정의합니다. 패키지 설치의 경우 `main`은 `github:openclaw/openclaw#main`에 매핑됩니다.
|
||||
- `--dry-run`: 구성 쓰기, 설치, Plugin 동기화 또는 다시 시작 없이 계획된 업데이트 작업(채널/태그/대상/다시 시작 흐름)을 미리 봅니다.
|
||||
- `--json`: 손상되었거나 언로드할 수 없는 관리형 Plugin이 코어 업데이트 성공 후 복구가 필요할 때의 `postUpdate.plugins.warnings`와 업데이트 후 Plugin 동기화 중 npm Plugin 아티팩트 드리프트가 감지될 때의 `postUpdate.plugins.integrityDrifts`를 포함해, 기계가 읽을 수 있는 `UpdateRunResult` JSON을 출력합니다.
|
||||
- `--timeout <seconds>`: 단계별 제한 시간입니다(기본값은 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)을 참고하세요.
|
||||
|
||||
<Note>
|
||||
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`은 읽기 전용으로 유지됩니다.
|
||||
</Note>
|
||||
|
||||
<Warning>
|
||||
다운그레이드는 이전 버전이 구성을 손상시킬 수 있으므로 확인이 필요합니다.
|
||||
이전 버전은 구성을 손상시킬 수 있으므로 다운그레이드에는 확인이 필요합니다.
|
||||
</Warning>
|
||||
|
||||
## `update status`
|
||||
|
||||
활성 업데이트 채널 + git 태그/브랜치/SHA(소스 checkout의 경우)와 업데이트 사용 가능 여부를 표시합니다.
|
||||
활성 업데이트 채널과 git 태그/브랜치/SHA(소스 체크아웃의 경우), 그리고 업데이트 가능 여부를 표시합니다.
|
||||
|
||||
```bash
|
||||
openclaw update status
|
||||
@ -75,125 +71,91 @@ openclaw update status --timeout 10
|
||||
옵션:
|
||||
|
||||
- `--json`: 기계가 읽을 수 있는 상태 JSON을 출력합니다.
|
||||
- `--timeout <seconds>`: 검사 제한 시간(기본값은 3초).
|
||||
- `--timeout <seconds>`: 검사 제한 시간입니다(기본값은 3초).
|
||||
|
||||
## `update wizard`
|
||||
|
||||
업데이트 채널을 선택하고 업데이트 후 Gateway를 다시 시작할지 확인하는 대화형 흐름입니다
|
||||
(기본값은 재시작). git checkout 없이 `dev`를 선택하면 새로 만들도록 제안합니다.
|
||||
업데이트 채널을 선택하고 업데이트 후 Gateway를 다시 시작할지 확인하는 대화형 흐름입니다(기본값은 다시 시작). git 체크아웃 없이 `dev`를 선택하면 하나를 만들도록 제안합니다.
|
||||
|
||||
옵션:
|
||||
|
||||
- `--timeout <seconds>`: 각 업데이트 단계의 제한 시간(기본값 `1800`)
|
||||
- `--timeout <seconds>`: 각 업데이트 단계의 제한 시간입니다(기본값 `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를 수행합니다.
|
||||
|
||||
### 업데이트 단계
|
||||
|
||||
<Steps>
|
||||
<Step title="깨끗한 worktree 확인">
|
||||
<Step title="Verify clean worktree">
|
||||
커밋되지 않은 변경 사항이 없어야 합니다.
|
||||
</Step>
|
||||
<Step title="채널 전환">
|
||||
<Step title="Switch channel">
|
||||
선택한 채널(태그 또는 브랜치)로 전환합니다.
|
||||
</Step>
|
||||
<Step title="업스트림 가져오기">
|
||||
<Step title="Fetch upstream">
|
||||
Dev 전용입니다.
|
||||
</Step>
|
||||
<Step title="사전 빌드(dev 전용)">
|
||||
임시 worktree에서 TypeScript 빌드를 실행합니다. tip이 실패하면 최대 10개 커밋까지 거슬러 올라가 가장 최신의 빌드 가능한 커밋을 찾습니다. 이 사전 검사 중 lint도 실행하려면 `OPENCLAW_UPDATE_PREFLIGHT_LINT=1`을 설정하세요. 사용자 업데이트 호스트는 CI runner보다 작은 경우가 많으므로 lint는 제한된 직렬 모드로 실행됩니다.
|
||||
<Step title="Preflight build (dev only)">
|
||||
임시 worktree에서 TypeScript 빌드를 실행합니다. 팁이 실패하면 최대 10개 커밋까지 뒤로 이동해 빌드 가능한 최신 커밋을 찾습니다. 이 사전 검사 중 lint도 실행하려면 `OPENCLAW_UPDATE_PREFLIGHT_LINT=1`을 설정하세요. 사용자 업데이트 호스트는 CI 러너보다 작은 경우가 많기 때문에 lint는 제한된 직렬 모드로 실행됩니다.
|
||||
</Step>
|
||||
<Step title="Rebase">
|
||||
선택한 커밋 위로 rebase합니다(dev 전용).
|
||||
</Step>
|
||||
<Step title="의존성 설치">
|
||||
repo 패키지 관리자를 사용합니다. pnpm checkout의 경우, 업데이트 프로그램은 pnpm workspace 안에서 `npm run build`를 실행하는 대신 필요할 때 `pnpm`을 부트스트랩합니다(`corepack`을 먼저 사용한 다음 임시 `npm install pnpm@10` 대체 경로 사용).
|
||||
<Step title="Install dependencies">
|
||||
저장소 패키지 관리자를 사용합니다. pnpm 체크아웃의 경우 업데이트 프로그램은 pnpm workspace 내부에서 `npm run build`를 실행하는 대신, 필요할 때 `pnpm`을 부트스트랩합니다(먼저 `corepack`을 사용하고, 이후 임시 `npm install pnpm@10` 대체 경로 사용).
|
||||
</Step>
|
||||
<Step title="Control UI 빌드">
|
||||
Gateway와 Control UI를 빌드합니다.
|
||||
<Step title="Build Control UI">
|
||||
Gateway와 제어 UI를 빌드합니다.
|
||||
</Step>
|
||||
<Step title="doctor 실행">
|
||||
`openclaw doctor`를 최종 안전 업데이트 검사로 실행합니다.
|
||||
<Step title="Run doctor">
|
||||
최종 안전 업데이트 검사로 `openclaw doctor`를 실행합니다.
|
||||
</Step>
|
||||
<Step title="plugins 동기화">
|
||||
plugins를 활성 채널에 동기화합니다. Dev는 bundled plugins를 사용하고, stable 및 beta는 npm을 사용합니다. 추적 중인 Plugin 설치를 업데이트합니다.
|
||||
<Step title="Sync plugins">
|
||||
Plugin을 활성 채널에 동기화합니다. Dev는 번들 Plugin을 사용하고, stable 및 beta는 npm을 사용합니다. 추적 중인 Plugin 설치를 업데이트합니다.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
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가 대체합니다. 정확한 버전과 명시적 태그는 다시 작성되지 않습니다.
|
||||
|
||||
<Warning>
|
||||
정확히 고정된 npm Plugin 업데이트가 저장된 설치 레코드와 무결성이 다른 아티팩트로 해석되면, `openclaw update`는 해당 Plugin 아티팩트 업데이트를 설치하는 대신 중단합니다. 새 아티팩트를 신뢰할 수 있는지 확인한 후에만 Plugin을 명시적으로 다시 설치하거나 업데이트하세요.
|
||||
정확히 고정된 npm Plugin 업데이트가 저장된 설치 레코드와 무결성이 다른 아티팩트로 확인되면, `openclaw update`는 해당 Plugin 아티팩트 업데이트를 설치하는 대신 중단합니다. 새 아티팩트를 신뢰할 수 있다고 확인한 뒤에만 Plugin을 명시적으로 다시 설치하거나 업데이트하세요.
|
||||
</Warning>
|
||||
|
||||
<Note>
|
||||
관리형 Plugin에 범위가 한정된 업데이트 후 Plugin 동기화 실패는 core 업데이트가 성공한 후 경고로 보고됩니다. JSON 결과는 최상위 업데이트 `status: "ok"`를 유지하고, `openclaw doctor --fix` 및 `openclaw plugins inspect <id> --runtime --json` 안내와 함께 `postUpdate.plugins.status: "warning"`을 보고합니다. 예기치 않은 업데이트 프로그램 또는 동기화 예외는 여전히 업데이트 결과를 실패로 처리합니다. Plugin 설치 또는 업데이트 오류를 수정한 다음 `openclaw doctor --fix` 또는 `openclaw update`를 다시 실행하세요.
|
||||
관리형 Plugin으로 범위가 한정된 업데이트 후 Plugin 동기화 실패는 코어 업데이트가 성공한 뒤 경고로 보고됩니다. JSON 결과는 최상위 업데이트 `status: "ok"`를 유지하고, `openclaw doctor --fix` 및 `openclaw plugins inspect <id> --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`를 시도하는 대신, 패키지 관리자별 오류와 함께 조기에 중지합니다.
|
||||
</Note>
|
||||
|
||||
## `--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)
|
||||
|
||||
@ -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.<channel>.streaming`)를 스트리밍할 수 있습니다.
|
||||
**채널 참고:** `*.blockStreaming`이 명시적으로 `true`로 설정되지 않으면 블록 스트리밍은 **꺼져 있습니다**. 채널은 블록 답장 없이 실시간 미리보기(`channels.<channel>.streaming`)를 스트리밍할 수 있습니다.
|
||||
|
||||
설정 위치 알림: `blockStreaming*` 기본값은 루트 설정이 아니라 `agents.defaults` 아래에 있습니다.
|
||||
|
||||
## 미리보기 스트리밍 모드
|
||||
|
||||
표준 키: `channels.<channel>.streaming`
|
||||
정식 키: `channels.<channel>.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) - 채널별 스트리밍 지원
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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
|
||||
---
|
||||
|
||||
<Warning>
|
||||
TCP 브리지는 **제거되었습니다**. 현재 OpenClaw 빌드에는 브리지 리스너가 포함되지 않으며 `bridge.*` 구성 키도 더 이상 스키마에 존재하지 않습니다. 이 페이지는 역사적 참고용으로만 유지됩니다. 모든 node/operator 클라이언트에는 [Gateway Protocol](/ko/gateway/protocol)을 사용하세요.
|
||||
TCP 브리지는 **제거되었습니다**. 현재 OpenClaw 빌드는 브리지 리스너를 제공하지 않으며 `bridge.*` 구성 키는 더 이상 스키마에 없습니다. 이 페이지는 역사적 참고용으로만 유지됩니다. 모든 노드/운영자 클라이언트에는 [Gateway 프로토콜](/ko/gateway/protocol)을 사용하세요.
|
||||
</Warning>
|
||||
|
||||
## 존재했던 이유
|
||||
|
||||
- **보안 경계**: 브리지는 전체 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)
|
||||
|
||||
@ -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 '<json>' --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 '<json>' --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|auto|pi>`는 해당 프로세스의 `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/<model>"].params.thinking`을 직접 정의하지 않는 한 thinking 모드를 자동으로 활성화합니다.
|
||||
Z.AI 모델은 도구 호출 스트리밍을 위해 기본적으로 `tool_stream`을 활성화합니다. 비활성화하려면 `agents.defaults.models["zai/<model>"].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으로 보내기 전에 인메모리 컨텍스트에서 **오래된 도구
|
||||
<Accordion title="cache-ttl 모드 동작">
|
||||
|
||||
- `mode: "cache-ttl"`은 가지치기 패스를 활성화합니다.
|
||||
- `ttl`은 가지치기를 다시 실행할 수 있는 빈도(마지막 캐시 터치 이후)를 제어합니다.
|
||||
- 가지치기는 먼저 과도하게 큰 도구 결과를 소프트 트림한 뒤, 필요한 경우 더 오래된 도구 결과를 하드 클리어합니다.
|
||||
- `ttl`은 가지치기를 다시 실행할 수 있는 빈도를 제어합니다(마지막 캐시 터치 이후).
|
||||
- 가지치기는 먼저 너무 큰 도구 결과를 소프트 트림한 다음, 필요하면 더 오래된 도구 결과를 하드 클리어합니다.
|
||||
|
||||
**소프트 트림**은 시작 부분과 끝부분을 유지하고 중간에 `...`을 삽입합니다.
|
||||
**소프트 트림**은 시작 부분과 끝 부분을 유지하고 중간에 `...`을 삽입합니다.
|
||||
|
||||
**하드 클리어**는 전체 도구 결과를 자리 표시자로 대체합니다.
|
||||
**하드 클리어**는 전체 도구 결과를 자리표시자로 대체합니다.
|
||||
|
||||
참고:
|
||||
|
||||
- 이미지 블록은 절대 트림되거나 클리어되지 않습니다.
|
||||
- 비율은 문자 기반(근사치)이며 정확한 토큰 수가 아닙니다.
|
||||
- 어시스턴트 메시지가 `keepLastAssistants`보다 적으면 가지치기를 건너뜁니다.
|
||||
- 이미지 블록은 절대 트림/클리어되지 않습니다.
|
||||
- 비율은 정확한 토큰 수가 아니라 문자 기반(근사값)입니다.
|
||||
- `keepLastAssistants`보다 assistant 메시지가 적으면 가지치기를 건너뜁니다.
|
||||
|
||||
</Accordion>
|
||||
|
||||
동작 세부 정보는 [세션 가지치기](/ko/concepts/session-pruning)를 참고하세요.
|
||||
동작 세부 정보는 [세션 가지치기](/ko/concepts/session-pruning)를 참조하세요.
|
||||
|
||||
### 블록 스트리밍
|
||||
|
||||
@ -660,9 +663,9 @@ LLM으로 보내기 전에 인메모리 컨텍스트에서 **오래된 도구
|
||||
|
||||
- Telegram이 아닌 채널은 블록 응답을 활성화하려면 명시적으로 `*.blockStreaming: true`가 필요합니다.
|
||||
- 채널 재정의: `channels.<channel>.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으로 보내기 전에 인메모리 컨텍스트에서 **오래된 도구
|
||||
|
||||
<Accordion title="Sandbox details">
|
||||
|
||||
**백엔드:**
|
||||
**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:<id>"`는
|
||||
`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=<derived from OPENCLAW_BROWSER_CDP_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=<N>`으로 변경할 수 있습니다. Chromium의
|
||||
기본 프로세스 제한을 사용하려면 `0`으로 설정하세요.
|
||||
- `noSandbox`가 활성화된 경우 `--no-sandbox`도 추가됩니다.
|
||||
- 기본값은 컨테이너 이미지 기준입니다. 컨테이너 기본값을 변경하려면 사용자 지정
|
||||
- `noSandbox`가 활성화된 경우 `--no-sandbox`가 추가됩니다.
|
||||
- 기본값은 컨테이너 이미지 기준선입니다. 컨테이너 기본값을 변경하려면 사용자 지정
|
||||
엔트리포인트가 있는 사용자 지정 브라우저 이미지를 사용하세요.
|
||||
|
||||
</Accordion>
|
||||
|
||||
브라우저 샌드박싱과 `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`)로 확인하며, 위의 라우트 바인딩 계층 순서를 사용하지 않습니다.
|
||||
|
||||
### 에이전트별 접근 프로필
|
||||
### 에이전트별 액세스 프로필
|
||||
|
||||
<Accordion title="전체 접근 권한(샌드박스 없음)">
|
||||
<Accordion title="전체 액세스(샌드박스 없음)">
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -1064,7 +1067,7 @@ scripts/sandbox-browser-setup.sh # optional browser image
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="읽기 전용 도구 + 워크스페이스">
|
||||
<Accordion title="읽기 전용 도구 + 작업 공간">
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -1093,7 +1096,7 @@ scripts/sandbox-browser-setup.sh # optional browser image
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="파일 시스템 액세스 없음(메시징 전용)">
|
||||
<Accordion title="파일 시스템 접근 없음(메시징 전용)">
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -1139,7 +1142,7 @@ scripts/sandbox-browser-setup.sh # optional browser image
|
||||
|
||||
</Accordion>
|
||||
|
||||
우선순위 세부 정보는 [멀티 에이전트 샌드박스 및 도구](/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.<timestamp>` 대화 기록 아카이브의 보존 기간입니다. 기본값은 `pruneAfter`이며, 비활성화하려면 `false`로 설정합니다.
|
||||
- `maxDiskBytes`: 선택 사항인 세션 디렉터리 디스크 예산입니다. `warn` 모드에서는 경고를 기록하고, `enforce` 모드에서는 가장 오래된 아티팩트/세션부터 제거합니다.
|
||||
- `highWaterBytes`: 예산 정리 후 선택 사항인 목표값입니다. 기본값은 `maxDiskBytes`의 `80%`입니다.
|
||||
- `resetArchiveRetention`: `*.reset.<timestamp>` 트랜스크립트 아카이브의 보존 기간입니다. 기본값은 `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"`입니다.
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -1255,36 +1258,36 @@ scripts/sandbox-browser-setup.sh # optional browser image
|
||||
|
||||
### 응답 접두사
|
||||
|
||||
채널/계정별 재정의: `channels.<channel>.responsePrefix`, `channels.<channel>.accounts.<id>.responsePrefix`.
|
||||
채널별/계정별 재정의: `channels.<channel>.responsePrefix`, `channels.<channel>.accounts.<id>.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.<channel>.ackReaction`, `channels.<channel>.accounts.<id>.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.<provider>`로 자동 마이그레이션됩니다.
|
||||
- 음성 ID는 `ELEVENLABS_VOICE_ID` 또는 `SAG_VOICE_ID`로 대체됩니다.
|
||||
- 기존 평면 Talk 키(`talk.voiceId`, `talk.voiceAliases`, `talk.modelId`, `talk.outputFormat`, `talk.apiKey`)는 호환성 전용입니다. 유지된 config를 `talk.providers.<provider>`로 다시 작성하려면 `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)
|
||||
|
||||
@ -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` | 모든 그룹/룸 메시지 차단 |
|
||||
|
||||
<Note>
|
||||
`channels.defaults.groupPolicy`는 프로바이더의 `groupPolicy`가 설정되지 않았을 때 기본값을 설정합니다.
|
||||
페어링 코드는 1시간 후 만료됩니다. 대기 중인 DM 페어링 요청은 **채널당 3개**로 제한됩니다.
|
||||
프로바이더 블록이 완전히 누락된 경우(`channels.<provider>` 없음), 런타임 그룹 정책은 시작 경고와 함께 `allowlist`(실패 시 닫힘)로 대체됩니다.
|
||||
프로바이더 블록이 완전히 누락된 경우(`channels.<provider>` 없음), 런타임 그룹 정책은 시작 경고와 함께 `allowlist`(실패 시 닫힘)로 폴백합니다.
|
||||
</Note>
|
||||
|
||||
### 채널 모델 재정의
|
||||
|
||||
`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.<channel>.contextVisibility`.
|
||||
- `channels.defaults.heartbeat.showOk`: 정상 채널 상태를 Heartbeat 출력에 포함합니다.
|
||||
- `channels.defaults.heartbeat.showAlerts`: 성능 저하/오류 상태를 Heartbeat 출력에 포함합니다.
|
||||
- `channels.defaults.groupPolicy`: 프로바이더 수준 `groupPolicy`가 설정되지 않았을 때의 폴백 그룹 정책입니다.
|
||||
- `channels.defaults.contextVisibility`: 모든 채널의 기본 보조 컨텍스트 표시 모드입니다. 값: `all`(기본값, 인용/스레드/기록 컨텍스트 모두 포함), `allowlist`(허용 목록에 있는 발신자의 컨텍스트만 포함), `allowlist_quote`(allowlist와 같지만 명시적 인용/답장 컨텍스트 유지). 채널별 재정의: `channels.<channel>.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.<id>.sendReadReceipts`, `channels.whatsapp.accounts.<id>.dmPolicy`, `channels.whatsapp.accounts.<id>.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<TOKEN>`이 아니라 `https://api.telegram.org` 또는 자체 호스팅/프록시 루트를 사용하세요. `openclaw doctor --fix`는 실수로 붙은 후행 `/bot<TOKEN>` 접미사를 제거합니다.
|
||||
- 선택적 `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<TOKEN>`이 아니라 `https://api.telegram.org` 또는 자체 호스팅/프록시 루트를 사용하세요. `openclaw doctor --fix`는 실수로 붙은 후행 `/bot<TOKEN>` 접미사를 제거합니다.
|
||||
- 선택 사항인 `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:<id>`(DM) 또는 `channel:<id>`(길드 채널)를 사용합니다. 숫자 ID만 있는 값은 거부됩니다.
|
||||
- 길드 슬러그는 소문자이며 공백은 `-`로 대체됩니다. 채널 키는 슬러그 처리된 이름을 사용합니다(`#` 없음). 길드 ID를 권장합니다.
|
||||
- 봇이 작성한 메시지는 기본적으로 무시됩니다. `allowBots: true`는 이를 활성화합니다. 봇을 멘션한 봇 메시지만 허용하려면 `allowBots: "mentions"`를 사용하세요(자기 메시지는 계속 필터링됨).
|
||||
- `channels.discord.guilds.<id>.ignoreOtherMentions`(및 채널 재정의)는 봇은 멘션하지 않고 다른 사용자나 역할을 멘션한 메시지를 삭제합니다(@everyone/@here 제외).
|
||||
- `channels.discord.mentionAliases`는 전송 전에 안정적인 아웃바운드 `@handle` 텍스트를 Discord 사용자 ID에 매핑하므로, 임시 디렉터리 캐시가 비어 있어도 알려진 팀원을 결정적으로 멘션할 수 있습니다. 계정별 재정의는 `channels.discord.accounts.<accountId>.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:<id>`(DM) 또는 `channel:<id>`(길드 채널)를 사용하세요. 숫자 ID만 단독으로 쓰면 거부됩니다.
|
||||
- 길드 슬러그는 소문자이며 공백은 `-`로 대체됩니다. 채널 키는 슬러그 처리된 이름을 사용합니다(`#` 없음). 길드 ID 사용을 권장합니다.
|
||||
- 봇이 작성한 메시지는 기본적으로 무시됩니다. `allowBots: true`는 이를 활성화합니다. 봇을 멘션한 봇 메시지만 허용하려면 `allowBots: "mentions"`를 사용하세요. 단, 자체 메시지는 계속 필터링됩니다.
|
||||
- `channels.discord.guilds.<id>.ignoreOtherMentions`(및 채널 재정의)는 봇은 멘션하지 않고 다른 사용자나 역할을 멘션한 메시지를 드롭합니다(@everyone/@here 제외).
|
||||
- `channels.discord.mentionAliases`는 전송 전에 안정적인 아웃바운드 `@handle` 텍스트를 Discord 사용자 ID에 매핑하므로, 일시적 디렉터리 캐시가 비어 있어도 알려진 팀원을 결정적으로 멘션할 수 있습니다. 계정별 재정의는 `channels.discord.accounts.<accountId>.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.<id>.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/<spaceId>` 또는 `users/<userId>`를 사용합니다.
|
||||
- `channels.googlechat.dangerouslyAllowNameMatching`은 변경 가능한 이메일 주체 매칭을 다시 활성화합니다(비상 호환성 모드).
|
||||
- 환경 대체값: `GOOGLE_CHAT_SERVICE_ACCOUNT` 또는 `GOOGLE_CHAT_SERVICE_ACCOUNT_FILE`.
|
||||
- 전달 대상에는 `spaces/<spaceId>` 또는 `users/<userId>`를 사용하세요.
|
||||
- `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:<id>`(DM) 또는 `channel:<id>`를 사용합니다.
|
||||
- 선택 사항인 `channels.slack.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다.
|
||||
- `channels.slack.streaming.mode`는 표준 Slack 스트림 모드 키입니다. `channels.slack.streaming.nativeTransport`는 Slack의 네이티브 스트리밍 전송을 제어합니다. 레거시 `streamMode`, 불리언 `streaming`, `nativeStreaming` 값은 런타임 별칭으로 유지됩니다. 저장된 구성을 다시 쓰려면 `openclaw doctor --fix`를 실행하세요.
|
||||
- 전달 대상에는 `user:<id>`(DM) 또는 `channel:<id>`를 사용하세요.
|
||||
|
||||
**반응 알림 모드:** `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.<channelId>.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:<id>` 대상을 선호하세요. 채팅을 나열하려면 `imsg chats --limit 20`을 사용하세요.
|
||||
- `chat_id:<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).
|
||||
|
||||
<Accordion title="iMessage SSH 래퍼 예시">
|
||||
|
||||
@ -677,17 +678,17 @@ Matrix는 Plugin 기반이며 `channels.matrix` 아래에서 구성됩니다.
|
||||
- `channels.matrix.proxy`는 Matrix HTTP 트래픽을 명시적 HTTP(S) 프록시를 통해 라우팅합니다. 명명된 계정은 `channels.matrix.accounts.<id>.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.<id>.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.<channel>.accounts.default`로 이동합니다. Matrix는 기존의 일치하는 명명된/기본 대상을 대신 보존할 수 있습니다.
|
||||
- `bindings[].match.accountId`를 사용하여 각 계정을 다른 에이전트로 라우팅합니다.
|
||||
- 단일 계정 최상위 채널 구성 상태에서 `openclaw channels add`(또는 채널 온보딩)를 통해 기본값이 아닌 계정을 추가하면, OpenClaw는 먼저 계정 범위 최상위 단일 계정 값을 채널 계정 맵으로 승격하여 원래 계정이 계속 작동하도록 합니다. 대부분의 채널은 이를 `channels.<channel>.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.<channel>.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` 아래에서 구성됩니다.
|
||||
|
||||
<Accordion title="명령 세부 정보">
|
||||
|
||||
- 이 블록은 명령 표면을 구성합니다. 현재 내장 및 번들 명령 카탈로그는 [슬래시 명령](/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.<provider>.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.<provider>.commands.nativeSkills`로 채널별 네이티브 skill 등록을 재정의하세요.
|
||||
- `channels.telegram.customCommands`는 추가 Telegram 봇 메뉴 항목을 추가합니다.
|
||||
- `bash: true`는 호스트 셸에 대해 `! <cmd>`를 활성화합니다. `tools.elevated.enabled`가 필요하며 발신자가 `tools.elevated.allowFrom.<channel>`에 있어야 합니다.
|
||||
- `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`는 호스트 셸에 대해 `! <cmd>`를 활성화합니다. `tools.elevated.enabled`와 `tools.elevated.allowFrom.<channel>`에 포함된 발신자가 필요합니다.
|
||||
- `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.<provider>.configWrites`는 채널별 구성 변경을 제어합니다(기본값: true).
|
||||
- 다중 계정 채널의 경우 `channels.<provider>.accounts.<id>.configWrites`도 해당 계정을 대상으로 하는 쓰기를 제어합니다(예: `/allowlist --config --account <id>` 또는 `/config set channels.<provider>.accounts.<id>...`).
|
||||
- `restart: false`는 `/restart`와 Gateway 재시작 도구 동작을 비활성화합니다. 기본값: `true`.
|
||||
- `ownerAllowFrom`은 소유자 전용 명령/도구를 위한 명시적 소유자 허용 목록입니다. `allowFrom`과 별개입니다.
|
||||
- `channels.<provider>.configWrites`는 채널별 구성 변경을 게이트합니다(기본값: true).
|
||||
- 다중 계정 채널의 경우 `channels.<provider>.accounts.<id>.configWrites`도 해당 계정을 대상으로 하는 쓰기를 게이트합니다(예: `/allowlist --config --account <id>` 또는 `/config set channels.<provider>.accounts.<id>...`).
|
||||
- `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)
|
||||
|
||||
@ -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)을 참조하세요.
|
||||
|
||||
@ -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.<skillKey>.enabled: false`는 번들/설치되어 있더라도 skill을 비활성화합니다.
|
||||
- `entries.<skillKey>.apiKey`: 기본 환경 변수를 선언하는 Skills를 위한 편의 기능입니다(일반 텍스트 문자열 또는 SecretRef 객체).
|
||||
- `entries.<skillKey>.apiKey`: 기본 env var를 선언하는 Skills를 위한 편의 기능(plaintext string 또는 SecretRef object).
|
||||
|
||||
---
|
||||
|
||||
## Plugin
|
||||
## Plugins
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -163,59 +167,59 @@ OpenClaw가 관리하는 MCP 서버 정의는 `mcp.servers` 아래에 있으며,
|
||||
}
|
||||
```
|
||||
|
||||
- `~/.openclaw/extensions`, `<workspace>/.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.<id>.apiKey`: Plugin 수준 API 키 편의 필드입니다(Plugin에서 지원하는 경우).
|
||||
- `plugins.entries.<id>.env`: Plugin 범위 환경 변수 맵.
|
||||
- `plugins.entries.<id>.hooks.allowPromptInjection`: `false`이면 core가 `before_prompt_build`를 차단하고 레거시 `before_agent_start`의 프롬프트 변경 필드를 무시하면서, 레거시 `modelOverride`와 `providerOverride`는 보존합니다. 네이티브 Plugin hooks와 지원되는 번들 제공 hook 디렉터리에 적용됩니다.
|
||||
- `plugins.entries.<id>.hooks.allowConversationAccess`: `true`이면 신뢰할 수 있는 비번들 plugins가 `llm_input`, `llm_output`, `before_agent_finalize`, `agent_end` 같은 typed hooks에서 원시 대화 내용을 읽을 수 있습니다.
|
||||
- `plugins.entries.<id>.subagent.allowModelOverride`: 이 Plugin이 백그라운드 하위 에이전트 실행에 대해 실행별 `provider` 및 `model` override를 요청할 수 있도록 명시적으로 신뢰합니다.
|
||||
- `plugins.entries.<id>.subagent.allowedModels`: 신뢰할 수 있는 하위 에이전트 override를 위한 표준 `provider/model` 대상의 선택적 허용 목록입니다. 어떤 모델이든 허용하려는 의도가 있을 때만 `"*"`를 사용하세요.
|
||||
- `plugins.entries.<id>.config`: Plugin 정의 구성 객체입니다(사용 가능한 경우 네이티브 OpenClaw Plugin 스키마로 검증).
|
||||
- 채널 Plugin 계정/런타임 설정은 `channels.<id>` 아래에 있으며, 중앙 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`, `<workspace>/.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.<id>.apiKey`: Plugin 수준 API key 편의 필드(Plugin에서 지원하는 경우).
|
||||
- `plugins.entries.<id>.env`: Plugin 범위 env var 맵.
|
||||
- `plugins.entries.<id>.hooks.allowPromptInjection`: `false`이면 core가 `before_prompt_build`를 차단하고 legacy `before_agent_start`의 prompt 변경 필드를 무시하며, legacy `modelOverride`와 `providerOverride`는 보존합니다. 네이티브 Plugin hook 및 지원되는 bundle 제공 hook 디렉터리에 적용됩니다.
|
||||
- `plugins.entries.<id>.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.<id>.subagent.allowModelOverride`: 이 Plugin이 background subagent 실행마다 `provider` 및 `model` override를 요청하도록 명시적으로 신뢰합니다.
|
||||
- `plugins.entries.<id>.subagent.allowedModels`: 신뢰할 수 있는 subagent override를 위한 표준 `provider/model` 대상의 선택적 allowlist. 어떤 모델이든 허용하려는 의도가 있을 때만 `"*"`를 사용하세요.
|
||||
- `plugins.entries.<id>.config`: Plugin 정의 config object(사용 가능한 경우 네이티브 OpenClaw Plugin schema로 검증됨).
|
||||
- 채널 Plugin 계정/런타임 설정은 `channels.<id>` 아래에 있으며, 중앙 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.<name>.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.<name>.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` 아래에 있으며,
|
||||
}
|
||||
```
|
||||
|
||||
<Accordion title="Gateway 필드 세부 정보">
|
||||
<Accordion title="Gateway field details">
|
||||
|
||||
- `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.<provider>.healthMonitor.enabled`: 전역 모니터는 활성화한 채 상태 모니터 재시작에서 채널별로 제외하는 설정입니다.
|
||||
- `channels.<provider>.accounts.<accountId>.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.<provider>.healthMonitor.enabled`: 전역 모니터는 활성화한 채로 상태 모니터 재시작을 채널별로 제외합니다.
|
||||
- `channels.<provider>.accounts.<accountId>.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 거부 목록에서 도구 이름을 제거합니다.
|
||||
|
||||
</Accordion>
|
||||
@ -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 <token>` 또는 `x-openclaw-token: <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/<name>` → `hooks.mappings`를 통해 확인됩니다.
|
||||
- 템플릿으로 렌더링된 매핑 `sessionKey` 값은 외부에서 제공된 것으로 처리되며, 역시 `hooks.allowRequestSessionKey=true`가 필요합니다.
|
||||
- 요청 페이로드의 `sessionKey`는 `hooks.allowRequestSessionKey=true`인 경우에만 허용됩니다(기본값: `false`).
|
||||
- `POST /hooks/<name>` → `hooks.mappings`를 통해 해석됨
|
||||
- 템플릿으로 렌더링된 매핑 `sessionKey` 값은 외부에서 제공된 것으로 처리되며, 이 역시 `hooks.allowRequestSessionKey=true`가 필요합니다.
|
||||
|
||||
<Accordion title="Mapping details">
|
||||
<Accordion title="매핑 세부 정보">
|
||||
|
||||
- `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가 설정된 경우 허용되어야 함).
|
||||
|
||||
</Accordion>
|
||||
|
||||
### 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://<gateway-host>:<gateway.port>/__openclaw__/canvas/`
|
||||
- `http://<gateway-host>:<gateway.port>/__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
|
||||
|
||||
- 에이전트별 프로필은 `<agentDir>/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.<id>.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`로 알 수 없는 키를 제거할 수 있음).
|
||||
|
||||
<Accordion title="레거시 브리지 구성(기록 참고)">
|
||||
<Accordion title="레거시 브리지 구성(역사적 참고 자료)">
|
||||
|
||||
```json
|
||||
{
|
||||
@ -1092,11 +1095,11 @@ CLI 안내 설정 흐름(`onboard`, `configure`, `doctor`)에서 작성하는
|
||||
}
|
||||
```
|
||||
|
||||
- `sessionRetention`: 완료된 격리된 Cron 실행 세션을 `sessions.json`에서 정리하기 전에 보관할 기간입니다. 보관된 삭제 Cron transcript의 정리도 제어합니다. 기본값: `24h`; 비활성화하려면 `false`로 설정하세요.
|
||||
- `runLog.maxBytes`: 정리 전에 실행 로그 파일(`cron/runs/<jobId>.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/<jobId>.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에 대해 명확한 메시지를 제공합니다.
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -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 복구 단계 포함).
|
||||
|
||||
</Tab>
|
||||
<Tab title="--repair">
|
||||
@ -54,7 +54,7 @@ openclaw doctor
|
||||
openclaw doctor --non-interactive
|
||||
```
|
||||
|
||||
프롬프트 없이 실행하고 안전한 마이그레이션만 적용합니다(config 정규화 + 디스크상 state 이동). 사람의 확인이 필요한 재시작/서비스/샌드박스 작업은 건너뜁니다. 레거시 state 마이그레이션은 감지되면 자동으로 실행됩니다.
|
||||
프롬프트 없이 실행하고 안전한 마이그레이션만 적용합니다(config 정규화 + 디스크 내 state 이동). 사람의 확인이 필요한 restart/service/sandbox 작업은 건너뜁니다. 레거시 state 마이그레이션은 감지되면 자동으로 실행됩니다.
|
||||
|
||||
</Tab>
|
||||
<Tab title="--deep">
|
||||
@ -77,64 +77,64 @@ cat ~/.openclaw/openclaw.json
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="상태, UI, 업데이트">
|
||||
- git 설치의 선택적 사전 업데이트(대화형 전용).
|
||||
- UI 프로토콜 최신 상태 검사(프로토콜 스키마가 더 최신이면 Control UI를 다시 빌드).
|
||||
- git 설치에 대한 선택적 사전 업데이트(대화형 전용).
|
||||
- UI 프로토콜 최신성 검사(프로토콜 스키마가 더 최신이면 Control UI를 다시 빌드).
|
||||
- 상태 검사 + 재시작 프롬프트.
|
||||
- Skills 상태 요약(적격/누락/차단) 및 Plugin 상태.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Config 및 마이그레이션">
|
||||
<Accordion title="Config와 마이그레이션">
|
||||
- 레거시 값에 대한 config 정규화.
|
||||
- 레거시 플랫 `talk.*` 필드에서 `talk.provider` + `talk.providers.<provider>`로 Talk config 마이그레이션.
|
||||
- 레거시 Chrome extension config 및 Chrome MCP 준비 상태에 대한 Browser 마이그레이션 검사.
|
||||
- 레거시 평면 `talk.*` 필드에서 `talk.provider` + `talk.providers.<provider>`로 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로 취급되어 보존됩니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="State 및 무결성">
|
||||
- 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`).
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Gateway, 서비스, supervisor">
|
||||
- 샌드박싱이 활성화된 경우 샌드박스 이미지 복구.
|
||||
- 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`).
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Auth, 보안, pairing">
|
||||
- 열린 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).
|
||||
<Accordion title="Auth, 보안, 페어링">
|
||||
- open DM 정책에 대한 보안 경고.
|
||||
- local token mode에 대한 Gateway auth 검사(토큰 소스가 없으면 토큰 생성을 제안하며 token SecretRef config를 덮어쓰지 않음).
|
||||
- 디바이스 페어링 문제 감지(대기 중인 최초 pair 요청, 대기 중인 role/scope upgrade, 오래된 local device-token cache drift, paired-record auth drift).
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Workspace 및 shell">
|
||||
- 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를 씁니다.
|
||||
|
||||
</Accordion>
|
||||
@ -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)를 제안합니다.
|
||||
</Accordion>
|
||||
<Accordion title="1. Config 정규화">
|
||||
config에 레거시 값 형태(예: channel-specific override가 없는 `messages.ackReaction`)가 포함되어 있으면 doctor가 이를 현재 스키마로 정규화합니다.
|
||||
config에 레거시 값 형태(예: 채널별 override가 없는 `messages.ackReaction`)가 포함되어 있으면 doctor는 이를 현재 스키마로 정규화합니다.
|
||||
|
||||
여기에는 레거시 Talk flat field가 포함됩니다. 현재 public Talk speech config는 `talk.provider` + `talk.providers.<provider>`이고, 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.<provider>`이고, 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"` 설정을 안내합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="2. 레거시 config key 마이그레이션">
|
||||
config에 deprecated key가 포함되어 있으면 다른 command는 실행을 거부하고 `openclaw doctor`를 실행하라고 요청합니다.
|
||||
<Accordion title="2. 레거시 config 키 마이그레이션">
|
||||
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.<provider>`
|
||||
- 레거시 최상위 실시간 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.<provider>`(`openai`/`elevenlabs`/`microsoft`/`edge`) → `messages.tts.providers.<provider>`
|
||||
@ -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.<id>.timeoutSeconds` 사용
|
||||
- `agents.defaults.llm` 제거; 느린 provider/model timeout에는 `models.providers.<id>.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.<channel>.accounts` 항목이 `channels.<channel>.defaultAccount` 또는 `accounts.default` 없이 구성되어 있으면, Doctor는 fallback 라우팅이 예상치 못한 계정을 선택할 수 있다고 경고합니다.
|
||||
- `channels.<channel>.defaultAccount`가 알 수 없는 계정 ID로 설정되어 있으면, Doctor는 경고하고 구성된 계정 ID를 나열합니다.
|
||||
- 두 개 이상의 `channels.<channel>.accounts` 항목이 `channels.<channel>.defaultAccount` 또는 `accounts.default` 없이 설정된 경우, doctor는 fallback routing이 예상치 못한 계정을 선택할 수 있다고 경고합니다.
|
||||
- `channels.<channel>.defaultAccount`가 알 수 없는 account ID로 설정된 경우, doctor는 경고하고 설정된 account ID를 나열합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="2b. OpenCode provider overrides">
|
||||
`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 및 비용을 복원할 수 있도록 경고합니다.
|
||||
</Accordion>
|
||||
<Accordion title="2c. Browser migration and Chrome MCP readiness">
|
||||
브라우저 설정이 여전히 제거된 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를 사용합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="2d. OAuth TLS prerequisites">
|
||||
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가 실행됩니다.
|
||||
</Accordion>
|
||||
<Accordion title="2e. Codex OAuth provider overrides">
|
||||
이전에 `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는 계속 지원되며 이 경고를 트리거하지 않습니다.
|
||||
</Accordion>
|
||||
<Accordion title="2f. Codex route repair">
|
||||
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를 사용한다”는 뜻입니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="2g. Session route cleanup">
|
||||
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하세요.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="3. Legacy state migrations (disk layout)">
|
||||
Doctor는 오래된 온디스크 레이아웃을 현재 구조로 마이그레이션할 수 있습니다.
|
||||
Doctor는 오래된 on-disk layout을 현재 구조로 migration할 수 있습니다.
|
||||
|
||||
- 세션 저장소 + transcript:
|
||||
- Session store + transcript:
|
||||
- `~/.openclaw/sessions/`에서 `~/.openclaw/agents/<agentId>/sessions/`로
|
||||
- 에이전트 디렉터리:
|
||||
- Agent dir:
|
||||
- `~/.openclaw/agent/`에서 `~/.openclaw/agents/<agentId>/agent/`로
|
||||
- WhatsApp 인증 상태(Baileys):
|
||||
- WhatsApp auth state(Baileys):
|
||||
- 레거시 `~/.openclaw/credentials/*.json`에서(`oauth.json` 제외)
|
||||
- `~/.openclaw/credentials/whatsapp/<accountId>/...`로(기본 계정 ID: `default`)
|
||||
- `~/.openclaw/credentials/whatsapp/<accountId>/...`로(기본 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` 변경을 트리거하지 않습니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="3a. Legacy plugin manifest migrations">
|
||||
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가 제거됩니다.
|
||||
</Accordion>
|
||||
<Accordion title="3b. Legacy cron store migrations">
|
||||
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`를 사용하세요.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="3c. 세션 잠금 정리">
|
||||
Doctor는 모든 에이전트 세션 디렉터리에서 오래된 쓰기 잠금 파일, 즉 세션이 비정상적으로 종료될 때 남겨진 파일을 검사합니다. 발견된 각 잠금 파일에 대해 경로, PID, PID가 아직 살아 있는지 여부, 잠금 기간, 오래된 것으로 간주되는지 여부(죽은 PID 또는 30분 초과)를 보고합니다. `--fix` / `--repair` 모드에서는 오래된 잠금 파일을 자동으로 제거합니다. 그렇지 않으면 참고 메시지를 출력하고 `--fix`로 다시 실행하라고 안내합니다.
|
||||
Doctor는 모든 에이전트 세션 디렉터리에서 오래된 쓰기 잠금 파일, 즉 세션이 비정상 종료되었을 때 남은 파일을 스캔합니다. 발견된 각 잠금 파일에 대해 경로, PID, PID가 아직 살아 있는지 여부, 잠금 경과 시간, 오래된 것으로 간주되는지 여부(죽은 PID 또는 30분 초과)를 보고합니다. `--fix` / `--repair` 모드에서는 오래된 잠금 파일을 자동으로 제거합니다. 그렇지 않으면 참고 메시지를 출력하고 `--fix`로 다시 실행하라고 안내합니다.
|
||||
</Accordion>
|
||||
<Accordion title="3d. 세션 트랜스크립트 브랜치 복구">
|
||||
Doctor는 2026.4.24 프롬프트 트랜스크립트 재작성 버그로 생성된 중복 브랜치 형태를 찾기 위해 에이전트 세션 JSONL 파일을 검사합니다. 이 형태는 OpenClaw 내부 런타임 컨텍스트가 있는 버려진 사용자 턴과, 동일한 표시용 사용자 프롬프트를 포함하는 활성 형제 브랜치로 구성됩니다. `--fix` / `--repair` 모드에서 doctor는 영향을 받은 각 파일을 원본 옆에 백업하고 트랜스크립트를 활성 브랜치로 다시 작성하여 Gateway 기록과 메모리 리더가 더 이상 중복 턴을 보지 않게 합니다.
|
||||
<Accordion title="3d. 세션 transcript 브랜치 복구">
|
||||
Doctor는 2026.4.24 프롬프트 transcript 재작성 버그로 생성된 중복 브랜치 형태를 찾기 위해 에이전트 세션 JSONL 파일을 스캔합니다. 이는 OpenClaw 내부 런타임 컨텍스트가 있는 버려진 사용자 턴과 동일한 표시 사용자 프롬프트를 포함하는 활성 형제 항목이 함께 있는 형태입니다. `--fix` / `--repair` 모드에서 doctor는 영향을 받은 각 파일을 원본 옆에 백업하고 transcript를 활성 브랜치로 다시 작성하여 Gateway 기록 및 메모리 리더가 더 이상 중복 턴을 보지 않게 합니다.
|
||||
</Accordion>
|
||||
<Accordion title="4. 상태 무결성 검사(세션 지속성, 라우팅, 안전)">
|
||||
상태 디렉터리는 운영상의 중추입니다. 이 디렉터리가 사라지면 다른 곳에 백업이 없는 한 세션, 자격 증명, 로그, 설정을 잃게 됩니다.
|
||||
<Accordion title="4. 상태 무결성 검사(세션 지속성, 라우팅 및 안전성)">
|
||||
상태 디렉터리는 운영상의 중추입니다. 이것이 사라지면 다른 곳에 백업이 없는 한 세션, 자격 증명, 로그, 구성을 잃게 됩니다.
|
||||
|
||||
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`으로 강화할 것을 제안합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="5. 모델 인증 상태(OAuth 만료)">
|
||||
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)
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="6. 훅 모델 검증">
|
||||
`hooks.gmail.model`이 설정되어 있으면 doctor는 카탈로그와 허용 목록에 대해 모델 참조를 검증하고, 해석되지 않거나 허용되지 않으면 경고합니다.
|
||||
<Accordion title="6. Hooks 모델 검증">
|
||||
`hooks.gmail.model`이 설정된 경우 doctor는 카탈로그 및 허용 목록을 기준으로 모델 참조를 검증하고, 확인할 수 없거나 허용되지 않는 경우 경고합니다.
|
||||
</Accordion>
|
||||
<Accordion title="7. 샌드박스 이미지 복구">
|
||||
샌드박싱이 활성화되어 있으면 doctor는 Docker 이미지를 확인하고, 현재 이미지가 없을 경우 빌드하거나 레거시 이름으로 전환하도록 제안합니다.
|
||||
샌드박스가 활성화된 경우 doctor는 Docker 이미지를 검사하고 현재 이미지가 없으면 빌드하거나 레거시 이름으로 전환할 것을 제안합니다.
|
||||
</Accordion>
|
||||
<Accordion title="7b. Plugin 설치 정리">
|
||||
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 작업으로 남아 있습니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="8. Gateway 서비스 마이그레이션 및 정리 힌트">
|
||||
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`을 설정하세요.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="8b. 시작 Matrix 마이그레이션">
|
||||
Matrix 채널 계정에 보류 중이거나 실행 가능한 레거시 상태 마이그레이션이 있으면 doctor는 (`--fix` / `--repair` 모드에서) 마이그레이션 전 스냅샷을 만든 다음 최선의 마이그레이션 단계인 레거시 Matrix 상태 마이그레이션과 레거시 암호화 상태 준비를 실행합니다. 두 단계 모두 치명적이지 않습니다. 오류는 기록되고 시작은 계속됩니다. 읽기 전용 모드(`--fix` 없이 `openclaw doctor`)에서는 이 검사를 완전히 건너뜁니다.
|
||||
<Accordion title="8b. 시작 시 Matrix 마이그레이션">
|
||||
Matrix 채널 계정에 보류 중이거나 조치 가능한 레거시 상태 마이그레이션이 있는 경우 doctor는 (`--fix` / `--repair` 모드에서) 마이그레이션 전 스냅샷을 만든 다음 최선의 마이그레이션 단계를 실행합니다. 레거시 Matrix 상태 마이그레이션 및 레거시 암호화 상태 준비가 이에 해당합니다. 두 단계 모두 치명적이지 않습니다. 오류는 로그에 기록되고 시작은 계속됩니다. 읽기 전용 모드(`--fix` 없이 `openclaw doctor`)에서는 이 검사를 완전히 건너뜁니다.
|
||||
</Accordion>
|
||||
<Accordion title="8c. 기기 페어링 및 인증 드리프트">
|
||||
Doctor는 이제 일반 상태 검사 과정의 일부로 기기 페어링 상태를 검사합니다.
|
||||
이제 Doctor는 일반 상태 점검의 일부로 기기 페어링 상태를 검사합니다.
|
||||
|
||||
보고하는 항목:
|
||||
|
||||
- 보류 중인 최초 페어링 요청
|
||||
- 이미 페어링된 기기의 보류 중인 역할 업그레이드
|
||||
- 이미 페어링된 기기의 보류 중인 범위 업그레이드
|
||||
- 기기 ID는 여전히 일치하지만 기기 ID 정보가 승인된 레코드와 더 이상 일치하지 않는 공개 키 불일치 복구
|
||||
- 승인된 역할에 대한 활성 토큰이 없는 페어링 레코드
|
||||
- 범위가 승인된 페어링 기준선 밖으로 드리프트한 페어링 토큰
|
||||
- Gateway 측 토큰 회전보다 오래되었거나 오래된 범위 메타데이터를 가진 현재 머신의 로컬 캐시 기기 토큰 항목
|
||||
- 기기 id는 여전히 일치하지만 기기 identity가 더 이상 승인된 레코드와 일치하지 않는 공개 키 불일치 복구
|
||||
- 승인된 역할에 대한 활성 토큰이 없는 페어링된 레코드
|
||||
- 범위가 승인된 페어링 기준선 밖으로 드리프트된 페어링 토큰
|
||||
- Gateway 측 토큰 rotation보다 오래되었거나 오래된 범위 메타데이터를 포함하는 현재 머신의 로컬 캐시 기기 토큰 항목
|
||||
|
||||
Doctor는 페어링 요청을 자동 승인하거나 기기 토큰을 자동 회전하지 않습니다. 대신 정확한 다음 단계를 출력합니다.
|
||||
Doctor는 페어링 요청을 자동 승인하거나 기기 토큰을 자동 rotation하지 않습니다. 대신 정확한 다음 단계를 출력합니다.
|
||||
|
||||
- `openclaw devices list`로 보류 중인 요청 검사
|
||||
- `openclaw devices approve <requestId>`로 정확한 요청 승인
|
||||
- `openclaw devices rotate --device <deviceId> --role <role>`로 새 토큰 회전
|
||||
- `openclaw devices remove <deviceId>`로 오래된 레코드 제거 및 재승인
|
||||
- `openclaw devices rotate --device <deviceId> --role <role>`로 새 토큰 rotation
|
||||
- `openclaw devices remove <deviceId>`로 오래된 레코드 제거 후 다시 승인
|
||||
|
||||
이것은 흔한 "이미 페어링되었지만 여전히 페어링 필요가 표시됨" 허점을 닫습니다. doctor는 이제 최초 페어링, 보류 중인 역할/범위 업그레이드, 오래된 토큰/기기 ID 정보 드리프트를 구분합니다.
|
||||
이는 흔한 "이미 페어링되었지만 여전히 페어링 필요 메시지가 표시되는" 문제를 해결합니다. 이제 doctor는 최초 페어링, 보류 중인 역할/범위 업그레이드, 오래된 토큰/기기 identity 드리프트를 구분합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="9. 보안 경고">
|
||||
Doctor는 제공자가 허용 목록 없이 DM에 열려 있거나 정책이 위험한 방식으로 설정된 경우 경고를 출력합니다.
|
||||
Doctor는 제공자가 허용 목록 없이 DM에 열려 있거나 정책이 위험한 방식으로 구성된 경우 경고를 출력합니다.
|
||||
</Accordion>
|
||||
<Accordion title="10. systemd linger(Linux)">
|
||||
systemd 사용자 서비스로 실행 중이면 doctor는 로그아웃 후에도 Gateway가 계속 살아 있도록 lingering이 활성화되어 있는지 확인합니다.
|
||||
systemd 사용자 서비스로 실행 중인 경우 doctor는 Gateway가 로그아웃 후에도 살아 있도록 lingering이 활성화되어 있는지 확인합니다.
|
||||
</Accordion>
|
||||
<Accordion title="11. 워크스페이스 상태(Skills, Plugin, 레거시 디렉터리)">
|
||||
Doctor는 기본 에이전트에 대한 워크스페이스 상태 요약을 출력합니다.
|
||||
<Accordion title="11. Workspace 상태(Skills, Plugin 및 레거시 디렉터리)">
|
||||
Doctor는 기본 에이전트의 Workspace 상태 요약을 출력합니다.
|
||||
|
||||
- **Skills 상태**: 적격, 요구 사항 누락, 허용 목록 차단 Skills 수를 셉니다.
|
||||
- **레거시 워크스페이스 디렉터리**: 현재 워크스페이스와 함께 `~/openclaw` 또는 기타 레거시 워크스페이스 디렉터리가 있으면 경고합니다.
|
||||
- **Plugin 상태**: 활성화/비활성화/오류 Plugin 수를 셉니다. 오류가 있는 경우 Plugin ID를 나열합니다. 번들 Plugin 기능을 보고합니다.
|
||||
- **레거시 Workspace 디렉터리**: `~/openclaw` 또는 기타 레거시 Workspace 디렉터리가 현재 Workspace와 함께 존재할 때 경고합니다.
|
||||
- **Plugin 상태**: 활성화/비활성화/오류 Plugin 수를 셉니다. 오류가 있는 경우 Plugin ID를 나열하고 번들 Plugin 기능을 보고합니다.
|
||||
- **Plugin 호환성 경고**: 현재 런타임과 호환성 문제가 있는 Plugin을 표시합니다.
|
||||
- **Plugin 진단**: Plugin 레지스트리가 로드 시 출력한 경고 또는 오류를 표시합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="11b. 부트스트랩 파일 크기">
|
||||
Doctor는 워크스페이스 부트스트랩 파일(예: `AGENTS.md`, `CLAUDE.md` 또는 기타 삽입된 컨텍스트 파일)이 설정된 문자 예산에 가깝거나 초과했는지 확인합니다. 파일별 원시 문자 수와 삽입된 문자 수, 잘림 비율, 잘림 원인(`max/file` 또는 `max/total`), 총 예산 대비 총 삽입 문자 수를 보고합니다. 파일이 잘렸거나 한도에 가까우면 doctor는 `agents.defaults.bootstrapMaxChars`와 `agents.defaults.bootstrapTotalMaxChars` 조정 팁을 출력합니다.
|
||||
<Accordion title="11b. Bootstrap 파일 크기">
|
||||
Doctor는 Workspace Bootstrap 파일(예: `AGENTS.md`, `CLAUDE.md` 또는 기타 주입된 컨텍스트 파일)이 구성된 문자 예산에 가깝거나 초과하는지 확인합니다. 파일별 원시 문자 수와 주입된 문자 수, 잘림 비율, 잘림 원인(`max/file` 또는 `max/total`), 전체 예산 대비 총 주입 문자 비율을 보고합니다. 파일이 잘렸거나 한도에 가까우면 doctor는 `agents.defaults.bootstrapMaxChars` 및 `agents.defaults.bootstrapTotalMaxChars` 조정 팁을 출력합니다.
|
||||
</Accordion>
|
||||
<Accordion title="11d. 오래된 채널 Plugin 정리">
|
||||
`openclaw doctor --fix`가 누락된 채널 Plugin을 제거할 때, 해당 Plugin을 참조하던 매달린 채널 범위 설정도 제거합니다. 여기에는 `channels.<id>` 항목, 채널 이름을 지정한 Heartbeat 대상, `agents.*.models["<channel>/*"]` 재정의가 포함됩니다. 이렇게 하면 채널 런타임은 사라졌지만 설정이 여전히 Gateway에 바인딩을 요청하는 Gateway 부팅 루프를 방지합니다.
|
||||
`openclaw doctor --fix`가 누락된 채널 Plugin을 제거할 때 해당 Plugin을 참조하던 dangling 채널 범위 구성도 함께 제거합니다. 여기에는 `channels.<id>` 항목, 해당 채널 이름을 지정한 Heartbeat 대상, `agents.*.models["<channel>/*"]` override가 포함됩니다. 이렇게 하면 채널 런타임은 사라졌지만 구성에서 여전히 Gateway에 바인딩을 요청하는 Gateway 부팅 루프를 방지합니다.
|
||||
</Accordion>
|
||||
<Accordion title="11c. 셸 완성">
|
||||
Doctor는 현재 셸(zsh, bash, fish 또는 PowerShell)에 탭 완성이 설치되어 있는지 확인합니다.
|
||||
<Accordion title="11c. 셸 completion">
|
||||
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
|
||||
<Accordion title="12. Gateway 인증 검사(로컬 토큰)">
|
||||
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가 구성되지 않은 경우에만 생성을 강제합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="12b. SecretRef 인식 읽기 전용 복구">
|
||||
일부 복구 흐름은 런타임의 빠른 실패 동작을 약화하지 않고 구성된 자격 증명을 검사해야 합니다.
|
||||
<Accordion title="12b. 읽기 전용 SecretRef 인식 복구">
|
||||
일부 복구 흐름은 런타임 빠른 실패 동작을 약화하지 않고 구성된 자격 증명을 검사해야 합니다.
|
||||
|
||||
- `openclaw doctor --fix`는 이제 대상 지정 구성 복구에 상태 계열 명령과 동일한 읽기 전용 SecretRef 요약 모델을 사용합니다.
|
||||
- `openclaw doctor --fix`는 이제 대상 config 복구에 status 계열 명령과 동일한 읽기 전용 SecretRef 요약 모델을 사용합니다.
|
||||
- 예: Telegram `allowFrom` / `groupAllowFrom` `@username` 복구는 사용 가능한 경우 구성된 봇 자격 증명을 사용하려고 시도합니다.
|
||||
- Telegram 봇 토큰이 SecretRef로 구성되었지만 현재 명령 경로에서 사용할 수 없는 경우, doctor는 토큰이 누락되었다고 잘못 보고하거나 충돌하는 대신 자격 증명이 구성되었지만 사용할 수 없다고 보고하고 자동 확인을 건너뜁니다.
|
||||
- Telegram 봇 토큰이 SecretRef로 구성되어 있지만 현재 명령 경로에서 사용할 수 없는 경우, doctor는 자격 증명이 구성되었지만 사용할 수 없다고 보고하고, 토큰이 누락된 것으로 잘못 보고하거나 충돌하는 대신 자동 확인을 건너뜁니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="13. Gateway 상태 확인 + 재시작">
|
||||
진단 도구는 상태 확인을 실행하고 Gateway가 비정상으로 보이면 재시작을 제안합니다.
|
||||
Doctor는 상태 확인을 실행하고 Gateway가 비정상으로 보이면 재시작을 제안합니다.
|
||||
</Accordion>
|
||||
<Accordion title="13b. 메모리 검색 준비 상태">
|
||||
진단 도구는 구성된 메모리 검색 임베딩 제공자가 기본 에이전트에 대해 준비되었는지 확인합니다. 동작은 구성된 백엔드와 제공자에 따라 달라집니다.
|
||||
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`을 사용하세요.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="14. 채널 상태 경고">
|
||||
Gateway가 정상 상태이면 진단 도구는 채널 상태 검사를 실행하고 제안된 수정과 함께 경고를 보고합니다.
|
||||
Gateway가 정상 상태이면 doctor는 채널 상태 검사를 실행하고 제안된 수정과 함께 경고를 보고합니다.
|
||||
</Accordion>
|
||||
<Accordion title="15. 감독자 구성 감사 + 복구">
|
||||
진단 도구는 설치된 감독자 구성(launchd/systemd/schtasks)에 누락되었거나 오래된 기본값(예: systemd network-online 의존성 및 재시작 지연)이 있는지 확인합니다. 불일치를 발견하면 업데이트를 권장하고 서비스 파일/작업을 현재 기본값으로 다시 쓸 수 있습니다.
|
||||
<Accordion title="15. Supervisor config 감사 + 복구">
|
||||
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`를 통해 언제든지 전체 재작성을 강제할 수 있습니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="16. Gateway 런타임 + 포트 진단">
|
||||
진단 도구는 서비스 런타임(PID, 마지막 종료 상태)을 검사하고 서비스가 설치되어 있지만 실제로 실행 중이 아닐 때 경고합니다. 또한 Gateway 포트(기본값 `18789`)에서 포트 충돌을 확인하고 가능한 원인(Gateway가 이미 실행 중, SSH 터널)을 보고합니다.
|
||||
Doctor는 service 런타임(PID, 마지막 종료 상태)을 검사하고, service가 설치되어 있지만 실제로 실행 중이 아닐 때 경고합니다. 또한 Gateway 포트(기본값 `18789`)의 포트 충돌을 확인하고 가능한 원인(Gateway가 이미 실행 중, SSH 터널)을 보고합니다.
|
||||
</Accordion>
|
||||
<Accordion title="17. Gateway 런타임 모범 사례">
|
||||
진단 도구는 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에 기록됩니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="18. 구성 쓰기 + 마법사 메타데이터">
|
||||
진단 도구는 모든 구성 변경 사항을 유지하고 doctor 실행을 기록하기 위해 마법사 메타데이터를 표시합니다.
|
||||
<Accordion title="18. Config 쓰기 + wizard 메타데이터">
|
||||
Doctor는 config 변경 사항을 유지하고 doctor 실행을 기록하기 위해 wizard 메타데이터를 표시합니다.
|
||||
</Accordion>
|
||||
<Accordion title="19. 작업 공간 팁(백업 + 메모리 시스템)">
|
||||
진단 도구는 작업 공간 메모리 시스템이 없을 때 이를 제안하고, 작업 공간이 아직 git으로 관리되지 않는 경우 백업 팁을 출력합니다.
|
||||
<Accordion title="19. Workspace 팁(백업 + 메모리 시스템)">
|
||||
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)를 참조하세요.
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 관련 항목
|
||||
|
||||
- [Gateway 실행 가이드](/ko/gateway)
|
||||
- [Gateway runbook](/ko/gateway)
|
||||
- [Gateway 문제 해결](/ko/gateway/troubleshooting)
|
||||
|
||||
@ -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` 사용).
|
||||
|
||||
이렇게 하면 기존 파일 로그는 안정적으로 유지하면서 대화형 출력은 훑어보기 쉬워집니다.
|
||||
이렇게 하면 기존 파일 로그를 안정적으로 유지하면서 대화형 출력을 훑어보기 쉽게 만들 수 있습니다.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
|
||||
@ -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.*` 필드 참조
|
||||
|
||||
@ -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`입니다.
|
||||
|
||||
<Warning>
|
||||
이 경로는 Gateway 인증(운영자 범위)을 사용합니다. 공개 미인증 `/metrics` 엔드포인트로 노출하지 마세요. 다른 운영자 API에 사용하는 것과 동일한 인증 경로를 통해 스크레이프하세요.
|
||||
이 라우트는 Gateway 인증(운영자 범위)을 사용합니다. 공개 무인증 `/metrics` 엔드포인트로 노출하지 마세요. 다른 운영자 API에 사용하는 것과 동일한 인증 경로를 통해 스크레이프하세요.
|
||||
</Warning>
|
||||
|
||||
트레이스, 로그, OTLP 푸시, OpenTelemetry GenAI 의미론적 속성은 [OpenTelemetry 내보내기](/ko/gateway/opentelemetry)를 참조하세요.
|
||||
트레이스, 로그, OTLP 푸시, OpenTelemetry GenAI 시맨틱 속성은 [OpenTelemetry 내보내기](/ko/gateway/opentelemetry)를 참고하세요.
|
||||
|
||||
## 빠른 시작
|
||||
|
||||
@ -39,7 +39,7 @@ GET /api/diagnostics/prometheus
|
||||
</Step>
|
||||
<Step title="Plugin 활성화">
|
||||
<Tabs>
|
||||
<Tab title="구성">
|
||||
<Tab title="Config">
|
||||
```json5
|
||||
{
|
||||
plugins: {
|
||||
@ -62,10 +62,10 @@ GET /api/diagnostics/prometheus
|
||||
</Tabs>
|
||||
</Step>
|
||||
<Step title="Gateway 다시 시작">
|
||||
HTTP 경로는 Plugin 시작 시 등록되므로, 활성화한 뒤 다시 로드하세요.
|
||||
HTTP 라우트는 Plugin 시작 시 등록되므로 활성화한 뒤 다시 로드하세요.
|
||||
</Step>
|
||||
<Step title="보호된 경로 스크레이프">
|
||||
운영자 클라이언트가 사용하는 것과 동일한 Gateway 인증을 보내세요.
|
||||
<Step title="보호된 라우트 스크레이프">
|
||||
운영자 클라이언트가 사용하는 것과 동일한 Gateway 인증을 보내세요:
|
||||
|
||||
```bash
|
||||
curl -H "Authorization: Bearer $OPENCLAW_GATEWAY_TOKEN" \
|
||||
@ -89,7 +89,7 @@ GET /api/diagnostics/prometheus
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
`diagnostics.enabled: true`가 필요합니다. 이 값이 없으면 Plugin은 여전히 HTTP 경로를 등록하지만 진단 이벤트가 내보내기 도구로 유입되지 않으므로 응답이 비어 있습니다.
|
||||
`diagnostics.enabled: true`가 필요합니다. 이 값이 없으면 Plugin은 여전히 HTTP 라우트를 등록하지만 내보내기로 진단 이벤트가 흐르지 않으므로 응답이 비어 있습니다.
|
||||
</Note>
|
||||
|
||||
## 내보내는 메트릭
|
||||
@ -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
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="제한된 저카디널리티 레이블">
|
||||
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`으로 대체됩니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="시리즈 한도 및 초과 계산">
|
||||
내보내기 도구는 카운터, 게이지, 히스토그램을 합쳐 메모리에 보관하는 시계열을 **2048**개로 제한합니다. 이 한도를 넘는 새 시리즈는 삭제되며, 그때마다 `openclaw_prometheus_series_dropped_total`이 1씩 증가합니다.
|
||||
<Accordion title="시리즈 한도와 오버플로 계정">
|
||||
exporter는 메모리에 보존되는 시계열을 카운터, 게이지, 히스토그램을 합쳐 **2048**개 시리즈로 제한합니다. 이 한도를 넘는 새 시리즈는 삭제되며, 그때마다 `openclaw_prometheus_series_dropped_total`이 1씩 증가합니다.
|
||||
|
||||
이 카운터는 상위 속성이 고카디널리티 값을 누출하고 있음을 나타내는 강한 신호로 관찰하세요. 내보내기 도구는 한도를 자동으로 올리지 않습니다. 값이 증가하면 한도를 비활성화하지 말고 원인을 수정하세요.
|
||||
이 카운터를 상위 속성에서 높은 카디널리티 값이 누출되고 있다는 강한 신호로 관찰하세요. exporter는 한도를 자동으로 올리지 않습니다. 값이 증가하면 한도를 비활성화하지 말고 원인을 수정하세요.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Prometheus 출력에 절대 나타나지 않는 항목">
|
||||
- 프롬프트 텍스트, 응답 텍스트, 도구 입력, 도구 출력, 시스템 프롬프트
|
||||
- 원시 공급자 요청 ID(해당하는 경우 span에는 제한된 해시만 포함되며, 메트릭에는 절대 포함되지 않음)
|
||||
- Talk 대화 기록, 오디오 페이로드, 호출 ID, 방 ID, 핸드오프 토큰, 턴 ID, 원시 세션 ID
|
||||
- 원시 제공자 요청 ID(해당하는 경우 span에는 제한된 해시만 포함되며, 메트릭에는 절대 포함되지 않음)
|
||||
- 세션 키와 세션 ID
|
||||
- 호스트 이름, 파일 경로, 비밀 값
|
||||
|
||||
@ -172,26 +179,26 @@ increase(openclaw_prometheus_series_dropped_total[15m]) > 0
|
||||
```
|
||||
|
||||
<Tip>
|
||||
교차 공급자 대시보드에는 `gen_ai_client_token_usage`를 선호하세요. 이 메트릭은 OpenTelemetry GenAI 의미론적 규칙을 따르며 OpenClaw가 아닌 GenAI 서비스의 메트릭과도 일관됩니다.
|
||||
교차 제공자 대시보드에는 `gen_ai_client_token_usage`를 선호하세요. 이는 OpenTelemetry GenAI 의미 체계 규칙을 따르며 OpenClaw가 아닌 GenAI 서비스의 메트릭과도 일관됩니다.
|
||||
</Tip>
|
||||
|
||||
## Prometheus와 OpenTelemetry 내보내기 중 선택하기
|
||||
## Prometheus와 OpenTelemetry 내보내기 중 선택
|
||||
|
||||
OpenClaw는 두 표면을 독립적으로 모두 지원합니다. 둘 중 하나만 실행하거나, 둘 다 실행하거나, 둘 다 실행하지 않을 수 있습니다.
|
||||
OpenClaw는 두 인터페이스를 독립적으로 모두 지원합니다. 둘 중 하나를 실행하거나, 둘 다 실행하거나, 둘 다 실행하지 않을 수 있습니다.
|
||||
|
||||
<Tabs>
|
||||
<Tab title="diagnostics-prometheus">
|
||||
- **Pull** 모델: Prometheus가 `/api/diagnostics/prometheus`를 스크레이프합니다.
|
||||
- 외부 수집기가 필요 없습니다.
|
||||
- 외부 collector가 필요하지 않습니다.
|
||||
- 일반 Gateway 인증을 통해 인증됩니다.
|
||||
- 표면은 메트릭 전용입니다(트레이스 또는 로그 없음).
|
||||
- 이미 Prometheus + Grafana로 표준화된 스택에 가장 적합합니다.
|
||||
- 인터페이스는 메트릭 전용입니다(트레이스나 로그 없음).
|
||||
- Prometheus + Grafana로 이미 표준화된 스택에 가장 적합합니다.
|
||||
|
||||
</Tab>
|
||||
<Tab title="diagnostics-otel">
|
||||
- **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)를 참조하세요.
|
||||
|
||||
</Tab>
|
||||
@ -200,26 +207,26 @@ OpenClaw는 두 표면을 독립적으로 모두 지원합니다. 둘 중 하나
|
||||
## 문제 해결
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="빈 응답 본문">
|
||||
- 구성에서 `diagnostics.enabled: true`를 확인하세요.
|
||||
- `openclaw plugins list --enabled`로 Plugin이 활성화되고 로드되었는지 확인하세요.
|
||||
- 일부 트래픽을 생성하세요. 카운터와 히스토그램은 이벤트가 하나 이상 발생한 뒤에만 줄을 내보냅니다.
|
||||
<Accordion title="응답 본문이 비어 있음">
|
||||
- config에서 `diagnostics.enabled: true`를 확인하세요.
|
||||
- Plugin이 활성화되어 있고 `openclaw plugins list --enabled`로 로드되었는지 확인하세요.
|
||||
- 트래픽을 생성하세요. 카운터와 히스토그램은 이벤트가 하나 이상 발생한 뒤에만 줄을 내보냅니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="401 / 인증되지 않음">
|
||||
엔드포인트에는 Gateway 운영자 범위(`auth: "gateway"`와 `gatewayRuntimeScopeSurface: "trusted-operator"`)가 필요합니다. Prometheus가 다른 Gateway 운영자 경로에 사용하는 것과 동일한 토큰 또는 비밀번호를 사용하세요. 공개 미인증 모드는 없습니다.
|
||||
엔드포인트에는 Gateway operator 범위(`auth: "gateway"` 및 `gatewayRuntimeScopeSurface: "trusted-operator"`)가 필요합니다. Prometheus가 다른 Gateway operator 경로에 사용하는 것과 동일한 토큰 또는 비밀번호를 사용하세요. 공개 미인증 모드는 없습니다.
|
||||
</Accordion>
|
||||
<Accordion title="`openclaw_prometheus_series_dropped_total`이 증가하는 경우">
|
||||
새 속성이 **2048**개 시리즈 한도를 초과하고 있습니다. 최근 메트릭에서 예기치 않게 카디널리티가 높은 레이블을 검사하고 원인을 수정하세요. 내보내기 도구는 레이블을 조용히 다시 쓰는 대신 의도적으로 새 시리즈를 삭제합니다.
|
||||
<Accordion title="`openclaw_prometheus_series_dropped_total`이 증가함">
|
||||
새 속성이 **2048**개 시리즈 한도를 초과하고 있습니다. 최근 메트릭에서 예상치 못하게 카디널리티가 높은 label을 점검하고 원인에서 수정하세요. exporter는 label을 조용히 다시 쓰는 대신 의도적으로 새 시리즈를 삭제합니다.
|
||||
</Accordion>
|
||||
<Accordion title="다시 시작한 뒤 Prometheus에 오래된 시리즈가 표시되는 경우">
|
||||
Plugin은 상태를 메모리에만 보관합니다. Gateway를 다시 시작하면 카운터는 0으로 재설정되고 게이지는 다음에 보고된 값에서 다시 시작합니다. 재설정을 깔끔하게 처리하려면 PromQL `rate()`와 `increase()`를 사용하세요.
|
||||
<Accordion title="Gateway 재시작 후 Prometheus에 오래된 시리즈가 표시됨">
|
||||
Plugin은 상태를 메모리에만 보관합니다. Gateway를 재시작하면 카운터는 0으로 재설정되고 게이지는 다음에 보고되는 값에서 다시 시작합니다. 재설정을 깔끔하게 처리하려면 PromQL `rate()`와 `increase()`를 사용하세요.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
## 관련 항목
|
||||
## 관련
|
||||
|
||||
- [진단 내보내기](/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 푸시
|
||||
|
||||
@ -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://<magicdns>/`(또는 구성된 `gateway.controlUi.basePath`)
|
||||
열기: `https://<magicdns>/`(또는 구성한 `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://<tailscale-ip>:18789/`
|
||||
- WebSocket: `ws://<tailscale-ip>:18789`
|
||||
|
||||
<Note>
|
||||
Loopback(`http://127.0.0.1:18789`)은 이 모드에서 작동하지 **않습니다**.
|
||||
이 모드에서는 루프백(`http://127.0.0.1:18789`)이 작동하지 **않습니다**.
|
||||
</Note>
|
||||
|
||||
### 공개 인터넷(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 앱 변형이 필요합니다.
|
||||
|
||||
## 더 알아보기
|
||||
|
||||
1190
docs/ko/help/faq.md
1190
docs/ko/help/faq.md
File diff suppressed because it is too large
Load Diff
@ -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 사용
|
||||
|
||||
<Steps>
|
||||
<Step title="Fly 앱 만들기">
|
||||
<Step title="Fly 앱 생성">
|
||||
```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`(산호세).
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="fly.toml 구성">
|
||||
앱 이름과 요구 사항에 맞게 `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"` | 볼륨에 상태를 영구 저장합니다 |
|
||||
|
||||
</Step>
|
||||
|
||||
@ -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`에 시크릿이 들어가지 않습니다.
|
||||
|
||||
</Step>
|
||||
|
||||
@ -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:
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="설정 파일 만들기">
|
||||
머신에 SSH로 접속해 적절한 설정을 만듭니다.
|
||||
<Step title="구성 파일 생성">
|
||||
머신에 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:
|
||||
</Step>
|
||||
|
||||
<Step title="Gateway 접근">
|
||||
### 제어 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 <machine-id> --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 <machine-id>
|
||||
|
||||
잠금 파일은 하위 디렉터리가 아니라 `/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 <machine-id> --command "node dist/index.js gateway --port 300
|
||||
fly machine update <machine-id> --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)
|
||||
|
||||
@ -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/<agentId>/agent/auth-profiles.json`, `.env`가 포함됩니다.
|
||||
`agents/<agentId>/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에서 수행할 수 있습니다.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="GCP 프로젝트 만들기">
|
||||
<Step title="GCP 프로젝트 생성">
|
||||
**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" 검색 > 활성화
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="VM 만들기">
|
||||
<Step title="VM 생성">
|
||||
**머신 유형:**
|
||||
|
||||
| 유형 | 사양 | 비용 | 참고 |
|
||||
| --------- | ------------------------ | ------------------ | -------------------------------------------- |
|
||||
| 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도 작동합니다. 패키지를 그에 맞게 매핑하세요.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="VM에 SSH로 접속">
|
||||
<Step title="VM에 SSH 접속">
|
||||
**CLI:**
|
||||
|
||||
```bash
|
||||
@ -157,7 +157,7 @@ Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요.
|
||||
|
||||
Compute Engine 대시보드에서 VM 옆의 "SSH" 버튼을 클릭합니다.
|
||||
|
||||
참고: VM 생성 후 SSH 키 전파에는 1-2분이 걸릴 수 있습니다. 연결이 거부되면 기다렸다가 다시 시도하세요.
|
||||
참고: VM 생성 후 SSH 키 전파에 1-2분이 걸릴 수 있습니다. 연결이 거부되면 기다린 뒤 다시 시도하세요.
|
||||
|
||||
</Step>
|
||||
|
||||
@ -169,7 +169,7 @@ Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요.
|
||||
sudo usermod -aG docker $USER
|
||||
```
|
||||
|
||||
그룹 변경 사항을 적용하려면 로그아웃했다가 다시 로그인합니다.
|
||||
그룹 변경이 적용되도록 로그아웃한 뒤 다시 로그인합니다.
|
||||
|
||||
```bash
|
||||
exit
|
||||
@ -200,9 +200,9 @@ Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="영구 호스트 디렉터리 만들기">
|
||||
<Step title="영구 호스트 디렉터리 생성">
|
||||
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/<agentId>/agent/auth-profiles.json`에 있습니다.
|
||||
|
||||
</Step>
|
||||
@ -283,14 +282,14 @@ Ubuntu도 작동합니다. 패키지를 그에 맞게 매핑하세요.
|
||||
]
|
||||
```
|
||||
|
||||
`--allow-unconfigured`는 부트스트랩 편의를 위한 것일 뿐이며, 적절한 Gateway 구성을 대체하지 않습니다. 배포에 맞게 인증(`gateway.auth.token` 또는 비밀번호)을 설정하고 안전한 바인드 설정을 사용하세요.
|
||||
`--allow-unconfigured`는 부트스트랩 편의를 위한 것일 뿐이며, 적절한 gateway 구성을 대체하지 않습니다. 배포 환경에 맞게 인증(`gateway.auth.token` 또는 비밀번호)을 설정하고 안전한 bind 설정을 사용하세요.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="공유 Docker VM 런타임 단계">
|
||||
일반적인 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도 작동합니다. 패키지를 그에 맞게 매핑하세요.
|
||||
</Step>
|
||||
|
||||
<Step title="GCP별 실행 참고 사항">
|
||||
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`를 구성한 포트로 바꾸세요.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="노트북에서 액세스">
|
||||
Gateway 포트를 전달하도록 SSH 터널을 만듭니다.
|
||||
<Step title="노트북에서 접근">
|
||||
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 <requestId>
|
||||
```
|
||||
|
||||
공유 지속성과 업데이트 참조가 다시 필요한가요?
|
||||
공유 지속성과 업데이트 참고 자료가 다시 필요하신가요?
|
||||
[Docker VM Runtime](/ko/install/docker-vm-runtime#what-persists-where) 및 [Docker VM Runtime 업데이트](/ko/install/docker-vm-runtime#updates)를 참조하세요.
|
||||
|
||||
</Step>
|
||||
@ -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)
|
||||
|
||||
@ -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/<agentId>/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가 상태를 유지한다고 가정합니다.
|
||||
이를 일회용 인프라로 취급하지 마세요.
|
||||
이를 폐기 가능한 인프라로 취급하지 마세요.
|
||||
|
||||
</Step>
|
||||
|
||||
@ -104,7 +102,7 @@ Gateway에는 다음 방식으로 액세스할 수 있습니다:
|
||||
curl -fsSL https://get.docker.com | sh
|
||||
```
|
||||
|
||||
확인합니다:
|
||||
확인:
|
||||
|
||||
```bash
|
||||
docker --version
|
||||
@ -119,13 +117,13 @@ Gateway에는 다음 방식으로 액세스할 수 있습니다:
|
||||
cd openclaw
|
||||
```
|
||||
|
||||
이 가이드는 바이너리 영속성을 보장하기 위해 사용자 지정 이미지를 빌드한다고 가정합니다.
|
||||
이 가이드는 바이너리 지속성을 보장하기 위해 사용자 지정 이미지를 빌드한다고 가정합니다.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="영구 호스트 디렉터리 생성">
|
||||
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/<agentId>/agent/auth-profiles.json`에 있습니다.
|
||||
|
||||
</Step>
|
||||
@ -208,34 +205,34 @@ Gateway에는 다음 방식으로 액세스할 수 있습니다:
|
||||
]
|
||||
```
|
||||
|
||||
`--allow-unconfigured`는 부트스트랩 편의를 위한 것일 뿐이며, 적절한 gateway 구성을 대체하지 않습니다. 배포 환경에 맞게 인증(`gateway.auth.token` 또는 비밀번호)을 설정하고 안전한 bind 설정을 사용하세요.
|
||||
`--allow-unconfigured`는 부트스트랩 편의를 위한 것일 뿐이며, 적절한 gateway 구성을 대체하지 않습니다. 배포 환경에는 여전히 인증(`gateway.auth.token` 또는 비밀번호)을 설정하고 안전한 바인딩 설정을 사용하세요.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="공유 Docker VM 런타임 단계">
|
||||
일반적인 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)
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Hetzner별 액세스">
|
||||
공유 빌드 및 실행 단계를 완료한 후, 터널을 열기 위해 다음 설정을 완료합니다:
|
||||
<Step title="Hetzner 전용 접근">
|
||||
공유 빌드 및 실행 단계를 마친 후, 터널을 열기 위해 다음 설정을 완료하세요:
|
||||
|
||||
**필수 조건:** 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 토큰을 사용합니다. 비밀번호 인증으로 전환했다면 대신 해당 비밀번호를 사용하세요.
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
공유 영속성 맵은 [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 설정을 보완합니다.
|
||||
|
||||
<Note>
|
||||
커뮤니티에서 유지 관리합니다. 문제나 기여는 위의 저장소 링크를 참고하세요.
|
||||
커뮤니티에서 유지 관리합니다. 문제나 기여는 위 저장소 링크를 참고하세요.
|
||||
</Note>
|
||||
|
||||
## 다음 단계
|
||||
|
||||
@ -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 모듈입니다.
|
||||
|
||||
<Info>
|
||||
[nix-openclaw](https://github.com/openclaw/nix-openclaw) 저장소는 Nix 설치의 기준 소스입니다. 이 페이지는 간단한 개요입니다.
|
||||
[nix-openclaw](https://github.com/openclaw/nix-openclaw) 저장소는 Nix 설치의 단일 기준입니다. 이 페이지는 간단한 개요입니다.
|
||||
</Info>
|
||||
|
||||
## 제공되는 것
|
||||
|
||||
- Gateway + macOS 앱 + 도구(whisper, spotify, cameras) -- 모두 고정됨
|
||||
- 재부팅 후에도 유지되는 launchd 서비스
|
||||
- 선언적 구성을 지원하는 Plugin 시스템
|
||||
- 선언적 설정을 지원하는 Plugin 시스템
|
||||
- 즉시 롤백: `home-manager switch --rollback`
|
||||
|
||||
## 빠른 시작
|
||||
|
||||
<Steps>
|
||||
<Step title="Install Determinate Nix">
|
||||
Nix가 아직 설치되어 있지 않다면 [Determinate Nix installer](https://github.com/DeterminateSystems/nix-installer) 안내를 따르세요.
|
||||
<Step title="Determinate Nix 설치">
|
||||
Nix가 아직 설치되어 있지 않다면 [Determinate Nix installer](https://github.com/DeterminateSystems/nix-installer) 지침을 따르세요.
|
||||
</Step>
|
||||
<Step title="Create a local flake">
|
||||
nix-openclaw 저장소의 에이전트 우선 템플릿을 사용하세요.
|
||||
<Step title="로컬 flake 만들기">
|
||||
nix-openclaw 저장소의 agent-first 템플릿을 사용하세요.
|
||||
```bash
|
||||
mkdir -p ~/code/openclaw-local
|
||||
# Copy templates/agent-first/flake.nix from the nix-openclaw repo
|
||||
```
|
||||
</Step>
|
||||
<Step title="Configure secrets">
|
||||
<Step title="시크릿 설정">
|
||||
메시징 봇 토큰과 모델 제공자 API 키를 설정하세요. `~/.secrets/`의 일반 파일로도 충분합니다.
|
||||
</Step>
|
||||
<Step title="Fill in template placeholders and switch">
|
||||
<Step title="템플릿 플레이스홀더를 채우고 전환">
|
||||
```bash
|
||||
home-manager switch
|
||||
```
|
||||
</Step>
|
||||
<Step title="Verify">
|
||||
<Step title="확인">
|
||||
launchd 서비스가 실행 중이고 봇이 메시지에 응답하는지 확인하세요.
|
||||
</Step>
|
||||
</Steps>
|
||||
@ -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.<name>.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 프로필 바이너리를 자동으로
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="nix-openclaw" href="https://github.com/openclaw/nix-openclaw" icon="arrow-up-right-from-square">
|
||||
기준 소스 Home Manager 모듈 및 전체 설정 가이드입니다.
|
||||
단일 기준인 Home Manager 모듈 및 전체 설정 가이드입니다.
|
||||
</Card>
|
||||
<Card title="Setup wizard" href="/ko/start/wizard" icon="wand-magic-sparkles">
|
||||
<Card title="설정 마법사" href="/ko/start/wizard" icon="wand-magic-sparkles">
|
||||
Nix를 사용하지 않는 CLI 설정 안내입니다.
|
||||
</Card>
|
||||
<Card title="Docker" href="/ko/install/docker" icon="docker">
|
||||
Nix를 사용하지 않는 대안인 컨테이너 기반 설정입니다.
|
||||
Nix 대안으로 컨테이너화된 설정입니다.
|
||||
</Card>
|
||||
<Card title="Updating" href="/ko/install/updating" icon="arrow-up-right-from-square">
|
||||
<Card title="업데이트" href="/ko/install/updating" icon="arrow-up-right-from-square">
|
||||
패키지와 함께 Home Manager로 관리되는 설치를 업데이트합니다.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@ -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 <url>` / `--token <token>` / `--timeout <ms>`: 표준 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 <level>`**(예: `openclaw --log-level debug gateway run`)도 전달할 수 있으며, 해당 명령에 대해 환경 변수를 재정의합니다.
|
||||
**`OPENCLAW_LOG_LEVEL`** 환경 변수(예: `OPENCLAW_LOG_LEVEL=debug`)로 둘 다 재정의할 수 있습니다. 환경 변수는 구성 파일보다 우선하므로 `openclaw.json`을 편집하지 않고 단일 실행의 상세도를 높일 수 있습니다. 또한 전역 CLI 옵션 **`--log-level <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.*` 필드 참조
|
||||
|
||||
@ -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.<chatId>.disableAudioPreflight: true`를 설정하세요.
|
||||
- 주제별로 재정의하려면 `channels.telegram.groups.<chatId>.topics.<threadId>.disableAudioPreflight`를 설정하세요(건너뛰려면 `true`, 강제로 활성화하려면 `false`).
|
||||
- 해당 그룹의 preflight 전사문 멘션 확인을 건너뛰려면 `channels.telegram.groups.<chatId>.disableAudioPreflight: true`를 설정하세요.
|
||||
- topic별로 재정의하려면 `channels.telegram.groups.<chatId>.topics.<threadId>.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는 `<output-dir>/<media-basename>.txt`를 읽습니다. `txt`가 아닌 출력 형식은 stdout 파싱으로 폴백합니다.
|
||||
- 답장 큐가 차단되지 않도록 타임아웃을 합리적으로 유지하세요(`timeoutSeconds`, 기본값 60초).
|
||||
- `parakeet-mlx`의 경우 `--output-dir`를 전달하면, `--output-format`이 `txt`이거나 생략되었을 때 OpenClaw는 `<output-dir>/<media-basename>.txt`를 읽습니다. `txt`가 아닌 출력 형식은 stdout 파싱으로 fallback합니다.
|
||||
- 응답 큐가 차단되지 않도록 시간 초과(`timeoutSeconds`, 기본값 60초)를 합리적으로 유지하세요.
|
||||
- preflight 전사는 멘션 감지를 위해 **첫 번째** 오디오 첨부 파일만 처리합니다. 추가 오디오는 기본 미디어 이해 단계에서 처리됩니다.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
- [미디어 이해](/ko/nodes/media-understanding)
|
||||
- [대화 모드](/ko/nodes/talk)
|
||||
- [음성 깨우기](/ko/nodes/voicewake)
|
||||
- [음성 wake](/ko/nodes/voicewake)
|
||||
|
||||
@ -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 <path-or-url> [--message <caption>]`
|
||||
- `--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/<filename>` 같은 상대 경로로 다시 작성됩니다.
|
||||
- 미디어 이해(`tools.media.*` 또는 공유 `tools.media.models`를 통해 구성된 경우)는 템플릿 처리 전에 실행되며, `Body`에 `[Image]`, `[Audio]`, `[Video]` 블록을 삽입할 수 있습니다.
|
||||
- 오디오는 `{{Transcript}}`를 설정하고 명령 파싱에 전사를 사용하므로 슬래시 명령이 계속 작동합니다.
|
||||
- 동영상 및 이미지 설명은 명령 파싱을 위해 모든 캡션 텍스트를 보존합니다.
|
||||
- 활성 기본 이미지 모델이 이미 비전을 기본 지원하는 경우, OpenClaw는 `[Image]` 요약 블록을 건너뛰고 원본 이미지를 대신 모델에 전달합니다.
|
||||
- 기본적으로 일치하는 첫 번째 이미지/오디오/동영상 첨부 파일만 처리됩니다. 여러 첨부 파일을 처리하려면 `tools.media.<cap>.attachments`를 설정하세요.
|
||||
- 인바운드 웹 메시지에 미디어가 포함된 경우 OpenClaw는 임시 파일로 다운로드하고 템플릿 변수를 노출합니다.
|
||||
- 인바운드 미디어용 `{{MediaUrl}}` 의사 URL.
|
||||
- 명령 실행 전에 작성되는 `{{MediaPath}}` 로컬 임시 경로.
|
||||
- 세션별 Docker 샌드박스가 활성화된 경우 인바운드 미디어는 샌드박스 워크스페이스로 복사되고, `MediaPath`/`MediaUrl`은 `media/inbound/<filename>` 같은 상대 경로로 다시 작성됩니다.
|
||||
- 미디어 이해가 `tools.media.*` 또는 공유 `tools.media.models`를 통해 구성된 경우 템플릿 처리 전에 실행되며, `[Image]`, `[Audio]`, `[Video]` 블록을 `Body`에 삽입할 수 있습니다.
|
||||
- 오디오는 `{{Transcript}}`를 설정하고 명령 파싱에 전사문을 사용하므로 슬래시 명령도 계속 작동합니다.
|
||||
- 비디오 및 이미지 설명은 명령 파싱을 위해 모든 캡션 텍스트를 보존합니다.
|
||||
- 활성 기본 이미지 모델이 이미 기본적으로 비전을 지원하는 경우 OpenClaw는 `[Image]` 요약 블록을 건너뛰고 대신 원본 이미지를 모델에 전달합니다.
|
||||
- 기본적으로 일치하는 첫 번째 이미지/오디오/비디오 첨부 파일만 처리됩니다. 여러 첨부 파일을 처리하려면 `tools.media.<cap>.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`).
|
||||
- 너무 큰 미디어는 이해 단계를 건너뛰지만, 응답은 원본 본문으로 계속 진행됩니다.
|
||||
|
||||
## 테스트 참고 사항
|
||||
|
||||
- 이미지/오디오/문서 사례에 대한 전송 및 응답 흐름을 다룹니다.
|
||||
- 이미지의 재압축(크기 제한)과 오디오의 음성 메모 플래그를 검증합니다.
|
||||
- 이미지 재압축(크기 제한)과 오디오의 음성 메모 플래그를 검증합니다.
|
||||
- 여러 미디어 응답이 순차 전송으로 확장되는지 확인합니다.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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 <spec> --omit=dev --ignore-scripts --no-audit --no-fund
|
||||
```
|
||||
|
||||
`openclaw plugins install npm-pack:<path.tgz>`는 로컬 npm-pack 타볼에 대해
|
||||
동일한 관리형 npm 루트를 사용합니다. OpenClaw는 타볼의 npm 메타데이터를
|
||||
읽고, 복사된 `file:` 종속성으로 관리형 루트에 추가한 뒤, 일반 npm 설치를
|
||||
실행하고, Plugin을 신뢰하기 전에 설치된 lockfile 메타데이터를 검증합니다.
|
||||
이는 로컬 pack 산출물이 시뮬레이션하는 레지스트리 산출물처럼 동작해야 하는
|
||||
패키지 수락 및 릴리스 후보 증명 용도입니다.
|
||||
`openclaw plugins install npm-pack:<path.tgz>`는 로컬 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 <id>
|
||||
@ -106,44 +80,26 @@ openclaw plugins install <source>
|
||||
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/<id>`에서 로드되므로 패키지
|
||||
로컬 워크스페이스 종속성을 사용할 수 있고 편집 내용이 직접 반영됩니다. 소스
|
||||
체크아웃 개발은 pnpm 전용입니다. 저장소 루트에서 일반 `npm install`을
|
||||
실행하는 것은 번들 Plugin 종속성을 준비하는 지원되는 방법이 아닙니다.
|
||||
소스 checkout에서 OpenClaw는 저장소를 pnpm monorepo로 취급합니다. `pnpm install` 후에는 번들 Plugin이 `extensions/<id>`에서 로드되므로 패키지 로컬 workspace 의존성을 사용할 수 있고, 편집 내용이 직접 반영됩니다. 소스 checkout 개발은 pnpm 전용입니다. 저장소 루트에서 일반 `npm install`을 실행하는 것은 번들 Plugin 의존성을 준비하는 지원 방식이 아닙니다.
|
||||
|
||||
| 설치 형태 | 번들 Plugin 위치 | 종속성 소유자 |
|
||||
| 설치 형태 | 번들 Plugin 위치 | 의존성 소유자 |
|
||||
| -------------------------------- | ------------------------------------- | -------------------------------------------------------------------- |
|
||||
| `npm install -g openclaw` | 패키지 내부의 빌드된 런타임 트리 | OpenClaw 패키지 및 명시적 Plugin 설치/업데이트/doctor 흐름 |
|
||||
| Git 체크아웃 및 `pnpm install` | `extensions/<id>` 워크스페이스 패키지 | 각 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/<id>` 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가 남지 않습니다.
|
||||
|
||||
이 경로들은 레거시 잔여물일 뿐입니다. 새 설치에서는 이를 생성하지 않아야 합니다.
|
||||
이 경로들은 레거시 잔여물일 뿐입니다. 새 설치가 이들을 생성해서는 안 됩니다.
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -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.<hookName>`은 `hooks.timeoutMs`를 재정의하고, 이는 Plugin 작성자가 지정한 `api.on(..., { timeoutMs })` 값을 재정의합니다. 구성된 각 값은 600000밀리초 이하의 양의 정수여야 합니다. 알려진 느린 훅에는 훅별 재정의를 선호하여 한 Plugin이 모든 곳에서 더 긴 예산을 받지 않게 하세요.
|
||||
`hooks.timeouts.<hookName>`은 `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.<id>.hooks.allowPromptInjection=false`로 비활성화할 수 있습니다.
|
||||
프롬프트를 변경하는 훅과 지속되는 다음 턴 주입은 Plugin별로
|
||||
`plugins.entries.<id>.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)
|
||||
|
||||
@ -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 <plugin-id> --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 <plugin-id>` 호출은 기록된 해당 태그를 재사용합니다. 명시적인 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 <plugin-id> --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:<package>
|
||||
openclaw plugins install <package>
|
||||
```
|
||||
|
||||
접두사가 없는 형식은 여전히 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 <package>
|
||||
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) - 매니페스트 및 패키지 메타데이터
|
||||
|
||||
@ -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` 객체에 대한 참조입니다. 호스트 내부 구현을 직접 가져오는 대신 이 헬퍼를 사용하세요.
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="채널 Plugin" href="/ko/plugins/sdk-channel-plugins">
|
||||
채널 Plugin에서 이러한 헬퍼를 맥락에 맞게 사용하는 단계별 가이드입니다.
|
||||
채널 Plugin에서 이 헬퍼를 맥락에 맞게 사용하는 단계별 가이드입니다.
|
||||
</Card>
|
||||
<Card title="프로바이더 Plugin" href="/ko/plugins/sdk-provider-plugins">
|
||||
프로바이더 Plugin에서 이러한 헬퍼를 맥락에 맞게 사용하는 단계별 가이드입니다.
|
||||
<Card title="제공자 Plugin" href="/ko/plugins/sdk-provider-plugins">
|
||||
제공자 Plugin에서 이 헬퍼를 맥락에 맞게 사용하는 단계별 가이드입니다.
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
@ -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(...)`는 호환성과 오프라인 유지보수식 재작성에 사용할 수 있도록 남아 있습니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="api.runtime.agent.defaults">
|
||||
기본 모델 및 프로바이더 상수입니다.
|
||||
기본 모델 및 제공자 상수입니다.
|
||||
|
||||
```typescript
|
||||
const model = api.runtime.agent.defaults.model; // e.g. "anthropic/claude-sonnet-4-6"
|
||||
@ -166,14 +169,14 @@ register(api) {
|
||||
```
|
||||
|
||||
<Warning>
|
||||
모델 재정의(`provider`/`model`)에는 config에서 `plugins.entries.<id>.subagent.allowModelOverride: true`를 통한 운영자 옵트인이 필요합니다. 신뢰할 수 없는 Plugin도 하위 에이전트를 실행할 수 있지만, 재정의 요청은 거부됩니다.
|
||||
모델 재정의(`provider`/`model`)에는 구성에서 `plugins.entries.<id>.subagent.allowModelOverride: true`를 통해 운영자의 옵트인이 필요합니다. 신뢰할 수 없는 Plugin도 하위 에이전트를 실행할 수는 있지만, 재정의 요청은 거부됩니다.
|
||||
</Warning>
|
||||
|
||||
`deleteSession(...)`은 같은 Plugin이 `api.runtime.subagent.run(...)`을 통해 만든 세션을 삭제할 수 있습니다. 임의의 사용자 또는 운영자 세션을 삭제하려면 여전히 관리자 범위의 Gateway 요청이 필요합니다.
|
||||
`deleteSession(...)`은 동일한 Plugin이 `api.runtime.subagent.run(...)`을 통해 생성한 세션을 삭제할 수 있습니다. 임의의 사용자 또는 운영자 세션을 삭제하려면 여전히 관리자 범위의 Gateway 요청이 필요합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="api.runtime.nodes">
|
||||
연결된 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 도구가 같은 강제 적용 경로를 공유합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="api.runtime.tasks.managedFlows">
|
||||
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 })`을 사용하세요. 원시 사용자 입력에서 바인딩하지 마세요.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="api.runtime.tts">
|
||||
@ -245,7 +248,7 @@ register(api) {
|
||||
});
|
||||
```
|
||||
|
||||
코어 `messages.tts` 구성과 프로바이더 선택을 사용합니다. PCM 오디오 버퍼와 샘플 레이트를 반환합니다.
|
||||
코어 `messages.tts` 구성과 제공자 선택을 사용합니다. PCM 오디오 버퍼와 샘플 레이트를 반환합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="api.runtime.mediaUnderstanding">
|
||||
@ -279,7 +282,7 @@ register(api) {
|
||||
});
|
||||
```
|
||||
|
||||
출력이 생성되지 않으면(예: 건너뛴 입력) `{ text: undefined }`를 반환합니다.
|
||||
출력이 생성되지 않으면(예: 입력이 건너뛰어진 경우) `{ text: undefined }`를 반환합니다.
|
||||
|
||||
<Info>
|
||||
`api.runtime.stt.transcribeAudioFile(...)`는 `api.runtime.mediaUnderstanding.transcribeAudioFile(...)`의 호환성 별칭으로 유지됩니다.
|
||||
@ -338,7 +341,7 @@ register(api) {
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="api.runtime.config">
|
||||
현재 런타임 구성 스냅샷과 트랜잭션 방식의 구성 쓰기입니다. 활성 호출 경로에 이미 전달된 구성을 우선 사용하고, 핸들러가 프로세스 스냅샷을 직접 필요로 할 때만 `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에서 재시작 제어권을 가져오지 않고 작성자의 의도를 기록합니다.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="api.runtime.system">
|
||||
@ -392,7 +395,7 @@ register(api) {
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="api.runtime.modelAuth">
|
||||
모델 및 provider 인증 확인.
|
||||
모델 및 공급자 인증 확인.
|
||||
|
||||
```typescript
|
||||
const auth = await api.runtime.modelAuth.getApiKeyForModel({ model, cfg });
|
||||
@ -404,7 +407,7 @@ register(api) {
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="api.runtime.state">
|
||||
상태 디렉터리 확인 및 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 만료.
|
||||
|
||||
<Warning>
|
||||
이 릴리스에서는 번들 Plugin만 지원됩니다.
|
||||
@ -439,7 +442,7 @@ register(api) {
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="api.runtime.channel">
|
||||
채널별 런타임 헬퍼입니다(채널 Plugin이 로드된 경우 사용 가능).
|
||||
채널별 런타임 헬퍼(채널 Plugin이 로드된 경우 사용 가능).
|
||||
|
||||
`api.runtime.channel.mentions`는 런타임 주입을 사용하는 번들 채널 Plugin을 위한 공유 인바운드 멘션 정책 표면입니다.
|
||||
|
||||
@ -483,10 +486,10 @@ register(api) {
|
||||
|
||||
## 런타임 참조 저장
|
||||
|
||||
`register` 콜백 외부에서 사용하도록 런타임 참조를 저장하려면 `createPluginRuntimeStore`를 사용하세요.
|
||||
`register` 콜백 외부에서 사용할 런타임 참조를 저장하려면 `createPluginRuntimeStore`를 사용하세요.
|
||||
|
||||
<Steps>
|
||||
<Step title="Create the store">
|
||||
<Step title="저장소 생성">
|
||||
```typescript
|
||||
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
|
||||
import type { PluginRuntime } from "openclaw/plugin-sdk/runtime-store";
|
||||
@ -498,7 +501,7 @@ register(api) {
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="Wire into the entry point">
|
||||
<Step title="진입점에 연결">
|
||||
```typescript
|
||||
export default defineChannelPluginEntry({
|
||||
id: "my-plugin",
|
||||
@ -509,7 +512,7 @@ register(api) {
|
||||
});
|
||||
```
|
||||
</Step>
|
||||
<Step title="Access from other files">
|
||||
<Step title="다른 파일에서 접근">
|
||||
```typescript
|
||||
export function getRuntime() {
|
||||
return store.getRuntime(); // throws if not initialized
|
||||
@ -524,7 +527,7 @@ register(api) {
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
런타임 저장소 ID에는 `pluginId`를 우선 사용하세요. 저수준 `key` 형식은 하나의 Plugin이 의도적으로 둘 이상의 런타임 슬롯을 필요로 하는 드문 경우에 사용합니다.
|
||||
런타임 저장소 ID에는 `pluginId`를 우선 사용하세요. 저수준 `key` 형식은 하나의 Plugin이 의도적으로 둘 이상의 런타임 슬롯을 필요로 하는 드문 경우를 위한 것입니다.
|
||||
</Note>
|
||||
|
||||
## 기타 최상위 `api` 필드
|
||||
@ -532,7 +535,7 @@ register(api) {
|
||||
`api.runtime` 외에도 API 객체는 다음을 제공합니다.
|
||||
|
||||
<ParamField path="api.id" type="string">
|
||||
Plugin id.
|
||||
Plugin ID.
|
||||
</ParamField>
|
||||
<ParamField path="api.name" type="string">
|
||||
Plugin 표시 이름.
|
||||
@ -547,7 +550,7 @@ register(api) {
|
||||
범위 지정 로거(`debug`, `info`, `warn`, `error`).
|
||||
</ParamField>
|
||||
<ParamField path="api.registrationMode" type="PluginRegistrationMode">
|
||||
현재 로드 모드입니다. `"setup-runtime"`은 전체 엔트리 전의 가벼운 시작/설정 구간입니다.
|
||||
현재 로드 모드입니다. `"setup-runtime"`은 전체 진입 이전의 경량 시작/설정 기간입니다.
|
||||
</ParamField>
|
||||
<ParamField path="api.resolvePath(input)" type="(string) => string">
|
||||
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) — 하위 경로 참조
|
||||
|
||||
@ -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/<routeId>`
|
||||
- `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 <secret>` 또는 `x-openclaw-webhook-secret: <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)
|
||||
|
||||
@ -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 사용자 계정을 자동화합니다.
|
||||
|
||||
<Warning>
|
||||
비공식 자동화는 계정 정지 또는 차단으로 이어질 수 있습니다. 사용에 따른 책임은 사용자에게 있습니다.
|
||||
비공식 자동화는 계정 정지 또는 차단으로 이어질 수 있습니다. 본인 책임하에 사용하세요.
|
||||
</Warning>
|
||||
|
||||
## 명명
|
||||
|
||||
채널 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 <threadId> --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)
|
||||
|
||||
@ -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/` |
|
||||
|
||||
## 시작하기
|
||||
|
||||
<Steps>
|
||||
<Step title="Create an account">
|
||||
[app.kilo.ai](https://app.kilo.ai)로 이동하여 로그인하거나 계정을 만든 다음, API Keys로 이동해 새 키를 생성합니다.
|
||||
<Step title="계정 만들기">
|
||||
[app.kilo.ai](https://app.kilo.ai)로 이동해 로그인하거나 계정을 만든 다음, API Keys로 이동하여 새 키를 생성합니다.
|
||||
</Step>
|
||||
<Step title="Run onboarding">
|
||||
<Step title="온보딩 실행">
|
||||
```bash
|
||||
openclaw onboard --auth-choice kilocode-api-key
|
||||
```
|
||||
@ -42,7 +40,7 @@ Kilo Gateway는 단일 엔드포인트와 API 키 뒤에서 여러 모델로 요
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="Verify the model is available">
|
||||
<Step title="모델 사용 가능 여부 확인">
|
||||
```bash
|
||||
openclaw models list --provider kilocode
|
||||
```
|
||||
@ -51,31 +49,38 @@ Kilo Gateway는 단일 엔드포인트와 API 키 뒤에서 여러 모델로 요
|
||||
|
||||
## 기본 모델
|
||||
|
||||
기본 모델은 Kilo Gateway에서 관리하는 제공자 소유의 스마트 라우팅 모델인 `kilocode/kilo/auto`입니다.
|
||||
기본 모델은 Kilo Gateway가 관리하는 공급자 소유 스마트 라우팅
|
||||
모델인 `kilocode/kilo/auto`입니다.
|
||||
|
||||
<Note>
|
||||
OpenClaw는 `kilocode/kilo/auto`를 안정적인 기본 참조로 취급하지만, 해당 경로에 대해 소스 기반 작업-업스트림-모델 매핑을 게시하지는 않습니다. `kilocode/kilo/auto` 뒤의 정확한 업스트림 라우팅은 OpenClaw에 하드코딩되어 있지 않고 Kilo Gateway가 소유합니다.
|
||||
OpenClaw는 `kilocode/kilo/auto`를 안정적인 기본 참조로 취급하지만, 해당 경로에 대한
|
||||
소스 기반 작업-업스트림 모델 매핑을 게시하지 않습니다. `kilocode/kilo/auto` 뒤의 정확한
|
||||
업스트림 라우팅은 OpenClaw에 하드코딩되어 있지 않고 Kilo Gateway가 소유합니다.
|
||||
</Note>
|
||||
|
||||
## 기본 제공 카탈로그
|
||||
## 내장 카탈로그
|
||||
|
||||
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` 사용 |
|
||||
|
||||
<Tip>
|
||||
시작 시 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`)가 포함됩니다.
|
||||
</Tip>
|
||||
|
||||
## 설정 예시
|
||||
## 구성 예시
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -89,25 +94,31 @@ Gateway에서 사용할 수 있는 모든 모델은 `kilocode/` 접두사와 함
|
||||
```
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Transport and compatibility">
|
||||
Kilo Gateway는 소스에서 OpenRouter 호환으로 문서화되어 있으므로, 네이티브 OpenAI 요청 형태가 아니라 프록시 스타일의 OpenAI 호환 경로를 유지합니다.
|
||||
<Accordion title="전송 및 호환성">
|
||||
Kilo Gateway는 소스에서 OpenRouter 호환으로 문서화되어 있으므로 네이티브 OpenAI 요청 형태가 아니라
|
||||
프록시 스타일의 OpenAI 호환 경로에 유지됩니다.
|
||||
|
||||
- Gemini 기반 Kilo 참조는 프록시-Gemini 경로를 유지하므로, OpenClaw는 네이티브 Gemini 재생 검증이나 부트스트랩 재작성 없이 그곳에서 Gemini 사고 서명 정제를 유지합니다.
|
||||
- Gemini 기반 Kilo 참조는 프록시 Gemini 경로에 유지되므로 OpenClaw는
|
||||
네이티브 Gemini 재생 검증이나 부트스트랩 재작성을 활성화하지 않고도
|
||||
그곳에서 Gemini 사고 서명 정리를 유지합니다.
|
||||
- Kilo Gateway는 내부적으로 API 키와 함께 Bearer 토큰을 사용합니다.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Stream wrapper and reasoning">
|
||||
Kilo의 공유 스트림 래퍼는 제공자 앱 헤더를 추가하고 지원되는 구체 모델 참조에 대해 프록시 추론 페이로드를 정규화합니다.
|
||||
<Accordion title="스트림 래퍼 및 추론">
|
||||
Kilo의 공유 스트림 래퍼는 공급자 앱 헤더를 추가하고 지원되는 구체적인 모델 참조에 대해
|
||||
프록시 추론 페이로드를 정규화합니다.
|
||||
|
||||
<Warning>
|
||||
`kilocode/kilo/auto` 및 기타 프록시 추론 미지원 힌트는 추론 주입을 건너뜁니다. 추론 지원이 필요하면 `kilocode/anthropic/claude-sonnet-4` 같은 구체 모델 참조를 사용하세요.
|
||||
`kilocode/kilo/auto` 및 다른 프록시 추론 미지원 힌트는 추론
|
||||
주입을 건너뜁니다. 추론 지원이 필요하면
|
||||
`kilocode/anthropic/claude-sonnet-4` 같은 구체적인 모델 참조를 사용하세요.
|
||||
</Warning>
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Troubleshooting">
|
||||
- 시작 시 모델 검색에 실패하면 OpenClaw는 `kilocode/kilo/auto`가 포함된 번들 정적 카탈로그로 대체합니다.
|
||||
<Accordion title="문제 해결">
|
||||
- 시작 시 모델 검색에 실패하면 OpenClaw는 `kilocode/kilo/auto`가 포함된 번들 정적 카탈로그로 폴백합니다.
|
||||
- API 키가 유효하고 Kilo 계정에서 원하는 모델이 활성화되어 있는지 확인하세요.
|
||||
- Gateway가 데몬으로 실행되는 경우 해당 프로세스에서 `KILOCODE_API_KEY`를 사용할 수 있는지 확인하세요(예: `~/.openclaw/.env` 또는 `env.shellEnv`를 통해).
|
||||
|
||||
@ -117,11 +128,11 @@ Gateway에서 사용할 수 있는 모든 모델은 `kilocode/` 접두사와 함
|
||||
## 관련 항목
|
||||
|
||||
<CardGroup cols={2}>
|
||||
<Card title="Model selection" href="/ko/concepts/model-providers" icon="layers">
|
||||
제공자, 모델 참조, 장애 조치 동작 선택.
|
||||
<Card title="모델 선택" href="/ko/concepts/model-providers" icon="layers">
|
||||
공급자, 모델 참조, 장애 조치 동작 선택.
|
||||
</Card>
|
||||
<Card title="Configuration reference" href="/ko/gateway/configuration-reference" icon="gear">
|
||||
전체 OpenClaw 설정 참조입니다.
|
||||
<Card title="구성 참조" href="/ko/gateway/configuration-reference" icon="gear">
|
||||
전체 OpenClaw 구성 참조.
|
||||
</Card>
|
||||
<Card title="Kilo Gateway" href="https://app.kilo.ai" icon="arrow-up-right-from-square">
|
||||
Kilo Gateway 대시보드, API 키, 계정 관리.
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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<package.json version>`을 합성합니다; 실제 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<package.json version>`을 합성합니다. 실제 게시는 여전히 실제 릴리스 태그가 필요합니다
|
||||
- 두 워크플로 모두 실제 게시 및 승격 경로는 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 <full-sha>
|
||||
```
|
||||
|
||||
이 helper는 `release-ci/<sha>-...`를 push하고, 해당 branch에서 `ref=<sha>`로 `Full Release Validation`을
|
||||
dispatch하고, 모든 child workflow `headSha`가
|
||||
target과 일치하는지 검증한 뒤 temporary branch를 삭제합니다. 이렇게 하면 실수로 더 새로운
|
||||
`main` child run을 증명하는 일을 피할 수 있습니다.
|
||||
헬퍼는 `release-ci/<sha>-...`를 푸시하고, 해당 브랜치에서 `ref=<sha>`로 `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=<release-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>`를 사용하지 마세요. 원시 커밋 SHA는 워크플로 디스패치 ref가 될 수 없으므로, `pnpm ci:full-release --sha <sha>`를 사용하여 고정된 임시 브랜치를 만드세요.
|
||||
이 워크플로는 대상 ref를 확인하고, `target_ref=<release-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>`를 사용하지
|
||||
마세요. 원시 커밋 SHA는 워크플로 디스패치 ref가 될 수 없으므로,
|
||||
`pnpm ci:full-release --sha <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=<lane[,lane]>`을 사용하세요. 생성된 재실행 명령에는 사용 가능한 경우 이전 `package_artifact_run_id`와 준비된 Docker 이미지 입력이 포함되므로, 실패한 lane이 동일한 tarball과 GHCR 이미지를 재사용할 수 있습니다.
|
||||
재실행하기 전에 Docker 아티팩트를 사용하세요. 릴리스 경로 스케줄러는 lane 로그,
|
||||
`summary.json`, `failures.json`, 단계 타이밍, 스케줄러 계획 JSON, 재실행 명령이 포함된
|
||||
`.artifacts/docker-tests/`를 업로드합니다. 집중 복구에는 모든 릴리스 chunk를 재실행하는
|
||||
대신 재사용 가능한 live/E2E 워크플로에서 `docker_lanes=<lane[,lane]>`을 사용하세요.
|
||||
생성된 재실행 명령에는 사용 가능한 경우 이전 `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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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)
|
||||
|
||||
@ -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는 프록시 정책을 검사, 테스트 또는 인증하지 않습니다.
|
||||
- 프록시 정책 변경은 보안에 민감한 운영 변경으로 취급하세요.
|
||||
|
||||
@ -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.<name>`)은 제한적인 `plugins.allow` 아래에서도 번들 브라우저 Plugin을 활성화하며, 채널 구성 동작과 일치합니다. `plugins.entries.browser.enabled=true`와 `tools.alsoAllow: ["browser"]`만으로는 허용 목록 멤버십을 대체할 수 없습니다. `plugins.allow`를 완전히 제거해도 기본값이 복원됩니다.
|
||||
예를 들어 `browser.enabled=true` 또는 `browser.profiles.<name>` 같은 명시적 루트 `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이 활성화되면 에이전트의 사용 가능
|
||||
|
||||
<AccordionGroup>
|
||||
|
||||
<Accordion title="포트와 도달 가능성">
|
||||
<Accordion title="포트와 접근 가능성">
|
||||
|
||||
- 제어 서비스는 `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 수명 주기 정리는 여전히 세션 종료 시 명시적으로 추적된 탭을 닫습니다. 기본 세션은 활성 탭을 재사용 가능하게 유지한 뒤, 백그라운드에서 유휴 상태이거나 초과된 추적 탭을 닫습니다.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="SSRF 정책">
|
||||
|
||||
- 브라우저 탐색과 탭 열기는 탐색 전에 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이 활성화되면 에이전트의 사용 가능
|
||||
|
||||
<Accordion title="프로필 동작">
|
||||
|
||||
- `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.<name>.userDataDir`를 설정하세요. 이 경로도 OS 홈 디렉터리에 대해 `~`를 허용합니다.
|
||||
- 기존 세션 프로필이 기본값이 아닌 Chromium 사용자 프로필(Brave, Edge 등)에 연결해야 할 때 `browser.profiles.<name>.userDataDir`를 설정하세요. 이 경로도 OS 홈 디렉터리에 대해 `~`를 허용합니다.
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -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.<name>.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.<name>.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=<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_API_KEY>`를 실제 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/<kind>/<id>` 또는
|
||||
`/devtools/browser|page|worker|shared_worker|service_worker/<id>` 경로가 있는
|
||||
`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_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=<name>`을 허용합니다. CLI는 `--browser-profile`을 사용합니다.
|
||||
모든 제어 엔드포인트는 `?profile=<name>`을 허용하며, 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 <url>`(DevTools HTTP 검색 엔드포인트).
|
||||
- `http(s)://...` → `--browserUrl <url>`(DevTools HTTP discovery 엔드포인트).
|
||||
- `ws(s)://...` → `--wsEndpoint <url>`(직접 CDP WebSocket).
|
||||
|
||||
엔드포인트 플래그와 `userDataDir`은 함께 사용할 수 없습니다. `cdpUrl`이 설정되면,
|
||||
Chrome MCP가 프로필 디렉터리를 여는 대신 엔드포인트 뒤의 실행 중인 브라우저에 연결하므로
|
||||
Chrome MCP 실행 시 `userDataDir`은 무시됩니다.
|
||||
엔드포인트 플래그와 `userDataDir`은 함께 사용할 수 없습니다. `cdpUrl`이 설정되면
|
||||
Chrome MCP가 프로필 디렉터리를 여는 대신 엔드포인트 뒤의 실행 중인 브라우저에 연결하므로,
|
||||
Chrome MCP 실행에서 `userDataDir`은 무시됩니다.
|
||||
|
||||
<Accordion title="Existing-session 기능 제한">
|
||||
<Accordion title="Existing-session feature limitations">
|
||||
|
||||
관리형 `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`는 여전히 관리형 브라우저 경로가 필요합니다.
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -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 "<name>" is not reachable at <cdpUrl>`
|
||||
- 루프백 외부 CDP 서비스가 `attachOnly: true` 없이 구성된 경우
|
||||
- loopback 외부 CDP 서비스가 `attachOnly: true` 없이 구성되어 있을 때
|
||||
`Port <port> is in use for profile "<name>" 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"`로 고정하지 않는 한 도구가 자동으로 해당 노드로 라우팅할 수 있습니다.
|
||||
|
||||
이렇게 하면 에이전트가 결정적으로 동작하고 취약한 선택자를 피할 수 있습니다.
|
||||
이를 통해 에이전트를 결정론적으로 유지하고 깨지기 쉬운 선택자를 피할 수 있습니다.
|
||||
|
||||
## 관련 항목
|
||||
|
||||
|
||||
@ -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)를 참조하세요.
|
||||
|
||||
<Steps>
|
||||
@ -62,21 +59,21 @@ Plugin은 OpenClaw에 새 기능을 확장합니다. 채널, 모델 제공자,
|
||||
openclaw gateway restart
|
||||
```
|
||||
|
||||
그런 다음 구성 파일의 `plugins.entries.\<id\>.config` 아래에서 설정하세요.
|
||||
그런 다음 구성 파일의 `plugins.entries.\<id\>.config` 아래에서 설정합니다.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="채팅 네이티브 관리">
|
||||
실행 중인 Gateway에서 소유자 전용 `/plugins enable` 및 `/plugins disable`은
|
||||
Gateway 구성 리로더를 트리거합니다. Gateway는 프로세스 안에서 Plugin 런타임
|
||||
표면을 다시 로드하며, 새 에이전트 턴은 새로 고친 레지스트리에서
|
||||
도구 목록을 다시 빌드합니다. `/plugins install`은 Plugin 소스 코드를 변경하므로
|
||||
Gateway는 현재 프로세스가 이미 가져온 모듈을 안전하게
|
||||
다시 로드할 수 있는 척하는 대신 재시작을 요청합니다.
|
||||
표면을 다시 로드하고, 새로운 에이전트 턴은 새로 고친 레지스트리에서 도구 목록을
|
||||
다시 빌드합니다. `/plugins install`은 Plugin 소스 코드를 변경하므로,
|
||||
Gateway는 현재 프로세스가 이미 가져온 모듈을 안전하게 다시 로드할 수 있는 척하는 대신
|
||||
재시작을 요청합니다.
|
||||
|
||||
</Step>
|
||||
|
||||
<Step title="Plugin 확인">
|
||||
<Step title="Plugin 검증">
|
||||
```bash
|
||||
openclaw plugins inspect <plugin-id> --runtime --json
|
||||
|
||||
@ -84,9 +81,8 @@ Plugin은 OpenClaw에 새 기능을 확장합니다. 채널, 모델 제공자,
|
||||
openclaw <plugin-command> --help
|
||||
```
|
||||
|
||||
등록된 도구, 서비스, gateway 메서드, 훅 또는 Plugin 소유 CLI 명령을 증명해야 할 때는
|
||||
`--runtime`을 사용하세요. 일반 `inspect`는 콜드
|
||||
매니페스트/레지스트리 검사이며, 의도적으로 Plugin 런타임 가져오기를 피합니다.
|
||||
등록된 도구, 서비스, Gateway 메서드, 훅 또는 Plugin 소유 CLI 명령을 증명해야 할 때는 `--runtime`을 사용합니다. 일반 `inspect`는 콜드
|
||||
매니페스트/레지스트리 검사이며 의도적으로 Plugin 런타임 가져오기를 피합니다.
|
||||
|
||||
</Step>
|
||||
</Steps>
|
||||
@ -99,79 +95,74 @@ Plugin은 OpenClaw에 새 기능을 확장합니다. 채널, 모델 제공자,
|
||||
/plugin enable <plugin-id>
|
||||
```
|
||||
|
||||
설치 경로는 CLI와 같은 리졸버를 사용합니다. 로컬 경로/아카이브, 명시적
|
||||
설치 경로는 CLI와 동일한 해석기를 사용합니다. 로컬 경로/아카이브, 명시적
|
||||
`clawhub:<pkg>`, 명시적 `npm:<pkg>`, 명시적 `npm-pack:<path.tgz>`,
|
||||
명시적 `git:<repo>`, 또는 npm을 통한 베어 패키지 사양입니다.
|
||||
명시적 `git:<repo>`, 또는 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/<id>`에서 번들 Plugin을 로드하므로 수정 사항과 패키지 로컬 의존성이 직접 사용됩니다.
|
||||
일반 npm 루트 설치는 패키징된 OpenClaw용이며, 소스 체크아웃
|
||||
소스 체크아웃은 pnpm 워크스페이스입니다. 번들 Plugin을 수정하려고 OpenClaw를 클론했다면
|
||||
`pnpm install`을 실행하세요. 그러면 OpenClaw는 `extensions/<id>`에서 번들 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와 함께 제공됨)
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="모델 제공자(기본적으로 활성화됨)">
|
||||
@ -264,10 +249,10 @@ npm이 `@openclaw/*` Plugin 패키지를 deprecated로 보고하면, 해당 패
|
||||
|
||||
<Accordion title="메모리 Plugin">
|
||||
- `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)를 참조하세요.
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -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.\<id\>` | 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`를 사용하세요.
|
||||
|
||||
<Accordion title="Plugin 상태: 비활성화됨 vs 누락됨 vs 유효하지 않음">
|
||||
- **비활성화됨**: Plugin은 존재하지만 활성화 규칙이 꺼 두었습니다. 구성은 보존됩니다.
|
||||
- **누락됨**: 구성이 검색에서 찾지 못한 Plugin id를 참조합니다.
|
||||
- **유효하지 않음**: Plugin은 존재하지만 구성이 선언된 스키마와 일치하지 않습니다. Gateway 시작은 해당 Plugin만 건너뜁니다. `openclaw doctor --fix`는 유효하지 않은 항목을 비활성화하고 구성 페이로드를 제거하여 격리할 수 있습니다.
|
||||
- **비활성화됨**: Plugin은 존재하지만 활성화 규칙이 껐습니다. 구성은 보존됩니다.
|
||||
- **누락됨**: 구성이 검색에서 찾지 못한 Plugin ID를 참조합니다.
|
||||
- **유효하지 않음**: Plugin은 존재하지만 해당 구성이 선언된 스키마와 일치하지 않습니다. Gateway 시작은 해당 Plugin만 건너뜁니다. `openclaw doctor --fix`는 해당 항목을 비활성화하고 구성 페이로드를 제거하여 유효하지 않은 항목을 격리할 수 있습니다.
|
||||
|
||||
</Accordion>
|
||||
|
||||
@ -331,11 +316,11 @@ OpenClaw는 다음 순서로 Plugin을 스캔합니다(첫 번째 일치가 우
|
||||
|
||||
<Steps>
|
||||
<Step title="구성 경로">
|
||||
`plugins.load.paths` - 명시적 파일 또는 디렉터리 경로입니다. OpenClaw 자체 패키지 번들 Plugin 디렉터리를 다시 가리키는 경로는 무시됩니다.
|
||||
`plugins.load.paths` - 명시적 파일 또는 디렉터리 경로. OpenClaw 자체 패키지 번들 Plugin 디렉터리를 다시 가리키는 경로는 무시됩니다.
|
||||
오래된 별칭을 제거하려면 `openclaw doctor --fix`를 실행하세요.
|
||||
</Step>
|
||||
|
||||
<Step title="워크스페이스 Plugin">
|
||||
<Step title="작업 영역 Plugin">
|
||||
`\<workspace\>/.openclaw/<plugin-root>/*.ts` 및 `\<workspace\>/.openclaw/<plugin-root>/*/index.ts`.
|
||||
</Step>
|
||||
|
||||
@ -344,39 +329,40 @@ OpenClaw는 다음 순서로 Plugin을 스캔합니다(첫 번째 일치가 우
|
||||
</Step>
|
||||
|
||||
<Step title="번들 Plugin">
|
||||
OpenClaw와 함께 제공됩니다. 다수는 기본적으로 활성화됩니다(모델 제공자, 음성).
|
||||
그 외에는 명시적인 활성화가 필요합니다.
|
||||
OpenClaw와 함께 제공됩니다. 많은 항목은 기본적으로 활성화됩니다(모델 제공자, 음성).
|
||||
다른 항목은 명시적 활성화가 필요합니다.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
패키지 설치와 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.\<id\>.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.\<id\>.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 <id> --runtime --json`을 사용하세요. `llm_input`, `llm_output`, `before_agent_finalize`, `agent_end` 같은 비번들 대화 훅에는 `plugins.entries.<id>.hooks.allowConversationAccess=true`가 필요합니다.
|
||||
- `openclaw gateway status --deep --require-rpc`를 실행하고 활성 Gateway URL, 프로필, 구성 경로, 프로세스가 편집 중인 대상인지 확인하세요.
|
||||
- Plugin 설치/구성/코드 변경 후 실시간 Gateway를 다시 시작하세요. 래퍼 컨테이너에서는 PID 1이 단순히 슈퍼바이저일 수 있습니다. 하위 `openclaw gateway run` 프로세스를 다시 시작하거나 신호를 보내세요.
|
||||
- `openclaw plugins inspect <id> --runtime --json`을 사용해 훅 등록과 진단을 확인하세요. `before_model_resolve`, `before_agent_reply`, `before_agent_run`, `llm_input`, `llm_output`, `before_agent_finalize`, `agent_end` 같은 비번들 대화 훅에는 `plugins.entries.<id>.hooks.allowConversationAccess=true`가 필요합니다.
|
||||
- 모델 전환에는 `before_model_resolve`를 선호하세요. 에이전트 턴의 모델 해석 전에 실행됩니다. `llm_output`은 모델 시도가 어시스턴트 출력을 생성한 후에만 실행됩니다.
|
||||
- 유효한 세션 모델을 증명하려면 `openclaw sessions` 또는 Gateway 세션/상태 표면을 사용하고, 제공자 페이로드를 디버깅할 때는 `--raw-stream --raw-stream-path <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 <plugin-id> --runtime --json
|
||||
```
|
||||
|
||||
그런 다음 해당 Plugin을 업데이트, 재설치 또는 비활성화하세요. Plugin 작성자는 값비싼 종속성 로딩을 도구 팩터리 내부에서 수행하는 대신 도구 실행 경로 뒤로 이동해야 합니다.
|
||||
그런 다음 해당 Plugin을 업데이트, 재설치 또는 비활성화하세요. Plugin 작성자는 비용이 큰 의존성 로딩을 도구 팩터리 내부에서 수행하지 말고 도구 실행 경로 뒤로 옮겨야 합니다.
|
||||
|
||||
### 중복 채널 또는 도구 소유권
|
||||
|
||||
@ -409,24 +395,24 @@ openclaw plugins inspect <plugin-id> --runtime --json
|
||||
- `channel setup already registered: <channel-id> (<plugin-id>)`
|
||||
- `plugin tool name conflict (<plugin-id>): <tool-name>`
|
||||
|
||||
이는 활성화된 Plugin이 둘 이상 같은 채널, 설정 흐름 또는 도구 이름을 소유하려 한다는 뜻입니다. 가장 흔한 원인은 이제 동일한 채널 id를 제공하는 번들 Plugin 옆에 외부 채널 Plugin이 설치된 경우입니다.
|
||||
이는 활성화된 Plugin이 둘 이상 같은 채널, 설정 흐름 또는 도구 이름을 소유하려 한다는 뜻입니다. 가장 흔한 원인은 이제 동일한 채널 ID를 제공하는 번들 Plugin 옆에 외부 채널 Plugin이 설치되어 있는 경우입니다.
|
||||
|
||||
디버그 단계:
|
||||
|
||||
- 활성화된 모든 Plugin과 출처를 보려면 `openclaw plugins list --enabled --verbose`를 실행하세요.
|
||||
- `openclaw plugins list --enabled --verbose`를 실행해 활성화된 모든 Plugin과 원본을 확인하세요.
|
||||
- 의심되는 각 Plugin에 대해 `openclaw plugins inspect <id> --runtime --json`을 실행하고 `channels`, `channelConfigs`, `tools`, 진단을 비교하세요.
|
||||
- Plugin 패키지를 설치하거나 제거한 후에는 저장된 메타데이터가 현재 설치를 반영하도록 `openclaw plugins registry --refresh`를 실행하세요.
|
||||
- Plugin 패키지를 설치하거나 제거한 뒤에는 영구 저장된 메타데이터가 현재 설치를 반영하도록 `openclaw plugins registry --refresh`를 실행하세요.
|
||||
- 설치, 레지스트리 또는 구성 변경 후 Gateway를 다시 시작하세요.
|
||||
|
||||
수정 옵션:
|
||||
|
||||
- 한 Plugin이 동일한 채널 id에 대해 다른 Plugin을 의도적으로 대체한다면, 선호되는 Plugin은 낮은 우선순위의 Plugin id로 `channelConfigs.<channel-id>.preferOver`를 선언해야 합니다. [/plugins/manifest#replacing-another-channel-plugin](/ko/plugins/manifest#replacing-another-channel-plugin)을 참조하세요.
|
||||
- 중복이 우발적이라면 `plugins.entries.<plugin-id>.enabled: false`로 한쪽을 비활성화하거나 오래된 Plugin 설치를 제거하세요.
|
||||
- 두 Plugin을 모두 명시적으로 활성화한 경우 OpenClaw는 해당 요청을 유지하고 충돌을 보고합니다. 채널 소유자를 하나 선택하거나 Plugin 소유 도구의 이름을 바꿔 런타임 표면이 모호하지 않도록 하세요.
|
||||
- 한 Plugin이 의도적으로 동일한 채널 ID에 대해 다른 Plugin을 대체하는 경우, 선호되는 Plugin은 더 낮은 우선순위의 Plugin ID로 `channelConfigs.<channel-id>.preferOver`를 선언해야 합니다. [/plugins/manifest#replacing-another-channel-plugin](/ko/plugins/manifest#replacing-another-channel-plugin)을 참조하세요.
|
||||
- 중복이 우발적인 경우 `plugins.entries.<plugin-id>.enabled: false`로 한쪽을 비활성화하거나 오래된 Plugin 설치를 제거하세요.
|
||||
- 두 Plugin을 모두 명시적으로 활성화한 경우 OpenClaw는 해당 요청을 유지하고 충돌을 보고합니다. 런타임 표면이 모호하지 않도록 채널의 소유자를 하나 선택하거나 Plugin 소유 도구의 이름을 변경하세요.
|
||||
|
||||
## Plugin 슬롯(독점 카테고리)
|
||||
## Plugin 슬롯(배타적 범주)
|
||||
|
||||
일부 카테고리는 독점적입니다(한 번에 하나만 활성화됨).
|
||||
일부 범주는 배타적입니다(한 번에 하나만 활성화).
|
||||
|
||||
```json5
|
||||
{
|
||||
@ -442,7 +428,7 @@ openclaw plugins inspect <plugin-id> --runtime --json
|
||||
| 슬롯 | 제어 대상 | 기본값 |
|
||||
| --------------- | --------------------- | ------------------- |
|
||||
| `memory` | 활성 메모리 Plugin | `memory-core` |
|
||||
| `contextEngine` | 활성 컨텍스트 엔진 | `legacy` (내장) |
|
||||
| `contextEngine` | 활성 컨텍스트 엔진 | `legacy`(내장) |
|
||||
|
||||
## CLI 참조
|
||||
|
||||
@ -492,75 +478,81 @@ openclaw plugins enable <id>
|
||||
openclaw plugins disable <id>
|
||||
```
|
||||
|
||||
번들 Plugin은 OpenClaw와 함께 제공됩니다. 다수는 기본적으로 활성화되어 있습니다(예:
|
||||
번들 Plugin은 OpenClaw와 함께 제공됩니다. 많은 번들 Plugin이 기본적으로 활성화됩니다(예:
|
||||
번들 모델 제공자, 번들 음성 제공자, 번들 브라우저
|
||||
Plugin). 다른 번들 Plugin은 여전히 `openclaw plugins enable <id>`가 필요합니다.
|
||||
|
||||
`--force`는 기존에 설치된 Plugin 또는 훅 팩을 제자리에서 덮어씁니다. 추적되는 npm
|
||||
Plugin의 일반적인 업그레이드에는 `openclaw plugins update <id-or-npm-spec>`를 사용하세요.
|
||||
관리되는 설치 대상에 복사하지 않고 소스 경로를 재사용하는 `--link`와 함께 사용하는 것은
|
||||
지원되지 않습니다.
|
||||
`--force`는 기존에 설치된 Plugin 또는 hook pack을 그 자리에서 덮어씁니다. 추적되는 npm
|
||||
Plugin의 일반 업그레이드에는 `openclaw plugins update <id-or-npm-spec>`를 사용하세요.
|
||||
소스 경로를 관리형 설치 대상 위에 복사하는 대신 재사용하는 `--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 <id-or-npm-spec>`는 추적되는 설치에 적용됩니다. 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 <id-or-npm-spec>`는 추적되는 설치에 적용됩니다. 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 <name>`을 실행해 ClawHub가 다시 확인하도록 요청하세요.
|
||||
`--dangerously-force-unsafe-install`은 자신의 머신에서 이루어지는 설치에만 영향을 줍니다.
|
||||
ClawHub에 Plugin 재스캔을 요청하거나 차단된 릴리스를 공개 상태로 만들지는 않습니다.
|
||||
ClawHub에 게시한 Plugin이 스캔 때문에 숨겨졌거나 차단된 경우,
|
||||
ClawHub 대시보드를 열거나 `clawhub package rescan <name>`을 실행하여 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 <id>`는 번들 기반 Plugin에 대해 감지된 번들 기능과 지원되거나
|
||||
지원되지 않는 MCP 및 LSP 서버 항목도 보고합니다.
|
||||
`openclaw plugins inspect <id>`는 감지된 번들 기능과 번들 기반 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) - 서드 파티 목록
|
||||
|
||||
@ -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" });
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="extractMode" type="'markdown' | 'text'" default="markdown">
|
||||
주요 콘텐츠 추출 후의 출력 형식입니다.
|
||||
주요 콘텐츠 추출 후 출력 형식입니다.
|
||||
</ParamField>
|
||||
|
||||
<ParamField path="maxChars" type="number">
|
||||
출력을 이 문자 수로 잘라냅니다.
|
||||
출력을 지정한 문자 수로 잘라냅니다.
|
||||
</ParamField>
|
||||
|
||||
## 작동 방식
|
||||
@ -59,8 +59,8 @@ await web_fetch({ url: "https://example.com/article" });
|
||||
Firecrawl API를 통해 다시 시도합니다.
|
||||
</Step>
|
||||
<Step title="Cache">
|
||||
동일한 URL을 반복해서 가져오는 일을 줄이기 위해 결과를 15분 동안
|
||||
캐시합니다(설정 가능).
|
||||
동일한 URL의 반복 가져오기를 줄이기 위해 결과를 15분 동안(설정 가능)
|
||||
캐시합니다.
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
@ -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`로 자동 마이그레이션됩니다.
|
||||
|
||||
<Note>
|
||||
Firecrawl이 활성화되어 있고 해당 SecretRef가 확인되지 않았으며
|
||||
`FIRECRAWL_API_KEY` env 대체값도 없으면 gateway 시작이 빠르게 실패합니다.
|
||||
`FIRECRAWL_API_KEY` env 폴백도 없으면 Gateway 시작이 빠르게 실패합니다.
|
||||
</Note>
|
||||
|
||||
<Note>
|
||||
Firecrawl `baseUrl` 재정의는 제한됩니다. 호스팅 트래픽은
|
||||
Firecrawl `baseUrl` 재정의는 제한되어 있습니다. 호스팅 트래픽은
|
||||
`https://api.firecrawl.dev`를 사용하며, 자체 호스팅 재정의는 비공개 또는
|
||||
내부 엔드포인트를 대상으로 해야 하고, `http://`는 해당 비공개 대상에만 허용됩니다.
|
||||
내부 엔드포인트를 대상으로 해야 하고 `http://`는 이러한 비공개 대상에만 허용됩니다.
|
||||
</Note>
|
||||
|
||||
현재 런타임 동작:
|
||||
|
||||
- `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 확인 후 아웃바운드 정책을 적용하는 경우에만 활성화하세요.
|
||||
|
||||
<Note>
|
||||
HTTP(S) 프록시 env var가 설정되어 있지 않거나 대상 호스트가
|
||||
HTTP(S) 프록시 env 변수가 설정되어 있지 않거나 대상 호스트가
|
||||
`NO_PROXY`로 제외된 경우, `web_fetch`는 로컬 DNS 고정이 있는 일반 엄격 경로로
|
||||
대체됩니다.
|
||||
폴백합니다.
|
||||
</Note>
|
||||
|
||||
## 제한 및 안전
|
||||
## 제한 및 안전성
|
||||
|
||||
- `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 검색 및 스크레이핑 도구
|
||||
|
||||
Loading…
Reference in New Issue
Block a user