diff --git a/docs/ko/ci.md b/docs/ko/ci.md index b7b7bd8e0..ed489c1da 100644 --- a/docs/ko/ci.md +++ b/docs/ko/ci.md @@ -1,81 +1,82 @@ --- read_when: - - 어떤 CI 작업이 실행되었거나 실행되지 않은 이유를 이해해야 합니다 - - 실패한 GitHub Actions 검사를 디버깅하고 있습니다 -summary: CI 작업 그래프, 범위 게이트, 그리고 로컬 명령어 대응 항목 + - CI 작업이 실행되었거나 실행되지 않은 이유를 이해해야 합니다. + - 실패한 GitHub Actions 검사를 디버깅하고 있습니다. +summary: CI 작업 그래프, 범위 게이트, 그리고 로컬 명령 대응 항목 title: CI 파이프라인 x-i18n: - generated_at: "2026-04-22T04:21:25Z" + generated_at: "2026-04-22T06:00:32Z" model: gpt-5.4 provider: openai - source_hash: ae08bad6cbd0f2eced6c88a792a11bc1c2b1a2bfb003a56f70ff328a2739d3fc + source_hash: fc7ec59123aee65634736320dbf1cf5cdfb08786a78cca82ce9596fedc68b3cc source_path: ci.md workflow: 15 --- # CI 파이프라인 -CI는 `main`에 대한 모든 푸시와 모든 pull request에서 실행됩니다. 관련 없는 영역만 변경된 경우 비용이 큰 작업을 건너뛰기 위해 스마트 범위 지정을 사용합니다. +CI는 `main`에 대한 모든 푸시와 모든 pull request에서 실행됩니다. 스마트 범위 지정 기능을 사용해 관련 없는 영역만 변경된 경우 비용이 큰 작업을 건너뜁니다. ## 작업 개요 -| 작업 | 목적 | 실행 시점 | -| -------------------------------- | -------------------------------------------------------------------------------------------- | ----------------------------------- | -| `preflight` | docs 전용 변경, 변경된 범위, 변경된 extensions를 감지하고 CI 매니페스트를 빌드 | 드래프트가 아닌 모든 푸시 및 PR에서 항상 실행 | -| `security-scm-fast` | `zizmor`를 통한 개인 키 감지 및 워크플로 감사 | 드래프트가 아닌 모든 푸시 및 PR에서 항상 실행 | -| `security-dependency-audit` | npm advisory 기준의 의존성 없는 프로덕션 lockfile 감사 | 드래프트가 아닌 모든 푸시 및 PR에서 항상 실행 | -| `security-fast` | 빠른 보안 작업을 위한 필수 집계 작업 | 드래프트가 아닌 모든 푸시 및 PR에서 항상 실행 | -| `build-artifacts` | `dist/`와 Control UI를 한 번 빌드하고, 하위 작업이 재사용할 수 있는 아티팩트를 업로드 | Node 관련 변경 시 | -| `checks-fast-core` | bundled/plugin-contract/protocol 검사와 같은 빠른 Linux 정확성 레인 | Node 관련 변경 시 | -| `checks-fast-contracts-channels` | 안정적인 집계 검사 결과를 제공하는 샤딩된 채널 contract 검사 | Node 관련 변경 시 | -| `checks-node-extensions` | extension 전반에서 bundled-plugin 전체 테스트 샤드 실행 | Node 관련 변경 시 | -| `checks-node-core-test` | 채널, bundled, contract, extension 레인을 제외한 코어 Node 테스트 샤드 | Node 관련 변경 시 | -| `extension-fast` | 변경된 bundled plugin만 대상으로 하는 집중 테스트 | extension 변경이 감지될 때 | -| `check` | 샤딩된 메인 로컬 게이트 대응 항목: 프로덕션 타입, lint, 가드, 테스트 타입, 엄격한 스모크 | Node 관련 변경 시 | -| `check-additional` | 아키텍처, 경계, extension-surface 가드, package-boundary, gateway-watch 샤드 | Node 관련 변경 시 | -| `build-smoke` | 빌드된 CLI 스모크 테스트 및 시작 메모리 스모크 | Node 관련 변경 시 | -| `checks` | 나머지 Linux Node 레인: 채널 테스트 및 푸시 전용 Node 22 호환성 | Node 관련 변경 시 | -| `check-docs` | docs 포맷팅, lint, 깨진 링크 검사 | docs 변경 시 | -| `skills-python` | Python 기반 Skills에 대한 Ruff + pytest | Python-skill 관련 변경 시 | -| `checks-windows` | Windows 전용 테스트 레인 | Windows 관련 변경 시 | -| `macos-node` | 공유 빌드 아티팩트를 사용하는 macOS TypeScript 테스트 레인 | macOS 관련 변경 시 | -| `macos-swift` | macOS 앱용 Swift lint, 빌드, 테스트 | macOS 관련 변경 시 | -| `android` | Android 빌드 및 테스트 매트릭스 | Android 관련 변경 시 | +| 작업 | 목적 | 실행 시점 | +| -------------------------------- | ------------------------------------------------------------------------------------------ | ------------------------------------ | +| `preflight` | docs 전용 변경, 변경된 범위, 변경된 extensions를 감지하고 CI 매니페스트를 빌드합니다 | 초안이 아닌 모든 푸시와 PR에서 항상 실행 | +| `security-scm-fast` | `zizmor`를 통한 private key 탐지 및 워크플로 감사 | 초안이 아닌 모든 푸시와 PR에서 항상 실행 | +| `security-dependency-audit` | npm advisory를 기준으로 한 의존성 없는 프로덕션 lockfile 감사 | 초안이 아닌 모든 푸시와 PR에서 항상 실행 | +| `security-fast` | 빠른 보안 작업들을 위한 필수 집계 작업 | 초안이 아닌 모든 푸시와 PR에서 항상 실행 | +| `build-artifacts` | `dist/`와 Control UI를 한 번 빌드하고, 이후 작업에서 재사용할 수 있도록 아티팩트를 업로드합니다 | Node 관련 변경 | +| `checks-fast-core` | 번들/plugin-contract/protocol 검사와 같은 빠른 Linux 정확성 레인 | Node 관련 변경 | +| `checks-fast-contracts-channels` | 안정적인 집계 검사 결과를 갖는 샤딩된 channel contract 검사 | Node 관련 변경 | +| `checks-node-extensions` | extension 제품군 전반에 걸친 전체 번들-plugin 테스트 샤드 | Node 관련 변경 | +| `checks-node-core-test` | channel, 번들, contract, extension 레인을 제외한 Core Node 테스트 샤드 | Node 관련 변경 | +| `extension-fast` | 변경된 번들 plugins만 대상으로 하는 집중 테스트 | extension 변경이 감지된 경우 | +| `check` | 샤딩된 메인 로컬 게이트 대응 항목: 프로덕션 타입, lint, guard, 테스트 타입, 엄격한 smoke | Node 관련 변경 | +| `check-additional` | 아키텍처, 경계, extension-surface guard, package-boundary, gateway-watch 샤드 | Node 관련 변경 | +| `build-smoke` | 빌드된 CLI smoke 테스트와 startup-memory smoke | Node 관련 변경 | +| `checks` | 나머지 Linux Node 레인: channel 테스트와 푸시 전용 Node 22 호환성 | Node 관련 변경 | +| `check-docs` | docs 포맷팅, lint, 깨진 링크 검사 | Docs 변경 | +| `skills-python` | Python 기반 Skills에 대한 Ruff + pytest | Python-skill 관련 변경 | +| `checks-windows` | Windows 전용 테스트 레인 | Windows 관련 변경 | +| `macos-node` | 공유 빌드 아티팩트를 사용하는 macOS TypeScript 테스트 레인 | macOS 관련 변경 | +| `macos-swift` | macOS 앱용 Swift lint, 빌드, 테스트 | macOS 관련 변경 | +| `android` | Android 빌드 및 테스트 매트릭스 | Android 관련 변경 | ## Fail-Fast 순서 -작업은 비용이 큰 작업이 실행되기 전에 저렴한 검사가 먼저 실패하도록 정렬됩니다. +작업은 비용이 큰 작업이 실행되기 전에 저렴한 검사가 먼저 실패하도록 순서가 정해져 있습니다. -1. `preflight`가 어떤 레인이 존재하는지 자체를 결정합니다. `docs-scope`와 `changed-scope` 로직은 독립 작업이 아니라 이 작업 내부의 단계입니다. -2. `security-scm-fast`, `security-dependency-audit`, `security-fast`, `check`, `check-additional`, `check-docs`, `skills-python`은 더 무거운 아티팩트 및 플랫폼 매트릭스 작업을 기다리지 않고 빠르게 실패합니다. -3. `build-artifacts`는 빠른 Linux 레인과 겹쳐 실행되므로, 공유 빌드가 준비되는 즉시 하위 소비자가 시작할 수 있습니다. -4. 이후 더 무거운 플랫폼 및 런타임 레인이 분기됩니다: `checks-fast-core`, `checks-fast-contracts-channels`, `checks-node-extensions`, `checks-node-core-test`, `extension-fast`, `checks`, `checks-windows`, `macos-node`, `macos-swift`, `android`. +1. `preflight`가 어떤 레인이 실제로 존재하는지 결정합니다. `docs-scope`와 `changed-scope` 로직은 독립 작업이 아니라 이 작업 내부의 단계입니다. +2. `security-scm-fast`, `security-dependency-audit`, `security-fast`, `check`, `check-additional`, `check-docs`, `skills-python`은 더 무거운 artifact 및 플랫폼 매트릭스 작업을 기다리지 않고 빠르게 실패합니다. +3. `build-artifacts`는 빠른 Linux 레인과 병렬로 실행되므로, 공유 빌드가 준비되는 즉시 downstream 소비자가 시작할 수 있습니다. +4. 그 이후 더 무거운 플랫폼 및 런타임 레인이 분기됩니다: `checks-fast-core`, `checks-fast-contracts-channels`, `checks-node-extensions`, `checks-node-core-test`, `extension-fast`, `checks`, `checks-windows`, `macos-node`, `macos-swift`, `android`. -범위 로직은 `scripts/ci-changed-scope.mjs`에 있으며 `src/scripts/ci-changed-scope.test.ts`의 단위 테스트로 검증됩니다. -별도의 `install-smoke` 워크플로는 자체 `preflight` 작업을 통해 같은 범위 스크립트를 재사용합니다. 더 좁은 changed-smoke 신호에서 `run_install_smoke`를 계산하므로, Docker/install smoke는 설치, 패키징, 컨테이너 관련 변경에 대해서만 실행됩니다. +범위 로직은 `scripts/ci-changed-scope.mjs`에 있으며, `src/scripts/ci-changed-scope.test.ts`의 단위 테스트로 검증됩니다. +별도의 `install-smoke` 워크플로는 자체 `preflight` 작업을 통해 같은 범위 스크립트를 재사용합니다. 더 좁은 changed-smoke 신호에서 `run_install_smoke`를 계산하므로, Docker/install smoke는 install, packaging, container 관련 변경에 대해서만 실행됩니다. -로컬 changed-lane 로직은 `scripts/changed-lanes.mjs`에 있으며 `scripts/check-changed.mjs`에서 실행됩니다. 이 로컬 게이트는 광범위한 CI 플랫폼 범위보다 아키텍처 경계에 더 엄격합니다. 코어 프로덕션 변경은 코어 프로덕션 타입체크와 코어 테스트를 실행하고, 코어 테스트 전용 변경은 코어 테스트 타입체크/테스트만 실행하며, extension 프로덕션 변경은 extension 프로덕션 타입체크와 extension 테스트를 실행하고, extension 테스트 전용 변경은 extension 테스트 타입체크/테스트만 실행합니다. 공개 Plugin SDK 또는 plugin-contract 변경은 extension이 이러한 코어 contract에 의존하므로 extension 검증까지 확장됩니다. 릴리스 메타데이터 전용 버전 범프는 버전/구성/루트 의존성 검사만 대상으로 실행합니다. 알 수 없는 루트/구성 변경은 안전하게 모든 레인으로 확장됩니다. +로컬 변경 레인 로직은 `scripts/changed-lanes.mjs`에 있으며 `scripts/check-changed.mjs`가 이를 실행합니다. 이 로컬 게이트는 광범위한 CI 플랫폼 범위보다 아키텍처 경계에 대해 더 엄격합니다. core 프로덕션 변경은 core 프로덕션 typecheck와 core 테스트를 실행하고, core 테스트 전용 변경은 core 테스트 typecheck/tests만 실행하며, extension 프로덕션 변경은 extension 프로덕션 typecheck와 extension 테스트를 실행하고, extension 테스트 전용 변경은 extension 테스트 typecheck/tests만 실행합니다. 공개 Plugin SDK 또는 plugin-contract 변경은 extension이 그 core contract에 의존하므로 extension 검증까지 확장됩니다. 릴리스 메타데이터 전용 버전 범프는 대상이 제한된 version/config/root-dependency 검사를 실행합니다. 알 수 없는 root/config 변경은 안전하게 모든 레인으로 실패 처리됩니다. -푸시에서는 `checks` 매트릭스에 푸시 전용 `compat-node22` 레인이 추가됩니다. pull request에서는 이 레인이 건너뛰어지고, 매트릭스는 일반 테스트/채널 레인에 집중된 상태를 유지합니다. +푸시에서는 `checks` 매트릭스가 푸시 전용 `compat-node22` 레인을 추가합니다. pull request에서는 이 레인이 건너뛰어지고 매트릭스는 일반 테스트/channel 레인에 집중된 상태를 유지합니다. -가장 느린 Node 테스트 계열은 각 작업을 작게 유지하기 위해 include-file 샤드로 분할됩니다. 채널 contract는 registry와 코어 커버리지를 각각 8개의 가중 샤드로 분할하고, auto-reply reply command 테스트는 4개의 include-pattern 샤드로 분할하며, 그 외 큰 auto-reply reply prefix 그룹은 각각 2개의 샤드로 분할합니다. `check-additional`도 package-boundary compile/canary 작업과 런타임 topology gateway/architecture 작업을 분리합니다. +가장 느린 Node 테스트 계열은 각 작업이 작게 유지되도록 include-file 샤드로 분할됩니다. channel contract는 registry와 core 커버리지를 각각 8개의 가중 샤드로 분할하고, auto-reply reply command 테스트는 4개의 include-pattern 샤드로 분할하며, 그 외 큰 auto-reply reply prefix 그룹은 각각 2개의 샤드로 분할합니다. `check-additional`도 package-boundary compile/canary 작업을 runtime topology gateway/architecture 작업과 분리합니다. -같은 PR 또는 `main` ref에 더 새로운 푸시가 들어오면 GitHub는 대체된 작업을 `cancelled`로 표시할 수 있습니다. 같은 ref의 최신 실행도 실패하고 있지 않다면 이것은 CI 노이즈로 간주하세요. 집계 샤드 검사는 이 취소 사례를 명시적으로 표시하므로 테스트 실패와 더 쉽게 구분할 수 있습니다. +같은 PR 또는 `main` ref에 새 푸시가 도착하면 GitHub는 대체된 작업을 `cancelled`로 표시할 수 있습니다. 같은 ref의 최신 실행도 실패 중이 아닌 한, 이것은 CI 잡음으로 취급하세요. 집계 샤드 검사는 이 취소 사례를 명시적으로 알려 주므로 테스트 실패와 더 쉽게 구분할 수 있습니다. ## 러너 -| 러너 | 작업 | -| -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `blacksmith-16vcpu-ubuntu-2404` | `preflight`, `security-scm-fast`, `security-dependency-audit`, `security-fast`, `build-artifacts`, Linux 검사, docs 검사, Python Skills, `android` | -| `blacksmith-32vcpu-windows-2025` | `checks-windows` | -| `blacksmith-12vcpu-macos-latest` | `openclaw/openclaw`의 `macos-node`, `macos-swift`; 포크는 `macos-latest`로 대체 | +| 러너 | 작업 | +| -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | +| `ubuntu-24.04` | `preflight`; install-smoke preflight도 GitHub 호스팅 Ubuntu를 사용하므로 Blacksmith 매트릭스가 더 일찍 큐에 들어갈 수 있습니다 | +| `blacksmith-16vcpu-ubuntu-2404` | `security-scm-fast`, `security-dependency-audit`, `security-fast`, `build-artifacts`, Linux 검사, docs 검사, Python Skills, `android` | +| `blacksmith-32vcpu-windows-2025` | `checks-windows` | +| `blacksmith-12vcpu-macos-latest` | `macos-node`, `macos-swift` on `openclaw/openclaw`; 포크는 `macos-latest`로 대체됩니다 | ## 로컬 대응 항목 ```bash -pnpm changed:lanes # origin/main...HEAD에 대한 로컬 changed-lane 분류기 확인 -pnpm check:changed # 스마트 로컬 게이트: 경계 레인별 변경된 타입체크/lint/테스트 -pnpm check # 빠른 로컬 게이트: 프로덕션 tsgo + 샤딩된 lint + 병렬 빠른 가드 +pnpm changed:lanes # origin/main...HEAD에 대한 로컬 변경 레인 분류기 검사 +pnpm check:changed # 스마트 로컬 게이트: 경계 레인별 변경 typecheck/lint/tests +pnpm check # 빠른 로컬 게이트: 프로덕션 tsgo + 샤딩된 lint + 병렬 빠른 guard pnpm check:test-types pnpm check:timed # 단계별 시간 측정이 포함된 동일 게이트 pnpm build:strict-smoke @@ -85,5 +86,5 @@ pnpm test # vitest 테스트 pnpm test:channels pnpm test:contracts:channels pnpm check:docs # docs 포맷 + lint + 깨진 링크 -pnpm build # CI 아티팩트/build-smoke 레인이 중요할 때 dist 빌드 +pnpm build # CI artifact/build-smoke 레인이 중요할 때 dist 빌드 ``` diff --git a/docs/ko/concepts/typing-indicators.md b/docs/ko/concepts/typing-indicators.md index b2dc130c7..ab35745b1 100644 --- a/docs/ko/concepts/typing-indicators.md +++ b/docs/ko/concepts/typing-indicators.md @@ -1,41 +1,41 @@ --- read_when: - - 타이핑 표시 동작이나 기본값을 변경하는 경우 -summary: OpenClaw가 타이핑 표시를 보여주는 시점과 이를 조정하는 방법 -title: 타이핑 표시 + - 입력 중 표시 동작 또는 기본값 변경하기 +summary: OpenClaw가 입력 중 표시를 보여주는 경우와 이를 조정하는 방법 +title: 입력 중 표시 x-i18n: - generated_at: "2026-04-05T12:41:15Z" + generated_at: "2026-04-22T06:00:33Z" model: gpt-5.4 provider: openai - source_hash: 28c8c395a135fc0745181aab66a93582177e6acd0b3496debcbb98159a4f11dc + source_hash: 2e7e8ca448b6706b6f53fcb6a582be6d4a84715c82dfde3d53abe4268af3ae0d source_path: concepts/typing-indicators.md workflow: 15 --- -# 타이핑 표시 +# 입력 중 표시 -실행이 활성 상태인 동안 타이핑 표시는 채팅 채널로 전송됩니다. 타이핑이 **언제** 시작되는지는 -`agents.defaults.typingMode`로 제어하고, **얼마나 자주** 새로 고쳐지는지는 `typingIntervalSeconds`로 제어합니다. +실행이 활성화되어 있는 동안 입력 중 표시는 채팅 채널로 전송됩니다. +입력이 **언제** 시작되는지는 `agents.defaults.typingMode`로 제어하고, **얼마나 자주** 새로 고침되는지는 `typingIntervalSeconds`로 제어합니다. ## 기본값 -`agents.defaults.typingMode`가 **설정되지 않은 경우**, OpenClaw는 레거시 동작을 유지합니다. +`agents.defaults.typingMode`가 **설정되지 않은 경우**, OpenClaw는 기존 동작을 유지합니다. -- **다이렉트 채팅**: 모델 루프가 시작되면 즉시 타이핑이 시작됩니다. -- **멘션이 있는 그룹 채팅**: 즉시 타이핑이 시작됩니다. -- **멘션이 없는 그룹 채팅**: 메시지 텍스트 스트리밍이 시작될 때만 타이핑이 시작됩니다. -- **Heartbeat 실행**: 타이핑이 비활성화됩니다. +- **개인 채팅**: 모델 루프가 시작되면 즉시 입력이 시작됩니다. +- **멘션이 있는 그룹 채팅**: 즉시 입력이 시작됩니다. +- **멘션이 없는 그룹 채팅**: 메시지 텍스트 스트리밍이 시작될 때만 입력이 시작됩니다. +- **Heartbeat 실행**: 확인된 Heartbeat 대상이 입력 중 표시를 지원하는 채팅이고 입력 중 표시가 비활성화되어 있지 않으면, Heartbeat 실행이 시작될 때 입력이 시작됩니다. ## 모드 -`agents.defaults.typingMode`를 다음 중 하나로 설정하세요. +`agents.defaults.typingMode`를 다음 중 하나로 설정합니다. -- `never` — 어떤 경우에도 타이핑 표시를 보내지 않습니다. -- `instant` — 실행이 나중에 무음 응답 토큰만 반환하더라도, **모델 루프가 시작되자마자** 타이핑을 시작합니다. -- `thinking` — **첫 reasoning delta**에서 타이핑을 시작합니다(실행에 `reasoningLevel: "stream"` 필요). -- `message` — **첫 번째 무음이 아닌 텍스트 delta**에서 타이핑을 시작합니다(`NO_REPLY` 무음 토큰은 무시함). +- `never` — 입력 중 표시를 전혀 보내지 않습니다. +- `instant` — 실행이 나중에 무음 응답 토큰만 반환하더라도, **모델 루프가 시작되자마자** 입력을 시작합니다. +- `thinking` — **첫 번째 reasoning delta**에서 입력을 시작합니다(이 실행에 `reasoningLevel: "stream"` 필요). +- `message` — **첫 번째 비무음 텍스트 delta**에서 입력을 시작합니다(`NO_REPLY` 무음 토큰은 무시). -“얼마나 일찍 시작되는지”의 순서는 다음과 같습니다: +“얼마나 빨리 시작되는지” 순서: `never` → `message` → `thinking` → `instant` ## 구성 @@ -49,7 +49,7 @@ x-i18n: } ``` -세션별로 모드 또는 주기를 재정의할 수 있습니다. +세션별로 모드나 주기를 재정의할 수 있습니다. ```json5 { @@ -62,9 +62,8 @@ x-i18n: ## 참고 -- `message` 모드는 전체 페이로드가 정확히 무음 토큰일 때(예: `NO_REPLY` / `no_reply`, 대소문자 무시 일치) 무음 전용 응답에 대해 타이핑을 표시하지 않습니다. -- `thinking`은 실행이 reasoning을 스트리밍할 때만 동작합니다(`reasoningLevel: "stream"`). - 모델이 reasoning delta를 내보내지 않으면 타이핑은 시작되지 않습니다. -- Heartbeat는 모드와 관계없이 타이핑을 표시하지 않습니다. -- `typingIntervalSeconds`는 시작 시간이 아니라 **새로 고침 주기**를 제어합니다. - 기본값은 6초입니다. +- `message` 모드에서는 전체 페이로드가 정확히 무음 토큰인 경우 무음 전용 응답에 대해 입력 중 표시가 나타나지 않습니다(예: `NO_REPLY` / `no_reply`, 대소문자 구분 없이 일치). +- `thinking`은 실행이 reasoning을 스트리밍하는 경우에만 작동합니다(`reasoningLevel: "stream"`). 모델이 reasoning delta를 내보내지 않으면 입력이 시작되지 않습니다. +- Heartbeat 입력 중 표시는 확인된 전송 대상에 대한 활성 상태 신호입니다. `message` 또는 `thinking` 스트림 타이밍을 따르지 않고 Heartbeat 실행 시작 시 시작됩니다. 이를 비활성화하려면 `typingMode: "never"`로 설정하세요. +- `target: "none"`인 경우, 대상을 확인할 수 없는 경우, Heartbeat에 대해 채팅 전송이 비활성화된 경우, 또는 채널이 입력 중 표시를 지원하지 않는 경우 Heartbeat는 입력 중 표시를 보여주지 않습니다. +- `typingIntervalSeconds`는 시작 시간이 아니라 **새로 고침 주기**를 제어합니다. 기본값은 6초입니다. diff --git a/docs/ko/gateway/configuration-reference.md b/docs/ko/gateway/configuration-reference.md index de4515796..76ec865bf 100644 --- a/docs/ko/gateway/configuration-reference.md +++ b/docs/ko/gateway/configuration-reference.md @@ -1,70 +1,70 @@ --- read_when: - - 정확한 필드 수준 구성 의미 또는 기본값이 필요합니다 + - 정확한 필드 수준의 구성 의미 또는 기본값이 필요합니다 - 채널, 모델, Gateway 또는 도구 구성 블록을 검증하고 있습니다 summary: 핵심 OpenClaw 키, 기본값, 전용 하위 시스템 참조 링크를 위한 Gateway 구성 참조 title: 구성 참조 x-i18n: - generated_at: "2026-04-22T04:22:08Z" + generated_at: "2026-04-22T06:00:30Z" model: gpt-5.4 provider: openai - source_hash: 0313f47079536b93385b4e9c7680a896098ac05dce4e368d389a33e31b4649ac + source_hash: f0d6fc076f54e84bef5beefbcc42d8f172cc79792c716f76103894303e3042ac source_path: gateway/configuration-reference.md workflow: 15 --- # 구성 참조 -`~/.openclaw/openclaw.json`용 핵심 구성 참조입니다. 작업 중심 개요는 [구성](/ko/gateway/configuration)을 참조하세요. +`~/.openclaw/openclaw.json`을 위한 핵심 구성 참조입니다. 작업 중심 개요는 [Configuration](/ko/gateway/configuration)을 참조하세요. -이 페이지는 주요 OpenClaw 구성 표면을 다루며, 하위 시스템에 별도의 더 깊은 참조가 있는 경우 해당 링크로 연결합니다. 한 페이지에 모든 채널/Plugin 소유 명령 카탈로그나 모든 심층 메모리/QMD 조절 항목을 인라인으로 넣으려는 목적은 **없습니다**. +이 페이지는 주요 OpenClaw 구성 표면을 다루며, 하위 시스템에 자체적으로 더 깊은 참조가 있는 경우 해당 참조로 연결합니다. 이 페이지는 모든 채널/Plugin 소유 명령 카탈로그나 모든 심층 메모리/QMD 조절 항목을 한 페이지에 인라인으로 담으려는 목적은 **없습니다**. -코드 기준 진실: +코드 기준 정보: -- `openclaw config schema`는 검증과 Control UI에 사용되는 실제 JSON Schema를 출력하며, 사용 가능한 경우 번들/Plugin/채널 메타데이터를 병합합니다 -- `config.schema.lookup`는 드릴다운 도구용 경로 범위 스키마 노드 하나를 반환합니다 +- `openclaw config schema`는 검증 및 Control UI에 사용되는 실제 JSON Schema를 출력하며, 사용 가능한 경우 번들된/Plugin/채널 메타데이터가 병합됩니다 +- `config.schema.lookup`은 드릴다운 도구를 위해 경로 범위가 지정된 단일 스키마 노드를 반환합니다 - `pnpm config:docs:check` / `pnpm config:docs:gen`은 현재 스키마 표면에 대해 config-doc 기준 해시를 검증합니다 전용 심층 참조: -- `agents.defaults.memorySearch.*`, `memory.qmd.*`, `memory.citations`, `plugins.entries.memory-core.config.dreaming` 아래의 Dreaming 구성은 [메모리 구성 참조](/ko/reference/memory-config) -- 현재 내장 + 번들 명령 카탈로그는 [슬래시 명령](/ko/tools/slash-commands) -- 채널별 명령 표면은 해당 채널/Plugin 페이지 +- `agents.defaults.memorySearch.*`, `memory.qmd.*`, `memory.citations`, 그리고 `plugins.entries.memory-core.config.dreaming` 아래의 dreaming 구성을 위한 [메모리 구성 참조](/ko/reference/memory-config) +- 현재 내장 + 번들 명령 카탈로그를 위한 [Slash Commands](/ko/tools/slash-commands) +- 채널별 명령 표면을 위한 해당 채널/Plugin 페이지 -구성 형식은 **JSON5**입니다(주석 + 후행 쉼표 허용). 모든 필드는 선택 사항이며, 생략하면 OpenClaw는 안전한 기본값을 사용합니다. +구성 형식은 **JSON5**입니다(주석 + 후행 쉼표 허용). 모든 필드는 선택 사항이며, 생략하면 OpenClaw가 안전한 기본값을 사용합니다. --- ## 채널 -각 채널은 해당 구성 섹션이 존재하면 자동으로 시작됩니다(`enabled: false`가 아닌 한). +각 채널은 해당 구성 섹션이 존재하면 자동으로 시작됩니다(`enabled: false`인 경우 제외). -### DM 및 그룹 접근 +### DM 및 그룹 액세스 모든 채널은 DM 정책과 그룹 정책을 지원합니다: -| DM 정책 | 동작 | -| ------------------- | --------------------------------------------------------------- | -| `pairing` (기본값) | 알 수 없는 발신자는 일회성 페어링 코드를 받으며, 소유자가 승인해야 함 | -| `allowlist` | `allowFrom`(또는 페어링된 허용 저장소)에 있는 발신자만 허용 | -| `open` | 모든 수신 DM 허용(`allowFrom: ["*"]` 필요) | -| `disabled` | 모든 수신 DM 무시 | +| DM 정책 | 동작 | +| ------------------ | -------------------------------------------------------------- | +| `pairing` (기본값) | 알 수 없는 발신자는 1회용 페어링 코드를 받으며 소유자가 승인해야 함 | +| `allowlist` | `allowFrom`(또는 페어링된 허용 저장소)에 있는 발신자만 허용 | +| `open` | 모든 수신 DM 허용(`allowFrom: ["*"]` 필요) | +| `disabled` | 모든 수신 DM 무시 | -| 그룹 정책 | 동작 | +| 그룹 정책 | 동작 | | --------------------- | ------------------------------------------------------ | -| `allowlist` (기본값) | 구성된 허용 목록과 일치하는 그룹만 허용 | -| `open` | 그룹 허용 목록 우회(멘션 게이팅은 계속 적용됨) | -| `disabled` | 모든 그룹/룸 메시지 차단 | +| `allowlist` (기본값) | 구성된 허용 목록과 일치하는 그룹만 허용 | +| `open` | 그룹 허용 목록 우회(멘션 게이팅은 계속 적용됨) | +| `disabled` | 모든 그룹/룸 메시지 차단 | `channels.defaults.groupPolicy`는 공급자의 `groupPolicy`가 설정되지 않았을 때 기본값을 설정합니다. 페어링 코드는 1시간 후 만료됩니다. 대기 중인 DM 페어링 요청은 **채널당 3개**로 제한됩니다. -공급자 블록이 완전히 없으면(`channels.` 없음), 런타임 그룹 정책은 시작 경고와 함께 `allowlist`(fail-closed)로 대체됩니다. +공급자 블록이 완전히 누락된 경우(`channels.` 없음), 런타임 그룹 정책은 시작 시 경고와 함께 `allowlist`(fail-closed)로 대체됩니다. ### 채널 모델 재정의 -`channels.modelByChannel`을 사용해 특정 채널 ID를 모델에 고정합니다. 값은 `provider/model` 또는 구성된 모델 별칭을 허용합니다. 이 채널 매핑은 세션에 이미 모델 재정의가 없는 경우(예: `/model`로 설정된 경우)에 적용됩니다. +특정 채널 ID를 모델에 고정하려면 `channels.modelByChannel`을 사용하세요. 값은 `provider/model` 또는 구성된 모델 별칭을 허용합니다. 채널 매핑은 세션에 이미 모델 재정의가 없는 경우(예: `/model`을 통해 설정된 경우)에 적용됩니다. ```json5 { @@ -85,9 +85,9 @@ x-i18n: } ``` -### 채널 기본값과 Heartbeat +### 채널 기본값 및 Heartbeat -공급자 전반에서 공유되는 그룹 정책과 Heartbeat 동작에는 `channels.defaults`를 사용합니다: +공급자 전반에서 공유되는 그룹 정책 및 Heartbeat 동작에는 `channels.defaults`를 사용하세요: ```json5 { @@ -105,15 +105,15 @@ x-i18n: } ``` -- `channels.defaults.groupPolicy`: 공급자 수준 `groupPolicy`가 설정되지 않았을 때의 대체 그룹 정책입니다. -- `channels.defaults.contextVisibility`: 모든 채널의 기본 보조 컨텍스트 가시성 모드입니다. 값: `all`(기본값, 모든 인용/스레드/기록 컨텍스트 포함), `allowlist`(허용 목록 발신자의 컨텍스트만 포함), `allowlist_quote`(allowlist와 같지만 명시적 인용/답장 컨텍스트 유지). 채널별 재정의: `channels..contextVisibility`. -- `channels.defaults.heartbeat.showOk`: 정상 채널 상태를 Heartbeat 출력에 포함합니다. -- `channels.defaults.heartbeat.showAlerts`: 성능 저하/오류 상태를 Heartbeat 출력에 포함합니다. -- `channels.defaults.heartbeat.useIndicator`: 간결한 표시기 스타일 Heartbeat 출력을 렌더링합니다. +- `channels.defaults.groupPolicy`: 공급자 수준의 `groupPolicy`가 설정되지 않았을 때의 대체 그룹 정책입니다. +- `channels.defaults.contextVisibility`: 모든 채널에 대한 기본 추가 컨텍스트 표시 모드입니다. 값: `all`(기본값, 인용/스레드/기록 컨텍스트를 모두 포함), `allowlist`(허용 목록에 있는 발신자의 컨텍스트만 포함), `allowlist_quote`(allowlist와 같지만 명시적 인용/답글 컨텍스트 유지). 채널별 재정의: `channels..contextVisibility`. +- `channels.defaults.heartbeat.showOk`: Heartbeat 출력에 정상 채널 상태를 포함합니다. +- `channels.defaults.heartbeat.showAlerts`: Heartbeat 출력에 성능 저하/오류 상태를 포함합니다. +- `channels.defaults.heartbeat.useIndicator`: 간결한 표시기 스타일의 Heartbeat 출력을 렌더링합니다. ### WhatsApp -WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결된 세션이 존재하면 자동으로 시작됩니다. +WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결된 세션이 있으면 자동으로 시작됩니다. ```json5 { @@ -124,7 +124,7 @@ WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결 textChunkLimit: 4000, chunkMode: "length", // length | newline mediaMaxMb: 50, - sendReadReceipts: true, // 파란 체크 표시(self-chat 모드에서는 false) + sendReadReceipts: true, // 파란 체크 표시(셀프 채팅 모드에서는 false) groups: { "*": { requireMention: true }, }, @@ -164,8 +164,8 @@ WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결 } ``` -- 발신 명령은 `default` 계정이 있으면 기본적으로 해당 계정을 사용하고, 없으면 구성된 첫 번째 계정 ID(정렬 기준)를 사용합니다. -- 선택적 `channels.whatsapp.defaultAccount`는 구성된 계정 ID와 일치할 때 이 대체 기본 계정 선택을 재정의합니다. +- 발신 명령은 `default` 계정이 있으면 기본적으로 해당 계정을 사용하고, 없으면 구성된 첫 번째 계정 ID(정렬 순서)를 사용합니다. +- 선택 사항인 `channels.whatsapp.defaultAccount`는 구성된 계정 ID와 일치할 때 그 대체 기본 계정 선택을 재정의합니다. - 레거시 단일 계정 Baileys 인증 디렉터리는 `openclaw doctor`에 의해 `whatsapp/default`로 마이그레이션됩니다. - 계정별 재정의: `channels.whatsapp.accounts..sendReadReceipts`, `channels.whatsapp.accounts..dmPolicy`, `channels.whatsapp.accounts..allowFrom`. @@ -185,24 +185,24 @@ WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결 "*": { requireMention: true }, "-1001234567890": { allowFrom: ["@admin"], - systemPrompt: "답변은 간결하게 유지하세요.", + systemPrompt: "Keep answers brief.", topics: { "99": { requireMention: false, skills: ["search"], - systemPrompt: "주제를 벗어나지 마세요.", + systemPrompt: "Stay on topic.", }, }, }, }, customCommands: [ - { command: "backup", description: "Git 백업" }, - { command: "generate", description: "이미지 생성" }, + { command: "backup", description: "Git backup" }, + { command: "generate", description: "Create an image" }, ], historyLimit: 50, replyToMode: "first", // off | first | all | batched linkPreview: true, - streaming: "partial", // off | partial | block | progress (기본값: off, 미리보기 편집 속도 제한을 피하려면 명시적으로 옵트인) + streaming: "partial", // off | partial | block | progress (기본값: off; 미리보기 편집 속도 제한을 피하려면 명시적으로 opt in) actions: { reactions: true, sendMessage: true }, reactionNotifications: "own", // off | own | all mediaMaxMb: 100, @@ -225,11 +225,11 @@ WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결 } ``` -- 봇 토큰: `channels.telegram.botToken` 또는 `channels.telegram.tokenFile`(일반 파일만 허용, 심볼릭 링크는 거부), 기본 계정의 대체값으로 `TELEGRAM_BOT_TOKEN` 사용. -- 선택적 `channels.telegram.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. -- 다중 계정 설정(계정 ID 2개 이상)에서는 대체 라우팅을 피하기 위해 명시적인 기본값(`channels.telegram.defaultAccount` 또는 `channels.telegram.accounts.default`)을 설정하세요. `openclaw doctor`는 이 값이 없거나 잘못된 경우 경고합니다. -- `configWrites: false`는 Telegram에서 시작된 구성 쓰기(supergroup ID 마이그레이션, `/config set|unset`)를 차단합니다. -- `type: "acp"`인 최상위 `bindings[]` 항목은 포럼 토픽용 영구 ACP 바인딩을 구성합니다(`match.peer.id`에 정규 `chatId:topic:topicId` 사용). 필드 의미 체계는 [ACP 에이전트](/ko/tools/acp-agents#channel-specific-settings)에서 공유됩니다. +- 봇 토큰: `channels.telegram.botToken` 또는 `channels.telegram.tokenFile`(일반 파일만 허용, 심볼릭 링크는 거부됨), 기본 계정의 대체값으로 `TELEGRAM_BOT_TOKEN` 사용 가능. +- 선택 사항인 `channels.telegram.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. +- 다중 계정 설정(계정 ID 2개 이상)에서는 대체 라우팅을 피하기 위해 명시적 기본값(`channels.telegram.defaultAccount` 또는 `channels.telegram.accounts.default`)을 설정하세요. 이것이 누락되었거나 잘못되면 `openclaw doctor`가 경고합니다. +- `configWrites: false`는 Telegram에서 시작한 구성 쓰기(supergroup ID 마이그레이션, `/config set|unset`)를 차단합니다. +- `type: "acp"`를 사용하는 최상위 `bindings[]` 항목은 포럼 토픽에 대한 영구 ACP 바인딩을 구성합니다(`match.peer.id`에는 정식 `chatId:topic:topicId` 사용). 필드 의미는 [ACP Agents](/ko/tools/acp-agents#channel-specific-settings)와 공유됩니다. - Telegram 스트림 미리보기는 `sendMessage` + `editMessageText`를 사용합니다(직접 채팅과 그룹 채팅 모두에서 동작). - 재시도 정책: [재시도 정책](/ko/concepts/retry)을 참조하세요. @@ -278,7 +278,7 @@ WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결 requireMention: true, users: ["987654321098765432"], skills: ["docs"], - systemPrompt: "짧게만 답변하세요.", + systemPrompt: "Short answers only.", }, }, }, @@ -286,7 +286,7 @@ WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결 historyLimit: 20, textChunkLimit: 2000, chunkMode: "length", // length | newline - streaming: "off", // off | partial | block | progress (progress는 Discord에서 partial에 매핑됨) + streaming: "off", // off | partial | block | progress (progress는 Discord에서 partial로 매핑됨) maxLinesPerMessage: 17, ui: { components: { @@ -297,7 +297,7 @@ WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결 enabled: true, idleHours: 24, maxAgeHours: 0, - spawnSubagentSessions: false, // sessions_spawn({ thread: true })에 대한 옵트인 + spawnSubagentSessions: false, // sessions_spawn({ thread: true })에 대해 opt-in }, voice: { enabled: true, @@ -333,36 +333,36 @@ WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결 } ``` -- 토큰: `channels.discord.token`, 기본 계정의 대체값으로 `DISCORD_BOT_TOKEN` 사용. -- 명시적인 Discord `token`을 제공하는 직접 발신 호출은 해당 호출에 그 토큰을 사용합니다. 계정 재시도/정책 설정은 여전히 활성 런타임 스냅샷에서 선택된 계정에서 가져옵니다. -- 선택적 `channels.discord.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. -- 전달 대상에는 `user:`(DM) 또는 `channel:`(guild 채널)를 사용하세요. 숫자만 있는 ID는 거부됩니다. -- Guild slug는 소문자이며 공백은 `-`로 바뀝니다. 채널 키는 slug 처리된 이름(` #` 없음)을 사용합니다. guild ID 사용을 권장합니다. -- 봇이 작성한 메시지는 기본적으로 무시됩니다. `allowBots: true`는 이를 활성화합니다. `allowBots: "mentions"`를 사용하면 봇을 멘션한 봇 메시지만 허용합니다(자기 자신의 메시지는 여전히 필터링됨). -- `channels.discord.guilds..ignoreOtherMentions`(및 채널 재정의)는 봇은 멘션하지 않고 다른 사용자나 역할만 멘션한 메시지를 삭제합니다(`@everyone`/`@here` 제외). +- 토큰: `channels.discord.token`, 기본 계정의 대체값으로 `DISCORD_BOT_TOKEN` 사용 가능. +- 명시적 Discord `token`을 제공하는 직접 발신 호출은 해당 호출에 그 토큰을 사용합니다. 계정 재시도/정책 설정은 여전히 활성 런타임 스냅샷에서 선택된 계정에서 가져옵니다. +- 선택 사항인 `channels.discord.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. +- 전달 대상에는 `user:`(DM) 또는 `channel:`(guild 채널)를 사용하세요. 숫자 ID만 단독으로 쓰는 형식은 거부됩니다. +- Guild slug는 소문자이며 공백은 `-`로 대체됩니다. 채널 키는 slug 처리된 이름을 사용합니다(`#` 없음). 가능하면 guild ID를 우선 사용하세요. +- 봇이 작성한 메시지는 기본적으로 무시됩니다. `allowBots: true`로 활성화할 수 있으며, 봇을 멘션한 봇 메시지만 허용하려면 `allowBots: "mentions"`를 사용하세요(자체 메시지는 계속 필터링됨). +- `channels.discord.guilds..ignoreOtherMentions`(및 채널 재정의)는 봇을 멘션하지 않고 다른 사용자나 역할을 멘션한 메시지를 삭제합니다(`@everyone`/`@here` 제외). - `maxLinesPerMessage`(기본값 17)는 메시지가 2000자 미만이어도 줄 수가 많으면 분할합니다. - `channels.discord.threadBindings`는 Discord 스레드 바인딩 라우팅을 제어합니다: - - `enabled`: 스레드 바인딩 세션 기능(`/focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age`, 바인딩된 전달/라우팅)에 대한 Discord 재정의 - - `idleHours`: 비활성 자동 unfocus의 시간 단위 Discord 재정의(`0`이면 비활성화) - - `maxAgeHours`: 하드 최대 사용 기간의 시간 단위 Discord 재정의(`0`이면 비활성화) - - `spawnSubagentSessions`: `sessions_spawn({ thread: true })` 자동 스레드 생성/바인딩을 위한 옵트인 스위치 -- `type: "acp"`인 최상위 `bindings[]` 항목은 채널 및 스레드용 영구 ACP 바인딩을 구성합니다(`match.peer.id`에 채널/스레드 ID 사용). 필드 의미 체계는 [ACP 에이전트](/ko/tools/acp-agents#channel-specific-settings)에서 공유됩니다. + - `enabled`: 스레드 바인딩 세션 기능(` /focus`, `/unfocus`, `/agents`, `/session idle`, `/session max-age`, 그리고 바인딩된 전달/라우팅)에 대한 Discord 재정의 + - `idleHours`: 비활동 자동 unfocus에 대한 Discord 재정의(시간 단위, `0`은 비활성화) + - `maxAgeHours`: 하드 최대 수명에 대한 Discord 재정의(시간 단위, `0`은 비활성화) + - `spawnSubagentSessions`: `sessions_spawn({ thread: true })` 자동 스레드 생성/바인딩을 위한 opt-in 스위치 +- `type: "acp"`를 사용하는 최상위 `bindings[]` 항목은 채널과 스레드에 대한 영구 ACP 바인딩을 구성합니다(`match.peer.id`에는 채널/스레드 ID 사용). 필드 의미는 [ACP Agents](/ko/tools/acp-agents#channel-specific-settings)와 공유됩니다. - `channels.discord.ui.components.accentColor`는 Discord components v2 컨테이너의 강조 색상을 설정합니다. -- `channels.discord.voice`는 Discord 음성 채널 대화와 선택적 자동 참가 + TTS 재정의를 활성화합니다. -- `channels.discord.voice.daveEncryption` 및 `channels.discord.voice.decryptionFailureTolerance`는 `@discordjs/voice` DAVE 옵션으로 그대로 전달됩니다(기본값은 각각 `true`와 `24`). -- OpenClaw는 추가로 반복적인 복호화 실패 후 음성 세션에서 나갔다가 다시 참가하는 방식으로 음성 수신 복구를 시도합니다. -- `channels.discord.streaming`은 정식 스트림 모드 키입니다. 레거시 `streamMode` 및 불리언 `streaming` 값은 자동 마이그레이션됩니다. -- `channels.discord.autoPresence`는 런타임 가용성을 봇 presence에 매핑합니다(정상 => online, 성능 저하 => idle, 고갈 => dnd). 선택적으로 상태 텍스트 재정의도 허용합니다. -- `channels.discord.dangerouslyAllowNameMatching`은 변경 가능한 이름/태그 매칭을 다시 활성화합니다(비상 호환성 모드). -- `channels.discord.execApprovals`: Discord 네이티브 exec 승인 전달 및 승인자 권한 부여. +- `channels.discord.voice`는 Discord 음성 채널 대화와 선택적 자동 참여 + TTS 재정의를 활성화합니다. +- `channels.discord.voice.daveEncryption` 및 `channels.discord.voice.decryptionFailureTolerance`는 `@discordjs/voice` DAVE 옵션으로 그대로 전달됩니다(기본값은 각각 `true`, `24`). +- 또한 OpenClaw는 반복적인 복호화 실패 후 음성 세션에서 나갔다가 다시 참여하여 음성 수신 복구를 시도합니다. +- `channels.discord.streaming`은 표준 스트림 모드 키입니다. 레거시 `streamMode` 및 불리언 `streaming` 값은 자동 마이그레이션됩니다. +- `channels.discord.autoPresence`는 런타임 가용성을 봇 상태에 매핑합니다(정상 => online, 성능 저하 => idle, 고갈 => dnd). 선택적 상태 텍스트 재정의도 허용합니다. +- `channels.discord.dangerouslyAllowNameMatching`는 변경 가능한 이름/태그 매칭을 다시 활성화합니다(비상 호환성 모드). +- `channels.discord.execApprovals`: Discord 기본 exec 승인 전달 및 승인자 권한 부여. - `enabled`: `true`, `false`, 또는 `"auto"`(기본값). auto 모드에서는 `approvers` 또는 `commands.ownerAllowFrom`에서 승인자를 확인할 수 있을 때 exec 승인이 활성화됩니다. - - `approvers`: exec 요청을 승인할 수 있는 Discord 사용자 ID입니다. 생략하면 `commands.ownerAllowFrom`으로 대체됩니다. - - `agentFilter`: 선택적 에이전트 ID 허용 목록. 생략하면 모든 에이전트에 대한 승인을 전달합니다. - - `sessionFilter`: 선택적 세션 키 패턴(부분 문자열 또는 regex). - - `target`: 승인 프롬프트를 보낼 위치. `"dm"`(기본값)은 승인자 DM으로 보내고, `"channel"`은 원래 채널로 보내며, `"both"`는 둘 다로 보냅니다. target에 `"channel"`이 포함되면 버튼은 확인된 승인자만 사용할 수 있습니다. - - `cleanupAfterResolve`: `true`이면 승인, 거부 또는 타임아웃 후 승인 DM을 삭제합니다. + - `approvers`: exec 요청을 승인할 수 있는 Discord 사용자 ID입니다. 생략 시 `commands.ownerAllowFrom`으로 대체됩니다. + - `agentFilter`: 선택적 에이전트 ID 허용 목록입니다. 모든 에이전트의 승인을 전달하려면 생략하세요. + - `sessionFilter`: 선택적 세션 키 패턴(부분 문자열 또는 정규식)입니다. + - `target`: 승인 프롬프트를 보낼 위치입니다. `"dm"`(기본값)은 승인자 DM으로 전송하고, `"channel"`은 원래 채널로 전송하며, `"both"`는 둘 다로 전송합니다. target에 `"channel"`이 포함된 경우 버튼은 확인된 승인자만 사용할 수 있습니다. + - `cleanupAfterResolve`: `true`이면 승인, 거부 또는 시간 초과 후 승인 DM을 삭제합니다. -**반응 알림 모드:** `off`(없음), `own`(봇의 메시지, 기본값), `all`(모든 메시지), `allowlist`(모든 메시지에서 `guilds..users` 기준). +**리액션 알림 모드:** `off`(없음), `own`(봇 메시지, 기본값), `all`(모든 메시지), `allowlist`(`guilds..users`의 사용자가 보낸 모든 메시지). ### Google Chat @@ -393,11 +393,11 @@ WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결 } ``` -- 서비스 계정 JSON: 인라인(`serviceAccount`) 또는 파일 기반(`serviceAccountFile`). +- 서비스 계정 JSON: 인라인(`serviceAccount`) 또는 파일 기반(`serviceAccountFile`)입니다. - 서비스 계정 SecretRef(`serviceAccountRef`)도 지원됩니다. - 환경 변수 대체값: `GOOGLE_CHAT_SERVICE_ACCOUNT` 또는 `GOOGLE_CHAT_SERVICE_ACCOUNT_FILE`. - 전달 대상에는 `spaces/` 또는 `users/`를 사용하세요. -- `channels.googlechat.dangerouslyAllowNameMatching`은 변경 가능한 이메일 principal 매칭을 다시 활성화합니다(비상 호환성 모드). +- `channels.googlechat.dangerouslyAllowNameMatching`는 변경 가능한 이메일 principal 매칭을 다시 활성화합니다(비상 호환성 모드). ### Slack @@ -419,7 +419,7 @@ WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결 allowBots: false, users: ["U123"], skills: ["docs"], - systemPrompt: "짧게만 답변하세요.", + systemPrompt: "Short answers only.", }, }, historyLimit: 50, @@ -449,7 +449,7 @@ WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결 chunkMode: "length", streaming: { mode: "partial", // off | partial | block | progress - nativeTransport: true, // mode=partial일 때 Slack 네이티브 스트리밍 API 사용 + nativeTransport: true, // mode=partial일 때 Slack 기본 스트리밍 API 사용 }, mediaMaxMb: 20, execApprovals: { @@ -464,34 +464,30 @@ WhatsApp은 Gateway의 웹 채널(Baileys Web)을 통해 실행됩니다. 연결 } ``` -- **Socket mode**에는 `botToken`과 `appToken`이 모두 필요합니다(기본 계정 환경 변수 대체값: `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN`). +- **Socket mode**에는 `botToken`과 `appToken`이 모두 필요합니다(기본 계정 환경 변수 대체값은 `SLACK_BOT_TOKEN` + `SLACK_APP_TOKEN`). - **HTTP mode**에는 `botToken`과 `signingSecret`(루트 또는 계정별)이 필요합니다. -- `botToken`, `appToken`, `signingSecret`, `userToken`은 일반 텍스트 - 문자열 또는 SecretRef 객체를 받을 수 있습니다. -- Slack 계정 스냅샷은 `botTokenSource`, `botTokenStatus`, `appTokenStatus`, HTTP 모드에서는 - `signingSecretStatus` 같은 자격 증명별 소스/상태 필드를 노출합니다. - `configured_unavailable`은 해당 계정이 SecretRef를 통해 구성되어 있지만 현재 명령/런타임 경로에서 - secret 값을 해석할 수 없었음을 의미합니다. -- `configWrites: false`는 Slack에서 시작된 구성 쓰기를 차단합니다. -- 선택적 `channels.slack.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. -- `channels.slack.streaming.mode`는 정식 Slack 스트림 모드 키입니다. `channels.slack.streaming.nativeTransport`는 Slack의 네이티브 스트리밍 전송을 제어합니다. 레거시 `streamMode`, 불리언 `streaming`, `nativeStreaming` 값은 자동 마이그레이션됩니다. +- `botToken`, `appToken`, `signingSecret`, `userToken`은 일반 텍스트 문자열 또는 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`, 불리언 `streaming`, `nativeStreaming` 값은 자동 마이그레이션됩니다. - 전달 대상에는 `user:`(DM) 또는 `channel:`를 사용하세요. -**반응 알림 모드:** `off`, `own`(기본값), `all`, `allowlist`(`reactionAllowlist` 기준). +**리액션 알림 모드:** `off`, `own`(기본값), `all`, `allowlist`(`reactionAllowlist` 기준). -**스레드 세션 격리:** `thread.historyScope`는 스레드별(기본값) 또는 채널 전체에서 공유됩니다. `thread.inheritParent`는 부모 채널 transcript를 새 스레드에 복사합니다. +**스레드 세션 격리:** `thread.historyScope`는 스레드별(기본값) 또는 채널 전체에서 공유됩니다. `thread.inheritParent`는 부모 채널 대화를 새 스레드로 복사합니다. -- Slack 네이티브 스트리밍과 Slack assistant 스타일의 "is typing..." 스레드 상태는 답장 스레드 대상을 필요로 합니다. 최상위 DM은 기본적으로 스레드 밖에 머무르므로 스레드 스타일 미리보기 대신 `typingReaction` 또는 일반 전달을 사용합니다. -- `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 assistant 스타일의 "입력 중..." 스레드 상태에는 답글 스레드 대상이 필요합니다. 최상위 DM은 기본적으로 스레드 밖에서 유지되므로, 스레드 스타일 미리보기 대신 `typingReaction` 또는 일반 전달을 사용합니다. +- `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"`). -| 작업 그룹 | 기본값 | 참고 | -| ------------ | ------- | ---------------------- | -| reactions | 활성화 | 반응 추가 + 반응 목록 | -| messages | 활성화 | 읽기/전송/편집/삭제 | -| pins | 활성화 | 고정/고정 해제/목록 | -| memberInfo | 활성화 | 멤버 정보 | -| emojiList | 활성화 | 사용자 정의 이모지 목록 | +| 작업 그룹 | 기본값 | 참고 | +| ---------- | -------- | ------------------------ | +| reactions | 활성화됨 | 리액션 + 리액션 목록 | +| messages | 활성화됨 | 읽기/전송/편집/삭제 | +| pins | 활성화됨 | 고정/해제/목록 | +| memberInfo | 활성화됨 | 멤버 정보 | +| emojiList | 활성화됨 | 커스텀 이모지 목록 | ### Mattermost @@ -512,10 +508,10 @@ Mattermost는 Plugin으로 제공됩니다: `openclaw plugins install @openclaw/ "team-channel-id": { requireMention: false }, }, commands: { - native: true, // 옵트인 + native: true, // opt-in nativeSkills: true, callbackPath: "/api/channels/mattermost/command", - // reverse-proxy/공개 배포용 선택적 명시적 URL + // 리버스 프록시/공개 배포를 위한 선택적 명시 URL callbackUrl: "https://gateway.example.com/api/channels/mattermost/command", }, textChunkLimit: 4000, @@ -527,19 +523,18 @@ Mattermost는 Plugin으로 제공됩니다: `openclaw plugins install @openclaw/ 채팅 모드: `oncall`(@멘션 시 응답, 기본값), `onmessage`(모든 메시지), `onchar`(트리거 접두사로 시작하는 메시지). -Mattermost 네이티브 명령이 활성화된 경우: +Mattermost 기본 명령이 활성화된 경우: - `commands.callbackPath`는 전체 URL이 아니라 경로여야 합니다(예: `/api/channels/mattermost/command`). -- `commands.callbackUrl`은 OpenClaw Gateway 엔드포인트로 해석되어야 하며 Mattermost 서버에서 도달 가능해야 합니다. -- 네이티브 슬래시 콜백은 슬래시 명령 등록 중 Mattermost가 반환한 명령별 토큰으로 인증됩니다. 등록에 실패하거나 활성화된 명령이 없으면 OpenClaw는 다음과 함께 콜백을 거부합니다: +- `commands.callbackUrl`은 OpenClaw Gateway 엔드포인트로 해석되어야 하며 Mattermost 서버에서 접근 가능해야 합니다. +- 기본 slash 콜백은 slash 명령 등록 중 Mattermost가 반환한 명령별 토큰으로 인증됩니다. 등록에 실패했거나 활성화된 명령이 없으면 OpenClaw는 다음과 함께 콜백을 거부합니다: `Unauthorized: invalid command token.` -- 비공개/tailnet/내부 콜백 호스트의 경우 Mattermost는 - `ServiceSettings.AllowedUntrustedInternalConnections`에 콜백 호스트/도메인이 포함되어야 할 수 있습니다. +- 비공개/tailnet/내부 콜백 호스트의 경우, Mattermost는 콜백 호스트/도메인이 `ServiceSettings.AllowedUntrustedInternalConnections`에 포함되어야 할 수 있습니다. 전체 URL이 아니라 호스트/도메인 값을 사용하세요. -- `channels.mattermost.configWrites`: Mattermost에서 시작된 구성 쓰기를 허용하거나 거부합니다. -- `channels.mattermost.requireMention`: 채널에서 답장하기 전에 `@mention`을 요구합니다. -- `channels.mattermost.groups..requireMention`: 채널별 멘션 게이팅 재정의(`"*"`는 기본값). -- 선택적 `channels.mattermost.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. +- `channels.mattermost.configWrites`: Mattermost에서 시작한 구성 쓰기를 허용하거나 거부합니다. +- `channels.mattermost.requireMention`: 채널에서 응답하기 전에 `@mention`을 요구합니다. +- `channels.mattermost.groups..requireMention`: 채널별 멘션 게이팅 재정의입니다(기본값은 `"*"`). +- 선택 사항인 `channels.mattermost.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. ### Signal @@ -560,11 +555,11 @@ Mattermost 네이티브 명령이 활성화된 경우: } ``` -**반응 알림 모드:** `off`, `own`(기본값), `all`, `allowlist`(`reactionAllowlist` 기준). +**리액션 알림 모드:** `off`, `own`(기본값), `all`, `allowlist`(`reactionAllowlist` 기준). - `channels.signal.account`: 채널 시작을 특정 Signal 계정 식별자에 고정합니다. -- `channels.signal.configWrites`: Signal에서 시작된 구성 쓰기를 허용하거나 거부합니다. -- 선택적 `channels.signal.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. +- `channels.signal.configWrites`: Signal에서 시작한 구성 쓰기를 허용하거나 거부합니다. +- 선택 사항인 `channels.signal.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. ### BlueBubbles @@ -576,7 +571,7 @@ BlueBubbles는 권장되는 iMessage 경로입니다(Plugin 기반, `channels.bl bluebubbles: { enabled: true, dmPolicy: "pairing", - // serverUrl, password, webhookPath, 그룹 제어, 고급 작업: + // serverUrl, password, webhookPath, group controls, and advanced actions: // /channels/bluebubbles 참조 }, }, @@ -584,8 +579,8 @@ 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#channel-specific-settings). +- 선택 사항인 `channels.bluebubbles.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. +- `type: "acp"`를 사용하는 최상위 `bindings[]` 항목은 BlueBubbles 대화를 영구 ACP 세션에 바인딩할 수 있습니다. `match.peer.id`에는 BlueBubbles handle 또는 대상 문자열(`chat_id:*`, `chat_guid:*`, `chat_identifier:*`)을 사용하세요. 공유 필드 의미: [ACP Agents](/ko/tools/acp-agents#channel-specific-settings). - 전체 BlueBubbles 채널 구성은 [BlueBubbles](/ko/channels/bluebubbles)에 문서화되어 있습니다. ### iMessage @@ -614,17 +609,17 @@ OpenClaw는 `imsg rpc`를 생성합니다(stdio를 통한 JSON-RPC). 데몬이 } ``` -- 선택적 `channels.imessage.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. +- 선택 사항인 `channels.imessage.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. - Messages DB에 대한 전체 디스크 접근 권한이 필요합니다. -- `chat_id:` 대상을 권장합니다. 채팅 목록은 `imsg chats --limit 20`을 사용하세요. -- `cliPath`는 SSH 래퍼를 가리킬 수 있습니다. 첨부 파일을 SCP로 가져오려면 `remoteHost`(`host` 또는 `user@host`)를 설정하세요. -- `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#channel-specific-settings). +- 가능하면 `chat_id:` 대상을 사용하세요. 채팅 목록은 `imsg chats --limit 20`으로 확인할 수 있습니다. +- `cliPath`는 SSH 래퍼를 가리킬 수 있으며, SCP 첨부파일 가져오기를 위해 `remoteHost`(`host` 또는 `user@host`)를 설정하세요. +- `attachmentRoots` 및 `remoteAttachmentRoots`는 수신 첨부파일 경로를 제한합니다(기본값: `/Users/*/Library/Messages/Attachments`). +- SCP는 엄격한 호스트 키 검사를 사용하므로, 릴레이 호스트 키가 이미 `~/.ssh/known_hosts`에 존재하는지 확인하세요. +- `channels.imessage.configWrites`: iMessage에서 시작한 구성 쓰기를 허용하거나 거부합니다. +- `type: "acp"`를 사용하는 최상위 `bindings[]` 항목은 iMessage 대화를 영구 ACP 세션에 바인딩할 수 있습니다. `match.peer.id`에는 정규화된 handle 또는 명시적 채팅 대상(`chat_id:*`, `chat_guid:*`, `chat_identifier:*`)을 사용하세요. 공유 필드 의미: [ACP Agents](/ko/tools/acp-agents#channel-specific-settings). - + ```bash #!/usr/bin/env bash @@ -666,20 +661,20 @@ Matrix는 Plugin 기반이며 `channels.matrix` 아래에서 구성합니다. ``` - 토큰 인증은 `accessToken`을 사용하고, 비밀번호 인증은 `userId` + `password`를 사용합니다. -- `channels.matrix.proxy`는 Matrix HTTP 트래픽을 명시적인 HTTP(S) 프록시를 통해 라우팅합니다. 이름 있는 계정은 `channels.matrix.accounts..proxy`로 이를 재정의할 수 있습니다. -- `channels.matrix.network.dangerouslyAllowPrivateNetwork`는 비공개/내부 homeserver를 허용합니다. `proxy`와 이 네트워크 옵트인은 서로 독립적인 제어 항목입니다. +- `channels.matrix.proxy`는 Matrix HTTP 트래픽을 명시적 HTTP(S) 프록시를 통해 라우팅합니다. 명명된 계정은 `channels.matrix.accounts..proxy`로 이를 재정의할 수 있습니다. +- `channels.matrix.network.dangerouslyAllowPrivateNetwork`는 비공개/내부 homeserver를 허용합니다. `proxy`와 이 네트워크 opt-in은 서로 독립적인 제어입니다. - `channels.matrix.defaultAccount`는 다중 계정 설정에서 선호 계정을 선택합니다. -- `channels.matrix.autoJoin`의 기본값은 `off`이므로, 초대된 룸과 새 DM 스타일 초대는 `autoJoin: "allowlist"`와 `autoJoinAllowlist` 또는 `autoJoin: "always"`를 설정하기 전까지 무시됩니다. -- `channels.matrix.execApprovals`: Matrix 네이티브 exec 승인 전달 및 승인자 권한 부여. +- `channels.matrix.autoJoin`의 기본값은 `off`이므로, `autoJoin: "allowlist"`와 `autoJoinAllowlist` 또는 `autoJoin: "always"`를 설정하기 전까지 초대된 방과 새 DM 스타일 초대는 무시됩니다. +- `channels.matrix.execApprovals`: Matrix 기본 exec 승인 전달 및 승인자 권한 부여. - `enabled`: `true`, `false`, 또는 `"auto"`(기본값). auto 모드에서는 `approvers` 또는 `commands.ownerAllowFrom`에서 승인자를 확인할 수 있을 때 exec 승인이 활성화됩니다. - `approvers`: exec 요청을 승인할 수 있는 Matrix 사용자 ID(예: `@owner:example.org`)입니다. - - `agentFilter`: 선택적 에이전트 ID 허용 목록. 생략하면 모든 에이전트에 대한 승인을 전달합니다. - - `sessionFilter`: 선택적 세션 키 패턴(부분 문자열 또는 regex). - - `target`: 승인 프롬프트를 보낼 위치. `"dm"`(기본값), `"channel"`(원래 룸), 또는 `"both"`. + - `agentFilter`: 선택적 에이전트 ID 허용 목록입니다. 모든 에이전트의 승인을 전달하려면 생략하세요. + - `sessionFilter`: 선택적 세션 키 패턴(부분 문자열 또는 정규식)입니다. + - `target`: 승인 프롬프트를 보낼 위치입니다. `"dm"`(기본값), `"channel"`(원래 방), 또는 `"both"`입니다. - 계정별 재정의: `channels.matrix.accounts..execApprovals`. -- `channels.matrix.dm.sessionScope`는 Matrix DM을 세션으로 그룹화하는 방식을 제어합니다: `per-user`(기본값)는 라우팅된 피어 기준으로 공유하고, `per-room`은 각 DM 룸을 격리합니다. -- Matrix 상태 프로브와 라이브 디렉터리 조회는 런타임 트래픽과 동일한 프록시 정책을 사용합니다. -- 전체 Matrix 구성, 대상 지정 규칙, 설정 예시는 [Matrix](/ko/channels/matrix)에 문서화되어 있습니다. +- `channels.matrix.dm.sessionScope`는 Matrix DM이 세션으로 묶이는 방식을 제어합니다: `per-user`(기본값)는 라우팅된 피어 기준으로 공유하고, `per-room`은 각 DM 방을 격리합니다. +- Matrix 상태 프로브와 실시간 디렉터리 조회는 런타임 트래픽과 동일한 프록시 정책을 사용합니다. +- 전체 Matrix 구성, 대상 지정 규칙, 설정 예제는 [Matrix](/ko/channels/matrix)에 문서화되어 있습니다. ### Microsoft Teams @@ -691,7 +686,7 @@ Microsoft Teams는 Plugin 기반이며 `channels.msteams` 아래에서 구성합 msteams: { enabled: true, configWrites: true, - // appId, appPassword, tenantId, webhook, team/channel 정책: + // appId, appPassword, tenantId, webhook, team/channel policies: // /channels/msteams 참조 }, }, @@ -725,12 +720,12 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성합니다. ``` - 여기서 다루는 핵심 키 경로: `channels.irc`, `channels.irc.dmPolicy`, `channels.irc.configWrites`, `channels.irc.nickserv.*`. -- 선택적 `channels.irc.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. +- 선택 사항인 `channels.irc.defaultAccount`는 구성된 계정 ID와 일치할 때 기본 계정 선택을 재정의합니다. - 전체 IRC 채널 구성(호스트/포트/TLS/채널/허용 목록/멘션 게이팅)은 [IRC](/ko/channels/irc)에 문서화되어 있습니다. ### 다중 계정(모든 채널) -채널별로 여러 계정을 실행합니다(각 계정은 자체 `accountId`를 가짐): +채널별로 여러 계정을 실행할 수 있습니다(각각 자체 `accountId` 보유): ```json5 { @@ -738,11 +733,11 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성합니다. telegram: { accounts: { default: { - name: "기본 봇", + name: "Primary bot", botToken: "123456:ABC...", }, alerts: { - name: "알림 봇", + name: "Alerts bot", botToken: "987654:XYZ...", }, }, @@ -752,27 +747,27 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성합니다. ``` - `accountId`를 생략하면 `default`가 사용됩니다(CLI + 라우팅). -- 환경 변수 토큰은 **기본** 계정에만 적용됩니다. -- 계정별로 재정의하지 않는 한 기본 채널 설정은 모든 계정에 적용됩니다. +- 환경 변수 토큰은 **default** 계정에만 적용됩니다. +- 기본 채널 설정은 계정별로 재정의하지 않는 한 모든 계정에 적용됩니다. - 각 계정을 다른 에이전트로 라우팅하려면 `bindings[].match.accountId`를 사용하세요. -- `openclaw channels add`(또는 채널 온보딩)를 통해 비기본 계정을 추가할 때 여전히 단일 계정 최상위 채널 구성을 사용 중이면, OpenClaw는 원래 계정이 계속 작동하도록 계정 범위의 최상위 단일 계정 값을 먼저 채널 계정 맵으로 승격합니다. 대부분의 채널은 이를 `channels..accounts.default`로 이동합니다. Matrix는 대신 기존의 일치하는 이름 지정/기본 대상을 유지할 수 있습니다. -- 기존 채널 전용 바인딩(`accountId` 없음)은 계속 기본 계정과 일치하며, 계정 범위 바인딩은 여전히 선택 사항입니다. -- `openclaw doctor --fix`도 혼합된 형태를 복구하여 계정 범위의 최상위 단일 계정 값을 해당 채널에 대해 선택된 승격 계정으로 이동합니다. 대부분의 채널은 `accounts.default`를 사용합니다. Matrix는 대신 기존의 일치하는 이름 지정/기본 대상을 유지할 수 있습니다. +- `openclaw channels add`(또는 채널 온보딩)를 통해 비기본 계정을 추가할 때 여전히 단일 계정 최상위 채널 구성을 사용 중이면, OpenClaw는 원래 계정이 계속 동작하도록 계정 범위의 최상위 단일 계정 값을 먼저 채널 계정 맵으로 승격합니다. 대부분의 채널은 이를 `channels..accounts.default`로 이동하며, Matrix는 대신 기존의 일치하는 명명된/default 대상을 유지할 수 있습니다. +- 기존의 채널 전용 바인딩(`accountId` 없음)은 계속 기본 계정과 일치합니다. 계정 범위 바인딩은 여전히 선택 사항입니다. +- `openclaw doctor --fix`도 계정 범위의 최상위 단일 계정 값을 해당 채널에 대해 선택된 승격 계정으로 이동하여 혼합된 형태를 복구합니다. 대부분의 채널은 `accounts.default`를 사용하며, Matrix는 대신 기존의 일치하는 명명된/default 대상을 유지할 수 있습니다. ### 기타 Plugin 채널 많은 Plugin 채널은 `channels.`로 구성되며 전용 채널 페이지에 문서화되어 있습니다(예: Feishu, Matrix, LINE, Nostr, Zalo, Nextcloud Talk, Synology Chat, Twitch). -전체 채널 색인은 [채널](/ko/channels)을 참조하세요. +전체 채널 색인은 [Channels](/ko/channels)를 참조하세요. ### 그룹 채팅 멘션 게이팅 -그룹 메시지는 기본적으로 **멘션 필요**입니다(메타데이터 멘션 또는 안전한 regex 패턴). WhatsApp, Telegram, Discord, Google Chat, iMessage 그룹 채팅에 적용됩니다. +그룹 메시지는 기본적으로 **멘션 필요**입니다(메타데이터 멘션 또는 안전한 정규식 패턴). WhatsApp, Telegram, Discord, Google Chat, iMessage 그룹 채팅에 적용됩니다. **멘션 유형:** -- **메타데이터 멘션**: 네이티브 플랫폼 @멘션. WhatsApp self-chat 모드에서는 무시됩니다. -- **텍스트 패턴**: `agents.list[].groupChat.mentionPatterns`의 안전한 regex 패턴. 잘못된 패턴과 안전하지 않은 중첩 반복은 무시됩니다. -- 멘션 게이팅은 감지가 가능한 경우에만 적용됩니다(네이티브 멘션 또는 하나 이상의 패턴). +- **메타데이터 멘션**: 플랫폼 기본 @멘션. WhatsApp 셀프 채팅 모드에서는 무시됩니다. +- **텍스트 패턴**: `agents.list[].groupChat.mentionPatterns`의 안전한 정규식 패턴입니다. 잘못된 패턴과 안전하지 않은 중첩 반복은 무시됩니다. +- 멘션 게이팅은 감지가 가능한 경우에만 적용됩니다(기본 멘션 또는 최소 1개의 패턴이 있을 때). ```json5 { @@ -785,7 +780,7 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성합니다. } ``` -`messages.groupChat.historyLimit`는 전역 기본값을 설정합니다. 채널은 `channels..historyLimit`(또는 계정별)로 이를 재정의할 수 있습니다. 비활성화하려면 `0`으로 설정하세요. +`messages.groupChat.historyLimit`는 전역 기본값을 설정합니다. 채널은 `channels..historyLimit`(또는 계정별 설정)로 이를 재정의할 수 있습니다. 비활성화하려면 `0`으로 설정하세요. #### DM 기록 제한 @@ -806,9 +801,9 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성합니다. 지원 대상: `telegram`, `whatsapp`, `discord`, `slack`, `signal`, `imessage`, `msteams`. -#### self-chat 모드 +#### 셀프 채팅 모드 -자신의 번호를 `allowFrom`에 포함해 self-chat 모드를 활성화합니다(네이티브 @멘션은 무시하고, 텍스트 패턴에만 응답): +자기 번호를 `allowFrom`에 포함하면 셀프 채팅 모드가 활성화됩니다(기본 @멘션은 무시하고 텍스트 패턴에만 응답): ```json5 { @@ -834,8 +829,8 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성합니다. ```json5 { commands: { - native: "auto", // 지원될 때 네이티브 명령 등록 - nativeSkills: "auto", // 지원될 때 네이티브 Skills 명령 등록 + native: "auto", // 지원되는 경우 기본 명령 등록 + nativeSkills: "auto", // 지원되는 경우 기본 Skills 명령 등록 text: true, // 채팅 메시지에서 /commands 파싱 bash: false, // ! 허용(별칭: /bash) bashForegroundMs: 2000, @@ -858,32 +853,32 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성합니다. -- 이 블록은 명령 표면을 구성합니다. 현재 내장 + 번들 명령 카탈로그는 [슬래시 명령](/ko/tools/slash-commands)을 참조하세요. -- 이 페이지는 전체 명령 카탈로그가 아니라 **구성 키 참조**입니다. QQ Bot `/bot-ping` `/bot-help` `/bot-logs`, LINE `/card`, device-pair `/pair`, memory `/dreaming`, phone-control `/phone`, Talk `/voice` 같은 채널/Plugin 소유 명령은 해당 채널/Plugin 페이지와 [슬래시 명령](/ko/tools/slash-commands)에 문서화되어 있습니다. -- 텍스트 명령은 앞에 `/`가 붙은 **독립 실행형** 메시지여야 합니다. -- `native: "auto"`는 Discord/Telegram에서 네이티브 명령을 켜고 Slack에서는 꺼 둡니다. -- `nativeSkills: "auto"`는 Discord/Telegram에서 네이티브 Skills 명령을 켜고 Slack에서는 꺼 둡니다. -- 채널별 재정의: `channels.discord.commands.native`(bool 또는 `"auto"`). `false`는 이전에 등록된 명령을 제거합니다. -- 채널별 네이티브 Skills 등록은 `channels..commands.nativeSkills`로 재정의합니다. -- `channels.telegram.customCommands`는 추가 Telegram 봇 메뉴 항목을 추가합니다. -- `bash: true`는 호스트 셸용 `! `를 활성화합니다. `tools.elevated.enabled`가 필요하며 발신자는 `tools.elevated.allowFrom.`에 포함되어야 합니다. -- `config: true`는 `/config`를 활성화합니다(`openclaw.json` 읽기/쓰기). Gateway `chat.send` 클라이언트의 경우 지속적인 `/config set|unset` 쓰기에는 `operator.admin`도 필요합니다. 읽기 전용 `/config show`는 일반 쓰기 범위 operator 클라이언트에서도 계속 사용할 수 있습니다. -- `mcp: true`는 `mcp.servers` 아래 OpenClaw 관리 MCP 서버 구성을 위한 `/mcp`를 활성화합니다. +- 이 블록은 명령 표면을 구성합니다. 현재 내장 + 번들 명령 카탈로그는 [Slash Commands](/ko/tools/slash-commands)를 참조하세요. +- 이 페이지는 전체 명령 카탈로그가 아니라 **구성 키 참조**입니다. QQ Bot `/bot-ping` `/bot-help` `/bot-logs`, LINE `/card`, device-pair `/pair`, memory `/dreaming`, phone-control `/phone`, Talk `/voice`와 같은 채널/Plugin 소유 명령은 해당 채널/Plugin 페이지와 [Slash Commands](/ko/tools/slash-commands)에 문서화되어 있습니다. +- 텍스트 명령은 반드시 선행 `/`가 있는 **독립 실행형** 메시지여야 합니다. +- `native: "auto"`는 Discord/Telegram의 기본 명령을 켜고, Slack은 끕니다. +- `nativeSkills: "auto"`는 Discord/Telegram의 기본 Skills 명령을 켜고, Slack은 끕니다. +- 채널별 재정의: `channels.discord.commands.native`(bool 또는 `"auto"`). `false`는 이전에 등록된 명령을 해제합니다. +- `channels..commands.nativeSkills`로 채널별 기본 skill 등록을 재정의합니다. +- `channels.telegram.customCommands`는 추가 Telegram 봇 메뉴 항목을 더합니다. +- `bash: true`는 호스트 셸에 대해 `! `를 활성화합니다. `tools.elevated.enabled`와 발신자가 `tools.elevated.allowFrom.`에 포함되어 있어야 합니다. +- `config: true`는 `/config`를 활성화합니다(`openclaw.json` 읽기/쓰기). Gateway `chat.send` 클라이언트의 경우 영구적인 `/config set|unset` 쓰기에는 `operator.admin`도 필요합니다. 읽기 전용 `/config show`는 일반 쓰기 범위 operator 클라이언트에서도 계속 사용할 수 있습니다. +- `mcp: true`는 `mcp.servers` 아래의 OpenClaw 관리 MCP 서버 구성을 위한 `/mcp`를 활성화합니다. - `plugins: true`는 Plugin 검색, 설치, 활성화/비활성화 제어를 위한 `/plugins`를 활성화합니다. - `channels..configWrites`는 채널별 구성 변경을 제어합니다(기본값: true). -- 다중 계정 채널의 경우 `channels..accounts..configWrites`도 해당 계정을 대상으로 하는 쓰기를 제어합니다(예: `/allowlist --config --account ` 또는 `/config set channels..accounts....`). -- `restart: false`는 `/restart` 및 gateway restart 도구 작업을 비활성화합니다. 기본값: `true`. +- 다중 계정 채널의 경우, `channels..accounts..configWrites`도 해당 계정을 대상으로 하는 쓰기를 제어합니다(예: `/allowlist --config --account ` 또는 `/config set channels..accounts....`). +- `restart: false`는 `/restart`와 gateway restart 도구 작업을 비활성화합니다. 기본값: `true`. - `ownerAllowFrom`은 소유자 전용 명령/도구를 위한 명시적 소유자 허용 목록입니다. `allowFrom`과는 별개입니다. -- `ownerDisplay: "hash"`는 시스템 프롬프트에서 소유자 ID를 해시 처리합니다. 해시를 제어하려면 `ownerDisplaySecret`을 설정하세요. -- `allowFrom`은 공급자별입니다. 이 값을 설정하면 이것이 **유일한** 권한 부여 소스가 되며(채널 허용 목록/페어링과 `useAccessGroups`는 무시됨). -- `useAccessGroups: false`는 `allowFrom`이 설정되지 않았을 때 명령이 access-group 정책을 우회하도록 허용합니다. +- `ownerDisplay: "hash"`는 시스템 프롬프트에서 소유자 ID를 해시합니다. 해시를 제어하려면 `ownerDisplaySecret`을 설정하세요. +- `allowFrom`은 공급자별입니다. 설정되면 이것이 **유일한** 권한 부여 소스가 됩니다(채널 허용 목록/페어링과 `useAccessGroups`는 무시됨). +- `useAccessGroups: false`는 `allowFrom`이 설정되지 않았을 때 명령이 액세스 그룹 정책을 우회하도록 허용합니다. - 명령 문서 맵: - - 내장 + 번들 카탈로그: [슬래시 명령](/ko/tools/slash-commands) - - 채널별 명령 표면: [채널](/ko/channels) + - 내장 + 번들 카탈로그: [Slash Commands](/ko/tools/slash-commands) + - 채널별 명령 표면: [Channels](/ko/channels) - QQ Bot 명령: [QQ Bot](/ko/channels/qqbot) - - 페어링 명령: [페어링](/ko/channels/pairing) + - 페어링 명령: [Pairing](/ko/channels/pairing) - LINE 카드 명령: [LINE](/ko/channels/line) - - 메모리 dreaming: [Dreaming](/ko/concepts/dreaming) + - memory dreaming: [Dreaming](/ko/concepts/dreaming) @@ -903,7 +898,7 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성합니다. ### `agents.defaults.repoRoot` -시스템 프롬프트의 Runtime 줄에 표시되는 선택적 저장소 루트입니다. 설정하지 않으면 OpenClaw가 workspace에서 위로 거슬러 올라가며 자동 감지합니다. +시스템 프롬프트의 Runtime 줄에 표시되는 선택적 저장소 루트입니다. 설정하지 않으면 OpenClaw가 workspace에서 위로 탐색하며 자동 감지합니다. ```json5 { @@ -913,7 +908,7 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성합니다. ### `agents.defaults.skills` -`agents.list[].skills`를 설정하지 않은 에이전트에 대한 선택적 기본 Skills 허용 목록입니다. +`agents.list[].skills`를 설정하지 않은 에이전트에 적용할 선택적 기본 skill 허용 목록입니다. ```json5 { @@ -922,21 +917,20 @@ IRC는 Plugin 기반이며 `channels.irc` 아래에서 구성합니다. list: [ { id: "writer" }, // github, weather 상속 { id: "docs", skills: ["docs-search"] }, // 기본값 대체 - { id: "locked-down", skills: [] }, // Skills 없음 + { id: "locked-down", skills: [] }, // skills 없음 ], }, } ``` -- 기본적으로 Skills 제한 없이 사용하려면 `agents.defaults.skills`를 생략하세요. +- 기본적으로 제한 없는 Skills를 사용하려면 `agents.defaults.skills`를 생략하세요. - 기본값을 상속하려면 `agents.list[].skills`를 생략하세요. -- Skills를 사용하지 않으려면 `agents.list[].skills: []`로 설정하세요. -- 비어 있지 않은 `agents.list[].skills` 목록은 해당 에이전트의 최종 집합이며, - 기본값과 병합되지 않습니다. +- skills를 사용하지 않으려면 `agents.list[].skills: []`로 설정하세요. +- 비어 있지 않은 `agents.list[].skills` 목록은 해당 에이전트의 최종 집합이며, 기본값과 병합되지 않습니다. ### `agents.defaults.skipBootstrap` -workspace 부트스트랩 파일(`AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, `BOOTSTRAP.md`)의 자동 생성을 비활성화합니다. +workspace bootstrap 파일(`AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, `BOOTSTRAP.md`)의 자동 생성을 비활성화합니다. ```json5 { @@ -946,9 +940,9 @@ workspace 부트스트랩 파일(`AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.m ### `agents.defaults.contextInjection` -workspace 부트스트랩 파일이 시스템 프롬프트에 주입되는 시점을 제어합니다. 기본값: `"always"`. +workspace bootstrap 파일을 시스템 프롬프트에 언제 주입할지 제어합니다. 기본값: `"always"`. -- `"continuation-skip"`: 안전한 연속 턴(assistant 응답 완료 후)에서는 workspace 부트스트랩 재주입을 건너뛰어 프롬프트 크기를 줄입니다. Heartbeat 실행과 Compaction 후 재시도는 계속 컨텍스트를 다시 구성합니다. +- `"continuation-skip"`: 안전한 연속 턴(완료된 assistant 응답 이후)에서는 workspace bootstrap 재주입을 건너뛰어 프롬프트 크기를 줄입니다. Heartbeat 실행과 post-Compaction 재시도는 계속 컨텍스트를 다시 구성합니다. ```json5 { @@ -958,7 +952,7 @@ workspace 부트스트랩 파일이 시스템 프롬프트에 주입되는 시 ### `agents.defaults.bootstrapMaxChars` -잘리기 전 workspace 부트스트랩 파일당 최대 문자 수. 기본값: `12000`. +잘리기 전 workspace bootstrap 파일당 최대 문자 수입니다. 기본값: `12000`. ```json5 { @@ -968,7 +962,7 @@ workspace 부트스트랩 파일이 시스템 프롬프트에 주입되는 시 ### `agents.defaults.bootstrapTotalMaxChars` -모든 workspace 부트스트랩 파일에 걸쳐 주입되는 최대 총 문자 수. 기본값: `60000`. +모든 workspace bootstrap 파일에 걸쳐 주입되는 총 최대 문자 수입니다. 기본값: `60000`. ```json5 { @@ -978,12 +972,12 @@ workspace 부트스트랩 파일이 시스템 프롬프트에 주입되는 시 ### `agents.defaults.bootstrapPromptTruncationWarning` -부트스트랩 컨텍스트가 잘렸을 때 에이전트에게 보이는 경고 텍스트를 제어합니다. +bootstrap 컨텍스트가 잘렸을 때 에이전트에게 보이는 경고 텍스트를 제어합니다. 기본값: `"once"`. - `"off"`: 시스템 프롬프트에 경고 텍스트를 절대 주입하지 않습니다. -- `"once"`: 고유한 잘림 시그니처마다 한 번만 경고를 주입합니다(권장). -- `"always"`: 잘림이 있을 때마다 모든 실행에서 경고를 주입합니다. +- `"once"`: 고유한 잘림 시그니처당 한 번만 경고를 주입합니다(권장). +- `"always"`: 잘림이 존재할 때마다 모든 실행에서 경고를 주입합니다. ```json5 { @@ -993,21 +987,19 @@ workspace 부트스트랩 파일이 시스템 프롬프트에 주입되는 시 ### 컨텍스트 예산 소유 맵 -OpenClaw에는 대용량 프롬프트/컨텍스트 예산이 여러 개 있으며, -의도적으로 하나의 일반적인 조절 항목이 아니라 하위 시스템별로 나뉘어 있습니다. +OpenClaw에는 대용량 프롬프트/컨텍스트 예산이 여러 개 있으며, 이들은 의도적으로 하나의 일반 조절 항목으로 합쳐지지 않고 하위 시스템별로 분리되어 있습니다. - `agents.defaults.bootstrapMaxChars` / `agents.defaults.bootstrapTotalMaxChars`: - 일반 workspace 부트스트랩 주입. + 일반 workspace bootstrap 주입. - `agents.defaults.startupContext.*`: - 최근 일일 `memory/*.md` 파일을 포함한 일회성 `/new` 및 `/reset` - 시작 프렐류드. + 최근 일별 `memory/*.md` 파일을 포함한 일회성 `/new` 및 `/reset` 시작 prelude. - `skills.limits.*`: - 시스템 프롬프트에 주입되는 축약 Skills 목록. + 시스템 프롬프트에 주입되는 간결한 skills 목록. - `agents.defaults.contextLimits.*`: - 제한된 런타임 발췌 및 런타임 소유 블록 주입. + 제한된 런타임 발췌와 런타임 소유 블록 주입. - `memory.qmd.limits.*`: - 인덱싱된 메모리 검색 스니펫 및 주입 크기 조절. + 인덱싱된 memory 검색 스니펫 및 주입 크기 조절. 한 에이전트에만 다른 예산이 필요할 때만 일치하는 에이전트별 재정의를 사용하세요: @@ -1016,7 +1008,7 @@ OpenClaw에는 대용량 프롬프트/컨텍스트 예산이 여러 개 있으 #### `agents.defaults.startupContext` -비어 있는 `/new` 및 `/reset` 실행 시 주입되는 첫 턴 시작 프렐류드를 제어합니다. +기본 `/new` 및 `/reset` 실행 시 주입되는 첫 턴 시작 prelude를 제어합니다. ```json5 { @@ -1037,7 +1029,7 @@ OpenClaw에는 대용량 프롬프트/컨텍스트 예산이 여러 개 있으 #### `agents.defaults.contextLimits` -제한된 런타임 컨텍스트 표면을 위한 공유 기본값입니다. +제한된 런타임 컨텍스트 표면에 대한 공유 기본값입니다. ```json5 { @@ -1054,18 +1046,14 @@ OpenClaw에는 대용량 프롬프트/컨텍스트 예산이 여러 개 있으 } ``` -- `memoryGetMaxChars`: 잘림 메타데이터와 이어보기 알림이 추가되기 전 - 기본 `memory_get` 발췌 상한. -- `memoryGetDefaultLines`: `lines`가 생략되었을 때 기본 `memory_get` 줄 범위. -- `toolResultMaxChars`: 지속된 결과와 오버플로 복구에 사용되는 - 실제 도구 결과 상한. -- `postCompactionMaxChars`: Compaction 후 새로고침 주입 중 사용되는 - AGENTS.md 발췌 상한. +- `memoryGetMaxChars`: 잘림 메타데이터와 연속 안내가 추가되기 전 기본 `memory_get` 발췌 상한입니다. +- `memoryGetDefaultLines`: `lines`가 생략되었을 때 기본 `memory_get` 줄 범위입니다. +- `toolResultMaxChars`: 저장된 결과와 오버플로 복구에 사용되는 실시간 도구 결과 상한입니다. +- `postCompactionMaxChars`: post-Compaction 새로고침 주입 중 사용되는 AGENTS.md 발췌 상한입니다. #### `agents.list[].contextLimits` -공유 `contextLimits` 조절 항목에 대한 에이전트별 재정의입니다. 생략된 필드는 -`agents.defaults.contextLimits`에서 상속됩니다. +공유 `contextLimits` 조절 항목에 대한 에이전트별 재정의입니다. 생략된 필드는 `agents.defaults.contextLimits`에서 상속됩니다. ```json5 { @@ -1091,7 +1079,7 @@ OpenClaw에는 대용량 프롬프트/컨텍스트 예산이 여러 개 있으 #### `skills.limits.maxSkillsPromptChars` -시스템 프롬프트에 주입되는 축약 Skills 목록의 전역 상한입니다. 이는 필요 시 `SKILL.md` 파일을 읽는 동작에는 영향을 주지 않습니다. +시스템 프롬프트에 주입되는 간결한 skills 목록의 전역 상한입니다. 이는 필요 시 `SKILL.md` 파일을 읽는 동작에는 영향을 주지 않습니다. ```json5 { @@ -1105,7 +1093,7 @@ OpenClaw에는 대용량 프롬프트/컨텍스트 예산이 여러 개 있으 #### `agents.list[].skillsLimits.maxSkillsPromptChars` -Skills 프롬프트 예산에 대한 에이전트별 재정의입니다. +skills 프롬프트 예산에 대한 에이전트별 재정의입니다. ```json5 { @@ -1124,11 +1112,11 @@ Skills 프롬프트 예산에 대한 에이전트별 재정의입니다. ### `agents.defaults.imageMaxDimensionPx` -공급자 호출 전 transcript/도구 이미지 블록에서 가장 긴 이미지 변의 최대 픽셀 크기입니다. +공급자 호출 전에 transcript/tool 이미지 블록에서 이미지의 가장 긴 변에 허용되는 최대 픽셀 크기입니다. 기본값: `1200`. -더 낮은 값은 일반적으로 스크린샷이 많은 실행에서 비전 토큰 사용량과 요청 페이로드 크기를 줄입니다. -더 높은 값은 더 많은 시각적 세부 정보를 보존합니다. +값을 낮추면 일반적으로 스크린샷이 많은 실행에서 vision 토큰 사용량과 요청 페이로드 크기가 줄어듭니다. +값을 높이면 더 많은 시각적 디테일을 보존합니다. ```json5 { @@ -1188,7 +1176,7 @@ Skills 프롬프트 예산에 대한 에이전트별 재정의입니다. }, params: { cacheRetention: "long" }, // 전역 기본 공급자 매개변수 embeddedHarness: { - runtime: "auto", // auto | pi | 등록된 harness id(예: codex) + runtime: "auto", // auto | pi | 등록된 harness id, 예: codex fallback: "pi", // pi | none }, pdfMaxBytesMb: 10, @@ -1205,48 +1193,48 @@ Skills 프롬프트 예산에 대한 에이전트별 재정의입니다. } ``` -- `model`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 받을 수 있습니다. +- `model`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 허용합니다. - 문자열 형식은 기본 모델만 설정합니다. - - 객체 형식은 기본 모델과 순서가 있는 장애 조치 모델을 설정합니다. -- `imageModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 받을 수 있습니다. + - 객체 형식은 기본 모델과 순서가 있는 장애 조치 모델을 함께 설정합니다. +- `imageModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 허용합니다. - `image` 도구 경로에서 비전 모델 구성으로 사용됩니다. - - 선택된/기본 모델이 이미지 입력을 받을 수 없을 때 대체 라우팅으로도 사용됩니다. -- `imageGenerationModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 받을 수 있습니다. + - 선택된/기본 모델이 이미지 입력을 받을 수 없을 때 대체 라우팅에도 사용됩니다. +- `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`. - - 공급자/모델을 직접 선택하는 경우, 일치하는 공급자 인증/API 키도 구성해야 합니다(예: `google/*`에는 `GEMINI_API_KEY` 또는 `GOOGLE_API_KEY`, `openai/*`에는 `OPENAI_API_KEY`, `fal/*`에는 `FAL_KEY`). - - 생략해도 `image_generate`는 인증이 연결된 기본 공급자를 추론할 수 있습니다. 먼저 현재 기본 공급자를 시도한 뒤, 남은 등록된 이미지 생성 공급자를 공급자 ID 순서대로 시도합니다. -- `musicGenerationModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 받을 수 있습니다. + - 일반적인 값: 기본 Gemini 이미지 생성을 위한 `google/gemini-3.1-flash-image-preview`, fal용 `fal/fal-ai/flux/dev`, OpenAI Images용 `openai/gpt-image-2`. + - 공급자/모델을 직접 선택하는 경우, 일치하는 공급자 인증/API 키도 함께 구성하세요(예: `google/*`에는 `GEMINI_API_KEY` 또는 `GOOGLE_API_KEY`, `openai/*`에는 `OPENAI_API_KEY`, `fal/*`에는 `FAL_KEY`). + - 생략해도 `image_generate`는 인증이 설정된 공급자 기본값을 추론할 수 있습니다. 먼저 현재 기본 공급자를 시도하고, 그다음 등록된 나머지 이미지 생성 공급자를 공급자 ID 순서대로 시도합니다. +- `musicGenerationModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 허용합니다. - 공통 음악 생성 기능과 내장 `music_generate` 도구에서 사용됩니다. - 일반적인 값: `google/lyria-3-clip-preview`, `google/lyria-3-pro-preview`, `minimax/music-2.5+`. - - 생략해도 `music_generate`는 인증이 연결된 기본 공급자를 추론할 수 있습니다. 먼저 현재 기본 공급자를 시도한 뒤, 남은 등록된 음악 생성 공급자를 공급자 ID 순서대로 시도합니다. - - 공급자/모델을 직접 선택하는 경우, 일치하는 공급자 인증/API 키도 구성해야 합니다. -- `videoGenerationModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 받을 수 있습니다. - - 공통 비디오 생성 기능과 내장 `video_generate` 도구에서 사용됩니다. + - 생략해도 `music_generate`는 인증이 설정된 공급자 기본값을 추론할 수 있습니다. 먼저 현재 기본 공급자를 시도하고, 그다음 등록된 나머지 음악 생성 공급자를 공급자 ID 순서대로 시도합니다. + - 공급자/모델을 직접 선택하는 경우, 일치하는 공급자 인증/API 키도 함께 구성하세요. +- `videoGenerationModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 허용합니다. + - 공통 동영상 생성 기능과 내장 `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 순서대로 시도합니다. - - 공급자/모델을 직접 선택하는 경우, 일치하는 공급자 인증/API 키도 구성해야 합니다. - - 번들 Qwen 비디오 생성 공급자는 최대 출력 비디오 1개, 입력 이미지 1개, 입력 비디오 4개, 길이 10초, 그리고 공급자 수준 `size`, `aspectRatio`, `resolution`, `audio`, `watermark` 옵션을 지원합니다. -- `pdfModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 받을 수 있습니다. + - 생략해도 `video_generate`는 인증이 설정된 공급자 기본값을 추론할 수 있습니다. 먼저 현재 기본 공급자를 시도하고, 그다음 등록된 나머지 동영상 생성 공급자를 공급자 ID 순서대로 시도합니다. + - 공급자/모델을 직접 선택하는 경우, 일치하는 공급자 인증/API 키도 함께 구성하세요. + - 번들된 Qwen 동영상 생성 공급자는 최대 출력 동영상 1개, 입력 이미지 1개, 입력 동영상 4개, 최대 10초 길이, 그리고 공급자 수준 `size`, `aspectRatio`, `resolution`, `audio`, `watermark` 옵션을 지원합니다. +- `pdfModel`: 문자열(`"provider/model"`) 또는 객체(`{ primary, fallbacks }`)를 허용합니다. - `pdf` 도구의 모델 라우팅에 사용됩니다. - - 생략하면 PDF 도구는 `imageModel`, 그다음 해결된 세션/기본 모델로 대체됩니다. -- `pdfMaxBytesMb`: 호출 시점에 `maxBytesMb`를 전달하지 않았을 때 `pdf` 도구에 적용되는 기본 PDF 크기 제한입니다. + - 생략하면 PDF 도구는 `imageModel`, 그다음 확인된 세션/기본 모델로 대체됩니다. +- `pdfMaxBytesMb`: 호출 시점에 `maxBytesMb`가 전달되지 않았을 때 `pdf` 도구의 기본 PDF 크기 제한입니다. - `pdfMaxPages`: `pdf` 도구의 추출 대체 모드에서 고려하는 기본 최대 페이지 수입니다. - `verboseDefault`: 에이전트의 기본 verbose 수준입니다. 값: `"off"`, `"on"`, `"full"`. 기본값: `"off"`. - `elevatedDefault`: 에이전트의 기본 elevated-output 수준입니다. 값: `"off"`, `"on"`, `"ask"`, `"full"`. 기본값: `"on"`. -- `model.primary`: 형식은 `provider/model`입니다(예: `openai/gpt-5.4`). 공급자를 생략하면 OpenClaw는 먼저 별칭을 시도하고, 그다음 정확한 모델 ID에 대한 고유한 구성 공급자 일치를 시도한 후에야 구성된 기본 공급자로 대체합니다(더 이상 권장되지 않는 호환 동작이므로 명시적인 `provider/model`을 권장). 해당 공급자가 더 이상 구성된 기본 모델을 제공하지 않으면, OpenClaw는 오래된 제거된 공급자 기본값을 그대로 표시하는 대신 구성된 첫 번째 공급자/모델로 대체합니다. -- `models`: `/model`용 구성된 모델 카탈로그 및 허용 목록입니다. 각 항목에는 `alias`(바로가기)와 `params`(공급자별, 예: `temperature`, `maxTokens`, `cacheRetention`, `context1m`)를 포함할 수 있습니다. +- `model.primary`: 형식은 `provider/model`입니다(예: `openai/gpt-5.4`). 공급자를 생략하면 OpenClaw는 먼저 별칭을 시도하고, 그다음 해당 정확한 모델 ID에 대한 고유한 구성 공급자 일치를 시도한 뒤, 마지막으로 구성된 기본 공급자로 대체합니다(이 방식은 더 이상 권장되지 않는 호환성 동작이므로 명시적인 `provider/model`을 권장합니다). 해당 공급자가 더 이상 구성된 기본 모델을 제공하지 않으면, OpenClaw는 오래된 제거된 공급자 기본값을 표시하는 대신 첫 번째 구성된 공급자/모델로 대체합니다. +- `models`: `/model`용 구성된 모델 카탈로그 및 허용 목록입니다. 각 항목에는 `alias`(단축키)와 `params`(공급자별, 예: `temperature`, `maxTokens`, `cacheRetention`, `context1m`)가 포함될 수 있습니다. - `params`: 모든 모델에 적용되는 전역 기본 공급자 매개변수입니다. `agents.defaults.params`에 설정합니다(예: `{ cacheRetention: "long" }`). -- `params` 병합 우선순위(구성): `agents.defaults.params`(전역 기본값)는 `agents.defaults.models["provider/model"].params`(모델별)로 재정의되고, 그다음 `agents.list[].params`(일치하는 에이전트 ID)가 키별로 재정의합니다. 자세한 내용은 [프롬프트 캐싱](/ko/reference/prompt-caching)을 참조하세요. -- `embeddedHarness`: 기본 저수준 임베디드 에이전트 런타임 정책입니다. `runtime: "auto"`를 사용하면 등록된 Plugin harness가 지원되는 모델을 가져가도록 하고, `runtime: "pi"`는 내장 Pi harness를 강제하며, `runtime: "codex"`처럼 등록된 harness ID를 지정할 수도 있습니다. 자동 Pi 대체를 비활성화하려면 `fallback: "none"`으로 설정하세요. -- 이 필드를 변경하는 구성 작성기(예: `/models set`, `/models set-image`, 장애 조치 추가/제거 명령)는 가능한 경우 정식 객체 형식으로 저장하고 기존 장애 조치 목록을 보존합니다. -- `maxConcurrent`: 세션 전반에서 병렬로 실행할 수 있는 최대 에이전트 수입니다(각 세션은 여전히 직렬화됨). 기본값: 4. +- `params` 병합 우선순위(구성): `agents.defaults.params`(전역 기본값)는 `agents.defaults.models["provider/model"].params`(모델별)로 재정의되고, 이어서 `agents.list[].params`(일치하는 에이전트 ID)가 키별로 재정의합니다. 자세한 내용은 [Prompt Caching](/ko/reference/prompt-caching)을 참조하세요. +- `embeddedHarness`: 기본 저수준 임베디드 에이전트 런타임 정책입니다. `runtime: "auto"`를 사용하면 등록된 Plugin harness가 지원되는 모델을 가져가도록 할 수 있고, `runtime: "pi"`는 내장 PI harness를 강제하며, `runtime: "codex"`처럼 등록된 harness ID를 직접 지정할 수도 있습니다. 자동 PI 대체를 비활성화하려면 `fallback: "none"`을 설정하세요. +- 이 필드를 변경하는 구성 작성기(예: `/models set`, `/models set-image`, 대체 모델 추가/제거 명령)는 표준 객체 형식으로 저장하며 가능하면 기존 대체 목록을 보존합니다. +- `maxConcurrent`: 세션 전체에서 동시에 실행할 수 있는 최대 병렬 에이전트 실행 수입니다(각 세션은 여전히 직렬화됨). 기본값: 4. ### `agents.defaults.embeddedHarness` -`embeddedHarness`는 임베디드 에이전트 턴을 실행하는 저수준 실행기를 제어합니다. -대부분의 배포는 기본값 `{ runtime: "auto", fallback: "pi" }`를 유지해야 합니다. -번들 Codex 앱 서버 harness처럼 신뢰할 수 있는 Plugin이 네이티브 harness를 제공할 때 사용하세요. +`embeddedHarness`는 어떤 저수준 실행기가 임베디드 에이전트 턴을 실행할지 제어합니다. +대부분의 배포에서는 기본값인 `{ runtime: "auto", fallback: "pi" }`를 유지하면 됩니다. +번들된 Codex 앱 서버 harness처럼 신뢰할 수 있는 Plugin이 기본 harness를 제공할 때 사용하세요. ```json5 { @@ -1262,15 +1250,15 @@ Skills 프롬프트 예산에 대한 에이전트별 재정의입니다. } ``` -- `runtime`: `"auto"`, `"pi"`, 또는 등록된 Plugin harness ID. 번들 Codex Plugin은 `codex`를 등록합니다. -- `fallback`: `"pi"` 또는 `"none"`. `"pi"`는 내장 Pi harness를 호환성 대체값으로 유지합니다. `"none"`은 누락되었거나 지원되지 않는 Plugin harness 선택 시 조용히 Pi를 사용하는 대신 실패하게 만듭니다. -- 환경 변수 재정의: `OPENCLAW_AGENT_RUNTIME=`는 `runtime`을 재정의하고, `OPENCLAW_AGENT_HARNESS_FALLBACK=none`은 해당 프로세스에 대해 Pi 대체를 비활성화합니다. +- `runtime`: `"auto"`, `"pi"`, 또는 등록된 Plugin harness ID입니다. 번들된 Codex Plugin은 `codex`를 등록합니다. +- `fallback`: `"pi"` 또는 `"none"`입니다. `"pi"`는 Plugin harness가 선택되지 않았을 때 내장 PI harness를 호환성 대체로 유지합니다. `"none"`은 누락되었거나 지원되지 않는 Plugin harness 선택이 PI를 조용히 사용하는 대신 실패하게 만듭니다. 선택된 Plugin harness의 실패는 항상 직접 표시됩니다. +- 환경 변수 재정의: `OPENCLAW_AGENT_RUNTIME=`는 `runtime`을 재정의하고, `OPENCLAW_AGENT_HARNESS_FALLBACK=none`은 해당 프로세스에서 PI 대체를 비활성화합니다. - Codex 전용 배포의 경우 `model: "codex/gpt-5.4"`, `embeddedHarness.runtime: "codex"`, `embeddedHarness.fallback: "none"`을 설정하세요. -- 이는 임베디드 채팅 harness만 제어합니다. 미디어 생성, 비전, PDF, 음악, 비디오, TTS는 여전히 각자의 공급자/모델 설정을 사용합니다. +- 이는 임베디드 채팅 harness만 제어합니다. 미디어 생성, 비전, PDF, 음악, 동영상, TTS는 여전히 해당 공급자/모델 설정을 사용합니다. -**내장 별칭 축약형** (`agents.defaults.models`에 모델이 있을 때만 적용됨): +**내장 alias 단축 표기** (`agents.defaults.models`에 모델이 있을 때만 적용됨): -| 별칭 | 모델 | +| Alias | 모델 | | ------------------- | -------------------------------------- | | `opus` | `anthropic/claude-opus-4-6` | | `sonnet` | `anthropic/claude-sonnet-4-6` | @@ -1281,11 +1269,11 @@ Skills 프롬프트 예산에 대한 에이전트별 재정의입니다. | `gemini-flash` | `google/gemini-3-flash-preview` | | `gemini-flash-lite` | `google/gemini-3.1-flash-lite-preview` | -구성한 별칭은 항상 기본값보다 우선합니다. +구성한 alias는 항상 기본값보다 우선합니다. Z.AI GLM-4.x 모델은 `--thinking off`를 설정하거나 `agents.defaults.models["zai/"].params.thinking`을 직접 정의하지 않는 한 자동으로 thinking 모드를 활성화합니다. Z.AI 모델은 도구 호출 스트리밍을 위해 기본적으로 `tool_stream`을 활성화합니다. 비활성화하려면 `agents.defaults.models["zai/"].params.tool_stream`을 `false`로 설정하세요. -Anthropic Claude 4.6 모델은 명시적인 thinking 수준이 설정되지 않으면 기본적으로 `adaptive` thinking을 사용합니다. +Anthropic Claude 4.6 모델은 명시적 thinking 수준이 설정되지 않았을 때 기본적으로 `adaptive` thinking을 사용합니다. ### `agents.defaults.cliBackends` @@ -1319,17 +1307,17 @@ Anthropic Claude 4.6 모델은 명시적인 thinking 수준이 설정되지 않 - CLI 백엔드는 텍스트 우선이며, 도구는 항상 비활성화됩니다. - `sessionArg`가 설정된 경우 세션이 지원됩니다. -- `imageArg`가 파일 경로를 받을 수 있으면 이미지 전달도 지원됩니다. +- `imageArg`가 파일 경로를 받을 수 있으면 이미지 전달이 지원됩니다. ### `agents.defaults.systemPromptOverride` -OpenClaw가 조합한 전체 시스템 프롬프트를 고정 문자열로 대체합니다. 기본 수준(`agents.defaults.systemPromptOverride`) 또는 에이전트별(`agents.list[].systemPromptOverride`)로 설정할 수 있습니다. 에이전트별 값이 우선하며, 비어 있거나 공백만 있는 값은 무시됩니다. 통제된 프롬프트 실험에 유용합니다. +OpenClaw가 조합한 전체 시스템 프롬프트를 고정 문자열로 대체합니다. 기본 수준(`agents.defaults.systemPromptOverride`) 또는 에이전트별(`agents.list[].systemPromptOverride`)로 설정할 수 있습니다. 에이전트별 값이 우선하며, 비어 있거나 공백만 있는 값은 무시됩니다. 제어된 프롬프트 실험에 유용합니다. ```json5 { agents: { defaults: { - systemPromptOverride: "당신은 도움이 되는 assistant입니다.", + systemPromptOverride: "You are a helpful assistant.", }, }, } @@ -1337,7 +1325,7 @@ OpenClaw가 조합한 전체 시스템 프롬프트를 고정 문자열로 대 ### `agents.defaults.heartbeat` -주기적인 Heartbeat 실행입니다. +주기적 Heartbeat 실행입니다. ```json5 { @@ -1348,13 +1336,13 @@ OpenClaw가 조합한 전체 시스템 프롬프트를 고정 문자열로 대 model: "openai/gpt-5.4-mini", includeReasoning: false, includeSystemPromptSection: true, // 기본값: true; false이면 시스템 프롬프트에서 Heartbeat 섹션 생략 - lightContext: false, // 기본값: false; true이면 workspace 부트스트랩 파일 중 HEARTBEAT.md만 유지 - isolatedSession: false, // 기본값: false; true이면 각 Heartbeat를 새 세션에서 실행(대화 기록 없음) + lightContext: false, // 기본값: false; true이면 workspace bootstrap 파일 중 HEARTBEAT.md만 유지 + isolatedSession: false, // 기본값: false; true이면 각 heartbeat를 새 세션에서 실행(대화 기록 없음) session: "main", to: "+15555550123", directPolicy: "allow", // allow (기본값) | block target: "none", // 기본값: none | 옵션: last | whatsapp | telegram | discord | ... - prompt: "HEARTBEAT.md가 있으면 읽으세요...", + prompt: "Read HEARTBEAT.md if it exists...", ackMaxChars: 300, suppressToolErrorWarnings: false, timeoutSeconds: 45, @@ -1364,14 +1352,14 @@ 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 섹션을 생략하고 bootstrap 컨텍스트에 `HEARTBEAT.md`를 주입하지 않습니다. 기본값: `true`. - `suppressToolErrorWarnings`: true이면 Heartbeat 실행 중 도구 오류 경고 페이로드를 숨깁니다. - `timeoutSeconds`: 중단되기 전 Heartbeat 에이전트 턴에 허용되는 최대 시간(초)입니다. 설정하지 않으면 `agents.defaults.timeoutSeconds`를 사용합니다. -- `directPolicy`: 직접/DM 전달 정책입니다. `allow`(기본값)는 직접 대상 전달을 허용합니다. `block`은 직접 대상 전달을 막고 `reason=dm-blocked`를 발생시킵니다. -- `lightContext`: true이면 Heartbeat 실행은 경량 부트스트랩 컨텍스트를 사용하고 workspace 부트스트랩 파일 중 `HEARTBEAT.md`만 유지합니다. -- `isolatedSession`: true이면 각 Heartbeat는 이전 대화 기록이 없는 새 세션에서 실행됩니다. Cron의 `sessionTarget: "isolated"`와 같은 격리 패턴입니다. Heartbeat당 토큰 비용을 약 100K에서 약 2~5K 토큰으로 줄입니다. -- 에이전트별 설정: `agents.list[].heartbeat`를 설정하세요. 어떤 에이전트든 `heartbeat`를 정의하면 **해당 에이전트들만** Heartbeat를 실행합니다. +- `directPolicy`: 직접/DM 전달 정책입니다. `allow`(기본값)는 직접 대상 전달을 허용합니다. `block`은 직접 대상 전달을 억제하고 `reason=dm-blocked`를 발생시킵니다. +- `lightContext`: true이면 Heartbeat 실행은 경량 bootstrap 컨텍스트를 사용하고 workspace bootstrap 파일 중 `HEARTBEAT.md`만 유지합니다. +- `isolatedSession`: true이면 각 Heartbeat는 이전 대화 기록이 없는 새 세션에서 실행됩니다. Cron의 `sessionTarget: "isolated"`와 동일한 격리 패턴입니다. Heartbeat당 토큰 비용을 약 100K에서 약 2~5K 토큰으로 줄입니다. +- 에이전트별: `agents.list[].heartbeat`를 설정하세요. 어느 하나의 에이전트라도 `heartbeat`를 정의하면 **그 에이전트들만** Heartbeat를 실행합니다. - Heartbeat는 전체 에이전트 턴을 실행하므로, 간격이 짧을수록 더 많은 토큰을 소모합니다. ### `agents.defaults.compaction` @@ -1382,19 +1370,19 @@ OpenClaw가 조합한 전체 시스템 프롬프트를 고정 문자열로 대 defaults: { compaction: { mode: "safeguard", // default | safeguard - provider: "my-provider", // 등록된 compaction provider Plugin의 id(선택 사항) + provider: "my-provider", // 등록된 compaction provider Plugin의 id (선택 사항) timeoutSeconds: 900, reserveTokensFloor: 24000, identifierPolicy: "strict", // strict | off | custom - identifierInstructions: "배포 ID, 티켓 ID, host:port 쌍을 정확히 보존하세요.", // identifierPolicy=custom일 때 사용 + identifierInstructions: "Preserve deployment IDs, ticket IDs, and host:port pairs exactly.", // identifierPolicy=custom일 때 사용 postCompactionSections: ["Session Startup", "Red Lines"], // []이면 재주입 비활성화 model: "openrouter/anthropic/claude-sonnet-4-6", // 선택적 compaction 전용 모델 재정의 - notifyUser: true, // compaction 시작/완료 시 짧은 알림 전송(기본값: false) + notifyUser: true, // compaction 시작/완료 시 간단한 알림 전송(기본값: false) memoryFlush: { enabled: true, softThresholdTokens: 6000, - systemPrompt: "세션이 곧 compaction에 도달합니다. 지금 지속성 있는 메모리를 저장하세요.", - prompt: "lasting notes가 있으면 memory/YYYY-MM-DD.md에 작성하고, 저장할 내용이 없으면 정확히 silent token NO_REPLY로 응답하세요.", + systemPrompt: "Session nearing compaction. Store durable memories now.", + prompt: "Write any lasting notes to memory/YYYY-MM-DD.md; reply with the exact silent token NO_REPLY if nothing to store.", }, }, }, @@ -1402,19 +1390,19 @@ OpenClaw가 조합한 전체 시스템 프롬프트를 고정 문자열로 대 } ``` -- `mode`: `default` 또는 `safeguard`(긴 기록을 위한 청크 요약). [Compaction](/ko/concepts/compaction)을 참조하세요. -- `provider`: 등록된 compaction provider Plugin의 ID입니다. 설정하면 내장 LLM 요약 대신 해당 공급자의 `summarize()`가 호출됩니다. 실패 시 내장 방식으로 대체됩니다. 공급자를 설정하면 `mode: "safeguard"`가 강제됩니다. [Compaction](/ko/concepts/compaction)을 참조하세요. -- `timeoutSeconds`: OpenClaw가 중단하기 전 단일 compaction 작업에 허용되는 최대 초입니다. 기본값: `900`. +- `mode`: `default` 또는 `safeguard`(긴 기록에 대한 청크 기반 요약). [Compaction](/ko/concepts/compaction)을 참조하세요. +- `provider`: 등록된 compaction provider Plugin의 id입니다. 설정되면 내장 LLM 요약 대신 해당 provider의 `summarize()`가 호출됩니다. 실패 시 내장 방식으로 대체됩니다. provider를 설정하면 `mode: "safeguard"`가 강제됩니다. [Compaction](/ko/concepts/compaction)을 참조하세요. +- `timeoutSeconds`: OpenClaw가 중단하기 전 단일 compaction 작업에 허용되는 최대 시간(초)입니다. 기본값: `900`. - `identifierPolicy`: `strict`(기본값), `off`, 또는 `custom`. `strict`는 compaction 요약 중 내장된 불투명 식별자 보존 지침을 앞에 추가합니다. -- `identifierInstructions`: `identifierPolicy=custom`일 때 사용하는 선택적 사용자 정의 식별자 보존 텍스트입니다. -- `postCompactionSections`: compaction 후 다시 주입할 선택적 AGENTS.md H2/H3 섹션 이름입니다. 기본값은 `["Session Startup", "Red Lines"]`이며, 재주입을 비활성화하려면 `[]`로 설정하세요. 설정하지 않았거나 명시적으로 이 기본 쌍으로 설정한 경우, 이전 `Every Session`/`Safety` 제목도 레거시 대체값으로 허용됩니다. -- `model`: compaction 요약에만 사용하는 선택적 `provider/model-id` 재정의입니다. 메인 세션은 한 모델을 유지하고 compaction 요약은 다른 모델에서 실행해야 할 때 사용합니다. 설정하지 않으면 compaction은 세션의 기본 모델을 사용합니다. -- `notifyUser`: `true`이면 compaction 시작 시와 완료 시 사용자에게 짧은 알림을 보냅니다(예: "Compacting context..." 및 "Compaction complete"). compaction을 조용히 유지하기 위해 기본적으로 비활성화됩니다. -- `memoryFlush`: 자동 compaction 전에 지속성 있는 메모리를 저장하는 조용한 agentic 턴입니다. workspace가 읽기 전용이면 건너뜁니다. +- `identifierInstructions`: `identifierPolicy=custom`일 때 사용되는 선택적 사용자 지정 식별자 보존 텍스트입니다. +- `postCompactionSections`: compaction 후 재주입할 선택적 AGENTS.md H2/H3 섹션 이름입니다. 기본값은 `["Session Startup", "Red Lines"]`이며, 재주입을 비활성화하려면 `[]`로 설정하세요. 설정되지 않았거나 명시적으로 이 기본 쌍으로 설정된 경우, 레거시 대체값으로 이전 `Every Session`/`Safety` 제목도 허용됩니다. +- `model`: compaction 요약에만 적용되는 선택적 `provider/model-id` 재정의입니다. 메인 세션은 한 모델을 유지하고 compaction 요약은 다른 모델에서 실행해야 할 때 사용하세요. 설정하지 않으면 compaction은 세션의 기본 모델을 사용합니다. +- `notifyUser`: `true`이면 compaction 시작 및 완료 시 사용자에게 간단한 알림을 보냅니다(예: "Compacting context..." 및 "Compaction complete"). 기본적으로는 compaction을 조용히 유지하기 위해 비활성화되어 있습니다. +- `memoryFlush`: 내구성 있는 메모리를 저장하기 위해 자동 compaction 전에 실행되는 조용한 agentic turn입니다. workspace가 읽기 전용이면 건너뜁니다. ### `agents.defaults.contextPruning` -LLM에 보내기 전에 메모리 내 컨텍스트에서 **오래된 도구 결과**를 정리합니다. 디스크의 세션 기록은 **수정하지 않습니다**. +LLM으로 보내기 전에 메모리 내 컨텍스트에서 **오래된 도구 결과**를 가지치기합니다. 디스크의 세션 기록은 **수정하지 않습니다**. ```json5 { @@ -1428,7 +1416,7 @@ LLM에 보내기 전에 메모리 내 컨텍스트에서 **오래된 도구 결 hardClearRatio: 0.5, minPrunableToolChars: 50000, softTrim: { maxChars: 4000, headChars: 1500, tailChars: 1500 }, - hardClear: { enabled: true, placeholder: "[오래된 도구 결과 내용이 지워졌습니다]" }, + hardClear: { enabled: true, placeholder: "[Old tool result content cleared]" }, tools: { deny: ["browser", "canvas"] }, }, }, @@ -1438,23 +1426,23 @@ LLM에 보내기 전에 메모리 내 컨텍스트에서 **오래된 도구 결 -- `mode: "cache-ttl"`은 정리 패스를 활성화합니다. -- `ttl`은 마지막 캐시 터치 이후 언제 다시 정리를 실행할 수 있는지를 제어합니다. -- 정리는 먼저 큰 도구 결과를 soft-trim한 뒤, 필요하면 더 오래된 도구 결과를 hard-clear합니다. +- `mode: "cache-ttl"`은 가지치기 패스를 활성화합니다. +- `ttl`은 마지막 캐시 터치 이후 가지치기를 다시 실행할 수 있는 빈도를 제어합니다. +- 가지치기는 먼저 너무 큰 도구 결과를 soft-trim하고, 필요하면 그다음 오래된 도구 결과를 hard-clear합니다. -**Soft-trim**은 시작 + 끝을 유지하고 중간에 `...`를 삽입합니다. +**Soft-trim**은 시작과 끝을 유지하고 중간에 `...`를 삽입합니다. **Hard-clear**는 전체 도구 결과를 placeholder로 대체합니다. 참고: -- 이미지 블록은 절대 잘리거나 지워지지 않습니다. +- 이미지 블록은 절대 trim/clear되지 않습니다. - 비율은 정확한 토큰 수가 아니라 문자 수 기준(대략적)입니다. -- `keepLastAssistants`보다 적은 assistant 메시지만 존재하면 정리를 건너뜁니다. +- assistant 메시지가 `keepLastAssistants`보다 적으면 가지치기를 건너뜁니다. -동작 세부 사항은 [세션 정리](/ko/concepts/session-pruning)를 참조하세요. +동작 세부 사항은 [Session Pruning](/ko/concepts/session-pruning)을 참조하세요. ### 블록 스트리밍 @@ -1474,11 +1462,11 @@ LLM에 보내기 전에 메모리 내 컨텍스트에서 **오래된 도구 결 - Telegram이 아닌 채널은 블록 응답을 활성화하려면 명시적으로 `*.blockStreaming: true`가 필요합니다. - 채널 재정의: `channels..blockStreamingCoalesce`(및 계정별 변형). Signal/Slack/Discord/Google Chat의 기본값은 `minChars: 1500`입니다. -- `humanDelay`: 블록 응답 사이의 무작위 지연입니다. `natural` = 800–2500ms. 에이전트별 재정의: `agents.list[].humanDelay`. +- `humanDelay`: 블록 응답 사이의 무작위 대기 시간입니다. `natural` = 800–2500ms. 에이전트별 재정의: `agents.list[].humanDelay`. -동작 및 청크 세부 사항은 [스트리밍](/ko/concepts/streaming)을 참조하세요. +동작 및 청크 세부 사항은 [Streaming](/ko/concepts/streaming)을 참조하세요. -### 입력 중 표시 +### 입력 표시기 ```json5 { @@ -1494,13 +1482,13 @@ LLM에 보내기 전에 메모리 내 컨텍스트에서 **오래된 도구 결 - 기본값: 직접 채팅/멘션에는 `instant`, 멘션되지 않은 그룹 채팅에는 `message`. - 세션별 재정의: `session.typingMode`, `session.typingIntervalSeconds`. -[입력 중 표시](/ko/concepts/typing-indicators)를 참조하세요. +[Typing Indicators](/ko/concepts/typing-indicators)를 참조하세요. ### `agents.defaults.sandbox` -임베디드 에이전트를 위한 선택적 sandboxing입니다. 전체 가이드는 [샌드박싱](/ko/gateway/sandboxing)을 참조하세요. +임베디드 에이전트를 위한 선택적 샌드박싱입니다. 전체 가이드는 [Sandboxing](/ko/gateway/sandboxing)을 참조하세요. ```json5 { @@ -1612,7 +1600,7 @@ LLM에 보내기 전에 메모리 내 컨텍스트에서 **오래된 도구 결 - `command`: SSH 클라이언트 명령(기본값: `ssh`) - `workspaceRoot`: 범위별 workspace에 사용하는 절대 원격 루트 - `identityFile` / `certificateFile` / `knownHostsFile`: OpenSSH에 전달되는 기존 로컬 파일 -- `identityData` / `certificateData` / `knownHostsData`: 런타임에 OpenClaw가 임시 파일로 구체화하는 인라인 내용 또는 SecretRef +- `identityData` / `certificateData` / `knownHostsData`: OpenClaw가 런타임 시 임시 파일로 구체화하는 인라인 내용 또는 SecretRef - `strictHostKeyChecking` / `updateHostKeys`: OpenSSH 호스트 키 정책 조절 항목 **SSH 인증 우선순위:** @@ -1620,26 +1608,26 @@ LLM에 보내기 전에 메모리 내 컨텍스트에서 **오래된 도구 결 - `identityData`가 `identityFile`보다 우선 - `certificateData`가 `certificateFile`보다 우선 - `knownHostsData`가 `knownHostsFile`보다 우선 -- SecretRef 기반 `*Data` 값은 샌드박스 세션 시작 전에 활성 secrets 런타임 스냅샷에서 해석됩니다 +- SecretRef 기반 `*Data` 값은 샌드박스 세션이 시작되기 전에 활성 비밀 런타임 스냅샷에서 확인됩니다 **SSH 백엔드 동작:** -- 생성 또는 재생성 후 원격 workspace를 한 번 시드합니다 -- 이후 원격 SSH workspace를 정식 기준으로 유지합니다 -- `exec`, 파일 도구, 미디어 경로를 SSH를 통해 라우팅합니다 -- 원격 변경 사항을 호스트로 자동 동기화하지 않습니다 -- 샌드박스 브라우저 컨테이너는 지원하지 않습니다 +- 생성 또는 재생성 후 원격 workspace를 한 번 시드함 +- 이후 원격 SSH workspace를 표준으로 유지함 +- `exec`, 파일 도구, 미디어 경로를 SSH를 통해 라우팅함 +- 원격 변경 사항을 호스트로 자동 동기화하지 않음 +- 샌드박스 브라우저 컨테이너를 지원하지 않음 -**Workspace 접근:** +**Workspace 액세스:** -- `none`: `~/.openclaw/sandboxes` 아래 범위별 sandbox workspace -- `ro`: sandbox workspace는 `/workspace`, 에이전트 workspace는 `/agent`에 읽기 전용으로 마운트 -- `rw`: 에이전트 workspace를 `/workspace`에 읽기/쓰기 마운트 +- `none`: `~/.openclaw/sandboxes` 아래 범위별 샌드박스 workspace +- `ro`: 샌드박스 workspace는 `/workspace`, 에이전트 workspace는 `/agent`에 읽기 전용으로 마운트 +- `rw`: 에이전트 workspace를 `/workspace`에 읽기/쓰기 가능으로 마운트 **범위:** - `session`: 세션별 컨테이너 + workspace -- `agent`: 에이전트별 컨테이너 + workspace 하나(기본값) +- `agent`: 에이전트별 컨테이너 + workspace 1개(기본값) - `shared`: 공유 컨테이너 및 workspace(세션 간 격리 없음) **OpenShell Plugin 구성:** @@ -1670,32 +1658,32 @@ LLM에 보내기 전에 메모리 내 컨텍스트에서 **오래된 도구 결 **OpenShell 모드:** -- `mirror`: exec 전에 로컬에서 원격으로 시드하고 exec 후 다시 동기화합니다. 로컬 workspace가 정식 기준으로 유지됩니다 -- `remote`: 샌드박스가 생성될 때 한 번만 원격에 시드한 뒤, 이후 원격 workspace를 정식 기준으로 유지합니다 +- `mirror`: exec 전에 로컬에서 원격으로 시드하고, exec 후 다시 동기화함. 로컬 workspace가 표준으로 유지됨 +- `remote`: 샌드박스 생성 시 원격을 한 번 시드한 뒤, 원격 workspace를 표준으로 유지함 -`remote` 모드에서는 시드 단계 이후 OpenClaw 외부에서 수행한 호스트 로컬 편집이 샌드박스에 자동 동기화되지 않습니다. -전송은 OpenShell 샌드박스로의 SSH를 사용하지만, 샌드박스 생명주기와 선택적 mirror 동기화는 Plugin이 관리합니다. +`remote` 모드에서는 OpenClaw 외부에서 수행된 호스트 로컬 편집이 시드 단계 이후 샌드박스에 자동 동기화되지 않습니다. +전송은 OpenShell 샌드박스로의 SSH를 사용하지만, 샌드박스 수명 주기와 선택적 mirror 동기화는 Plugin이 담당합니다. **`setupCommand`**는 컨테이너 생성 후 한 번 실행됩니다(`sh -lc` 사용). 네트워크 송신, 쓰기 가능한 루트, 루트 사용자가 필요합니다. -**컨테이너 기본값은 `network: "none"`**입니다 — 에이전트에 외부 접근이 필요하면 `"bridge"`(또는 사용자 정의 bridge 네트워크)로 설정하세요. -`"host"`는 차단됩니다. `"container:"`는 기본적으로 차단되며, -명시적으로 `sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true`를 설정한 경우에만 허용됩니다(비상 모드). +**컨테이너는 기본적으로 `network: "none"`**입니다 — 에이전트에 외부 액세스가 필요하면 `"bridge"`(또는 사용자 지정 bridge 네트워크)로 설정하세요. +`"host"`는 차단됩니다. `"container:"`도 기본적으로 차단되며, +명시적으로 `sandbox.docker.dangerouslyAllowContainerNamespaceJoin: true`를 설정한 경우에만 허용됩니다(비상용). -**수신 첨부 파일**은 활성 workspace의 `media/inbound/*`에 준비됩니다. +**수신 첨부파일**은 활성 workspace의 `media/inbound/*`에 임시 저장됩니다. -**`docker.binds`**는 추가 호스트 디렉터리를 마운트하며, 전역 및 에이전트별 bind가 병합됩니다. +**`docker.binds`**는 추가 호스트 디렉터리를 마운트하며, 전역 및 에이전트별 bind는 병합됩니다. -**샌드박스 브라우저** (`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 네트워크)입니다. 전역 bridge 연결이 정말 필요할 때만 `bridge`로 설정하세요. -- `cdpSourceRange`는 선택적으로 컨테이너 경계에서 CDP 수신을 CIDR 범위(예: `172.21.0.1/32`)로 제한합니다. -- `sandbox.browser.binds`는 추가 호스트 디렉터리를 샌드박스 브라우저 컨테이너에만 마운트합니다. 이 값을 설정하면(`[]` 포함) 브라우저 컨테이너에서는 `docker.binds`를 대체합니다. +- `allowHostControl: false`(기본값)는 샌드박스 세션이 호스트 브라우저를 대상으로 삼는 것을 차단합니다. +- `network`의 기본값은 `openclaw-sandbox-browser`(전용 bridge 네트워크)입니다. 전역 bridge 연결이 명시적으로 필요할 때만 `bridge`로 설정하세요. +- `cdpSourceRange`는 선택적으로 컨테이너 경계에서 CDP 수신을 CIDR 범위로 제한합니다(예: `172.21.0.1/32`). +- `sandbox.browser.binds`는 추가 호스트 디렉터리를 샌드박스 브라우저 컨테이너에만 마운트합니다. 설정되면(`[]` 포함) 브라우저 컨테이너에서는 `docker.binds`를 대체합니다. - 실행 기본값은 `scripts/sandbox-browser-entrypoint.sh`에 정의되어 있으며 컨테이너 호스트에 맞게 조정되어 있습니다: - `--remote-debugging-address=127.0.0.1` - - `--remote-debugging-port=` + - `--remote-debugging-port=` - `--user-data-dir=${HOME}/.chrome` - `--no-first-run` - `--no-default-browser-check` @@ -1712,16 +1700,16 @@ noVNC 옵저버 접근은 기본적으로 VNC 인증을 사용하며, OpenClaw - `--metrics-recording-only` - `--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`으로 다시 활성화할 수 있습니다. + - 워크플로가 확장 기능에 의존하는 경우 + `OPENCLAW_BROWSER_DISABLE_EXTENSIONS=0`으로 확장 기능을 다시 활성화할 수 있습니다. - `--renderer-process-limit=2`는 - `OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=`으로 변경할 수 있습니다. Chromium의 + `OPENCLAW_BROWSER_RENDERER_PROCESS_LIMIT=`으로 변경할 수 있으며, Chromium의 기본 프로세스 제한을 사용하려면 `0`으로 설정하세요. - - 그리고 `noSandbox`가 활성화되어 있을 때의 `--no-sandbox` 및 `--disable-setuid-sandbox`. - - 기본값은 컨테이너 이미지 기준선입니다. 컨테이너 기본값을 바꾸려면 사용자 정의 - browser 이미지와 사용자 정의 entrypoint를 사용하세요. + - `noSandbox`가 활성화된 경우 `--no-sandbox` 및 `--disable-setuid-sandbox`도 추가됩니다. + - 기본값은 컨테이너 이미지 기준선입니다. 컨테이너 기본값을 변경하려면 사용자 지정 + entrypoint가 있는 사용자 지정 브라우저 이미지를 사용하세요. @@ -1748,14 +1736,14 @@ scripts/sandbox-browser-setup.sh # 선택적 브라우저 이미지 agentDir: "~/.openclaw/agents/main/agent", model: "anthropic/claude-opus-4-6", // 또는 { primary, fallbacks } thinkingDefault: "high", // 에이전트별 thinking 수준 재정의 - reasoningDefault: "on", // 에이전트별 reasoning 가시성 재정의 + reasoningDefault: "on", // 에이전트별 reasoning 표시 재정의 fastModeDefault: false, // 에이전트별 fast mode 재정의 embeddedHarness: { runtime: "auto", fallback: "pi" }, params: { cacheRetention: "none" }, // 일치하는 defaults.models params를 키별로 재정의 - skills: ["docs-search"], // 설정 시 agents.defaults.skills를 대체 + skills: ["docs-search"], // 설정 시 agents.defaults.skills 대체 identity: { name: "Samantha", - theme: "도움이 되는 나무늘보", + theme: "helpful sloth", emoji: "🦥", avatar: "avatars/samantha.png", }, @@ -1783,27 +1771,27 @@ scripts/sandbox-browser-setup.sh # 선택적 브라우저 이미지 } ``` -- `id`: 안정적인 에이전트 ID(필수). -- `default`: 여러 개가 설정되면 첫 번째가 우선합니다(경고 로그 기록). 아무것도 설정되지 않으면 첫 번째 목록 항목이 기본값입니다. -- `model`: 문자열 형식은 `primary`만 재정의하고, 객체 형식 `{ primary, fallbacks }`는 둘 다 재정의합니다(`[]`는 전역 장애 조치 비활성화). `primary`만 재정의하는 Cron 작업은 `fallbacks: []`를 설정하지 않는 한 기본 장애 조치를 계속 상속합니다. -- `params`: `agents.defaults.models`에서 선택된 모델 항목 위에 병합되는 에이전트별 스트림 매개변수입니다. 전체 모델 카탈로그를 중복하지 않고 `cacheRetention`, `temperature`, `maxTokens` 같은 에이전트별 재정의에 사용하세요. -- `skills`: 선택적 에이전트별 Skills 허용 목록. 생략하면 `agents.defaults.skills`가 설정된 경우 상속합니다. 명시적 목록은 기본값과 병합되지 않고 대체하며, `[]`는 Skills 없음입니다. -- `thinkingDefault`: 선택적 에이전트별 기본 thinking 수준(`off | minimal | low | medium | high | xhigh | adaptive | max`). 메시지별 또는 세션별 재정의가 없을 때 이 에이전트에 대해 `agents.defaults.thinkingDefault`를 재정의합니다. -- `reasoningDefault`: 선택적 에이전트별 기본 reasoning 가시성(`on | off | stream`). 메시지별 또는 세션별 reasoning 재정의가 없을 때 적용됩니다. -- `fastModeDefault`: 선택적 에이전트별 기본 fast mode 값(`true | false`). 메시지별 또는 세션별 fast-mode 재정의가 없을 때 적용됩니다. -- `embeddedHarness`: 선택적 에이전트별 저수준 harness 정책 재정의. 한 에이전트만 Codex 전용으로 만들고 다른 에이전트는 기본 Pi 대체를 유지하려면 `{ runtime: "codex", fallback: "none" }`를 사용하세요. -- `runtime`: 선택적 에이전트별 런타임 설명자. 에이전트가 기본적으로 ACP harness 세션을 사용해야 한다면 `type: "acp"`와 `runtime.acp` 기본값(`agent`, `backend`, `mode`, `cwd`)을 사용하세요. -- `identity.avatar`: workspace 상대 경로, `http(s)` URL 또는 `data:` URI. +- `id`: 안정적인 에이전트 ID입니다(필수). +- `default`: 여러 개가 설정된 경우 첫 번째가 우선합니다(경고가 기록됨). 아무것도 설정되지 않으면 첫 번째 목록 항목이 기본값입니다. +- `model`: 문자열 형식은 `primary`만 재정의하고, 객체 형식 `{ primary, fallbacks }`는 둘 다 재정의합니다(`[]`는 전역 대체 모델 비활성화). `primary`만 재정의하는 Cron 작업은 `fallbacks: []`를 설정하지 않는 한 기본 대체 모델을 계속 상속합니다. +- `params`: `agents.defaults.models`에서 선택된 모델 항목 위에 병합되는 에이전트별 스트림 매개변수입니다. 전체 모델 카탈로그를 복제하지 않고 `cacheRetention`, `temperature`, `maxTokens` 같은 에이전트별 재정의에 사용하세요. +- `skills`: 선택적 에이전트별 skill 허용 목록입니다. 생략하면 `agents.defaults.skills`가 설정된 경우 이를 상속합니다. 명시적 목록은 기본값을 병합하지 않고 대체하며, `[]`는 skills 없음입니다. +- `thinkingDefault`: 선택적 에이전트별 기본 thinking 수준(`off | minimal | low | medium | high | xhigh | adaptive | max`)입니다. 메시지별 또는 세션 재정의가 없을 때 이 에이전트에 대해 `agents.defaults.thinkingDefault`를 재정의합니다. +- `reasoningDefault`: 선택적 에이전트별 기본 reasoning 표시 설정(`on | off | stream`)입니다. 메시지별 또는 세션 reasoning 재정의가 없을 때 적용됩니다. +- `fastModeDefault`: 선택적 에이전트별 기본 fast mode 설정(`true | false`)입니다. 메시지별 또는 세션 fast-mode 재정의가 없을 때 적용됩니다. +- `embeddedHarness`: 선택적 에이전트별 저수준 harness 정책 재정의입니다. 한 에이전트만 Codex 전용으로 만들고 다른 에이전트는 기본 PI 대체를 유지하려면 `{ runtime: "codex", fallback: "none" }`를 사용하세요. +- `runtime`: 선택적 에이전트별 런타임 descriptor입니다. 에이전트가 기본적으로 ACP harness 세션을 사용해야 할 경우 `type: "acp"`와 `runtime.acp` 기본값(`agent`, `backend`, `mode`, `cwd`)을 사용하세요. +- `identity.avatar`: workspace 기준 경로, `http(s)` URL 또는 `data:` URI입니다. - `identity`는 기본값을 파생합니다: `emoji`에서 `ackReaction`, `name`/`emoji`에서 `mentionPatterns`. -- `subagents.allowAgents`: `sessions_spawn`용 에이전트 ID 허용 목록(`["*"]` = 모든 에이전트, 기본값: 동일한 에이전트만). -- 샌드박스 상속 가드: 요청자 세션이 샌드박스 안에 있으면 `sessions_spawn`은 샌드박스 없이 실행될 대상을 거부합니다. +- `subagents.allowAgents`: `sessions_spawn`용 에이전트 ID 허용 목록입니다(`["*"]` = 아무거나, 기본값: 동일 에이전트만). +- 샌드박스 상속 보호: 요청자 세션이 샌드박스에 있으면 `sessions_spawn`은 샌드박스 없이 실행될 대상을 거부합니다. - `subagents.requireAgentId`: true이면 `agentId`를 생략한 `sessions_spawn` 호출을 차단합니다(명시적 프로필 선택 강제, 기본값: false). --- ## 다중 에이전트 라우팅 -하나의 Gateway 안에서 여러 개의 격리된 에이전트를 실행합니다. [다중 에이전트](/ko/concepts/multi-agent)를 참조하세요. +하나의 Gateway 안에서 여러 개의 격리된 에이전트를 실행합니다. [Multi-Agent](/ko/concepts/multi-agent)를 참조하세요. ```json5 { @@ -1822,7 +1810,7 @@ scripts/sandbox-browser-setup.sh # 선택적 브라우저 이미지 ### 바인딩 일치 필드 -- `type`(선택 사항): 일반 라우팅에는 `route`(타입이 없으면 기본값은 route), 영구 ACP 대화 바인딩에는 `acp`. +- `type`(선택 사항): 일반 라우팅에는 `route`(type이 없으면 기본적으로 route), 영구 ACP 대화 바인딩에는 `acp` - `match.channel`(필수) - `match.accountId`(선택 사항; `*` = 모든 계정, 생략 = 기본 계정) - `match.peer`(선택 사항; `{ kind: direct|group|channel, id }`) @@ -1838,13 +1826,13 @@ scripts/sandbox-browser-setup.sh # 선택적 브라우저 이미지 5. `match.accountId: "*"`(채널 전체) 6. 기본 에이전트 -각 계층 내에서는 첫 번째로 일치하는 `bindings` 항목이 우선합니다. +각 계층 안에서는 먼저 일치한 `bindings` 항목이 우선합니다. -`type: "acp"` 항목의 경우 OpenClaw는 정확한 대화 식별자(`match.channel` + 계정 + `match.peer.id`)로 해결하며, 위의 route 바인딩 계층 순서는 사용하지 않습니다. +`type: "acp"` 항목의 경우, OpenClaw는 정확한 대화 식별자(`match.channel` + account + `match.peer.id`)로 확인하며 위의 route 바인딩 계층 순서를 사용하지 않습니다. -### 에이전트별 접근 프로필 +### 에이전트별 액세스 프로필 - + ```json5 { @@ -1891,7 +1879,7 @@ scripts/sandbox-browser-setup.sh # 선택적 브라우저 이미지 - + ```json5 { @@ -1937,7 +1925,7 @@ scripts/sandbox-browser-setup.sh # 선택적 브라우저 이미지 -우선순위 세부 사항은 [다중 에이전트 샌드박스 및 도구](/ko/tools/multi-agent-sandbox-tools)를 참조하세요. +우선순위 세부 사항은 [Multi-Agent Sandbox & Tools](/ko/tools/multi-agent-sandbox-tools)를 참조하세요. --- @@ -1963,7 +1951,7 @@ scripts/sandbox-browser-setup.sh # 선택적 브라우저 이미지 }, resetTriggers: ["/new", "/reset"], store: "~/.openclaw/agents/{agentId}/sessions/sessions.json", - parentForkMaxTokens: 100000, // 이 토큰 수를 넘으면 부모 스레드 포크 건너뜀(0이면 비활성화) + parentForkMaxTokens: 100000, // 이 토큰 수를 초과하면 부모 스레드 포크 건너뜀(0이면 비활성화) maintenance: { mode: "warn", // warn | enforce pruneAfter: "30d", @@ -1975,8 +1963,8 @@ scripts/sandbox-browser-setup.sh # 선택적 브라우저 이미지 }, threadBindings: { enabled: true, - idleHours: 24, // 기본 비활성 자동 unfocus 시간 단위(`0`이면 비활성화) - maxAgeHours: 0, // 기본 하드 최대 사용 기간 시간 단위(`0`이면 비활성화) + idleHours: 24, // 기본 비활동 자동 unfocus 시간(`0`은 비활성화) + maxAgeHours: 0, // 기본 하드 최대 수명 시간(`0`은 비활성화) }, mainKey: "main", // 레거시(런타임은 항상 "main" 사용) agentToAgent: { maxPingPongTurns: 5 }, @@ -1990,35 +1978,35 @@ scripts/sandbox-browser-setup.sh # 선택적 브라우저 이미지 -- **`scope`**: 그룹 채팅 컨텍스트에 대한 기본 세션 그룹화 전략입니다. - - `per-sender`(기본값): 채널 컨텍스트 내에서 각 발신자는 격리된 세션을 가집니다. - - `global`: 채널 컨텍스트의 모든 참가자가 하나의 세션을 공유합니다(공유 컨텍스트가 의도된 경우에만 사용). +- **`scope`**: 그룹 채팅 컨텍스트를 위한 기본 세션 그룹화 전략입니다. + - `per-sender`(기본값): 채널 컨텍스트 내에서 각 발신자가 격리된 세션을 가집니다. + - `global`: 채널 컨텍스트의 모든 참여자가 하나의 세션을 공유합니다(공유 컨텍스트가 의도된 경우에만 사용). - **`dmScope`**: DM을 그룹화하는 방식입니다. - `main`: 모든 DM이 메인 세션을 공유합니다. - `per-peer`: 채널 전반에서 발신자 ID별로 격리합니다. - - `per-channel-peer`: 채널 + 발신자별로 격리합니다(다중 사용자 inbox에 권장). + - `per-channel-peer`: 채널 + 발신자별로 격리합니다(다중 사용자 받은편지함에 권장). - `per-account-channel-peer`: 계정 + 채널 + 발신자별로 격리합니다(다중 계정에 권장). -- **`identityLinks`**: 채널 간 세션 공유를 위해 정규 ID를 공급자 접두사가 붙은 피어에 매핑합니다. -- **`reset`**: 기본 재설정 정책입니다. `daily`는 로컬 시간 `atHour`에 재설정하고, `idle`은 `idleMinutes` 이후 재설정합니다. 둘 다 구성되면 먼저 만료되는 쪽이 우선합니다. -- **`resetByType`**: 유형별 재정의(`direct`, `group`, `thread`). 레거시 `dm`도 `direct`의 별칭으로 허용됩니다. -- **`parentForkMaxTokens`**: 포크된 스레드 세션을 만들 때 허용되는 부모 세션 `totalTokens`의 최대값입니다(기본값 `100000`). - - 부모 `totalTokens`가 이 값을 초과하면, OpenClaw는 부모 transcript 기록을 상속하지 않고 새 스레드 세션을 시작합니다. - - 이 가드를 비활성화하고 항상 부모 포크를 허용하려면 `0`으로 설정하세요. +- **`identityLinks`**: 채널 간 세션 공유를 위해 표준 ID를 공급자 접두사가 있는 peer에 매핑합니다. +- **`reset`**: 기본 리셋 정책입니다. `daily`는 현지 시간 `atHour`에 리셋하고, `idle`은 `idleMinutes` 후 리셋합니다. 둘 다 구성된 경우 먼저 만료되는 쪽이 우선합니다. +- **`resetByType`**: 유형별 재정의(`direct`, `group`, `thread`)입니다. 레거시 `dm`도 `direct`의 별칭으로 허용됩니다. +- **`parentForkMaxTokens`**: 포크된 스레드 세션을 만들 때 허용되는 최대 부모 세션 `totalTokens`입니다(기본값 `100000`). + - 부모 `totalTokens`가 이 값보다 크면 OpenClaw는 부모 transcript 기록을 상속하는 대신 새 스레드 세션을 시작합니다. + - 이 보호 기능을 비활성화하고 항상 부모 포크를 허용하려면 `0`으로 설정하세요. - **`mainKey`**: 레거시 필드입니다. 런타임은 메인 직접 채팅 버킷에 항상 `"main"`을 사용합니다. -- **`agentToAgent.maxPingPongTurns`**: 에이전트 간 교환 중 reply-back 턴의 최대 수입니다(정수, 범위: `0`–`5`). `0`이면 ping-pong 체이닝을 비활성화합니다. +- **`agentToAgent.maxPingPongTurns`**: 에이전트 간 교환 중 에이전트 사이의 최대 응답 왕복 수입니다(정수, 범위: `0`–`5`). `0`이면 핑퐁 체이닝이 비활성화됩니다. - **`sendPolicy`**: `channel`, `chatType`(`direct|group|channel`, 레거시 `dm` 별칭 포함), `keyPrefix`, `rawKeyPrefix`로 일치시킵니다. 첫 번째 deny가 우선합니다. - **`maintenance`**: 세션 저장소 정리 + 보존 제어입니다. - `mode`: `warn`은 경고만 출력하고, `enforce`는 정리를 적용합니다. - `pruneAfter`: 오래된 항목의 만료 기준 기간입니다(기본값 `30d`). - `maxEntries`: `sessions.json`의 최대 항목 수입니다(기본값 `500`). - `rotateBytes`: `sessions.json`이 이 크기를 초과하면 회전합니다(기본값 `10mb`). - - `resetArchiveRetention`: `*.reset.` transcript 아카이브의 보존 기간입니다. 기본값은 `pruneAfter`이며, 비활성화하려면 `false`로 설정하세요. + - `resetArchiveRetention`: `*.reset.` transcript 아카이브의 보존 기간입니다. 기본적으로 `pruneAfter`를 따르며, 비활성화하려면 `false`로 설정하세요. - `maxDiskBytes`: 선택적 세션 디렉터리 디스크 예산입니다. `warn` 모드에서는 경고를 기록하고, `enforce` 모드에서는 가장 오래된 아티팩트/세션부터 제거합니다. - - `highWaterBytes`: 예산 정리 후의 선택적 목표값입니다. 기본값은 `maxDiskBytes`의 `80%`입니다. + - `highWaterBytes`: 예산 정리 후 목표값입니다. 기본값은 `maxDiskBytes`의 `80%`입니다. - **`threadBindings`**: 스레드 바인딩 세션 기능의 전역 기본값입니다. - - `enabled`: 마스터 기본 스위치(공급자가 재정의 가능, Discord는 `channels.discord.threadBindings.enabled` 사용) - - `idleHours`: 비활성 자동 unfocus의 기본 시간 단위(`0`이면 비활성화, 공급자가 재정의 가능) - - `maxAgeHours`: 하드 최대 사용 기간의 기본 시간 단위(`0`이면 비활성화, 공급자가 재정의 가능) + - `enabled`: 마스터 기본 스위치입니다(공급자가 재정의할 수 있음. Discord는 `channels.discord.threadBindings.enabled` 사용) + - `idleHours`: 비활동 자동 unfocus의 기본 시간(`0`은 비활성화, 공급자가 재정의 가능) + - `maxAgeHours`: 하드 최대 수명의 기본 시간(`0`은 비활성화, 공급자가 재정의 가능) @@ -2058,34 +2046,34 @@ scripts/sandbox-browser-setup.sh # 선택적 브라우저 이미지 채널/계정별 재정의: `channels..responsePrefix`, `channels..accounts..responsePrefix`. -해결 순서(가장 구체적인 것이 우선): 계정 → 채널 → 전역. `""`는 비활성화하고 상위 단계 전파도 중단합니다. `"auto"`는 `[{identity.name}]`에서 파생됩니다. +해결 순서(가장 구체적인 것이 우선): 계정 → 채널 → 전역. `""`는 비활성화하고 상위 전파도 중단합니다. `"auto"`는 `[{identity.name}]`를 파생합니다. **템플릿 변수:** -| 변수 | 설명 | 예시 | -| ----------------- | ---------------------- | --------------------------- | -| `{model}` | 짧은 모델 이름 | `claude-opus-4-6` | -| `{modelFull}` | 전체 모델 식별자 | `anthropic/claude-opus-4-6` | -| `{provider}` | 공급자 이름 | `anthropic` | -| `{thinkingLevel}` | 현재 thinking 수준 | `high`, `low`, `off` | -| `{identity.name}` | 에이전트 identity 이름 | (`"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}`의 별칭입니다. -### Ack 반응 +### Ack 리액션 -- 기본값은 활성 에이전트의 `identity.emoji`이며, 없으면 `"👀"`입니다. 비활성화하려면 `""`로 설정하세요. +- 기본값은 활성 에이전트의 `identity.emoji`이고, 없으면 `"👀"`입니다. 비활성화하려면 `""`로 설정하세요. - 채널별 재정의: `channels..ackReaction`, `channels..accounts..ackReaction`. - 해결 순서: 계정 → 채널 → `messages.ackReaction` → identity 대체값. - 범위: `group-mentions`(기본값), `group-all`, `direct`, `all`. -- `removeAckAfterReply`: Slack, Discord, Telegram에서 답장 후 ack를 제거합니다. -- `messages.statusReactions.enabled`: Slack, Discord, Telegram에서 lifecycle 상태 반응을 활성화합니다. - Slack과 Discord에서는 설정하지 않으면 ack 반응이 활성화된 경우 상태 반응도 활성화된 상태를 유지합니다. - Telegram에서는 lifecycle 상태 반응을 활성화하려면 명시적으로 `true`로 설정해야 합니다. +- `removeAckAfterReply`: Slack, Discord, Telegram에서 응답 후 ack를 제거합니다. +- `messages.statusReactions.enabled`: Slack, Discord, Telegram에서 수명 주기 상태 리액션을 활성화합니다. + Slack과 Discord에서는 설정하지 않으면 ack 리액션이 활성화되어 있을 때 상태 리액션도 활성화된 상태를 유지합니다. + Telegram에서는 수명 주기 상태 리액션을 활성화하려면 이를 명시적으로 `true`로 설정하세요. -### 수신 디바운스 +### 수신 debounce -같은 발신자가 빠르게 보낸 텍스트 전용 메시지를 하나의 에이전트 턴으로 묶습니다. 미디어/첨부 파일은 즉시 플러시됩니다. 제어 명령은 디바운싱을 우회합니다. +같은 발신자의 빠른 텍스트 전용 메시지를 하나의 에이전트 턴으로 묶습니다. 미디어/첨부파일은 즉시 플러시됩니다. 제어 명령은 debounce를 우회합니다. ### TTS (text-to-speech) @@ -2128,12 +2116,12 @@ scripts/sandbox-browser-setup.sh # 선택적 브라우저 이미지 } ``` -- `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`로 대체될 수 있습니다. +- `modelOverrides`는 기본적으로 활성화되어 있으며, `modelOverrides.allowProvider`의 기본값은 `false`입니다(opt-in). +- API 키는 `ELEVENLABS_API_KEY`/`XI_API_KEY` 및 `OPENAI_API_KEY`로 대체됩니다. - `openai.baseUrl`은 OpenAI TTS 엔드포인트를 재정의합니다. 해결 순서는 config, 그다음 `OPENAI_TTS_BASE_URL`, 그다음 `https://api.openai.com/v1`입니다. -- `openai.baseUrl`이 OpenAI가 아닌 엔드포인트를 가리키면, OpenClaw는 이를 OpenAI 호환 TTS 서버로 간주하고 모델/음성 검증을 완화합니다. +- `openai.baseUrl`이 OpenAI가 아닌 엔드포인트를 가리키면, OpenClaw는 이를 OpenAI 호환 TTS 서버로 처리하고 모델/음성 검증을 완화합니다. --- @@ -2163,13 +2151,13 @@ Talk 모드(macOS/iOS/Android)의 기본값입니다. } ``` -- `talk.provider`는 여러 Talk 공급자가 구성된 경우 `talk.providers`의 키와 일치해야 합니다. +- `talk.provider`는 여러 Talk provider가 구성된 경우 `talk.providers`의 키와 일치해야 합니다. - 레거시 평면 Talk 키(`talk.voiceId`, `talk.voiceAliases`, `talk.modelId`, `talk.outputFormat`, `talk.apiKey`)는 호환성 전용이며 `talk.providers.`로 자동 마이그레이션됩니다. -- Voice ID는 `ELEVENLABS_VOICE_ID` 또는 `SAG_VOICE_ID`로 대체될 수 있습니다. -- `providers.*.apiKey`는 일반 텍스트 문자열 또는 SecretRef 객체를 받을 수 있습니다. -- `ELEVENLABS_API_KEY` 대체값은 구성된 Talk API 키가 없을 때만 적용됩니다. +- 음성 ID는 `ELEVENLABS_VOICE_ID` 또는 `SAG_VOICE_ID`로 대체됩니다. +- `providers.*.apiKey`는 일반 텍스트 문자열 또는 SecretRef 객체를 허용합니다. +- `ELEVENLABS_API_KEY` 대체값은 Talk API 키가 구성되지 않았을 때만 적용됩니다. - `providers.*.voiceAliases`를 사용하면 Talk 지시문에서 친숙한 이름을 사용할 수 있습니다. -- `silenceTimeoutMs`는 사용자가 말을 멈춘 뒤 transcript를 보내기 전까지 Talk 모드가 대기하는 시간을 제어합니다. 설정하지 않으면 플랫폼 기본 일시 정지 창이 유지됩니다(`macOS 및 Android에서는 700ms, iOS에서는 900ms`). +- `silenceTimeoutMs`는 사용자가 말을 멈춘 뒤 Talk 모드가 transcript를 보내기까지 대기하는 시간을 제어합니다. 설정하지 않으면 플랫폼 기본 일시 정지 시간 창이 유지됩니다(`macOS 및 Android는 700 ms, iOS는 900 ms`). --- @@ -2177,33 +2165,33 @@ Talk 모드(macOS/iOS/Android)의 기본값입니다. ### 도구 프로필 -`tools.profile`은 `tools.allow`/`tools.deny`보다 먼저 적용되는 기본 허용 목록을 설정합니다: +`tools.profile`은 `tools.allow`/`tools.deny` 전에 기본 허용 목록을 설정합니다. -로컬 온보딩은 값이 설정되지 않은 새 로컬 구성에 기본적으로 `tools.profile: "coding"`을 적용합니다(기존 명시적 프로필은 유지됨). +로컬 온보딩은 설정되지 않은 새 로컬 구성에 대해 기본적으로 `tools.profile: "coding"`을 설정합니다(기존의 명시적 프로필은 유지됨). -| 프로필 | 포함 항목 | -| ----------- | ------------------------------------------------------------------------------------------------------------------------------- | -| `minimal` | `session_status`만 | -| `coding` | `group:fs`, `group:runtime`, `group:web`, `group:sessions`, `group:memory`, `cron`, `image`, `image_generate`, `video_generate` | -| `messaging` | `group:messaging`, `sessions_list`, `sessions_history`, `sessions_send`, `session_status` | -| `full` | 제한 없음(설정하지 않은 경우와 동일) | +| 프로필 | 포함 항목 | +| ---------- | ----------------------------------------------------------------------------------------------------------------------------- | +| `minimal` | `session_status`만 | +| `coding` | `group:fs`, `group:runtime`, `group:web`, `group:sessions`, `group:memory`, `cron`, `image`, `image_generate`, `video_generate` | +| `messaging`| `group:messaging`, `sessions_list`, `sessions_history`, `sessions_send`, `session_status` | +| `full` | 제한 없음(설정하지 않은 경우와 동일) | ### 도구 그룹 -| 그룹 | 도구 | +| 그룹 | 도구 | | ------------------ | ----------------------------------------------------------------------------------------------------------------------- | -| `group:runtime` | `exec`, `process`, `code_execution` (`bash`는 `exec`의 별칭으로 허용됨) | -| `group:fs` | `read`, `write`, `edit`, `apply_patch` | +| `group:runtime` | `exec`, `process`, `code_execution` (`bash`는 `exec`의 별칭으로 허용됨) | +| `group:fs` | `read`, `write`, `edit`, `apply_patch` | | `group:sessions` | `sessions_list`, `sessions_history`, `sessions_send`, `sessions_spawn`, `sessions_yield`, `subagents`, `session_status` | -| `group:memory` | `memory_search`, `memory_get` | -| `group:web` | `web_search`, `x_search`, `web_fetch` | -| `group:ui` | `browser`, `canvas` | -| `group:automation` | `cron`, `gateway` | -| `group:messaging` | `message` | -| `group:nodes` | `nodes` | -| `group:agents` | `agents_list` | -| `group:media` | `image`, `image_generate`, `video_generate`, `tts` | -| `group:openclaw` | 모든 내장 도구(공급자 Plugin 제외) | +| `group:memory` | `memory_search`, `memory_get` | +| `group:web` | `web_search`, `x_search`, `web_fetch` | +| `group:ui` | `browser`, `canvas` | +| `group:automation` | `cron`, `gateway` | +| `group:messaging` | `message` | +| `group:nodes` | `nodes` | +| `group:agents` | `agents_list` | +| `group:media` | `image`, `image_generate`, `video_generate`, `tts` | +| `group:openclaw` | 모든 내장 도구(provider Plugin 제외) | ### `tools.allow` / `tools.deny` @@ -2217,7 +2205,7 @@ Talk 모드(macOS/iOS/Android)의 기본값입니다. ### `tools.byProvider` -특정 공급자나 모델에 대해 도구를 추가로 제한합니다. 순서: 기본 프로필 → 공급자 프로필 → 허용/거부. +특정 provider 또는 모델에 대해 도구를 추가로 제한합니다. 순서: 기본 프로필 → provider 프로필 → allow/deny. ```json5 { @@ -2233,7 +2221,7 @@ Talk 모드(macOS/iOS/Android)의 기본값입니다. ### `tools.elevated` -샌드박스 밖의 elevated exec 접근을 제어합니다: +샌드박스 외부의 elevated exec 액세스를 제어합니다: ```json5 { @@ -2249,9 +2237,9 @@ Talk 모드(macOS/iOS/Android)의 기본값입니다. } ``` -- 에이전트별 재정의(`agents.list[].tools.elevated`)는 더 제한적으로만 설정할 수 있습니다. -- `/elevated on|off|ask|full`은 상태를 세션별로 저장하며, 인라인 지시문은 단일 메시지에만 적용됩니다. -- Elevated `exec`는 샌드박싱을 우회하고 구성된 escape 경로를 사용합니다(기본값은 `gateway`, exec 대상이 `node`일 때는 `node`). +- 에이전트별 재정의(`agents.list[].tools.elevated`)는 추가 제한만 가능합니다. +- `/elevated on|off|ask|full`은 세션별 상태를 저장하며, 인라인 지시문은 단일 메시지에만 적용됩니다. +- Elevated `exec`는 샌드박싱을 우회하고 구성된 탈출 경로를 사용합니다(기본값은 `gateway`, exec 대상이 `node`일 때는 `node`). ### `tools.exec` @@ -2275,8 +2263,8 @@ Talk 모드(macOS/iOS/Android)의 기본값입니다. ### `tools.loopDetection` -도구 루프 안전 검사는 기본적으로 **비활성화**되어 있습니다. 감지를 활성화하려면 `enabled: true`로 설정하세요. -설정은 전역 `tools.loopDetection`에 정의할 수 있으며, 에이전트별로 `agents.list[].tools.loopDetection`에서 재정의할 수 있습니다. +도구 루프 안전성 검사는 기본적으로 **비활성화**되어 있습니다. 감지를 활성화하려면 `enabled: true`를 설정하세요. +설정은 전역 `tools.loopDetection`에 정의할 수 있고, 에이전트별 `agents.list[].tools.loopDetection`에서 재정의할 수 있습니다. ```json5 { @@ -2297,14 +2285,14 @@ Talk 모드(macOS/iOS/Android)의 기본값입니다. } ``` -- `historySize`: 루프 분석을 위해 유지할 최대 도구 호출 기록 수입니다. -- `warningThreshold`: 경고를 위한 반복적 무진전 패턴 임계값입니다. -- `criticalThreshold`: 심각한 루프를 차단하기 위한 더 높은 반복 임계값입니다. -- `globalCircuitBreakerThreshold`: 모든 무진전 실행을 강제 중단하는 하드 임계값입니다. -- `detectors.genericRepeat`: 동일 도구/동일 인자 반복 호출에 대해 경고합니다. +- `historySize`: 루프 분석을 위해 유지되는 최대 도구 호출 기록 수입니다. +- `warningThreshold`: 경고를 발생시키는 반복적인 무진전 패턴 임계값입니다. +- `criticalThreshold`: 심각한 루프를 차단하는 더 높은 반복 임계값입니다. +- `globalCircuitBreakerThreshold`: 모든 무진전 실행에 대한 하드 중단 임계값입니다. +- `detectors.genericRepeat`: 같은 도구/같은 인자 호출이 반복되면 경고합니다. - `detectors.knownPollNoProgress`: 알려진 폴링 도구(`process.poll`, `command_status` 등)의 무진전 상태에 대해 경고/차단합니다. -- `detectors.pingPong`: 교대로 반복되는 무진전 쌍 패턴에 대해 경고/차단합니다. -- `warningThreshold >= criticalThreshold`이거나 `criticalThreshold >= globalCircuitBreakerThreshold`이면 검증에 실패합니다. +- `detectors.pingPong`: 번갈아 나타나는 무진전 쌍 패턴에 대해 경고/차단합니다. +- `warningThreshold >= criticalThreshold` 또는 `criticalThreshold >= globalCircuitBreakerThreshold`이면 검증이 실패합니다. ### `tools.web` @@ -2314,14 +2302,14 @@ Talk 모드(macOS/iOS/Android)의 기본값입니다. web: { search: { enabled: true, - apiKey: "brave_api_key", // 또는 BRAVE_API_KEY 환경 변수 + apiKey: "brave_api_key", // 또는 BRAVE_API_KEY env maxResults: 5, timeoutSeconds: 30, cacheTtlMinutes: 15, }, fetch: { enabled: true, - provider: "firecrawl", // 선택 사항; 자동 감지를 원하면 생략 + provider: "firecrawl", // 선택 사항; 자동 감지하려면 생략 maxChars: 50000, maxCharsCap: 50000, maxResponseBytes: 2000000, @@ -2346,7 +2334,7 @@ Talk 모드(macOS/iOS/Android)의 기본값입니다. media: { concurrency: 2, asyncCompletion: { - directSend: false, // 옵트인: 완료된 비동기 음악/비디오를 채널로 직접 전송 + directSend: false, // opt-in: 완료된 비동기 music/video를 채널로 직접 전송 }, audio: { enabled: true, @@ -2372,9 +2360,9 @@ Talk 모드(macOS/iOS/Android)의 기본값입니다. -**공급자 항목** (`type: "provider"` 또는 생략): +**Provider 항목** (`type: "provider"` 또는 생략): -- `provider`: API 공급자 ID(`openai`, `anthropic`, `google`/`gemini`, `groq` 등) +- `provider`: API provider id (`openai`, `anthropic`, `google`/`gemini`, `groq` 등) - `model`: 모델 ID 재정의 - `profile` / `preferredProfile`: `auth-profiles.json` 프로필 선택 @@ -2385,17 +2373,17 @@ Talk 모드(macOS/iOS/Android)의 기본값입니다. **공통 필드:** -- `capabilities`: 선택적 목록(`image`, `audio`, `video`). 기본값: `openai`/`anthropic`/`minimax` → image, `google` → image+audio+video, `groq` → audio. -- `prompt`, `maxChars`, `maxBytes`, `timeoutSeconds`, `language`: 항목별 재정의. +- `capabilities`: 선택적 목록(`image`, `audio`, `video`)입니다. 기본값: `openai`/`anthropic`/`minimax` → image, `google` → image+audio+video, `groq` → audio. +- `prompt`, `maxChars`, `maxBytes`, `timeoutSeconds`, `language`: 항목별 재정의입니다. - 실패 시 다음 항목으로 대체됩니다. -공급자 인증은 표준 순서를 따릅니다: `auth-profiles.json` → 환경 변수 → `models.providers.*.apiKey`. +Provider 인증은 표준 순서를 따릅니다: `auth-profiles.json` → 환경 변수 → `models.providers.*.apiKey`. **비동기 완료 필드:** - `asyncCompletion.directSend`: `true`이면 완료된 비동기 `music_generate` 및 `video_generate` 작업이 먼저 직접 채널 전달을 시도합니다. 기본값: `false` - (레거시 요청자 세션 깨우기/모델 전달 경로). + (레거시 요청자 세션 wake/model 전달 경로). @@ -2433,24 +2421,24 @@ Talk 모드(macOS/iOS/Android)의 기본값입니다. - `self`: 현재 세션 키만. - `tree`: 현재 세션 + 현재 세션이 생성한 세션(subagent). -- `agent`: 현재 에이전트 ID에 속한 모든 세션(같은 에이전트 ID 아래에서 발신자별 세션을 실행하는 경우 다른 사용자도 포함될 수 있음). +- `agent`: 현재 에이전트 ID에 속한 모든 세션(동일 에이전트 ID 아래에서 발신자별 세션을 실행하면 다른 사용자도 포함될 수 있음). - `all`: 모든 세션. 에이전트 간 대상 지정에는 여전히 `tools.agentToAgent`가 필요합니다. -- 샌드박스 clamp: 현재 세션이 샌드박스 안에 있고 `agents.defaults.sandbox.sessionToolsVisibility="spawned"`이면 `tools.sessions.visibility="all"`이어도 가시성은 강제로 `tree`가 됩니다. +- 샌드박스 clamp: 현재 세션이 샌드박스에 있고 `agents.defaults.sandbox.sessionToolsVisibility="spawned"`이면 `tools.sessions.visibility="all"`이어도 가시성은 `tree`로 강제됩니다. ### `tools.sessions_spawn` -`sessions_spawn`의 인라인 첨부 파일 지원을 제어합니다. +`sessions_spawn`의 인라인 첨부파일 지원을 제어합니다. ```json5 { tools: { sessions_spawn: { attachments: { - enabled: false, // 옵트인: true로 설정하면 인라인 파일 첨부 허용 - maxTotalBytes: 5242880, // 모든 파일 합계 5MB + enabled: false, // opt-in: 인라인 파일 첨부 허용 시 true로 설정 + maxTotalBytes: 5242880, // 모든 파일 합계 5 MB maxFiles: 50, - maxFileBytes: 1048576, // 파일당 1MB - retainOnSessionKeep: false, // cleanup="keep"일 때 첨부 파일 유지 + maxFileBytes: 1048576, // 파일당 1 MB + retainOnSessionKeep: false, // cleanup="keep"일 때 첨부 유지 }, }, }, @@ -2459,12 +2447,12 @@ Talk 모드(macOS/iOS/Android)의 기본값입니다. 참고: -- 첨부 파일은 `runtime: "subagent"`에서만 지원됩니다. ACP 런타임은 이를 거부합니다. -- 파일은 `.manifest.json`과 함께 자식 workspace의 `.openclaw/attachments//`에 구체화됩니다. -- 첨부 파일 내용은 transcript 저장에서 자동으로 민감 정보 제거됩니다. -- Base64 입력은 엄격한 alphabet/padding 검사와 디코딩 전 크기 가드로 검증됩니다. -- 파일 권한은 디렉터리에 `0700`, 파일에 `0600`입니다. -- 정리는 `cleanup` 정책을 따릅니다: `delete`는 항상 첨부 파일을 제거하고, `keep`은 `retainOnSessionKeep: true`일 때만 유지합니다. +- 첨부파일은 `runtime: "subagent"`에서만 지원됩니다. ACP 런타임은 이를 거부합니다. +- 파일은 자식 workspace의 `.openclaw/attachments//`에 `.manifest.json`과 함께 구체화됩니다. +- 첨부파일 내용은 transcript 저장에서 자동으로 redaction됩니다. +- Base64 입력은 엄격한 알파벳/패딩 검사와 디코드 전 크기 보호를 통해 검증됩니다. +- 파일 권한은 디렉터리 `0700`, 파일 `0600`입니다. +- 정리는 `cleanup` 정책을 따릅니다: `delete`는 항상 첨부파일을 제거하고, `keep`은 `retainOnSessionKeep: true`일 때만 유지합니다. ### `tools.experimental` @@ -2482,9 +2470,9 @@ Talk 모드(macOS/iOS/Android)의 기본값입니다. 참고: -- `planTool`: 중요하고 여러 단계인 작업 추적을 위한 구조화된 `update_plan` 도구를 활성화합니다. -- 기본값: `false`. 단, `agents.defaults.embeddedPi.executionContract`(또는 에이전트별 재정의)가 OpenAI 또는 OpenAI Codex GPT-5 계열 실행에서 `"strict-agentic"`으로 설정된 경우는 예외입니다. 이 범위 밖에서도 강제로 켜려면 `true`, strict-agentic GPT-5 실행에서도 계속 끄려면 `false`로 설정하세요. -- 활성화되면 시스템 프롬프트에도 사용 지침이 추가되어 모델이 중요한 작업에만 이를 사용하고 한 번에 최대 한 단계만 `in_progress` 상태로 유지하도록 합니다. +- `planTool`: 사소하지 않은 다단계 작업 추적을 위한 구조화된 `update_plan` 도구를 활성화합니다. +- 기본값: `agents.defaults.embeddedPi.executionContract`(또는 에이전트별 재정의)가 OpenAI 또는 OpenAI Codex GPT-5 계열 실행에 대해 `"strict-agentic"`으로 설정된 경우를 제외하면 `false`입니다. 이 범위 밖에서도 강제로 활성화하려면 `true`, strict-agentic GPT-5 실행에서도 계속 비활성화하려면 `false`로 설정하세요. +- 활성화되면 시스템 프롬프트에도 사용 지침이 추가되어, 모델이 상당한 작업에만 이를 사용하고 동시에 최대 한 단계만 `in_progress` 상태로 유지하도록 합니다. ### `agents.defaults.subagents` @@ -2505,15 +2493,15 @@ Talk 모드(macOS/iOS/Android)의 기본값입니다. ``` - `model`: 생성된 sub-agent의 기본 모델입니다. 생략하면 sub-agent는 호출자의 모델을 상속합니다. -- `allowAgents`: 요청 에이전트가 자체 `subagents.allowAgents`를 설정하지 않은 경우 `sessions_spawn` 대상 에이전트 ID의 기본 허용 목록입니다(`["*"]` = 아무 에이전트나, 기본값: 동일 에이전트만). -- `runTimeoutSeconds`: 도구 호출이 `runTimeoutSeconds`를 생략했을 때 `sessions_spawn`의 기본 타임아웃(초)입니다. `0`은 타임아웃 없음입니다. +- `allowAgents`: 요청 에이전트가 자체 `subagents.allowAgents`를 설정하지 않았을 때 `sessions_spawn`의 대상 에이전트 ID 기본 허용 목록입니다(`["*"]` = 아무거나, 기본값: 동일 에이전트만). +- `runTimeoutSeconds`: 도구 호출에서 `runTimeoutSeconds`를 생략했을 때 `sessions_spawn`의 기본 제한 시간(초)입니다. `0`은 제한 시간 없음입니다. - subagent별 도구 정책: `tools.subagents.tools.allow` / `tools.subagents.tools.deny`. --- -## 사용자 정의 공급자와 기본 URL +## 사용자 지정 provider 및 base URL -OpenClaw는 내장 모델 카탈로그를 사용합니다. 사용자 정의 공급자는 config 또는 `~/.openclaw/agents//agent/models.json`의 `models.providers`를 통해 추가합니다. +OpenClaw는 내장 모델 카탈로그를 사용합니다. config 또는 `~/.openclaw/agents//agent/models.json`의 `models.providers`를 통해 사용자 지정 provider를 추가하세요. ```json5 { @@ -2542,292 +2530,672 @@ OpenClaw는 내장 모델 카탈로그를 사용합니다. 사용자 정의 공 } ``` -- 사용자 정의 인증이 필요하면 `authHeader: true` + `headers`를 사용하세요. -- 에이전트 구성 루트는 `OPENCLAW_AGENT_DIR`(또는 레거시 환경 변수 별칭 `PI_CODING_AGENT_DIR`)로 재정의합니다. -- 일치하는 공급자 ID의 병합 우선순위: +- 사용자 지정 인증이 필요하면 `authHeader: true` + `headers`를 사용하세요. +- 에이전트 구성 루트는 `OPENCLAW_AGENT_DIR`(또는 레거시 환경 변수 별칭 `PI_CODING_AGENT_DIR`)로 재정의할 수 있습니다. +- 일치하는 provider ID에 대한 병합 우선순위: - 비어 있지 않은 에이전트 `models.json`의 `baseUrl` 값이 우선합니다. - - 비어 있지 않은 에이전트 `apiKey` 값은 해당 공급자가 현재 config/auth-profile 컨텍스트에서 SecretRef로 관리되지 않을 때만 우선합니다. - - SecretRef로 관리되는 공급자 `apiKey` 값은 해결된 secret를 유지 저장하지 않고 소스 마커(`env ref의 경우 `ENV_VAR_NAME`, file/exec ref의 경우 `secretref-managed``)에서 다시 갱신됩니다. - - SecretRef로 관리되는 공급자 헤더 값은 소스 마커(`env ref의 경우 `secretref-env:ENV_VAR_NAME`, file/exec ref의 경우 `secretref-managed``)에서 다시 갱신됩니다. - - 비어 있거나 없는 에이전트 `apiKey`/`baseUrl`은 config의 `models.providers`로 대체됩니다. - - 일치하는 모델의 `contextWindow`/`maxTokens`는 명시적 config 값과 암시적 카탈로그 값 중 더 높은 값을 사용합니다. - - 일치하는 모델의 `contextTokens`는 명시적인 런타임 상한이 있으면 이를 유지합니다. 기본 모델 메타데이터를 바꾸지 않고 실제 컨텍스트를 제한하려면 이를 사용하세요. - - config가 `models.json`을 완전히 다시 쓰게 하려면 `models.mode: "replace"`를 사용하세요. - - 마커 저장은 소스 권위 원칙을 따릅니다: 마커는 해결된 런타임 secret 값이 아니라 활성 소스 config 스냅샷(해결 전)에서 기록됩니다. + - 비어 있지 않은 에이전트 `apiKey` 값은 해당 provider가 현재 config/auth-profile 컨텍스트에서 SecretRef 관리 대상이 아닐 때만 우선합니다. + - SecretRef 관리 대상 provider `apiKey` 값은 확인된 비밀을 영속화하는 대신 소스 마커(`env` 참조는 `ENV_VAR_NAME`, file/exec 참조는 `secretref-managed`)로부터 새로 고쳐집니다. + - SecretRef 관리 대상 provider 헤더 값은 소스 마커(`env` 참조는 `secretref-env:ENV_VAR_NAME`, file/exec 참조는 `secretref-managed`)로부터 새로 고쳐집니다. + - 비어 있거나 누락된 에이전트 `apiKey`/`baseUrl`은 config의 `models.providers`로 대체됩니다. + - 일치하는 모델의 `contextWindow`/`maxTokens`는 명시적 config 값과 암시적 카탈로그 값 중 더 큰 값을 사용합니다. + - 일치하는 모델의 `contextTokens`는 명시적 런타임 상한이 있을 경우 이를 보존합니다. 기본 모델 메타데이터를 변경하지 않고 유효 컨텍스트를 제한하려면 이를 사용하세요. + - config가 `models.json`을 완전히 다시 작성하도록 하려면 `models.mode: "replace"`를 사용하세요. + - 마커 영속성은 소스 권위적입니다. 마커는 확인된 런타임 비밀 값이 아니라 활성 소스 config 스냅샷(확인 전)에서 기록됩니다. -### 공급자 필드 세부 정보 +### Provider 필드 세부 정보 -- `models.mode`: 공급자 카탈로그 동작(`merge` 또는 `replace`). -- `models.providers`: 공급자 ID를 키로 하는 사용자 정의 공급자 맵. -- `models.providers.*.api`: 요청 어댑터(`openai-completions`, `openai-responses`, `anthropic-messages`, `google-generative-ai` 등). -- `models.providers.*.apiKey`: 공급자 자격 증명(SecretRef/환경 변수 치환 권장). -- `models.providers.*.auth`: 인증 전략(`api-key`, `token`, `oauth`, `aws-sdk`). -- `models.providers.*.injectNumCtxForOpenAICompat`: Ollama + `openai-completions`에서 요청에 `options.num_ctx`를 주입합니다(기본값: `true`). -- `models.providers.*.authHeader`: 필요 시 `Authorization` 헤더로 자격 증명을 강제 전달합니다. -- `models.providers.*.baseUrl`: 업스트림 API 기본 URL. -- `models.providers.*.headers`: 프록시/테넌트 라우팅용 추가 정적 헤더. -- `models.providers.*.request`: 모델 공급자 HTTP 요청을 위한 전송 재정의. - - `request.headers`: 추가 헤더(공급자 기본값과 병합됨). 값은 SecretRef를 받을 수 있습니다. - - `request.auth`: 인증 전략 재정의. 모드: `"provider-default"`(공급자의 기본 인증 사용), `"authorization-bearer"`(`token`과 함께), `"header"`(`headerName`, `value`, 선택적 `prefix`와 함께). - - `request.proxy`: HTTP 프록시 재정의. 모드: `"env-proxy"`(`HTTP_PROXY`/`HTTPS_PROXY` 환경 변수 사용), `"explicit-proxy"`(`url`과 함께). 두 모드 모두 선택적 `tls` 하위 객체를 받을 수 있습니다. - - `request.tls`: 직접 연결용 TLS 재정의. 필드: `ca`, `cert`, `key`, `passphrase`(모두 SecretRef 허용), `serverName`, `insecureSkipVerify`. - - `request.allowPrivateNetwork`: `true`이면 공급자 HTTP fetch 가드를 통해 DNS가 비공개, CGNAT 또는 유사한 범위로 해석될 때 `baseUrl`에 대한 HTTPS를 허용합니다(신뢰할 수 있는 자체 호스팅 OpenAI 호환 엔드포인트를 위한 operator 옵트인). WebSocket은 헤더/TLS에 동일한 `request`를 사용하지만 fetch SSRF 게이트는 사용하지 않습니다. 기본값 `false`. -- `models.providers.*.models`: 명시적 공급자 모델 카탈로그 항목. -- `models.providers.*.models.*.contextWindow`: 기본 모델 컨텍스트 창 메타데이터. -- `models.providers.*.models.*.contextTokens`: 선택적 런타임 컨텍스트 상한. 모델의 기본 `contextWindow`보다 더 작은 유효 컨텍스트 예산을 원할 때 사용하세요. -- `models.providers.*.models.*.compat.supportsDeveloperRole`: 선택적 호환성 힌트. `api: "openai-completions"`이고 비어 있지 않은 비기본 `baseUrl`(`api.openai.com`이 아닌 호스트)의 경우, OpenClaw는 런타임에서 이를 `false`로 강제합니다. `baseUrl`이 비어 있거나 생략되면 기본 OpenAI 동작을 유지합니다. -- `models.providers.*.models.*.compat.requiresStringContent`: 문자열 전용 OpenAI 호환 chat 엔드포인트를 위한 선택적 호환성 힌트. `true`이면 OpenClaw는 요청을 보내기 전에 순수 텍스트 `messages[].content` 배열을 일반 문자열로 평탄화합니다. -- `plugins.entries.amazon-bedrock.config.discovery`: Bedrock 자동 검색 설정 루트. +- `models.mode`: provider 카탈로그 동작(`merge` 또는 `replace`)입니다. +- `models.providers`: provider id를 키로 사용하는 사용자 지정 provider 맵입니다. +- `models.providers.*.api`: 요청 어댑터입니다(`openai-completions`, `openai-responses`, `anthropic-messages`, `google-generative-ai` 등). +- `models.providers.*.apiKey`: provider 자격 증명입니다(SecretRef/env 치환 권장). +- `models.providers.*.auth`: 인증 전략입니다(`api-key`, `token`, `oauth`, `aws-sdk`). +- `models.providers.*.injectNumCtxForOpenAICompat`: Ollama + `openai-completions`에 대해 요청에 `options.num_ctx`를 주입합니다(기본값: `true`). +- `models.providers.*.authHeader`: 필요할 때 `Authorization` 헤더를 통한 자격 증명 전송을 강제합니다. +- `models.providers.*.baseUrl`: 상위 API base URL입니다. +- `models.providers.*.headers`: 프록시/tenant 라우팅용 추가 정적 헤더입니다. +- `models.providers.*.request`: 모델 provider HTTP 요청에 대한 전송 재정의입니다. + - `request.headers`: 추가 헤더입니다(provider 기본값과 병합됨). 값은 SecretRef를 허용합니다. + - `request.auth`: 인증 전략 재정의입니다. 모드: `"provider-default"`(provider의 내장 인증 사용), `"authorization-bearer"`(`token`과 함께 사용), `"header"`(`headerName`, `value`, 선택적 `prefix`와 함께 사용). + - `request.proxy`: HTTP 프록시 재정의입니다. 모드: `"env-proxy"`(`HTTP_PROXY`/`HTTPS_PROXY` 환경 변수 사용), `"explicit-proxy"`(`url`과 함께 사용). 두 모드 모두 선택적 `tls` 하위 객체를 허용합니다. + - `request.tls`: 직접 연결에 대한 TLS 재정의입니다. 필드: `ca`, `cert`, `key`, `passphrase`(모두 SecretRef 허용), `serverName`, `insecureSkipVerify`. + - `request.allowPrivateNetwork`: `true`이면 provider HTTP fetch 가드를 통해 DNS가 비공개, CGNAT 또는 유사 범위로 해석될 때 `baseUrl`에 대한 HTTPS를 허용합니다(신뢰할 수 있는 자체 호스팅 OpenAI 호환 엔드포인트를 위한 operator opt-in). WebSocket은 헤더/TLS에는 같은 `request`를 사용하지만, 해당 fetch SSRF 게이트는 사용하지 않습니다. 기본값은 `false`. +- `models.providers.*.models`: 명시적인 provider 모델 카탈로그 항목입니다. +- `models.providers.*.models.*.contextWindow`: 기본 모델 컨텍스트 창 메타데이터입니다. +- `models.providers.*.models.*.contextTokens`: 선택적 런타임 컨텍스트 상한입니다. 모델의 기본 `contextWindow`보다 더 작은 유효 컨텍스트 예산을 원할 때 사용하세요. +- `models.providers.*.models.*.compat.supportsDeveloperRole`: 선택적 호환성 힌트입니다. `api: "openai-completions"`에서 비어 있지 않은 비기본 `baseUrl`(`api.openai.com`이 아닌 호스트)을 사용할 경우, OpenClaw는 런타임에 이를 강제로 `false`로 설정합니다. 비어 있거나 생략된 `baseUrl`은 기본 OpenAI 동작을 유지합니다. +- `models.providers.*.models.*.compat.requiresStringContent`: 문자열 전용 OpenAI 호환 채팅 엔드포인트를 위한 선택적 호환성 힌트입니다. `true`이면 OpenClaw는 요청 전송 전에 순수 텍스트 `messages[].content` 배열을 일반 문자열로 평탄화합니다. +- `plugins.entries.amazon-bedrock.config.discovery`: Bedrock 자동 검색 설정 루트입니다. - `plugins.entries.amazon-bedrock.config.discovery.enabled`: 암시적 검색 켜기/끄기. -- `plugins.entries.amazon-bedrock.config.discovery.region`: 검색용 AWS 리전. -- `plugins.entries.amazon-bedrock.config.discovery.providerFilter`: 대상 검색용 선택적 공급자 ID 필터. -- `plugins.entries.amazon-bedrock.config.discovery.refreshInterval`: 검색 새로고침 폴링 간격. +- `plugins.entries.amazon-bedrock.config.discovery.region`: 검색에 사용할 AWS 리전. +- `plugins.entries.amazon-bedrock.config.discovery.providerFilter`: 대상 검색을 위한 선택적 provider-id 필터. +- `plugins.entries.amazon-bedrock.config.discovery.refreshInterval`: 검색 새로 고침 폴링 간격. - `plugins.entries.amazon-bedrock.config.discovery.defaultContextWindow`: 검색된 모델의 대체 컨텍스트 창. - `plugins.entries.amazon-bedrock.config.discovery.defaultMaxTokens`: 검색된 모델의 대체 최대 출력 토큰 수. -### 공급자 예시 +### Provider 예제 -__OC_I18N_900071__ -Cerebras에는 `cerebras/zai-glm-4.7`을 사용하세요. Z.AI 직접 연결에는 `zai/glm-4.7`을 사용하세요. + +```json5 +{ + env: { CEREBRAS_API_KEY: "sk-..." }, + agents: { + defaults: { + model: { + primary: "cerebras/zai-glm-4.7", + fallbacks: ["cerebras/zai-glm-4.6"], + }, + models: { + "cerebras/zai-glm-4.7": { alias: "GLM 4.7 (Cerebras)" }, + "cerebras/zai-glm-4.6": { alias: "GLM 4.6 (Cerebras)" }, + }, + }, + }, + models: { + mode: "merge", + providers: { + cerebras: { + baseUrl: "https://api.cerebras.ai/v1", + apiKey: "${CEREBRAS_API_KEY}", + api: "openai-completions", + models: [ + { id: "zai-glm-4.7", name: "GLM 4.7 (Cerebras)" }, + { id: "zai-glm-4.6", name: "GLM 4.6 (Cerebras)" }, + ], + }, + }, + }, +} +``` + +Cerebras에는 `cerebras/zai-glm-4.7`을 사용하세요. Z.AI 직접 연결에는 `zai/glm-4.7`을 사용합니다. -__OC_I18N_900072__ -`OPENCODE_API_KEY`(또는 `OPENCODE_ZEN_API_KEY`)를 설정하세요. Zen 카탈로그에는 `opencode/...` 참조를, Go 카탈로그에는 `opencode-go/...` 참조를 사용하세요. 바로가기: `openclaw onboard --auth-choice opencode-zen` 또는 `openclaw onboard --auth-choice opencode-go`. + +```json5 +{ + agents: { + defaults: { + model: { primary: "opencode/claude-opus-4-6" }, + models: { "opencode/claude-opus-4-6": { alias: "Opus" } }, + }, + }, +} +``` + +`OPENCODE_API_KEY`(또는 `OPENCODE_ZEN_API_KEY`)를 설정하세요. Zen 카탈로그에는 `opencode/...` 참조를, Go 카탈로그에는 `opencode-go/...` 참조를 사용하세요. 단축키: `openclaw onboard --auth-choice opencode-zen` 또는 `openclaw onboard --auth-choice opencode-go`. -__OC_I18N_900073__ -`ZAI_API_KEY`를 설정하세요. `z.ai/*`와 `z-ai/*`는 허용되는 별칭입니다. 바로가기: `openclaw onboard --auth-choice zai-api-key`. + +```json5 +{ + agents: { + defaults: { + model: { primary: "zai/glm-4.7" }, + models: { "zai/glm-4.7": {} }, + }, + }, +} +``` + +`ZAI_API_KEY`를 설정하세요. `z.ai/*`와 `z-ai/*`는 허용되는 별칭입니다. 단축키: `openclaw onboard --auth-choice zai-api-key`. - 일반 엔드포인트: `https://api.z.ai/api/paas/v4` -- Coding 엔드포인트(기본값): `https://api.z.ai/api/coding/paas/v4` -- 일반 엔드포인트를 사용하려면 base URL 재정의를 포함한 사용자 정의 공급자를 정의하세요. +- 코딩 엔드포인트(기본값): `https://api.z.ai/api/coding/paas/v4` +- 일반 엔드포인트를 사용하려면 base URL 재정의가 있는 사용자 지정 provider를 정의하세요. -__OC_I18N_900074__ + +```json5 +{ + env: { MOONSHOT_API_KEY: "sk-..." }, + agents: { + defaults: { + model: { primary: "moonshot/kimi-k2.6" }, + models: { "moonshot/kimi-k2.6": { alias: "Kimi K2.6" } }, + }, + }, + models: { + mode: "merge", + providers: { + moonshot: { + baseUrl: "https://api.moonshot.ai/v1", + apiKey: "${MOONSHOT_API_KEY}", + api: "openai-completions", + models: [ + { + id: "kimi-k2.6", + name: "Kimi K2.6", + reasoning: false, + input: ["text", "image"], + cost: { input: 0.95, output: 4, cacheRead: 0.16, cacheWrite: 0 }, + contextWindow: 262144, + maxTokens: 262144, + }, + ], + }, + }, + }, +} +``` + 중국 엔드포인트의 경우: `baseUrl: "https://api.moonshot.cn/v1"` 또는 `openclaw onboard --auth-choice moonshot-api-key-cn`. -기본 Moonshot 엔드포인트는 공유 -`openai-completions` 전송에서 스트리밍 사용 호환성을 광고하며, OpenClaw는 이를 내장 공급자 ID만이 아니라 엔드포인트 기능에 따라 판단합니다. +기본 Moonshot 엔드포인트는 공유 `openai-completions` 전송에서 스트리밍 사용 호환성을 광고하며, +OpenClaw는 이를 내장 provider id만이 아니라 엔드포인트 기능을 기준으로 처리합니다. -__OC_I18N_900075__ -Anthropic 호환 내장 공급자입니다. 바로가기: `openclaw onboard --auth-choice kimi-code-api-key`. + +```json5 +{ + env: { KIMI_API_KEY: "sk-..." }, + agents: { + defaults: { + model: { primary: "kimi/kimi-code" }, + models: { "kimi/kimi-code": { alias: "Kimi Code" } }, + }, + }, +} +``` + +Anthropic 호환 내장 provider입니다. 단축키: `openclaw onboard --auth-choice kimi-code-api-key`. -__OC_I18N_900076__ -Base URL은 `/v1`을 제외해야 합니다(Anthropic 클라이언트가 이를 추가함). 바로가기: `openclaw onboard --auth-choice synthetic-api-key`. + +```json5 +{ + env: { SYNTHETIC_API_KEY: "sk-..." }, + agents: { + defaults: { + model: { primary: "synthetic/hf:MiniMaxAI/MiniMax-M2.5" }, + models: { "synthetic/hf:MiniMaxAI/MiniMax-M2.5": { alias: "MiniMax M2.5" } }, + }, + }, + models: { + mode: "merge", + providers: { + synthetic: { + baseUrl: "https://api.synthetic.new/anthropic", + apiKey: "${SYNTHETIC_API_KEY}", + api: "anthropic-messages", + models: [ + { + id: "hf:MiniMaxAI/MiniMax-M2.5", + name: "MiniMax M2.5", + reasoning: true, + input: ["text"], + cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }, + contextWindow: 192000, + maxTokens: 65536, + }, + ], + }, + }, + }, +} +``` + +Base URL에는 `/v1`를 포함하지 않아야 합니다(Anthropic 클라이언트가 이를 추가함). 단축키: `openclaw onboard --auth-choice synthetic-api-key`. - -__OC_I18N_900077__ -`MINIMAX_API_KEY`를 설정하세요. 바로가기: + + +```json5 +{ + agents: { + defaults: { + model: { primary: "minimax/MiniMax-M2.7" }, + models: { + "minimax/MiniMax-M2.7": { alias: "Minimax" }, + }, + }, + }, + models: { + mode: "merge", + providers: { + minimax: { + baseUrl: "https://api.minimax.io/anthropic", + apiKey: "${MINIMAX_API_KEY}", + api: "anthropic-messages", + models: [ + { + id: "MiniMax-M2.7", + name: "MiniMax M2.7", + reasoning: true, + input: ["text", "image"], + cost: { input: 0.3, output: 1.2, cacheRead: 0.06, cacheWrite: 0.375 }, + contextWindow: 204800, + maxTokens: 131072, + }, + ], + }, + }, + }, +} +``` + +`MINIMAX_API_KEY`를 설정하세요. 단축키: `openclaw onboard --auth-choice minimax-global-api` 또는 `openclaw onboard --auth-choice minimax-cn-api`. 모델 카탈로그는 기본적으로 M2.7만 포함합니다. -Anthropic 호환 스트리밍 경로에서 OpenClaw는 -명시적으로 `thinking`을 설정하지 않는 한 기본적으로 MiniMax thinking을 비활성화합니다. `/fast on` 또는 +Anthropic 호환 스트리밍 경로에서는, 명시적으로 `thinking`을 설정하지 않는 한 +OpenClaw는 기본적으로 MiniMax thinking을 비활성화합니다. `/fast on` 또는 `params.fastMode: true`는 `MiniMax-M2.7`을 -`MiniMax-M2.7-highspeed`로 다시 씁니다. +`MiniMax-M2.7-highspeed`로 다시 작성합니다. -[로컬 모델](/gateway/local-models)을 참조하세요. 요약: 충분한 하드웨어에서 LM Studio Responses API를 통해 대형 로컬 모델을 실행하고, 장애 조치를 위해 호스팅 모델은 병합 상태로 유지하세요. +[Local Models](/ko/gateway/local-models)를 참조하세요. 요약: 충분한 하드웨어에서 LM Studio Responses API로 대형 로컬 모델을 실행하고, 대체용으로 호스팅 모델은 병합된 상태로 유지하세요. --- ## Skills -__OC_I18N_900078__ -- `allowBundled`: 번들 Skills에만 적용되는 선택적 허용 목록입니다(관리형/workspace Skills에는 영향 없음). -- `load.extraDirs`: 추가 공유 skill 루트(가장 낮은 우선순위). -- `install.preferBrew`: `brew`를 사용할 수 있을 때 다른 설치 방식으로 대체하기 전에 - Homebrew 설치를 우선합니다. -- `install.nodeManager`: `metadata.openclaw.install` - 사양의 Node 설치 선호도(`npm` | `pnpm` | `yarn` | `bun`). -- `entries..enabled: false`는 번들/설치된 상태여도 해당 skill을 비활성화합니다. -- `entries..apiKey`: 기본 환경 변수를 선언하는 Skills를 위한 편의 항목입니다(일반 텍스트 문자열 또는 SecretRef 객체). + +```json5 +{ + skills: { + allowBundled: ["gemini", "peekaboo"], + load: { + extraDirs: ["~/Projects/agent-scripts/skills"], + }, + install: { + preferBrew: true, + nodeManager: "npm", // npm | pnpm | yarn | bun + }, + entries: { + "image-lab": { + apiKey: { source: "env", provider: "default", id: "GEMINI_API_KEY" }, // 또는 일반 텍스트 문자열 + env: { GEMINI_API_KEY: "GEMINI_KEY_HERE" }, + }, + peekaboo: { enabled: true }, + sag: { enabled: false }, + }, + }, +} +``` + +- `allowBundled`: 번들된 skills 전용 선택적 허용 목록입니다(관리형/workspace skills에는 영향 없음). +- `load.extraDirs`: 추가 공유 skill 루트입니다(가장 낮은 우선순위). +- `install.preferBrew`: true이면 `brew`를 사용할 수 있을 때 다른 설치 방식으로 대체하기 전에 Homebrew 설치를 우선합니다. +- `install.nodeManager`: `metadata.openclaw.install` 사양용 node 설치 관리자 기본 설정입니다(`npm` | `pnpm` | `yarn` | `bun`). +- `entries..enabled: false`는 번들되었거나 설치되었더라도 해당 skill을 비활성화합니다. +- `entries..apiKey`: 기본 환경 변수를 선언하는 skills를 위한 편의 필드입니다(일반 텍스트 문자열 또는 SecretRef 객체). --- ## Plugins -__OC_I18N_900079__ + +```json5 +{ + plugins: { + enabled: true, + allow: ["voice-call"], + deny: [], + load: { + paths: ["~/Projects/oss/voice-call-extension"], + }, + entries: { + "voice-call": { + enabled: true, + hooks: { + allowPromptInjection: false, + }, + config: { provider: "twilio" }, + }, + }, + }, +} +``` + - `~/.openclaw/extensions`, `/.openclaw/extensions`, 그리고 `plugins.load.paths`에서 로드됩니다. -- 검색은 네이티브 OpenClaw Plugin과 호환되는 Codex 번들 및 Claude 번들을 허용하며, manifest가 없는 Claude 기본 레이아웃 번들도 포함합니다. -- **구성 변경에는 gateway 재시작이 필요합니다.** -- `allow`: 선택적 허용 목록(목록에 있는 Plugin만 로드). `deny`가 우선합니다. -- `plugins.entries..apiKey`: Plugin 수준 API 키 편의 필드(Plugin이 지원하는 경우). -- `plugins.entries..env`: Plugin 범위 환경 변수 맵. -- `plugins.entries..hooks.allowPromptInjection`: `false`이면 core가 `before_prompt_build`를 차단하고, 레거시 `before_agent_start`의 프롬프트 변경 필드는 무시하면서 레거시 `modelOverride`와 `providerOverride`는 유지합니다. 네이티브 Plugin hook과 지원되는 번들 제공 hook 디렉터리에 적용됩니다. +- 검색은 기본 OpenClaw Plugin과 호환되는 Codex 번들, Claude 번들을 허용하며, manifest가 없는 Claude 기본 레이아웃 번들도 포함합니다. +- **구성 변경에는 Gateway 재시작이 필요합니다.** +- `allow`: 선택적 허용 목록입니다(목록에 있는 Plugin만 로드). `deny`가 우선합니다. +- `plugins.entries..apiKey`: Plugin 수준 API 키 편의 필드입니다(Plugin이 지원하는 경우). +- `plugins.entries..env`: Plugin 범위 환경 변수 맵입니다. +- `plugins.entries..hooks.allowPromptInjection`: `false`이면 core가 `before_prompt_build`를 차단하고 레거시 `before_agent_start`의 프롬프트 변경 필드를 무시하며, 레거시 `modelOverride`와 `providerOverride`는 유지합니다. 기본 Plugin 훅과 지원되는 번들 제공 훅 디렉터리에 적용됩니다. - `plugins.entries..subagent.allowModelOverride`: 이 Plugin이 백그라운드 subagent 실행에 대해 실행별 `provider` 및 `model` 재정의를 요청하도록 명시적으로 신뢰합니다. -- `plugins.entries..subagent.allowedModels`: 신뢰된 subagent 재정의에 사용할 정규 `provider/model` 대상의 선택적 허용 목록입니다. 어떤 모델이든 허용하려는 의도가 있을 때만 `"*"`를 사용하세요. -- `plugins.entries..config`: Plugin 정의 구성 객체(사용 가능한 경우 네이티브 OpenClaw Plugin 스키마로 검증됨). -- `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`). - - `onlyMainContent`: 페이지에서 메인 콘텐츠만 추출합니다(기본값: `true`). - - `maxAgeMs`: 최대 캐시 유지 기간(밀리초, 기본값: `172800000` / 2일). - - `timeoutSeconds`: 스크래프 요청 타임아웃(초, 기본값: `60`). -- `plugins.entries.xai.config.xSearch`: xAI X Search(Grok 웹 검색) 설정. - - `enabled`: X Search 공급자 활성화. - - `model`: 검색에 사용할 Grok 모델(예: `"grok-4-1-fast"`). -- `plugins.entries.memory-core.config.dreaming`: 메모리 Dreaming 설정. 단계와 임계값은 [Dreaming](/concepts/dreaming)을 참조하세요. - - `enabled`: Dreaming 마스터 스위치(기본값 `false`). - - `frequency`: 각 전체 Dreaming 스윕의 Cron 주기(기본값 `"0 3 * * *"`). - - 단계 정책과 임계값은 구현 세부 사항입니다(사용자 대상 구성 키 아님). -- 전체 메모리 구성은 [메모리 구성 참조](/reference/memory-config)에 있습니다: +- `plugins.entries..subagent.allowedModels`: 신뢰된 subagent 재정의를 위한 선택적 표준 `provider/model` 대상 허용 목록입니다. 어떤 모델이든 허용하려는 의도가 분명할 때만 `"*"`를 사용하세요. +- `plugins.entries..config`: Plugin이 정의한 구성 객체입니다(가능한 경우 기본 OpenClaw Plugin 스키마로 검증됨). +- `plugins.entries.firecrawl.config.webFetch`: Firecrawl 웹 fetch provider 설정입니다. + - `apiKey`: Firecrawl API 키입니다(SecretRef 허용). `plugins.entries.firecrawl.config.webSearch.apiKey`, 레거시 `tools.web.fetch.firecrawl.apiKey`, 또는 `FIRECRAWL_API_KEY` 환경 변수로 대체됩니다. + - `baseUrl`: Firecrawl API base URL입니다(기본값: `https://api.firecrawl.dev`). + - `onlyMainContent`: 페이지에서 본문 콘텐츠만 추출합니다(기본값: `true`). + - `maxAgeMs`: 최대 캐시 보관 시간(밀리초)입니다(기본값: `172800000` / 2일). + - `timeoutSeconds`: 스크래프 요청 제한 시간(초)입니다(기본값: `60`). +- `plugins.entries.xai.config.xSearch`: xAI X Search(Grok 웹 검색) 설정입니다. + - `enabled`: X Search provider를 활성화합니다. + - `model`: 검색에 사용할 Grok 모델입니다(예: `"grok-4-1-fast"`). +- `plugins.entries.memory-core.config.dreaming`: memory dreaming 설정입니다. 단계와 임계값은 [Dreaming](/ko/concepts/dreaming)을 참조하세요. + - `enabled`: 마스터 dreaming 스위치입니다(기본값 `false`). + - `frequency`: 전체 dreaming 스윕의 Cron 주기입니다(기본값 `"0 3 * * *"`). + - 단계 정책과 임계값은 구현 세부 사항입니다(사용자 대상 구성 키가 아님). +- 전체 memory 구성은 [메모리 구성 참조](/ko/reference/memory-config)에 있습니다: - `agents.defaults.memorySearch.*` - `memory.backend` - `memory.citations` - `memory.qmd.*` - `plugins.entries.memory-core.config.dreaming` -- 활성화된 Claude 번들 Plugin은 `settings.json`에서 임베디드 Pi 기본값도 제공할 수 있습니다. OpenClaw는 이를 원시 OpenClaw config 패치가 아니라 정제된 에이전트 설정으로 적용합니다. -- `plugins.slots.memory`: 활성 메모리 Plugin ID를 선택하거나, 메모리 Plugin을 비활성화하려면 `"none"`을 사용합니다. -- `plugins.slots.contextEngine`: 활성 컨텍스트 엔진 Plugin ID를 선택합니다. 다른 엔진을 설치하고 선택하지 않는 한 기본값은 `"legacy"`입니다. +- 활성화된 Claude 번들 Plugin도 `settings.json`에서 임베디드 Pi 기본값을 제공할 수 있으며, OpenClaw는 이를 원시 OpenClaw 구성 패치가 아니라 정제된 에이전트 설정으로 적용합니다. +- `plugins.slots.memory`: 활성 memory Plugin id를 선택하거나, memory Plugin을 비활성화하려면 `"none"`을 사용합니다. +- `plugins.slots.contextEngine`: 활성 context engine Plugin id를 선택합니다. 다른 engine을 설치하고 선택하지 않으면 기본값은 `"legacy"`입니다. - `plugins.installs`: `openclaw plugins update`에서 사용하는 CLI 관리 설치 메타데이터입니다. - `source`, `spec`, `sourcePath`, `installPath`, `version`, `resolvedName`, `resolvedVersion`, `resolvedSpec`, `integrity`, `shasum`, `resolvedAt`, `installedAt`를 포함합니다. - - `plugins.installs.*`는 관리되는 상태로 취급하세요. 수동 편집보다 CLI 명령을 우선 사용하세요. + - `plugins.installs.*`는 관리되는 상태로 취급하고, 수동 편집보다 CLI 명령을 우선 사용하세요. -[Plugins](/tools/plugin)을 참조하세요. +[Plugins](/ko/tools/plugin)를 참조하세요. --- -## 브라우저 -__OC_I18N_900080__ +## Browser + +```json5 +{ + browser: { + enabled: true, + evaluateEnabled: true, + defaultProfile: "user", + ssrfPolicy: { + // dangerouslyAllowPrivateNetwork: true, // 신뢰할 수 있는 비공개 네트워크 액세스에만 opt in + // allowPrivateNetwork: true, // 레거시 별칭 + // hostnameAllowlist: ["*.example.com", "example.com"], + // allowedHostnames: ["localhost"], + }, + profiles: { + openclaw: { cdpPort: 18800, color: "#FF4500" }, + work: { cdpPort: 18801, color: "#0066CC" }, + user: { driver: "existing-session", attachOnly: true, color: "#00AA00" }, + brave: { + driver: "existing-session", + attachOnly: true, + userDataDir: "~/Library/Application Support/BraveSoftware/Brave-Browser", + color: "#FB542B", + }, + remote: { cdpUrl: "http://10.0.0.42:9222", color: "#00AA00" }, + }, + color: "#FF4500", + // headless: false, + // noSandbox: false, + // extraArgs: [], + // executablePath: "/Applications/Brave Browser.app/Contents/MacOS/Brave Browser", + // attachOnly: false, + }, +} +``` + - `evaluateEnabled: false`는 `act:evaluate`와 `wait --fn`을 비활성화합니다. -- `ssrfPolicy.dangerouslyAllowPrivateNetwork`는 설정하지 않으면 비활성화되어, 브라우저 탐색은 기본적으로 strict 상태를 유지합니다. -- 비공개 네트워크 브라우저 탐색을 의도적으로 신뢰하는 경우에만 `ssrfPolicy.dangerouslyAllowPrivateNetwork: true`를 설정하세요. -- strict 모드에서는 원격 CDP 프로필 엔드포인트(`profiles.*.cdpUrl`)도 도달 가능성/검색 검사 중 동일한 비공개 네트워크 차단 대상이 됩니다. -- `ssrfPolicy.allowPrivateNetwork`은 레거시 별칭으로 계속 지원됩니다. -- strict 모드에서는 명시적 예외를 위해 `ssrfPolicy.hostnameAllowlist`와 `ssrfPolicy.allowedHostnames`를 사용하세요. +- `ssrfPolicy.dangerouslyAllowPrivateNetwork`는 설정하지 않으면 비활성화되어 있으므로, Browser 탐색은 기본적으로 엄격하게 유지됩니다. +- 비공개 네트워크 Browser 탐색을 의도적으로 신뢰하는 경우에만 `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)를 사용하세요. -- `existing-session` 프로필은 CDP 대신 Chrome MCP를 사용하며 선택된 호스트 또는 연결된 브라우저 노드를 통해 attach할 수 있습니다. -- `existing-session` 프로필은 Brave 또는 Edge 같은 특정 Chromium 기반 브라우저 프로필을 대상으로 삼기 위해 `userDataDir`를 설정할 수 있습니다. -- `existing-session` 프로필은 현재 Chrome MCP 라우트 제한을 유지합니다: - CSS 선택자 대상 지정 대신 snapshot/ref 기반 작업, 단일 파일 업로드 hook, - dialog 타임아웃 재정의 없음, `wait --load networkidle` 없음, - `responsebody`, PDF 내보내기, 다운로드 가로채기, 배치 작업 없음. -- 로컬에서 관리되는 `openclaw` 프로필은 `cdpPort`와 `cdpUrl`을 자동 할당합니다. 원격 CDP에만 `cdpUrl`을 명시적으로 설정하세요. -- 자동 감지 순서: 기본 브라우저가 Chromium 기반이면 우선 → Chrome → Brave → Edge → Chromium → Chrome Canary. +- `profiles.*.cdpUrl`은 `http://`, `https://`, `ws://`, `wss://`를 허용합니다. + OpenClaw가 `/json/version`을 검색하게 하려면 HTTP(S)를 사용하고, + provider가 직접 DevTools WebSocket URL을 제공할 경우 WS(S)를 사용하세요. +- `existing-session` 프로필은 CDP 대신 Chrome MCP를 사용하며, 선택한 호스트나 연결된 browser node를 통해 attach할 수 있습니다. +- `existing-session` 프로필은 Brave 또는 Edge 같은 특정 Chromium 기반 browser 프로필을 대상으로 삼기 위해 `userDataDir`를 설정할 수 있습니다. +- `existing-session` 프로필은 현재 Chrome MCP 경로 제한을 유지합니다: + CSS 선택자 대상 지정 대신 snapshot/ref 기반 작업, 단일 파일 업로드 훅, + 대화상자 timeout 재정의 없음, `wait --load networkidle` 없음, + `responsebody`, PDF 내보내기, 다운로드 가로채기, 일괄 작업 없음. +- 로컬 관리형 `openclaw` 프로필은 `cdpPort`와 `cdpUrl`을 자동 할당합니다. 원격 CDP에 대해서만 `cdpUrl`을 명시적으로 설정하세요. +- 자동 감지 순서: 기본 browser가 Chromium 기반인 경우 우선 → Chrome → Brave → Edge → Chromium → Chrome Canary. - Control 서비스: loopback 전용(`gateway.port`에서 파생된 포트, 기본값 `18791`). -- `extraArgs`는 로컬 Chromium 시작에 추가 실행 플래그를 더합니다(예: - `--disable-gpu`, 창 크기 지정, 디버그 플래그). +- `extraArgs`는 로컬 Chromium 시작에 추가 실행 플래그를 붙입니다(예: + `--disable-gpu`, 창 크기 조정, 디버그 플래그). --- ## UI -__OC_I18N_900081__ -- `seamColor`: 네이티브 앱 UI 크롬의 강조 색상입니다(Talk Mode 버블 색조 등). + +```json5 +{ + ui: { + seamColor: "#FF4500", + assistant: { + name: "OpenClaw", + avatar: "CB", // 이모지, 짧은 텍스트, 이미지 URL, 또는 data URI + }, + }, +} +``` + +- `seamColor`: 기본 앱 UI 크롬의 강조 색상입니다(Talk Mode 버블 색조 등). - `assistant`: Control UI identity 재정의입니다. 활성 에이전트 identity로 대체됩니다. --- ## Gateway -__OC_I18N_900082__ + +```json5 +{ + gateway: { + mode: "local", // local | remote + port: 18789, + bind: "loopback", + auth: { + mode: "token", // none | token | password | trusted-proxy + token: "your-token", + // password: "your-password", // 또는 OPENCLAW_GATEWAY_PASSWORD + // trustedProxy: { userHeader: "x-forwarded-user" }, // mode=trusted-proxy용; /gateway/trusted-proxy-auth 참조 + allowTailscale: true, + rateLimit: { + maxAttempts: 10, + windowMs: 60000, + lockoutMs: 300000, + exemptLoopback: true, + }, + }, + tailscale: { + mode: "off", // off | serve | funnel + resetOnExit: false, + }, + controlUi: { + enabled: true, + basePath: "/openclaw", + // root: "dist/control-ui", + // embedSandbox: "scripts", // strict | scripts | trusted + // allowExternalEmbedUrls: false, // 위험: 절대 외부 http(s) embed URL 허용 + // allowedOrigins: ["https://control.example.com"], // loopback이 아닌 Control UI에 필요 + // dangerouslyAllowHostHeaderOriginFallback: false, // 위험한 Host-header origin fallback 모드 + // allowInsecureAuth: false, + // dangerouslyDisableDeviceAuth: false, + }, + remote: { + url: "ws://gateway.tailnet:18789", + transport: "ssh", // ssh | direct + token: "your-token", + // password: "your-password", + }, + trustedProxies: ["10.0.0.1"], + // 선택 사항. 기본값 false. + allowRealIpFallback: false, + tools: { + // 추가 /tools/invoke HTTP deny + deny: ["browser"], + // 기본 HTTP deny 목록에서 도구 제거 + allow: ["gateway"], + }, + push: { + apns: { + relay: { + baseUrl: "https://relay.example.com", + timeoutMs: 10000, + }, + }, + }, + }, +} +``` + -- `mode`: `local`(gateway 실행) 또는 `remote`(원격 gateway에 연결). Gateway는 `local`이 아니면 시작을 거부합니다. -- `port`: WS + HTTP용 단일 멀티플렉스 포트. 우선순위: `--port` > `OPENCLAW_GATEWAY_PORT` > `gateway.port` > `18789`. +- `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 별칭**: `gateway.bind`에는 호스트 별칭(`0.0.0.0`, `127.0.0.1`, `localhost`, `::`, `::1`)이 아니라 bind 모드 값(`auto`, `loopback`, `lan`, `tailnet`, `custom`)을 사용하세요. -- **Docker 참고**: 기본 `loopback` bind는 컨테이너 내부의 `127.0.0.1`에서 수신합니다. Docker bridge 네트워킹(`-p 18789:18789`)에서는 트래픽이 `eth0`로 들어오므로 gateway에 접근할 수 없습니다. `--network host`를 사용하거나, 모든 인터페이스에서 수신하도록 `bind: "lan"`(또는 `customBindHost: "0.0.0.0"`를 사용하는 `bind: "custom"`)을 설정하세요. -- **인증**: 기본적으로 필요합니다. loopback이 아닌 bind에는 gateway 인증이 필요합니다. 실제로는 공유 토큰/비밀번호 또는 `gateway.auth.mode: "trusted-proxy"`를 사용하는 identity-aware reverse proxy를 의미합니다. 온보딩 마법사는 기본적으로 토큰을 생성합니다. +- **레거시 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 bridge 네트워킹(`-p 18789:18789`)에서는 트래픽이 `eth0`로 들어오므로 Gateway에 접근할 수 없습니다. `--network host`를 사용하거나, 모든 인터페이스에서 수신하려면 `bind: "lan"`(또는 `customBindHost: "0.0.0.0"`와 함께 `bind: "custom"`)을 설정하세요. +- **인증**: 기본적으로 필요합니다. loopback이 아닌 bind는 Gateway 인증이 필요합니다. 실제로는 공유 토큰/비밀번호 또는 `gateway.auth.mode: "trusted-proxy"`를 사용하는 identity-aware 리버스 프록시를 의미합니다. 온보딩 마법사는 기본적으로 토큰을 생성합니다. - `gateway.auth.token`과 `gateway.auth.password`가 모두 구성된 경우(SecretRef 포함), `gateway.auth.mode`를 `token` 또는 `password`로 명시적으로 설정하세요. 둘 다 구성되어 있고 mode가 설정되지 않으면 시작 및 서비스 설치/복구 흐름이 실패합니다. -- `gateway.auth.mode: "none"`: 명시적 무인증 모드입니다. 신뢰할 수 있는 local loopback 설정에만 사용하세요. 이는 의도적으로 온보딩 프롬프트에서는 제공되지 않습니다. -- `gateway.auth.mode: "trusted-proxy"`: 인증을 identity-aware reverse proxy에 위임하고 `gateway.trustedProxies`의 identity 헤더를 신뢰합니다([Trusted Proxy Auth](/gateway/trusted-proxy-auth) 참조). 이 모드는 **loopback이 아닌** 프록시 소스를 기대합니다. 같은 호스트의 loopback reverse proxy는 trusted-proxy 인증 조건을 충족하지 않습니다. -- `gateway.auth.allowTailscale`: `true`이면 Tailscale Serve identity 헤더가 Control UI/WebSocket 인증을 만족할 수 있습니다(`tailscale whois`로 검증). HTTP API 엔드포인트는 이 Tailscale 헤더 인증을 사용하지 않으며, 대신 gateway의 일반 HTTP 인증 모드를 따릅니다. 이 무토큰 흐름은 gateway 호스트가 신뢰된다는 가정을 전제로 합니다. `tailscale.mode = "serve"`일 때 기본값은 `true`입니다. -- `gateway.auth.rateLimit`: 선택적 인증 실패 제한기입니다. 클라이언트 IP별 및 인증 범위별로 적용됩니다(공유 secret와 device-token은 독립적으로 추적됨). 차단된 시도는 `429` + `Retry-After`를 반환합니다. - - 비동기 Tailscale Serve Control UI 경로에서는 동일한 `{scope, clientIp}`의 실패 시도가 실패 기록 전에 직렬화됩니다. 따라서 같은 클라이언트의 동시 잘못된 시도는 둘 다 단순 불일치로 통과하는 대신 두 번째 요청에서 제한기에 걸릴 수 있습니다. - - `gateway.auth.rateLimit.exemptLoopback`의 기본값은 `true`입니다. localhost 트래픽에도 의도적으로 속도 제한을 적용하려면(테스트 설정 또는 엄격한 프록시 배포) `false`로 설정하세요. -- 브라우저 출처 WS 인증 시도는 loopback 예외를 비활성화한 상태로 항상 제한됩니다(localhost 대상 브라우저 기반 brute force에 대한 defense-in-depth). -- loopback에서는 이러한 브라우저 출처 lockout이 정규화된 `Origin` - 값별로 격리되므로, 하나의 localhost origin에서 반복 실패가 발생해도 - 다른 origin이 자동으로 잠기지는 않습니다. +- `gateway.auth.mode: "none"`: 명시적 무인증 모드입니다. 신뢰할 수 있는 로컬 loopback 설정에서만 사용하세요. 이 옵션은 의도적으로 온보딩 프롬프트에서 제공되지 않습니다. +- `gateway.auth.mode: "trusted-proxy"`: 인증을 identity-aware 리버스 프록시에 위임하고 `gateway.trustedProxies`의 identity 헤더를 신뢰합니다([Trusted Proxy Auth](/ko/gateway/trusted-proxy-auth) 참조). 이 모드는 **loopback이 아닌** 프록시 소스를 기대합니다. 동일 호스트의 loopback 리버스 프록시는 trusted-proxy 인증 조건을 충족하지 않습니다. +- `gateway.auth.allowTailscale`: `true`이면 Tailscale Serve identity 헤더가 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 트래픽에도 의도적으로 rate limit를 적용하려면(`테스트 설정` 또는 엄격한 프록시 배포) `false`로 설정하세요. +- Browser 원본 WS 인증 시도는 항상 loopback 예외를 비활성화한 상태로 제한됩니다(localhost 브루트포스에 대한 defense-in-depth). +- loopback에서는 이러한 browser-origin lockout이 정규화된 `Origin` + 값별로 격리되므로, 하나의 localhost origin에서 반복 실패하더라도 + 다른 origin까지 자동으로 잠기지는 않습니다. - `tailscale.mode`: `serve`(tailnet 전용, loopback bind) 또는 `funnel`(공개, 인증 필요). -- `controlUi.allowedOrigins`: Gateway WebSocket 연결을 위한 명시적 브라우저 origin 허용 목록입니다. 브라우저 클라이언트가 loopback이 아닌 origin에서 연결될 것으로 예상되면 필요합니다. +- `controlUi.allowedOrigins`: Gateway WebSocket 연결을 위한 명시적 browser-origin 허용 목록입니다. browser 클라이언트가 loopback이 아닌 origin에서 연결될 것으로 예상되면 필요합니다. - `controlUi.dangerouslyAllowHostHeaderOriginFallback`: Host-header origin 정책에 의도적으로 의존하는 배포를 위해 Host-header origin fallback을 활성화하는 위험한 모드입니다. - `remote.transport`: `ssh`(기본값) 또는 `direct`(ws/wss). `direct`의 경우 `remote.url`은 `ws://` 또는 `wss://`여야 합니다. -- `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`: 신뢰된 비공개 네트워크 IP에 대한 평문 `ws://`를 허용하는 클라이언트 측 비상 재정의입니다. 기본값은 평문에 대해 여전히 loopback 전용입니다. -- `gateway.remote.token` / `.password`는 원격 클라이언트 자격 증명 필드입니다. 이것만으로 gateway 인증을 구성하지는 않습니다. -- `gateway.push.apns.relay.baseUrl`: 공식/TestFlight iOS 빌드가 relay 기반 등록을 gateway에 게시한 뒤 사용하는 외부 APNs relay의 기본 HTTPS URL입니다. 이 URL은 iOS 빌드에 컴파일된 relay URL과 일치해야 합니다. -- `gateway.push.apns.relay.timeoutMs`: gateway에서 relay로 보낼 때의 타임아웃(밀리초)입니다. 기본값은 `10000`입니다. -- relay 기반 등록은 특정 gateway identity에 위임됩니다. 페어링된 iOS 앱은 `gateway.identity.get`을 가져오고, 그 identity를 relay 등록에 포함하며, 등록 범위 send grant를 gateway로 전달합니다. 다른 gateway는 이 저장된 등록을 재사용할 수 없습니다. -- `OPENCLAW_APNS_RELAY_BASE_URL` / `OPENCLAW_APNS_RELAY_TIMEOUT_MS`: 위 relay 구성을 위한 임시 환경 변수 재정의입니다. +- `OPENCLAW_ALLOW_INSECURE_PRIVATE_WS=1`: 신뢰된 비공개 네트워크 IP에 대한 평문 `ws://`를 허용하는 클라이언트 측 비상용 재정의입니다. 기본값은 계속해서 loopback 전용 평문 허용입니다. +- `gateway.remote.token` / `.password`는 원격 클라이언트 자격 증명 필드입니다. 이것만으로 Gateway 인증을 구성하지는 않습니다. +- `gateway.push.apns.relay.baseUrl`: 공식/TestFlight iOS 빌드가 relay 기반 등록을 Gateway에 게시한 후 사용하는 외부 APNs relay의 기본 HTTPS URL입니다. 이 URL은 iOS 빌드에 컴파일된 relay URL과 일치해야 합니다. +- `gateway.push.apns.relay.timeoutMs`: Gateway에서 relay로 전송할 때의 제한 시간(밀리초)입니다. 기본값은 `10000`입니다. +- Relay 기반 등록은 특정 Gateway identity에 위임됩니다. 페어링된 iOS 앱은 `gateway.identity.get`을 가져오고, 그 identity를 relay 등록에 포함하며, 등록 범위 전송 권한을 Gateway로 전달합니다. 다른 Gateway는 저장된 등록을 재사용할 수 없습니다. +- `OPENCLAW_APNS_RELAY_BASE_URL` / `OPENCLAW_APNS_RELAY_TIMEOUT_MS`: 위 relay 구성에 대한 임시 환경 변수 재정의입니다. - `OPENCLAW_APNS_RELAY_ALLOW_HTTP=true`: loopback HTTP relay URL을 위한 개발 전용 비상 탈출구입니다. 프로덕션 relay URL은 HTTPS를 유지해야 합니다. -- `gateway.channelHealthCheckMinutes`: 채널 헬스 모니터 간격(분)입니다. 전역적으로 헬스 모니터 재시작을 비활성화하려면 `0`으로 설정하세요. 기본값: `5`. -- `gateway.channelStaleEventThresholdMinutes`: 오래된 소켓 임계값(분)입니다. `gateway.channelHealthCheckMinutes`보다 크거나 같아야 합니다. 기본값: `30`. -- `gateway.channelMaxRestartsPerHour`: 롤링 1시간 동안 채널/계정별 최대 헬스 모니터 재시작 수입니다. 기본값: `10`. -- `channels..healthMonitor.enabled`: 전역 모니터를 유지한 채 채널별로 헬스 모니터 재시작을 옵트아웃합니다. -- `channels..accounts..healthMonitor.enabled`: 다중 계정 채널의 계정별 재정의입니다. 설정되면 채널 수준 재정의보다 우선합니다. -- 로컬 gateway 호출 경로는 `gateway.auth.*`가 설정되지 않은 경우에만 `gateway.remote.*`를 대체값으로 사용할 수 있습니다. -- `gateway.auth.token` / `gateway.auth.password`가 SecretRef를 통해 명시적으로 구성되었으나 해결되지 않으면, 해결은 fail closed로 처리됩니다(원격 대체가 이를 가리지 않음). -- `trustedProxies`: TLS를 종료하거나 전달된 클라이언트 헤더를 주입하는 reverse proxy IP입니다. 직접 제어하는 프록시만 나열하세요. loopback 항목도 같은 호스트 프록시/로컬 감지 설정(예: Tailscale Serve 또는 로컬 reverse proxy)에서는 유효하지만, loopback 요청이 `gateway.auth.mode: "trusted-proxy"` 자격을 갖게 하지는 않습니다. -- `allowRealIpFallback`: `true`이면 `X-Forwarded-For`가 없을 때 gateway가 `X-Real-IP`를 허용합니다. 기본값은 fail-closed 동작을 위한 `false`입니다. -- `gateway.tools.deny`: HTTP `POST /tools/invoke`에 대해 차단할 추가 도구 이름입니다(기본 거부 목록 확장). -- `gateway.tools.allow`: 기본 HTTP 거부 목록에서 제거할 도구 이름입니다. +- `gateway.channelHealthCheckMinutes`: 채널 상태 모니터 간격(분)입니다. 전역적으로 상태 모니터 재시작을 비활성화하려면 `0`으로 설정하세요. 기본값: `5`. +- `gateway.channelStaleEventThresholdMinutes`: 오래된 소켓 임계값(분)입니다. 이를 `gateway.channelHealthCheckMinutes` 이상으로 유지하세요. 기본값: `30`. +- `gateway.channelMaxRestartsPerHour`: 채널/계정당 1시간 롤링 윈도우에서 허용되는 최대 상태 모니터 재시작 수입니다. 기본값: `10`. +- `channels..healthMonitor.enabled`: 전역 모니터는 유지하면서 채널별로 상태 모니터 재시작을 opt-out할 수 있습니다. +- `channels..accounts..healthMonitor.enabled`: 다중 계정 채널을 위한 계정별 재정의입니다. 설정되면 채널 수준 재정의보다 우선합니다. +- 로컬 Gateway 호출 경로는 `gateway.auth.*`가 설정되지 않았을 때만 대체값으로 `gateway.remote.*`를 사용할 수 있습니다. +- `gateway.auth.token` / `gateway.auth.password`가 SecretRef를 통해 명시적으로 구성되었는데 확인되지 않으면, 확인은 닫힌 상태로 실패합니다(원격 대체값이 이를 가리지 않음). +- `trustedProxies`: TLS를 종료하거나 전달된 클라이언트 헤더를 주입하는 리버스 프록시 IP입니다. 직접 제어하는 프록시만 나열하세요. loopback 항목은 동일 호스트 프록시/로컬 감지 설정(예: Tailscale Serve 또는 로컬 리버스 프록시)에서 여전히 유효하지만, 그렇다고 해서 loopback 요청이 `gateway.auth.mode: "trusted-proxy"` 대상이 되지는 않습니다. +- `allowRealIpFallback`: `true`이면 `X-Forwarded-For`가 없을 때 Gateway가 `X-Real-IP`를 허용합니다. fail-closed 동작을 위해 기본값은 `false`입니다. +- `gateway.tools.deny`: HTTP `POST /tools/invoke`에 대해 추가로 차단할 도구 이름입니다(기본 deny 목록 확장). +- `gateway.tools.allow`: 기본 HTTP deny 목록에서 도구 이름을 제거합니다. ### OpenAI 호환 엔드포인트 -- Chat Completions: 기본적으로 비활성화. `gateway.http.endpoints.chatCompletions.enabled: true`로 활성화하세요. +- Chat Completions: 기본적으로 비활성화되어 있습니다. `gateway.http.endpoints.chatCompletions.enabled: true`로 활성화하세요. - Responses API: `gateway.http.endpoints.responses.enabled`. -- Responses URL 입력 보안 강화: +- Responses URL 입력 강화: - `gateway.http.endpoints.responses.maxUrlParts` - `gateway.http.endpoints.responses.files.urlAllowlist` - `gateway.http.endpoints.responses.images.urlAllowlist` - 빈 allowlist는 설정되지 않은 것으로 처리됩니다. URL 가져오기를 비활성화하려면 + 빈 허용 목록은 설정되지 않은 것으로 처리됩니다. URL fetch를 비활성화하려면 `gateway.http.endpoints.responses.files.allowUrl=false` 및/또는 `gateway.http.endpoints.responses.images.allowUrl=false`를 사용하세요. -- 선택적 응답 보안 강화 헤더: - - `gateway.http.securityHeaders.strictTransportSecurity`(직접 제어하는 HTTPS origin에만 설정하세요. [Trusted Proxy Auth](/gateway/trusted-proxy-auth#tls-termination-and-hsts) 참조) +- 선택적 응답 강화 헤더: + - `gateway.http.securityHeaders.strictTransportSecurity`(직접 제어하는 HTTPS origin에 대해서만 설정하세요. [Trusted Proxy Auth](/ko/gateway/trusted-proxy-auth#tls-termination-and-hsts) 참조) ### 다중 인스턴스 격리 -하나의 호스트에서 고유한 포트와 상태 디렉터리로 여러 gateway를 실행합니다: -__OC_I18N_900083__ +하나의 호스트에서 고유한 포트와 상태 디렉터리로 여러 Gateway를 실행합니다: + +```bash +OPENCLAW_CONFIG_PATH=~/.openclaw/a.json \ +OPENCLAW_STATE_DIR=~/.openclaw-a \ +openclaw gateway --port 19001 +``` + 편의 플래그: `--dev`(`~/.openclaw-dev` + 포트 `19001` 사용), `--profile `(`~/.openclaw-` 사용). -[여러 Gateway](/gateway/multiple-gateways)를 참조하세요. +[Multiple Gateways](/ko/gateway/multiple-gateways)를 참조하세요. ### `gateway.tls` -__OC_I18N_900084__ -- `enabled`: gateway 리스너에서 TLS 종료(HTTPS/WSS)를 활성화합니다(기본값: `false`). -- `autoGenerate`: 명시적 파일이 구성되지 않았을 때 로컬 자체 서명 cert/key 쌍을 자동 생성합니다. 로컬/개발 용도로만 사용하세요. -- `certPath`: TLS 인증서 파일의 파일 시스템 경로. + +```json5 +{ + gateway: { + tls: { + enabled: false, + autoGenerate: false, + certPath: "/etc/openclaw/tls/server.crt", + keyPath: "/etc/openclaw/tls/server.key", + caPath: "/etc/openclaw/tls/ca-bundle.crt", + }, + }, +} +``` + +- `enabled`: Gateway 리스너에서 TLS 종료(HTTPS/WSS)를 활성화합니다(기본값: `false`). +- `autoGenerate`: 명시적 파일이 구성되지 않았을 때 로컬 self-signed 인증서/키 쌍을 자동 생성합니다. 로컬/개발용 전용입니다. +- `certPath`: TLS 인증서 파일의 파일 시스템 경로입니다. - `keyPath`: TLS 개인 키 파일의 파일 시스템 경로입니다. 권한을 제한해 두세요. -- `caPath`: 클라이언트 검증 또는 사용자 정의 신뢰 체인용 선택적 CA 번들 경로. +- `caPath`: 클라이언트 검증 또는 사용자 지정 신뢰 체인을 위한 선택적 CA 번들 경로입니다. ### `gateway.reload` -__OC_I18N_900085__ + +```json5 +{ + gateway: { + reload: { + mode: "hybrid", // off | restart | hot | hybrid + debounceMs: 500, + deferralTimeoutMs: 300000, + }, + }, +} +``` + - `mode`: 구성 편집을 런타임에 적용하는 방식을 제어합니다. - - `"off"`: 실시간 편집을 무시합니다. 변경 사항에는 명시적 재시작이 필요합니다. - - `"restart"`: 구성 변경 시 항상 gateway 프로세스를 재시작합니다. + - `"off"`: 라이브 편집을 무시합니다. 변경 사항에는 명시적 재시작이 필요합니다. + - `"restart"`: 구성 변경 시 항상 Gateway 프로세스를 재시작합니다. - `"hot"`: 재시작 없이 프로세스 내에서 변경 사항을 적용합니다. - `"hybrid"`(기본값): 먼저 hot reload를 시도하고, 필요하면 재시작으로 대체합니다. -- `debounceMs`: 구성 변경 적용 전 디바운스 창(ms)입니다(0 이상의 정수). -- `deferralTimeoutMs`: 진행 중인 작업을 기다리다가 강제 재시작하기 전까지의 최대 대기 시간(ms, 기본값: `300000` = 5분). +- `debounceMs`: 구성 변경 적용 전의 debounce 창(밀리초)입니다(음이 아닌 정수). +- `deferralTimeoutMs`: 진행 중인 작업을 기다리다가 재시작을 강제하기 전까지의 최대 대기 시간(밀리초)입니다(기본값: `300000` = 5분). --- -## Hook -__OC_I18N_900086__ +## Hooks + +```json5 +{ + hooks: { + enabled: true, + token: "shared-secret", + path: "/hooks", + maxBodyBytes: 262144, + defaultSessionKey: "hook:ingress", + allowRequestSessionKey: true, + allowedSessionKeyPrefixes: ["hook:", "hook:gmail:"], + allowedAgentIds: ["hooks", "main"], + presets: ["gmail"], + transformsDir: "~/.openclaw/hooks/transforms", + mappings: [ + { + match: { path: "gmail" }, + action: "agent", + agentId: "hooks", + wakeMode: "now", + name: "Gmail", + sessionKey: "hook:gmail:{{messages[0].id}}", + messageTemplate: "From: {{messages[0].from}}\nSubject: {{messages[0].subject}}\n{{messages[0].snippet}}", + deliver: true, + channel: "last", + model: "openai/gpt-5.4-mini", + }, + ], + }, +} +``` + 인증: `Authorization: Bearer ` 또는 `x-openclaw-token: `. 쿼리 문자열 hook 토큰은 거부됩니다. @@ -2835,74 +3203,123 @@ __OC_I18N_900086__ - `hooks.enabled=true`에는 비어 있지 않은 `hooks.token`이 필요합니다. - `hooks.token`은 `gateway.auth.token`과 **달라야** 합니다. Gateway 토큰 재사용은 거부됩니다. -- `hooks.path`는 `/`가 될 수 없습니다. `/hooks` 같은 전용 하위 경로를 사용하세요. +- `hooks.path`는 `/`일 수 없습니다. `/hooks` 같은 전용 하위 경로를 사용하세요. - `hooks.allowRequestSessionKey=true`이면 `hooks.allowedSessionKeyPrefixes`를 제한하세요(예: `["hook:"]`). -- 매핑 또는 preset이 템플릿된 `sessionKey`를 사용하면 `hooks.allowedSessionKeyPrefixes`와 `hooks.allowRequestSessionKey=true`를 설정하세요. 정적 매핑 키는 이 옵트인이 필요하지 않습니다. +- 매핑 또는 preset이 템플릿이 적용된 `sessionKey`를 사용하면, `hooks.allowedSessionKeyPrefixes`를 설정하고 `hooks.allowRequestSessionKey=true`도 설정해야 합니다. 정적 매핑 키는 이 opt-in이 필요하지 않습니다. **엔드포인트:** - `POST /hooks/wake` → `{ text, mode?: "now"|"next-heartbeat" }` - `POST /hooks/agent` → `{ message, name?, agentId?, sessionKey?, wakeMode?, deliver?, channel?, to?, model?, thinking?, timeoutSeconds? }` - 요청 페이로드의 `sessionKey`는 `hooks.allowRequestSessionKey=true`일 때만 허용됩니다(기본값: `false`). -- `POST /hooks/` → `hooks.mappings`를 통해 해결됨 - - 템플릿 렌더링된 매핑 `sessionKey` 값은 외부에서 제공된 것으로 취급되며 역시 `hooks.allowRequestSessionKey=true`가 필요합니다. +- `POST /hooks/` → `hooks.mappings`를 통해 확인됨 + - 템플릿 렌더링된 매핑 `sessionKey` 값은 외부에서 제공된 것으로 취급되며 `hooks.allowRequestSessionKey=true`가 필요합니다. -- `match.path`는 `/hooks` 이후의 하위 경로와 일치합니다(예: `/hooks/gmail` → `gmail`). +- `match.path`는 `/hooks` 뒤의 하위 경로와 일치합니다(예: `/hooks/gmail` → `gmail`). - `match.source`는 일반 경로에 대해 페이로드 필드와 일치합니다. - `{{messages[0].subject}}` 같은 템플릿은 페이로드에서 읽습니다. -- `transform`은 hook action을 반환하는 JS/TS 모듈을 가리킬 수 있습니다. - - `transform.module`은 상대 경로여야 하며 `hooks.transformsDir` 내부에 머물러야 합니다(절대 경로와 상위 디렉터리 이동은 거부됨). +- `transform`은 hook 작업을 반환하는 JS/TS 모듈을 가리킬 수 있습니다. + - `transform.module`은 상대 경로여야 하며 `hooks.transformsDir` 내부에 머물러야 합니다(절대 경로와 경로 순회는 거부됨). - `agentId`는 특정 에이전트로 라우팅하며, 알 수 없는 ID는 기본값으로 대체됩니다. - `allowedAgentIds`: 명시적 라우팅을 제한합니다(`*` 또는 생략 = 모두 허용, `[]` = 모두 거부). -- `defaultSessionKey`: 명시적인 `sessionKey` 없이 hook agent 실행을 할 때 사용하는 선택적 고정 세션 키입니다. -- `allowRequestSessionKey`: `/hooks/agent` 호출자와 템플릿 기반 매핑 세션 키가 `sessionKey`를 설정할 수 있도록 허용합니다(기본값: `false`). -- `allowedSessionKeyPrefixes`: 명시적 `sessionKey` 값(요청 + 매핑)에 대한 선택적 접두사 허용 목록입니다. 예: `["hook:"]`. 어떤 매핑이나 preset이든 템플릿된 `sessionKey`를 사용하면 필수가 됩니다. -- `deliver: true`는 최종 답장을 채널로 보냅니다. `channel`의 기본값은 `last`입니다. -- `model`은 이 hook 실행에 사용할 LLM을 재정의합니다(모델 카탈로그가 설정된 경우 허용된 모델이어야 함). +- `defaultSessionKey`: 명시적 `sessionKey`가 없는 hook agent 실행에 대한 선택적 고정 세션 키입니다. +- `allowRequestSessionKey`: `/hooks/agent` 호출자와 템플릿 기반 매핑 세션 키가 `sessionKey`를 설정하도록 허용합니다(기본값: `false`). +- `allowedSessionKeyPrefixes`: 명시적 `sessionKey` 값(요청 + 매핑)을 위한 선택적 접두사 허용 목록입니다. 예: `["hook:"]`. 어떤 매핑이나 preset이든 템플릿이 적용된 `sessionKey`를 사용할 경우 필수가 됩니다. +- `deliver: true`는 최종 응답을 채널로 보냅니다. `channel`의 기본값은 `last`입니다. +- `model`은 이 hook 실행의 LLM을 재정의합니다(모델 카탈로그가 설정된 경우 허용되어야 함). ### Gmail 통합 - 내장 Gmail preset은 `sessionKey: "hook:gmail:{{messages[0].id}}"`를 사용합니다. -- 이 메시지별 라우팅을 유지하려면 `hooks.allowRequestSessionKey: true`를 설정하고 `hooks.allowedSessionKeyPrefixes`를 Gmail 네임스페이스와 일치하도록 제한하세요. 예: `["hook:", "hook:gmail:"]`. -- `hooks.allowRequestSessionKey: false`가 필요하면 템플릿 기본값 대신 고정 `sessionKey`로 preset을 재정의하세요. -__OC_I18N_900087__ +- 이 메시지별 라우팅을 유지한다면 `hooks.allowRequestSessionKey: true`를 설정하고, `hooks.allowedSessionKeyPrefixes`를 Gmail 네임스페이스와 일치하도록 제한하세요. 예: `["hook:", "hook:gmail:"]`. +- `hooks.allowRequestSessionKey: false`가 필요하면, 템플릿 기본값 대신 정적 `sessionKey`로 preset을 재정의하세요. + +```json5 +{ + hooks: { + gmail: { + account: "openclaw@gmail.com", + topic: "projects//topics/gog-gmail-watch", + subscription: "gog-gmail-watch-push", + pushToken: "shared-push-token", + hookUrl: "http://127.0.0.1:18789/hooks/gmail", + includeBody: true, + maxBytes: 20000, + renewEveryMinutes: 720, + serve: { bind: "127.0.0.1", port: 8788, path: "/" }, + tailscale: { mode: "funnel", path: "/gmail-pubsub" }, + model: "openrouter/meta-llama/llama-3.3-70b-instruct:free", + thinking: "off", + }, + }, +} +``` + - 구성되면 Gateway는 부팅 시 `gog gmail watch serve`를 자동 시작합니다. 비활성화하려면 `OPENCLAW_SKIP_GMAIL_WATCHER=1`을 설정하세요. -- Gateway와 함께 별도의 `gog gmail watch serve`를 실행하지 마세요. +- Gateway와 별도로 `gog gmail watch serve`를 함께 실행하지 마세요. --- ## Canvas 호스트 -__OC_I18N_900088__ -- 에이전트가 편집 가능한 HTML/CSS/JS와 A2UI를 Gateway 포트 아래 HTTP로 제공합니다: + +```json5 +{ + canvasHost: { + root: "~/.openclaw/workspace/canvas", + liveReload: true, + // enabled: false, // 또는 OPENCLAW_SKIP_CANVAS_HOST=1 + }, +} +``` + +- 에이전트가 편집 가능한 HTML/CSS/JS와 A2UI를 Gateway 포트 아래의 HTTP로 제공합니다: - `http://:/__openclaw__/canvas/` - `http://:/__openclaw__/a2ui/` - 로컬 전용: `gateway.bind: "loopback"`(기본값)을 유지하세요. -- loopback이 아닌 bind에서는 canvas 경로도 다른 Gateway HTTP 표면과 동일하게 Gateway 인증(token/password/trusted-proxy)이 필요합니다. -- Node WebView는 보통 인증 헤더를 보내지 않습니다. node가 페어링되어 연결된 후 Gateway는 canvas/A2UI 접근용 node 범위 capability URL을 광고합니다. -- Capability URL은 활성 node WS 세션에 바인딩되며 빠르게 만료됩니다. IP 기반 대체는 사용하지 않습니다. -- 제공되는 HTML에 live-reload 클라이언트를 주입합니다. +- loopback이 아닌 bind의 경우: canvas 경로는 다른 Gateway HTTP 표면과 동일하게 Gateway 인증(token/password/trusted-proxy)이 필요합니다. +- Node WebView는 일반적으로 인증 헤더를 보내지 않습니다. node가 페어링되고 연결되면 Gateway는 canvas/A2UI 액세스를 위한 node 범위 capability URL을 광고합니다. +- Capability URL은 활성 node WS 세션에 바인딩되며 빠르게 만료됩니다. IP 기반 대체값은 사용되지 않습니다. +- 제공된 HTML에 live-reload 클라이언트를 주입합니다. - 비어 있으면 시작용 `index.html`을 자동 생성합니다. -- A2UI도 `/__openclaw__/a2ui/`에서 제공합니다. -- 변경 사항에는 gateway 재시작이 필요합니다. -- 대형 디렉터리 또는 `EMFILE` 오류가 있으면 live reload를 비활성화하세요. +- `/__openclaw__/a2ui/`에서 A2UI도 제공합니다. +- 변경 사항에는 Gateway 재시작이 필요합니다. +- 디렉터리가 크거나 `EMFILE` 오류가 발생하면 live reload를 비활성화하세요. --- ## 검색 ### mDNS (Bonjour) -__OC_I18N_900089__ + +```json5 +{ + discovery: { + mdns: { + mode: "minimal", // minimal | full | off + }, + }, +} +``` + - `minimal`(기본값): TXT 레코드에서 `cliPath` + `sshPort`를 생략합니다. - `full`: `cliPath` + `sshPort`를 포함합니다. -- 호스트 이름의 기본값은 `openclaw`입니다. `OPENCLAW_MDNS_HOSTNAME`으로 재정의하세요. +- 호스트 이름 기본값은 `openclaw`입니다. `OPENCLAW_MDNS_HOSTNAME`으로 재정의하세요. ### 광역(Wide-area, DNS-SD) -__OC_I18N_900090__ -`~/.openclaw/dns/` 아래에 유니캐스트 DNS-SD 영역을 기록합니다. 네트워크 간 검색에는 DNS 서버(CoreDNS 권장) + Tailscale split DNS와 함께 사용하세요. + +```json5 +{ + discovery: { + wideArea: { enabled: true }, + }, +} +``` + +`~/.openclaw/dns/` 아래에 유니캐스트 DNS-SD 존을 씁니다. 네트워크 간 검색을 위해 DNS 서버(CoreDNS 권장) + Tailscale 분할 DNS와 함께 사용하세요. 설정: `openclaw dns setup --apply`. @@ -2911,16 +3328,39 @@ __OC_I18N_900090__ ## 환경 ### `env` (인라인 환경 변수) -__OC_I18N_900091__ + +```json5 +{ + env: { + OPENROUTER_API_KEY: "sk-or-...", + vars: { + GROQ_API_KEY: "gsk-...", + }, + shellEnv: { + enabled: true, + timeoutMs: 15000, + }, + }, +} +``` + - 인라인 환경 변수는 프로세스 환경에 해당 키가 없을 때만 적용됩니다. - `.env` 파일: CWD `.env` + `~/.openclaw/.env`(둘 다 기존 변수를 재정의하지 않음). - `shellEnv`: 로그인 셸 프로필에서 누락된 예상 키를 가져옵니다. -- 전체 우선순위는 [환경](/help/environment)을 참조하세요. +- 전체 우선순위는 [Environment](/ko/help/environment)를 참조하세요. ### 환경 변수 치환 -어떤 config 문자열에서든 `${VAR_NAME}`으로 환경 변수를 참조할 수 있습니다: -__OC_I18N_900092__ +어떤 config 문자열에서도 `${VAR_NAME}`으로 환경 변수를 참조할 수 있습니다: + +```json5 +{ + gateway: { + auth: { token: "${OPENCLAW_GATEWAY_TOKEN}" }, + }, +} +``` + - 대문자 이름만 일치합니다: `[A-Z_][A-Z0-9_]*`. - 누락되었거나 비어 있는 변수는 config 로드 시 오류를 발생시킵니다. - 리터럴 `${VAR}`가 필요하면 `$${VAR}`로 이스케이프하세요. @@ -2928,145 +3368,313 @@ __OC_I18N_900092__ --- -## Secret +## 비밀 -Secret 참조는 추가 방식입니다. 일반 텍스트 값도 계속 동작합니다. +SecretRef는 추가적입니다. 일반 텍스트 값도 계속 동작합니다. ### `SecretRef` 하나의 객체 형식을 사용하세요: -__OC_I18N_900093__ + +```json5 +{ source: "env" | "file" | "exec", provider: "default", id: "..." } +``` + 검증: - `provider` 패턴: `^[a-z][a-z0-9_-]{0,63}$` - `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 Credential Surface](/reference/secretref-credential-surface) +- 표준 매트릭스: [SecretRef Credential Surface](/ko/reference/secretref-credential-surface) - `secrets apply`는 지원되는 `openclaw.json` 자격 증명 경로를 대상으로 합니다. -- `auth-profiles.json` 참조는 런타임 해석과 감사 범위에도 포함됩니다. +- `auth-profiles.json` 참조는 런타임 확인 및 감사 범위에도 포함됩니다. + +### 비밀 provider 구성 + +```json5 +{ + secrets: { + providers: { + default: { source: "env" }, // 선택적 명시적 env provider + filemain: { + source: "file", + path: "~/.openclaw/secrets.json", + mode: "json", + timeoutMs: 5000, + }, + vault: { + source: "exec", + command: "/usr/local/bin/openclaw-vault-resolver", + passEnv: ["PATH", "VAULT_ADDR"], + }, + }, + defaults: { + env: "default", + file: "filemain", + exec: "vault", + }, + }, +} +``` -### Secret 공급자 구성 -__OC_I18N_900094__ 참고: -- `file` 공급자는 `mode: "json"`과 `mode: "singleValue"`를 지원합니다(`singleValue` 모드에서는 `id`가 `"value"`여야 함). -- `exec` 공급자는 절대 `command` 경로가 필요하며 stdin/stdout의 프로토콜 페이로드를 사용합니다. -- 기본적으로 심볼릭 링크 명령 경로는 거부됩니다. 심볼릭 링크 경로를 허용하되 해석된 대상 경로를 검증하려면 `allowSymlinkCommand: true`를 설정하세요. -- `trustedDirs`가 구성되어 있으면 trusted-dir 검사는 해석된 대상 경로에 적용됩니다. -- `exec` 자식 환경은 기본적으로 최소화됩니다. 필요한 변수는 `passEnv`로 명시적으로 전달하세요. -- Secret 참조는 활성화 시점에 메모리 내 스냅샷으로 해석되며, 이후 요청 경로는 스냅샷만 읽습니다. -- 활성 표면 필터링은 활성화 중에 적용됩니다. 활성화된 표면의 해결되지 않은 참조는 시작/리로드 실패를 유발하고, 비활성 표면은 진단과 함께 건너뜁니다. +- `file` provider는 `mode: "json"`과 `mode: "singleValue"`를 지원합니다(`singleValue` 모드에서는 `id`가 반드시 `"value"`여야 함). +- `exec` provider는 절대 `command` 경로가 필요하며 stdin/stdout의 프로토콜 페이로드를 사용합니다. +- 기본적으로 심볼릭 링크 명령 경로는 거부됩니다. 해결된 대상 경로를 검증하면서 심볼릭 링크 경로를 허용하려면 `allowSymlinkCommand: true`를 설정하세요. +- `trustedDirs`가 구성된 경우, 신뢰 디렉터리 검사는 해결된 대상 경로에 적용됩니다. +- `exec` 자식 환경은 기본적으로 최소화되어 있으며, 필요한 변수는 `passEnv`로 명시적으로 전달하세요. +- SecretRef는 활성화 시점에 메모리 내 스냅샷으로 확인되며, 이후 요청 경로는 해당 스냅샷만 읽습니다. +- 활성 표면 필터링은 활성화 중에 적용됩니다: 활성 표면의 미해결 ref는 시작/리로드를 실패시키고, 비활성 표면은 진단과 함께 건너뜁니다. --- ## 인증 저장소 -__OC_I18N_900095__ + +```json5 +{ + auth: { + profiles: { + "anthropic:default": { provider: "anthropic", mode: "api_key" }, + "anthropic:work": { provider: "anthropic", mode: "api_key" }, + "openai-codex:personal": { provider: "openai-codex", mode: "oauth" }, + }, + order: { + anthropic: ["anthropic:default", "anthropic:work"], + "openai-codex": ["openai-codex:personal"], + }, + }, +} +``` + - 에이전트별 프로필은 `/auth-profiles.json`에 저장됩니다. -- `auth-profiles.json`은 정적 자격 증명 모드에서 값 수준 참조(`api_key`용 `keyRef`, `token`용 `tokenRef`)를 지원합니다. +- `auth-profiles.json`은 정적 자격 증명 모드에 대해 값 수준 ref(`api_key`용 `keyRef`, `token`용 `tokenRef`)를 지원합니다. - OAuth 모드 프로필(`auth.profiles..mode = "oauth"`)은 SecretRef 기반 auth-profile 자격 증명을 지원하지 않습니다. -- 정적 런타임 자격 증명은 메모리 내 해결된 스냅샷에서 오며, 레거시 정적 `auth.json` 항목은 발견 시 정리됩니다. -- 레거시 OAuth는 `~/.openclaw/credentials/oauth.json`에서 가져옵니다. -- [OAuth](/concepts/oauth)를 참조하세요. -- Secrets 런타임 동작과 `audit/configure/apply` 도구: [Secrets Management](/gateway/secrets). +- 정적 런타임 자격 증명은 메모리 내 확인 스냅샷에서 가져오며, 레거시 정적 `auth.json` 항목은 발견되면 제거됩니다. +- 레거시 OAuth 가져오기는 `~/.openclaw/credentials/oauth.json`에서 수행됩니다. +- [OAuth](/ko/concepts/oauth)를 참조하세요. +- 비밀 런타임 동작과 `audit/configure/apply` 도구: [Secrets Management](/ko/gateway/secrets). ### `auth.cooldowns` -__OC_I18N_900096__ -- `billingBackoffHours`: 실제 - 결제/크레딧 부족 오류로 프로필이 실패했을 때의 기본 backoff 시간(시간 단위, 기본값: `5`)입니다. 명시적인 결제 관련 텍스트는 - `401`/`403` 응답에서도 여기에 포함될 수 있지만, 공급자별 텍스트 - 매처는 여전히 해당 공급자 범위에만 적용됩니다(예: OpenRouter - `Key limit exceeded`). 재시도 가능한 HTTP `402` 사용량 창 또는 - 조직/워크스페이스 지출 한도 메시지는 대신 `rate_limit` 경로에 머뭅니다. -- `billingBackoffHoursByProvider`: 결제 backoff 시간에 대한 선택적 공급자별 재정의. -- `billingMaxHours`: 결제 backoff 지수 증가의 최대 시간(기본값: `24`). -- `authPermanentBackoffMinutes`: 신뢰도 높은 `auth_permanent` 실패에 대한 기본 backoff 시간(분 단위, 기본값: `10`). -- `authPermanentMaxMinutes`: `auth_permanent` backoff 증가의 최대 시간(분 단위, 기본값: `60`). -- `failureWindowHours`: backoff 카운터에 사용되는 롤링 시간 창(기본값: `24`). -- `overloadedProfileRotations`: model 장애 조치로 전환하기 전 overloaded 오류에 대해 동일 공급자 auth-profile 회전을 시도하는 최대 횟수입니다(기본값: `1`). `ModelNotReadyException` 같은 공급자 바쁨 형태가 여기에 포함됩니다. -- `overloadedBackoffMs`: overloaded 공급자/프로필 회전을 재시도하기 전의 고정 지연 시간(기본값: `0`). -- `rateLimitedProfileRotations`: model 장애 조치로 전환하기 전 rate-limit 오류에 대해 동일 공급자 auth-profile 회전을 시도하는 최대 횟수입니다(기본값: `1`). 이 rate-limit 버킷에는 `Too many concurrent requests`, `ThrottlingException`, `concurrency limit reached`, `workers_ai ... quota limit exceeded`, `resource exhausted` 같은 공급자 형태의 텍스트가 포함됩니다. + +```json5 +{ + auth: { + cooldowns: { + billingBackoffHours: 5, + billingBackoffHoursByProvider: { anthropic: 3, openai: 8 }, + billingMaxHours: 24, + authPermanentBackoffMinutes: 10, + authPermanentMaxMinutes: 60, + failureWindowHours: 24, + overloadedProfileRotations: 1, + overloadedBackoffMs: 0, + rateLimitedProfileRotations: 1, + }, + }, +} +``` + +- `billingBackoffHours`: 프로필이 실제 청구/잔액 부족 오류로 실패했을 때의 기본 백오프 시간(시간 단위)입니다(기본값: `5`). 명시적인 청구 관련 텍스트는 `401`/`403` 응답에서도 여기에 들어올 수 있지만, provider별 텍스트 매처는 여전히 해당 provider에만 범위가 제한됩니다(예: OpenRouter `Key limit exceeded`). 재시도 가능한 HTTP `402` 사용량 창 또는 조직/워크스페이스 지출 한도 메시지는 대신 `rate_limit` 경로에 남습니다. +- `billingBackoffHoursByProvider`: 청구 백오프 시간에 대한 선택적 provider별 재정의입니다. +- `billingMaxHours`: 청구 백오프의 지수 증가 상한(시간 단위)입니다(기본값: `24`). +- `authPermanentBackoffMinutes`: 높은 신뢰도의 `auth_permanent` 실패에 대한 기본 백오프(분 단위)입니다(기본값: `10`). +- `authPermanentMaxMinutes`: `auth_permanent` 백오프 증가의 상한(분 단위)입니다(기본값: `60`). +- `failureWindowHours`: 백오프 카운터에 사용되는 롤링 창(시간 단위)입니다(기본값: `24`). +- `overloadedProfileRotations`: 과부하 오류가 발생했을 때 모델 대체로 전환하기 전까지 동일 provider auth-profile을 회전시키는 최대 횟수입니다(기본값: `1`). `ModelNotReadyException` 같은 provider busy 형태가 여기에 해당합니다. +- `overloadedBackoffMs`: 과부하된 provider/profile 회전을 다시 시도하기 전의 고정 지연 시간입니다(기본값: `0`). +- `rateLimitedProfileRotations`: rate-limit 오류가 발생했을 때 모델 대체로 전환하기 전까지 동일 provider auth-profile을 회전시키는 최대 횟수입니다(기본값: `1`). 이 rate-limit 버킷에는 `Too many concurrent requests`, `ThrottlingException`, `concurrency limit reached`, `workers_ai ... quota limit exceeded`, `resource exhausted` 같은 provider 형태 텍스트도 포함됩니다. --- ## 로깅 -__OC_I18N_900097__ + +```json5 +{ + logging: { + level: "info", + file: "/tmp/openclaw/openclaw.log", + consoleLevel: "info", + consoleStyle: "pretty", // pretty | compact | json + redactSensitive: "tools", // off | tools + redactPatterns: ["\\bTOKEN\\b\\s*[=:]\\s*([\"']?)([^\\s\"']+)\\1"], + }, +} +``` + - 기본 로그 파일: `/tmp/openclaw/openclaw-YYYY-MM-DD.log`. -- 고정 경로를 사용하려면 `logging.file`을 설정하세요. +- 고정 경로가 필요하면 `logging.file`을 설정하세요. - `consoleLevel`은 `--verbose`일 때 `debug`로 올라갑니다. -- `maxFileBytes`: 로그 쓰기를 억제하기 전 최대 로그 파일 크기(바이트, 양의 정수, 기본값: `524288000` = 500MB). 프로덕션 배포에서는 외부 로그 회전을 사용하세요. +- `maxFileBytes`: 쓰기를 억제하기 전 최대 로그 파일 크기(바이트 단위)입니다(양의 정수, 기본값: `524288000` = 500 MB). 프로덕션 배포에서는 외부 로그 회전을 사용하세요. --- ## 진단 -__OC_I18N_900098__ + +```json5 +{ + diagnostics: { + enabled: true, + flags: ["telegram.*"], + stuckSessionWarnMs: 30000, + + otel: { + enabled: false, + endpoint: "https://otel-collector.example.com:4318", + protocol: "http/protobuf", // http/protobuf | grpc + headers: { "x-tenant-id": "my-org" }, + serviceName: "openclaw-gateway", + traces: true, + metrics: true, + logs: false, + sampleRate: 1.0, + flushIntervalMs: 5000, + }, + + cacheTrace: { + enabled: false, + filePath: "~/.openclaw/logs/cache-trace.jsonl", + includeMessages: true, + includePrompt: true, + includeSystem: true, + }, + }, +} +``` + - `enabled`: 계측 출력의 마스터 토글입니다(기본값: `true`). - `flags`: 대상 로그 출력을 활성화하는 플래그 문자열 배열입니다(`"telegram.*"` 또는 `"*"` 같은 와일드카드 지원). -- `stuckSessionWarnMs`: 세션이 처리 상태에 머무는 동안 stuck-session 경고를 발생시키는 기준 시간(ms)입니다. +- `stuckSessionWarnMs`: 세션이 처리 상태로 남아 있는 동안 stuck-session 경고를 발생시키는 기준 시간(밀리초)입니다. - `otel.enabled`: OpenTelemetry 내보내기 파이프라인을 활성화합니다(기본값: `false`). -- `otel.endpoint`: OTel 내보내기용 collector URL. +- `otel.endpoint`: OTel 내보내기를 위한 collector URL입니다. - `otel.protocol`: `"http/protobuf"`(기본값) 또는 `"grpc"`. -- `otel.headers`: OTel 내보내기 요청과 함께 전송되는 추가 HTTP/gRPC 메타데이터 헤더. -- `otel.serviceName`: 리소스 속성에 사용할 서비스 이름. -- `otel.traces` / `otel.metrics` / `otel.logs`: trace, metrics, 또는 log 내보내기 활성화. +- `otel.headers`: OTel 내보내기 요청과 함께 전송되는 추가 HTTP/gRPC 메타데이터 헤더입니다. +- `otel.serviceName`: 리소스 속성용 서비스 이름입니다. +- `otel.traces` / `otel.metrics` / `otel.logs`: trace, metrics 또는 log 내보내기를 활성화합니다. - `otel.sampleRate`: trace 샘플링 비율 `0`–`1`. -- `otel.flushIntervalMs`: 주기적 telemetry flush 간격(ms). -- `cacheTrace.enabled`: 임베디드 실행에 대한 cache trace 스냅샷 로깅(기본값: `false`). -- `cacheTrace.filePath`: cache trace JSONL 출력 경로(기본값: `$OPENCLAW_STATE_DIR/logs/cache-trace.jsonl`). -- `cacheTrace.includeMessages` / `includePrompt` / `includeSystem`: cache trace 출력에 무엇을 포함할지 제어합니다(모두 기본값: `true`). +- `otel.flushIntervalMs`: 주기적 telemetry flush 간격(밀리초)입니다. +- `cacheTrace.enabled`: 임베디드 실행에 대한 캐시 추적 스냅샷을 기록합니다(기본값: `false`). +- `cacheTrace.filePath`: 캐시 추적 JSONL의 출력 경로입니다(기본값: `$OPENCLAW_STATE_DIR/logs/cache-trace.jsonl`). +- `cacheTrace.includeMessages` / `includePrompt` / `includeSystem`: 캐시 추적 출력에 무엇을 포함할지 제어합니다(모두 기본값: `true`). --- ## 업데이트 -__OC_I18N_900099__ -- `channel`: npm/git 설치용 릴리스 채널 — `"stable"`, `"beta"`, 또는 `"dev"`. -- `checkOnStart`: gateway 시작 시 npm 업데이트를 확인합니다(기본값: `true`). + +```json5 +{ + update: { + channel: "stable", // stable | beta | dev + checkOnStart: true, + + auto: { + enabled: false, + stableDelayHours: 6, + stableJitterHours: 12, + betaCheckIntervalHours: 1, + }, + }, +} +``` + +- `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`). --- ## ACP -__OC_I18N_900100__ + +```json5 +{ + acp: { + enabled: false, + dispatch: { enabled: true }, + backend: "acpx", + defaultAgent: "main", + allowedAgents: ["main", "ops"], + maxConcurrentSessions: 10, + + stream: { + coalesceIdleMs: 50, + maxChunkChars: 1000, + repeatSuppression: true, + deliveryMode: "live", // live | final_only + hiddenBoundarySeparator: "paragraph", // none | space | newline | paragraph + maxOutputChars: 50000, + maxSessionUpdateChars: 500, + }, + + runtime: { + ttlMinutes: 30, + }, + }, +} +``` + - `enabled`: 전역 ACP 기능 게이트입니다(기본값: `false`). -- `dispatch.enabled`: ACP 세션 턴 디스패치의 독립 게이트입니다(기본값: `true`). ACP 명령은 계속 사용할 수 있게 두고 실행만 차단하려면 `false`로 설정하세요. -- `backend`: 기본 ACP 런타임 backend ID입니다(등록된 ACP 런타임 Plugin과 일치해야 함). -- `defaultAgent`: spawn 시 명시적 대상을 지정하지 않았을 때 사용하는 ACP 대상 에이전트 ID입니다. -- `allowedAgents`: ACP 런타임 세션에 허용되는 에이전트 ID의 허용 목록입니다. 비어 있으면 추가 제한이 없습니다. -- `maxConcurrentSessions`: 동시에 활성 상태일 수 있는 ACP 세션의 최대 수입니다. -- `stream.coalesceIdleMs`: 스트리밍 텍스트의 idle flush 창(ms)입니다. +- `dispatch.enabled`: ACP 세션 턴 디스패치를 위한 독립적인 게이트입니다(기본값: `true`). ACP 명령은 계속 사용 가능하게 유지하면서 실행만 차단하려면 `false`로 설정하세요. +- `backend`: 기본 ACP 런타임 backend id입니다(등록된 ACP 런타임 Plugin과 일치해야 함). +- `defaultAgent`: spawn이 명시적 대상을 지정하지 않을 때의 대체 ACP 대상 에이전트 ID입니다. +- `allowedAgents`: ACP 런타임 세션에 허용되는 에이전트 ID 허용 목록입니다. 비어 있으면 추가 제한이 없습니다. +- `maxConcurrentSessions`: 동시에 활성화될 수 있는 ACP 세션의 최대 수입니다. +- `stream.coalesceIdleMs`: 스트리밍 텍스트의 idle flush 창(밀리초)입니다. - `stream.maxChunkChars`: 스트리밍 블록 투영을 분할하기 전 최대 청크 크기입니다. - `stream.repeatSuppression`: 턴별 반복 상태/도구 줄을 억제합니다(기본값: `true`). - `stream.deliveryMode`: `"live"`는 점진적으로 스트리밍하고, `"final_only"`는 턴 종료 이벤트까지 버퍼링합니다. -- `stream.hiddenBoundarySeparator`: 숨겨진 도구 이벤트 뒤에 보이는 텍스트 앞에 넣는 구분자입니다(기본값: `"paragraph"`). +- `stream.hiddenBoundarySeparator`: 숨겨진 도구 이벤트 뒤에 표시되는 텍스트 앞의 구분자입니다(기본값: `"paragraph"`). - `stream.maxOutputChars`: ACP 턴당 투영되는 assistant 출력의 최대 문자 수입니다. - `stream.maxSessionUpdateChars`: 투영되는 ACP 상태/업데이트 줄의 최대 문자 수입니다. -- `stream.tagVisibility`: 스트리밍 이벤트에 대한 태그 이름과 불리언 가시성 재정의의 기록입니다. -- `runtime.ttlMinutes`: ACP 세션 작업자가 정리 대상이 되기 전까지의 idle TTL(분)입니다. -- `runtime.installCommand`: ACP 런타임 환경을 부트스트랩할 때 실행할 선택적 설치 명령입니다. +- `stream.tagVisibility`: 스트리밍 이벤트에 대한 태그 이름별 boolean 가시성 재정의 기록입니다. +- `runtime.ttlMinutes`: 정리 대상이 되기 전 ACP 세션 워커의 idle TTL(분 단위)입니다. +- `runtime.installCommand`: ACP 런타임 환경을 bootstrap할 때 실행할 선택적 설치 명령입니다. --- ## CLI -__OC_I18N_900101__ -- `cli.banner.taglineMode`는 배너 tagline 스타일을 제어합니다: - - `"random"`(기본값): 회전하는 재미있는/계절성 tagline. - - `"default"`: 고정된 중립 tagline(`All your chats, one OpenClaw.`). - - `"off"`: tagline 텍스트 없음(배너 제목/버전은 계속 표시됨). -- 전체 배너를 숨기려면(tagline만이 아니라) 환경 변수 `OPENCLAW_HIDE_BANNER=1`을 설정하세요. + +```json5 +{ + cli: { + banner: { + taglineMode: "off", // random | default | off + }, + }, +} +``` + +- `cli.banner.taglineMode`는 배너 태그라인 스타일을 제어합니다: + - `"random"`(기본값): 순환하는 유머/계절성 태그라인. + - `"default"`: 고정된 중립 태그라인(`All your chats, one OpenClaw.`). + - `"off"`: 태그라인 텍스트 없음(배너 제목/버전은 계속 표시됨). +- 전체 배너를 숨기려면(태그라인뿐 아니라) 환경 변수 `OPENCLAW_HIDE_BANNER=1`을 설정하세요. --- ## Wizard -CLI 가이드 설정 흐름(`onboard`, `configure`, `doctor`)이 기록하는 메타데이터: -__OC_I18N_900102__ +CLI 가이드 설정 흐름(`onboard`, `configure`, `doctor`)에서 기록하는 메타데이터: + +```json5 +{ + wizard: { + lastRunAt: "2026-01-01T00:00:00.000Z", + lastRunVersion: "2026.1.4", + lastRunCommit: "abc1234", + lastRunCommand: "configure", + lastRunMode: "local", + }, +} +``` + --- ## Identity @@ -3077,95 +3685,175 @@ __OC_I18N_900102__ ## Bridge (레거시, 제거됨) -현재 빌드에는 더 이상 TCP bridge가 포함되지 않습니다. Node는 Gateway WebSocket을 통해 연결됩니다. `bridge.*` 키는 더 이상 config schema의 일부가 아니며(제거할 때까지 검증 실패, `openclaw doctor --fix`로 알 수 없는 키 제거 가능). +현재 빌드에는 더 이상 TCP bridge가 포함되지 않습니다. Nodes는 Gateway WebSocket을 통해 연결됩니다. `bridge.*` 키는 더 이상 config 스키마의 일부가 아니며(제거 전까지 검증 실패, `openclaw doctor --fix`로 알 수 없는 키 제거 가능). + + + +```json +{ + "bridge": { + "enabled": true, + "port": 18790, + "bind": "tailnet", + "tls": { + "enabled": true, + "autoGenerate": true + } + } +} +``` - -__OC_I18N_900103__ --- ## Cron -__OC_I18N_900104__ -- `sessionRetention`: 완료된 격리 cron 실행 세션을 `sessions.json`에서 정리하기 전까지 유지하는 기간입니다. 삭제된 cron transcript 아카이브 정리도 함께 제어합니다. 기본값: `24h`; 비활성화하려면 `false`로 설정하세요. -- `runLog.maxBytes`: 정리 전 실행 로그 파일(`cron/runs/.jsonl`)당 최대 크기입니다. 기본값: `2_000_000` bytes. -- `runLog.keepLines`: 실행 로그 정리가 트리거될 때 유지할 최신 줄 수입니다. 기본값: `2000`. -- `webhookToken`: cron webhook POST 전달(`delivery.mode = "webhook"`)에 사용하는 bearer token입니다. 생략하면 인증 헤더를 보내지 않습니다. -- `webhook`: 저장된 작업 중 여전히 `notify: true`를 사용하는 경우에만 쓰이는 더 이상 권장되지 않는 레거시 fallback webhook URL(http/https)입니다. + +```json5 +{ + cron: { + enabled: true, + maxConcurrentRuns: 2, + webhook: "https://example.invalid/legacy", // 저장된 notify:true 작업용 레거시 대체값(더 이상 권장되지 않음) + webhookToken: "replace-with-dedicated-token", // 발신 webhook 인증용 선택적 bearer 토큰 + sessionRetention: "24h", // 기간 문자열 또는 false + runLog: { + maxBytes: "2mb", // 기본값 2_000_000 바이트 + keepLines: 2000, // 기본값 2000 + }, + }, +} +``` + +- `sessionRetention`: 완료된 격리 Cron 실행 세션을 `sessions.json`에서 가지치기하기 전까지 얼마나 오래 보관할지입니다. 아카이브된 삭제된 Cron transcript 정리도 제어합니다. 기본값: `24h`; 비활성화하려면 `false`로 설정하세요. +- `runLog.maxBytes`: 가지치기 전 실행 로그 파일(`cron/runs/.jsonl`)당 최대 크기입니다. 기본값: `2_000_000` 바이트. +- `runLog.keepLines`: 실행 로그 가지치기가 트리거될 때 유지되는 최신 줄 수입니다. 기본값: `2000`. +- `webhookToken`: Cron webhook POST 전달(`delivery.mode = "webhook"`)에 사용되는 bearer 토큰입니다. 생략하면 인증 헤더를 보내지 않습니다. +- `webhook`: `notify: true`가 아직 남아 있는 저장된 작업에만 사용되는 사용 중단된 레거시 대체 webhook URL(http/https)입니다. ### `cron.retry` -__OC_I18N_900105__ -- `maxAttempts`: 일회성 작업에서 일시적 오류 발생 시 최대 재시도 횟수입니다(기본값: `3`; 범위: `0`–`10`). -- `backoffMs`: 각 재시도 시도에 대한 backoff 지연(ms) 배열입니다(기본값: `[30000, 60000, 300000]`; 1–10개 항목). -- `retryOn`: 재시도를 유발하는 오류 유형 — `"rate_limit"`, `"overloaded"`, `"network"`, `"timeout"`, `"server_error"`. 생략하면 모든 일시적 유형을 재시도합니다. -일회성 cron 작업에만 적용됩니다. 반복 작업은 별도의 실패 처리 방식을 사용합니다. +```json5 +{ + cron: { + retry: { + maxAttempts: 3, + backoffMs: [30000, 60000, 300000], + retryOn: ["rate_limit", "overloaded", "network", "timeout", "server_error"], + }, + }, +} +``` + +- `maxAttempts`: 일회성 작업에서 일시적 오류 발생 시 최대 재시도 횟수입니다(기본값: `3`, 범위: `0`–`10`). +- `backoffMs`: 각 재시도 시도에 대한 백오프 지연 시간 배열(밀리초)입니다(기본값: `[30000, 60000, 300000]`, 1–10개 항목). +- `retryOn`: 재시도를 유발하는 오류 유형입니다 — `"rate_limit"`, `"overloaded"`, `"network"`, `"timeout"`, `"server_error"`. 생략하면 모든 일시적 유형을 재시도합니다. + +일회성 Cron 작업에만 적용됩니다. 반복 작업은 별도의 실패 처리 방식을 사용합니다. ### `cron.failureAlert` -__OC_I18N_900106__ -- `enabled`: cron 작업 실패 알림을 활성화합니다(기본값: `false`). -- `after`: 알림이 발생하기 전 연속 실패 횟수(양의 정수, 최소값: `1`). -- `cooldownMs`: 동일 작업에 대해 반복 알림 사이의 최소 시간(밀리초, 0 이상의 정수). -- `mode`: 전달 모드 — `"announce"`는 채널 메시지로 전송하고, `"webhook"`은 구성된 webhook으로 POST합니다. + +```json5 +{ + cron: { + failureAlert: { + enabled: false, + after: 3, + cooldownMs: 3600000, + mode: "announce", + accountId: "main", + }, + }, +} +``` + +- `enabled`: Cron 작업에 대한 실패 알림을 활성화합니다(기본값: `false`). +- `after`: 알림이 발생하기 전 연속 실패 횟수입니다(양의 정수, 최소값: `1`). +- `cooldownMs`: 동일 작업에 대해 반복 알림 사이의 최소 시간(밀리초)입니다(음이 아닌 정수). +- `mode`: 전달 모드입니다 — `"announce"`는 채널 메시지로 전송하고, `"webhook"`은 구성된 webhook으로 POST합니다. - `accountId`: 알림 전달 범위를 지정하는 선택적 계정 또는 채널 ID입니다. ### `cron.failureDestination` -__OC_I18N_900107__ -- 모든 작업에 대한 cron 실패 알림의 기본 대상입니다. + +```json5 +{ + cron: { + failureDestination: { + mode: "announce", + channel: "last", + to: "channel:C1234567890", + accountId: "main", + }, + }, +} +``` + +- 모든 작업에 대한 Cron 실패 알림의 기본 대상입니다. - `mode`: `"announce"` 또는 `"webhook"`이며, 충분한 대상 정보가 있으면 기본값은 `"announce"`입니다. -- `channel`: announce 전달용 채널 재정의입니다. `"last"`는 마지막으로 알려진 전달 채널을 재사용합니다. -- `to`: 명시적 announce 대상 또는 webhook URL입니다. webhook 모드에서는 필수입니다. -- `accountId`: 전달용 선택적 계정 재정의입니다. +- `channel`: announce 전달을 위한 채널 재정의입니다. `"last"`는 마지막으로 알려진 전달 채널을 재사용합니다. +- `to`: 명시적인 announce 대상 또는 webhook URL입니다. webhook 모드에서는 필수입니다. +- `accountId`: 전달을 위한 선택적 계정 재정의입니다. - 작업별 `delivery.failureDestination`이 이 전역 기본값을 재정의합니다. -- 전역 및 작업별 실패 대상이 모두 설정되지 않은 경우, 이미 `announce`로 전달되는 작업은 실패 시 그 기본 announce 대상으로 대체됩니다. +- 전역 또는 작업별 실패 대상이 둘 다 설정되지 않았을 때, 이미 `announce`로 전달되는 작업은 실패 시 해당 기본 announce 대상을 대체값으로 사용합니다. - `delivery.failureDestination`은 작업의 기본 `delivery.mode`가 `"webhook"`인 경우를 제외하면 `sessionTarget="isolated"` 작업에서만 지원됩니다. -[Cron 작업](/automation/cron-jobs)을 참조하세요. 격리된 cron 실행은 [백그라운드 작업](/automation/tasks)으로 추적됩니다. +[Cron Jobs](/ko/automation/cron-jobs)를 참조하세요. 격리된 Cron 실행은 [background tasks](/ko/automation/tasks)로 추적됩니다. --- ## 미디어 모델 템플릿 변수 -`tools.media.models[].args`에서 확장되는 템플릿 placeholder: +`tools.media.models[].args`에서 확장되는 템플릿 플레이스홀더: -| 변수 | 설명 | +| 변수 | 설명 | | ------------------ | ------------------------------------------------- | -| `{{Body}}` | 전체 수신 메시지 본문 | -| `{{RawBody}}` | 원시 본문(기록/발신자 래퍼 없음) | -| `{{BodyStripped}}` | 그룹 멘션이 제거된 본문 | -| `{{From}}` | 발신자 식별자 | -| `{{To}}` | 대상 식별자 | -| `{{MessageSid}}` | 채널 메시지 ID | -| `{{SessionId}}` | 현재 세션 UUID | -| `{{IsNewSession}}` | 새 세션이 생성되면 `"true"` | -| `{{MediaUrl}}` | 수신 미디어 pseudo-URL | -| `{{MediaPath}}` | 로컬 미디어 경로 | -| `{{MediaType}}` | 미디어 유형(image/audio/document/…) | -| `{{Transcript}}` | 오디오 transcript | -| `{{Prompt}}` | CLI 항목용으로 해결된 미디어 프롬프트 | -| `{{MaxChars}}` | CLI 항목용으로 해결된 최대 출력 문자 수 | -| `{{ChatType}}` | `"direct"` 또는 `"group"` | -| `{{GroupSubject}}` | 그룹 제목(best effort) | -| `{{GroupMembers}}` | 그룹 멤버 미리보기(best effort) | -| `{{SenderName}}` | 발신자 표시 이름(best effort) | -| `{{SenderE164}}` | 발신자 전화번호(best effort) | -| `{{Provider}}` | 공급자 힌트(whatsapp, telegram, discord 등) | +| `{{Body}}` | 전체 수신 메시지 본문 | +| `{{RawBody}}` | 원시 본문(기록/발신자 래퍼 없음) | +| `{{BodyStripped}}` | 그룹 멘션이 제거된 본문 | +| `{{From}}` | 발신자 식별자 | +| `{{To}}` | 대상 식별자 | +| `{{MessageSid}}` | 채널 메시지 ID | +| `{{SessionId}}` | 현재 세션 UUID | +| `{{IsNewSession}}` | 새 세션이 생성되었을 때 `"true"` | +| `{{MediaUrl}}` | 수신 미디어 pseudo-URL | +| `{{MediaPath}}` | 로컬 미디어 경로 | +| `{{MediaType}}` | 미디어 유형(image/audio/document/…) | +| `{{Transcript}}` | 오디오 transcript | +| `{{Prompt}}` | CLI 항목에 대해 확인된 미디어 프롬프트 | +| `{{MaxChars}}` | CLI 항목에 대해 확인된 최대 출력 문자 수 | +| `{{ChatType}}` | `"direct"` 또는 `"group"` | +| `{{GroupSubject}}` | 그룹 제목(best effort) | +| `{{GroupMembers}}` | 그룹 구성원 미리보기(best effort) | +| `{{SenderName}}` | 발신자 표시 이름(best effort) | +| `{{SenderE164}}` | 발신자 전화번호(best effort) | +| `{{Provider}}` | Provider 힌트(whatsapp, telegram, discord 등) | --- ## Config include (`$include`) -config를 여러 파일로 분리합니다: -__OC_I18N_900108__ +config를 여러 파일로 분할할 수 있습니다: + +```json5 +// ~/.openclaw/openclaw.json +{ + gateway: { port: 18789 }, + agents: { $include: "./agents.json5" }, + broadcast: { + $include: ["./clients/mueller.json5", "./clients/schmidt.json5"], + }, +} +``` + **병합 동작:** -- 단일 파일: 포함된 객체를 대체합니다. -- 파일 배열: 순서대로 깊은 병합을 수행합니다(뒤의 값이 앞의 값을 재정의). +- 단일 파일: 포함하는 객체를 대체합니다. +- 파일 배열: 순서대로 깊게 병합됩니다(뒤의 값이 앞의 값을 재정의). - 형제 키: include 이후 병합됩니다(포함된 값을 재정의). - 중첩 include: 최대 10단계 깊이까지. -- 경로: 포함하는 파일을 기준으로 상대 경로로 해석되지만, 최상위 config 디렉터리(`openclaw.json`의 `dirname`) 내부에 머물러야 합니다. 절대 경로/`../` 형식도 최종적으로 이 경계 안에서 해석되는 경우에만 허용됩니다. -- 오류: 누락된 파일, 파싱 오류, 순환 include에 대해 명확한 메시지를 제공합니다. +- 경로: 포함하는 파일을 기준으로 해석되지만 최상위 config 디렉터리(`openclaw.json`의 `dirname`) 내부에 머물러야 합니다. 절대 경로/`../` 형식도 최종적으로 그 경계 안으로 해석될 때만 허용됩니다. +- 오류: 누락된 파일, 구문 분석 오류, 순환 include에 대해 명확한 메시지를 제공합니다. --- -_관련 항목: [구성](/ko/gateway/configuration) · [구성 예시](/ko/gateway/configuration-examples) · [Doctor](/ko/gateway/doctor)_ +_관련: [Configuration](/ko/gateway/configuration) · [Configuration Examples](/ko/gateway/configuration-examples) · [Doctor](/ko/gateway/doctor)_ diff --git a/docs/ko/gateway/heartbeat.md b/docs/ko/gateway/heartbeat.md index 64a99edf9..41d855703 100644 --- a/docs/ko/gateway/heartbeat.md +++ b/docs/ko/gateway/heartbeat.md @@ -1,41 +1,41 @@ --- read_when: - - 하트비트 주기 또는 메시지 조정 - - 예약 작업에 대해 하트비트와 cron 중 무엇을 사용할지 결정하기 -summary: 하트비트 폴링 메시지 및 알림 규칙 -title: 하트비트 + - Heartbeat 주기 또는 메시지 조정 + - 예약된 작업에 대해 Heartbeat와 Cron 중에서 결정하기 +summary: Heartbeat 폴링 메시지 및 알림 규칙 +title: Heartbeat x-i18n: - generated_at: "2026-04-11T02:44:53Z" + generated_at: "2026-04-22T06:00:32Z" model: gpt-5.4 provider: openai - source_hash: e4485072148753076d909867a623696829bf4a82dcd0479b95d5d0cae43100b0 + source_hash: 13004e4e20b02b08aaf16f22cdf664d0b59da69446ecb30453db51ffdfd1d267 source_path: gateway/heartbeat.md workflow: 15 --- -# 하트비트 (Gateway) +# Heartbeat (Gateway) -> **하트비트와 Cron 중 무엇을 써야 하나요?** 언제 무엇을 사용할지에 대한 안내는 [Automation & Tasks](/ko/automation)를 참고하세요. +> **Heartbeat vs Cron?** 각각을 언제 사용해야 하는지에 대한 안내는 [자동화 및 작업](/ko/automation)을 참고하세요. -하트비트는 **주기적인 에이전트 턴**을 메인 세션에서 실행하여, -모델이 사용자에게 과도한 메시지를 보내지 않으면서 주의가 필요한 사항을 알려줄 수 있게 합니다. +Heartbeat는 메인 세션에서 **주기적인 에이전트 턴**을 실행하여, +모델이 과도하게 메시지를 보내지 않으면서 주의가 필요한 사항을 알려줄 수 있게 합니다. -하트비트는 예약된 메인 세션 턴이며, [background task](/ko/automation/tasks) 레코드를 생성하지 **않습니다**. -작업 레코드는 분리된 작업(ACP 실행, 서브에이전트, 격리된 cron 작업)을 위한 것입니다. +Heartbeat는 예약된 메인 세션 턴이며, [백그라운드 작업](/ko/automation/tasks) 레코드를 생성하지 **않습니다**. +작업 레코드는 분리된 작업(ACP 실행, 서브에이전트, 격리된 Cron 작업)에 사용됩니다. -문제 해결: [Scheduled Tasks](/ko/automation/cron-jobs#troubleshooting) +문제 해결: [예약된 작업](/ko/automation/cron-jobs#troubleshooting) ## 빠른 시작 (초보자) -1. 하트비트를 활성화된 상태로 둡니다(기본값은 `30m`, Anthropic OAuth/token 인증(Claude CLI 재사용 포함)일 때는 `1h`) 또는 원하는 주기를 설정합니다. -2. 에이전트 워크스페이스에 작은 `HEARTBEAT.md` 체크리스트 또는 `tasks:` 블록을 만듭니다(선택 사항이지만 권장). -3. 하트비트 메시지를 어디로 보낼지 결정합니다(`target: "none"`이 기본값이며, 마지막 연락처로 라우팅하려면 `target: "last"`로 설정). -4. 선택 사항: 투명성을 위해 하트비트 reasoning 전달을 활성화합니다. -5. 선택 사항: 하트비트 실행에 `HEARTBEAT.md`만 필요하다면 가벼운 bootstrap 컨텍스트를 사용합니다. -6. 선택 사항: 매 하트비트마다 전체 대화 기록을 보내지 않도록 격리 세션을 활성화합니다. -7. 선택 사항: 하트비트를 활성 시간대로 제한합니다(로컬 시간). +1. Heartbeat를 활성화된 상태로 두세요(기본값은 `30m`, Anthropic OAuth/토큰 인증(Claude CLI 재사용 포함)의 경우 `1h`) 또는 원하는 주기를 직접 설정하세요. +2. 에이전트 작업 공간에 작은 `HEARTBEAT.md` 체크리스트 또는 `tasks:` 블록을 만드세요(선택 사항이지만 권장). +3. Heartbeat 메시지를 어디로 보낼지 결정하세요(기본값은 `target: "none"`이며, 마지막 연락처로 보내려면 `target: "last"`로 설정). +4. 선택 사항: 투명성을 위해 heartbeat reasoning 전달을 활성화하세요. +5. 선택 사항: heartbeat 실행에 `HEARTBEAT.md`만 필요하다면 경량 부트스트랩 컨텍스트를 사용하세요. +6. 선택 사항: 각 heartbeat마다 전체 대화 기록을 보내지 않도록 격리된 세션을 활성화하세요. +7. 선택 사항: heartbeat를 활성 시간대(로컬 시간)로 제한하세요. -예시 구성: +예시 config: ```json5 { @@ -43,10 +43,10 @@ x-i18n: defaults: { heartbeat: { every: "30m", - target: "last", // 마지막 연락처로 명시적으로 전달 (기본값은 "none") - directPolicy: "allow", // 기본값: direct/DM 대상 허용; 억제하려면 "block"으로 설정 - lightContext: true, // 선택 사항: bootstrap 파일에서 HEARTBEAT.md만 주입 - isolatedSession: true, // 선택 사항: 매 실행마다 새 세션 사용(대화 기록 없음) + target: "last", // 마지막 연락처로 명시적 전달 (기본값은 "none") + directPolicy: "allow", // 기본값: 직접/DM 대상 허용; 억제하려면 "block"으로 설정 + lightContext: true, // 선택 사항: 부트스트랩 파일에서 HEARTBEAT.md만 주입 + isolatedSession: true, // 선택 사항: 매 실행마다 새 세션 사용 (대화 기록 없음) // activeHours: { start: "08:00", end: "24:00" }, // includeReasoning: true, // 선택 사항: 별도의 `Reasoning:` 메시지도 전송 }, @@ -57,61 +57,62 @@ x-i18n: ## 기본값 -- 간격: `30m` (또는 감지된 인증 모드가 Anthropic OAuth/token 인증인 경우 `1h`, Claude CLI 재사용 포함). `agents.defaults.heartbeat.every` 또는 에이전트별 `agents.list[].heartbeat.every`를 설정하세요. 비활성화하려면 `0m`을 사용합니다. +- 간격: `30m` (Anthropic OAuth/토큰 인증이 감지된 인증 모드이고 Claude CLI 재사용을 포함하는 경우 `1h`). `agents.defaults.heartbeat.every` 또는 에이전트별 `agents.list[].heartbeat.every`를 설정하세요. 비활성화하려면 `0m`을 사용합니다. - 프롬프트 본문(`agents.defaults.heartbeat.prompt`로 구성 가능): `Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.` -- 하트비트 프롬프트는 사용자 메시지로 **그대로** 전송됩니다. 시스템 - 프롬프트에는 기본 에이전트에 대해 하트비트가 활성화되어 있고 - 실행이 내부적으로 하트비트로 표시된 경우에만 “Heartbeat” 섹션이 포함됩니다. -- `0m`으로 하트비트를 비활성화하면 일반 실행도 bootstrap 컨텍스트에서 - `HEARTBEAT.md`를 제외하므로 모델이 하트비트 전용 지침을 보지 않습니다. -- 활성 시간(`heartbeat.activeHours`)은 구성된 시간대에서 검사됩니다. - 시간대 밖에서는 다음 유효 시간대의 틱까지 하트비트를 건너뜁니다. +- heartbeat 프롬프트는 사용자 메시지로 **있는 그대로** 전송됩니다. 시스템 + 프롬프트에는 기본 에이전트에 대해 heartbeat가 활성화되어 있고, + 실행에 내부 플래그가 설정된 경우에만 “Heartbeat” 섹션이 포함됩니다. +- heartbeat가 `0m`으로 비활성화되면 일반 실행에서도 부트스트랩 컨텍스트에서 `HEARTBEAT.md`가 제외되어 + 모델이 heartbeat 전용 지침을 보지 않게 됩니다. +- 활성 시간(`heartbeat.activeHours`)은 구성된 시간대에서 확인됩니다. + 시간 창 밖에서는 창 안의 다음 틱까지 heartbeat가 건너뛰어집니다. -## 하트비트 프롬프트의 목적 +## heartbeat 프롬프트의 용도 기본 프롬프트는 의도적으로 폭넓게 설계되어 있습니다: - **백그라운드 작업**: “Consider outstanding tasks”는 에이전트가 - 후속 작업(받은편지함, 캘린더, 리마인더, 대기 중인 작업)을 검토하고 긴급한 사항을 알리도록 유도합니다. -- **사람 확인**: “Checkup sometimes on your human during day time”는 - 가벼운 “필요한 것 있나요?” 메시지를 가끔 보내도록 유도하지만, 설정된 로컬 시간대를 사용해 - 야간 스팸은 피합니다([/concepts/timezone](/ko/concepts/timezone) 참고). + 후속 조치(받은편지함, 캘린더, 미리 알림, 대기 중인 작업)를 검토하고 + 긴급한 사항을 알려주도록 유도합니다. +- **사람 체크인**: “Checkup sometimes on your human during day time”은 + 가벼운 “필요한 것 있으세요?” 메시지를 때때로 보내도록 유도하지만, + 구성된 로컬 시간대를 사용해 야간 스팸은 피합니다([/concepts/timezone](/ko/concepts/timezone) 참고). -하트비트는 완료된 [background tasks](/ko/automation/tasks)에 반응할 수 있지만, 하트비트 실행 자체는 작업 레코드를 생성하지 않습니다. +Heartbeat는 완료된 [백그라운드 작업](/ko/automation/tasks)에 반응할 수 있지만, heartbeat 실행 자체가 작업 레코드를 생성하지는 않습니다. -하트비트가 매우 구체적인 작업(예: “Gmail PubSub +Heartbeat가 매우 구체적인 작업(예: “Gmail PubSub 통계 확인” 또는 “gateway 상태 검증”)을 하도록 하려면 `agents.defaults.heartbeat.prompt`(또는 -`agents.list[].heartbeat.prompt`)를 사용자 정의 본문으로 설정하세요(그대로 전송됨). +`agents.list[].heartbeat.prompt`)를 사용자 지정 본문으로 설정하세요(있는 그대로 전송됨). ## 응답 계약 -- 주의가 필요한 것이 없으면 **`HEARTBEAT_OK`**로 응답합니다. -- 하트비트 실행 중 OpenClaw는 응답의 **시작 또는 끝**에 `HEARTBEAT_OK`가 있으면 - 이를 ack로 처리합니다. 이 토큰은 제거되며, 남은 내용이 - **`ackMaxChars` 이하**(기본값: 300)면 응답은 폐기됩니다. -- `HEARTBEAT_OK`가 응답의 **중간**에 있으면 특별하게 처리되지 - 않습니다. -- 경고의 경우 **`HEARTBEAT_OK`를 포함하지 말고** 경고 텍스트만 반환하세요. +- 주의가 필요한 사항이 없으면 **`HEARTBEAT_OK`**로 응답하세요. +- heartbeat 실행 중 OpenClaw는 응답의 **시작 또는 끝**에 + `HEARTBEAT_OK`가 나타나면 이를 ack로 처리합니다. 토큰은 제거되며, + 남은 내용이 **≤ `ackMaxChars`**(기본값: 300)인 경우 응답은 폐기됩니다. +- `HEARTBEAT_OK`가 응답의 **중간**에 나타나면 특별히 + 처리되지 않습니다. +- 알림의 경우 **`HEARTBEAT_OK`를 포함하지 말고** 알림 텍스트만 반환하세요. -하트비트 외 실행에서는 메시지 시작/끝의 의도치 않은 `HEARTBEAT_OK`가 제거되고 -로그에 기록됩니다. 메시지가 `HEARTBEAT_OK`만으로 이루어져 있으면 폐기됩니다. +heartbeat 외부에서는 메시지 시작/끝의 의도치 않은 `HEARTBEAT_OK`가 제거되어 +로그에 기록되며, 메시지가 `HEARTBEAT_OK`만으로 이루어진 경우 폐기됩니다. -## 구성 +## Config ```json5 { agents: { defaults: { heartbeat: { - every: "30m", // 기본값: 30m (0m이면 비활성화) + every: "30m", // 기본값: 30m (`0m`은 비활성화) model: "anthropic/claude-opus-4-6", - includeReasoning: false, // 기본값: false (가능할 때 별도의 Reasoning: 메시지 전달) - lightContext: false, // 기본값: false; true이면 워크스페이스 bootstrap 파일에서 HEARTBEAT.md만 유지 - isolatedSession: false, // 기본값: false; true이면 매 하트비트를 새 세션에서 실행(대화 기록 없음) - target: "last", // 기본값: none | 옵션: last | none | (core 또는 plugin, 예: "bluebubbles") + includeReasoning: false, // 기본값: false (사용 가능할 때 별도의 Reasoning: 메시지 전달) + lightContext: false, // 기본값: false; true이면 작업 공간 부트스트랩 파일에서 HEARTBEAT.md만 유지 + isolatedSession: false, // 기본값: false; true이면 각 heartbeat를 새 세션에서 실행 (대화 기록 없음) + target: "last", // 기본값: none | 옵션: last | none | (코어 또는 Plugin, 예: "bluebubbles") to: "+15551234567", // 선택적 채널별 override - accountId: "ops-bot", // 선택적 멀티 계정 채널 id + accountId: "ops-bot", // 선택적 다중 계정 채널 id prompt: "Read HEARTBEAT.md if it exists (workspace context). Follow it strictly. Do not infer or repeat old tasks from prior chats. If nothing needs attention, reply HEARTBEAT_OK.", ackMaxChars: 300, // HEARTBEAT_OK 뒤에 허용되는 최대 문자 수 }, @@ -120,21 +121,21 @@ x-i18n: } ``` -### 범위 및 우선순위 +### 범위와 우선순위 -- `agents.defaults.heartbeat`는 전역 하트비트 동작을 설정합니다. -- `agents.list[].heartbeat`는 그 위에 병합되며, 어떤 에이전트든 `heartbeat` 블록이 있으면 **그 에이전트들만** 하트비트를 실행합니다. +- `agents.defaults.heartbeat`는 전역 heartbeat 동작을 설정합니다. +- `agents.list[].heartbeat`는 그 위에 병합됩니다. 어떤 에이전트든 `heartbeat` 블록이 있으면 **해당 에이전트들만** heartbeat를 실행합니다. - `channels.defaults.heartbeat`는 모든 채널의 가시성 기본값을 설정합니다. - `channels..heartbeat`는 채널 기본값을 override합니다. -- `channels..accounts..heartbeat`(멀티 계정 채널)는 채널별 설정을 override합니다. +- `channels..accounts..heartbeat`(다중 계정 채널)는 채널별 설정을 override합니다. -### 에이전트별 하트비트 +### 에이전트별 heartbeat -어떤 `agents.list[]` 항목이든 `heartbeat` 블록을 포함하면 **그 에이전트들만** -하트비트를 실행합니다. 에이전트별 블록은 `agents.defaults.heartbeat` -위에 병합되므로 공통 기본값을 한 번만 설정하고 에이전트별로 override할 수 있습니다. +어떤 `agents.list[]` 항목에든 `heartbeat` 블록이 포함되면 **해당 에이전트들만** +heartbeat를 실행합니다. 에이전트별 블록은 `agents.defaults.heartbeat` +위에 병합되므로, 공통 기본값을 한 번만 설정하고 에이전트별로 override할 수 있습니다. -예시: 에이전트가 두 개이고, 두 번째 에이전트만 하트비트를 실행합니다. +예시: 에이전트 두 개 중 두 번째 에이전트만 heartbeat를 실행합니다. ```json5 { @@ -142,7 +143,7 @@ x-i18n: defaults: { heartbeat: { every: "30m", - target: "last", // 마지막 연락처로 명시적으로 전달 (기본값은 "none") + target: "last", // 마지막 연락처로 명시적 전달 (기본값은 "none") }, }, list: [ @@ -164,7 +165,7 @@ x-i18n: ### 활성 시간 예시 -특정 시간대의 업무 시간으로 하트비트를 제한합니다: +특정 시간대의 업무 시간으로 heartbeat를 제한합니다: ```json5 { @@ -172,7 +173,7 @@ x-i18n: defaults: { heartbeat: { every: "30m", - target: "last", // 마지막 연락처로 명시적으로 전달 (기본값은 "none") + target: "last", // 마지막 연락처로 명시적 전달 (기본값은 "none") activeHours: { start: "09:00", end: "22:00", @@ -184,21 +185,21 @@ x-i18n: } ``` -이 시간대(동부 시간 기준 오전 9시 이전 또는 오후 10시 이후) 밖에서는 하트비트를 건너뜁니다. 창 안의 다음 예약 틱은 정상적으로 실행됩니다. +이 시간 창 밖(동부 표준시 기준 오전 9시 이전 또는 오후 10시 이후)에서는 heartbeat가 건너뛰어집니다. 창 안의 다음 예약 틱은 정상적으로 실행됩니다. ### 24/7 설정 -하트비트를 하루 종일 실행하려면 다음 패턴 중 하나를 사용하세요: +Heartbeat를 하루 종일 실행하려면 다음 패턴 중 하나를 사용하세요: -- `activeHours`를 아예 생략합니다(시간대 제한 없음, 기본 동작). +- `activeHours`를 완전히 생략합니다(시간 창 제한 없음; 이것이 기본 동작입니다). - 하루 전체 창을 설정합니다: `activeHours: { start: "00:00", end: "24:00" }`. -같은 `start`와 `end` 시간을 설정하지 마세요(예: `08:00`에서 `08:00`). -이 경우 너비가 0인 창으로 처리되어 하트비트가 항상 건너뛰어집니다. +`start`와 `end`를 같은 시간(예: `08:00`에서 `08:00`)으로 설정하지 마세요. +이 경우 너비가 0인 창으로 처리되어 heartbeat가 항상 건너뛰어집니다. -### 멀티 계정 예시 +### 다중 계정 예시 -Telegram과 같은 멀티 계정 채널에서 특정 계정을 대상으로 하려면 `accountId`를 사용합니다: +Telegram 같은 다중 계정 채널에서 특정 계정을 대상으로 하려면 `accountId`를 사용하세요: ```json5 { @@ -227,64 +228,67 @@ Telegram과 같은 멀티 계정 채널에서 특정 계정을 대상으로 하 ### 필드 참고 -- `every`: 하트비트 간격(duration 문자열, 기본 단위 = 분). -- `model`: 하트비트 실행용 선택적 모델 override (`provider/model`). -- `includeReasoning`: 활성화하면 가능할 때 별도의 `Reasoning:` 메시지도 전달합니다(`/reasoning on`과 동일한 형태). -- `lightContext`: true이면 하트비트 실행은 가벼운 bootstrap 컨텍스트를 사용하고 워크스페이스 bootstrap 파일에서 `HEARTBEAT.md`만 유지합니다. -- `isolatedSession`: true이면 각 하트비트는 이전 대화 기록이 없는 새 세션에서 실행됩니다. cron의 `sessionTarget: "isolated"`와 동일한 격리 패턴을 사용합니다. 하트비트당 토큰 비용을 크게 줄여줍니다. 최대 절감을 위해 `lightContext: true`와 함께 사용하세요. 전달 라우팅은 여전히 메인 세션 컨텍스트를 사용합니다. -- `session`: 하트비트 실행용 선택적 세션 키. - - `main` (기본값): 에이전트 메인 세션. +- `every`: heartbeat 간격(기간 문자열, 기본 단위 = 분). +- `model`: heartbeat 실행용 선택적 모델 override (`provider/model`). +- `includeReasoning`: 활성화되면 사용 가능할 때 별도의 `Reasoning:` 메시지도 전달합니다(`/reasoning on`과 동일한 형식). +- `lightContext`: true이면 heartbeat 실행은 경량 부트스트랩 컨텍스트를 사용하고 작업 공간 부트스트랩 파일에서는 `HEARTBEAT.md`만 유지합니다. +- `isolatedSession`: true이면 각 heartbeat는 이전 대화 기록 없이 새 세션에서 실행됩니다. Cron의 `sessionTarget: "isolated"`와 동일한 격리 패턴을 사용합니다. heartbeat당 토큰 비용을 크게 줄입니다. 최대 절감을 위해 `lightContext: true`와 함께 사용하세요. 전달 라우팅은 여전히 메인 세션 컨텍스트를 사용합니다. +- `session`: heartbeat 실행용 선택적 세션 키. + - `main`(기본값): 에이전트 메인 세션. - 명시적 세션 키(`openclaw sessions --json` 또는 [sessions CLI](/cli/sessions)에서 복사). - - 세션 키 형식은 [Sessions](/ko/concepts/session) 및 [Groups](/ko/channels/groups)를 참고하세요. + - 세션 키 형식: [Sessions](/ko/concepts/session) 및 [Groups](/ko/channels/groups)를 참고하세요. - `target`: - `last`: 마지막으로 사용한 외부 채널로 전달. - - 명시적 채널: 구성된 모든 채널 또는 plugin id(예: `discord`, `matrix`, `telegram`, `whatsapp`). - - `none` (기본값): 하트비트를 실행하지만 외부로는 **전달하지 않음**. -- `directPolicy`: direct/DM 전달 동작을 제어합니다: - - `allow` (기본값): direct/DM 하트비트 전달 허용. - - `block`: direct/DM 전달 억제(`reason=dm-blocked`). -- `to`: 선택적 수신자 override(채널별 id, 예: WhatsApp의 E.164 또는 Telegram chat id). Telegram topic/thread에는 `:topic:`를 사용하세요. -- `accountId`: 멀티 계정 채널용 선택적 계정 id. `target: "last"`일 때, 마지막으로 확인된 채널이 계정을 지원하면 그 채널에 적용되고, 그렇지 않으면 무시됩니다. 계정 id가 확인된 채널에 구성된 계정과 일치하지 않으면 전달은 건너뜁니다. + - 명시적 채널: 구성된 모든 채널 또는 Plugin id(예: `discord`, `matrix`, `telegram`, `whatsapp`). + - `none`(기본값): heartbeat는 실행하지만 외부로는 **전달하지 않음**. +- `directPolicy`: 직접/DM 전달 동작을 제어합니다. + - `allow`(기본값): 직접/DM heartbeat 전달 허용. + - `block`: 직접/DM 전달 억제(`reason=dm-blocked`). +- `to`: 선택적 수신자 override(채널별 id, 예: WhatsApp용 E.164 또는 Telegram chat id). Telegram topic/thread의 경우 `:topic:`를 사용하세요. +- `accountId`: 다중 계정 채널용 선택적 계정 id. `target: "last"`일 때 resolved된 마지막 채널이 계정을 지원하면 account id가 적용되고, 아니면 무시됩니다. account id가 resolved된 채널의 구성된 계정과 일치하지 않으면 전달이 건너뛰어집니다. - `prompt`: 기본 프롬프트 본문을 override합니다(병합되지 않음). -- `ackMaxChars`: `HEARTBEAT_OK` 뒤에 허용되는 최대 문자 수. -- `suppressToolErrorWarnings`: true이면 하트비트 실행 중 도구 오류 경고 payload를 억제합니다. -- `activeHours`: 하트비트 실행을 특정 시간 창으로 제한합니다. `start`(HH:MM, 포함, 하루 시작은 `00:00` 사용), `end`(HH:MM, 제외, 하루 끝은 `24:00` 허용), 선택적 `timezone`이 있는 객체입니다. - - 생략 또는 `"user"`: `agents.defaults.userTimezone`이 설정되어 있으면 그것을 사용하고, 아니면 호스트 시스템 시간대로 대체합니다. +- `ackMaxChars`: 전달 전에 `HEARTBEAT_OK` 뒤에 허용되는 최대 문자 수. +- `suppressToolErrorWarnings`: true이면 heartbeat 실행 중 도구 오류 경고 payload를 억제합니다. +- `activeHours`: heartbeat 실행을 시간 창으로 제한합니다. `start`(HH:MM, 포함, 하루 시작은 `00:00` 사용), `end`(HH:MM, 제외, 하루 끝으로 `24:00` 허용), 선택적 `timezone`을 포함하는 객체입니다. + - 생략되었거나 `"user"`인 경우: `agents.defaults.userTimezone`이 설정되어 있으면 이를 사용하고, 아니면 호스트 시스템 시간대로 대체합니다. - `"local"`: 항상 호스트 시스템 시간대를 사용합니다. - - 모든 IANA 식별자(예: `America/New_York`): 직접 사용하며, 유효하지 않으면 위 `"user"` 동작으로 대체됩니다. - - 활성 창에서는 `start`와 `end`가 같아서는 안 됩니다. 같으면 너비가 0인 창(항상 창 밖)으로 처리됩니다. - - 활성 시간 창 밖에서는 창 안의 다음 틱까지 하트비트를 건너뜁니다. + - 모든 IANA 식별자(예: `America/New_York`): 직접 사용되며, 유효하지 않으면 위의 `"user"` 동작으로 대체됩니다. + - 활성 시간 창으로 간주되려면 `start`와 `end`가 같아서는 안 됩니다. 같은 값은 너비가 0인 창(항상 창 밖)으로 처리됩니다. + - 활성 시간 창 밖에서는 창 안의 다음 틱까지 heartbeat가 건너뛰어집니다. ## 전달 동작 -- 하트비트는 기본적으로 에이전트의 메인 세션(`agent::`)에서 실행되며, - `session.scope = "global"`일 때는 `global`에서 실행됩니다. 특정 채널 세션(Discord/WhatsApp 등)으로 +- Heartbeat는 기본적으로 에이전트의 메인 세션(`agent::`)에서 실행되며, + `session.scope = "global"`이면 `global`에서 실행됩니다. 특정 채널 세션(Discord/WhatsApp 등)으로 override하려면 `session`을 설정하세요. - `session`은 실행 컨텍스트에만 영향을 주며, 전달은 `target`과 `to`로 제어됩니다. - 특정 채널/수신자에게 전달하려면 `target` + `to`를 설정하세요. - `target: "last"`를 사용하면 전달은 해당 세션의 마지막 외부 채널을 사용합니다. -- 하트비트 전달은 기본적으로 direct/DM 대상을 허용합니다. direct 대상 전송은 억제하면서 하트비트 턴은 계속 실행하려면 `directPolicy: "block"`을 설정하세요. -- 메인 큐가 바쁘면 하트비트는 건너뛰고 나중에 다시 시도합니다. -- `target`이 외부 대상이 없는 것으로 확인되면 실행은 계속되지만 - 발신 메시지는 전송되지 않습니다. -- `showOk`, `showAlerts`, `useIndicator`가 모두 비활성화되면 실행은 사전에 `reason=alerts-disabled`로 건너뜁니다. -- 경고 전달만 비활성화된 경우에도 OpenClaw는 하트비트를 실행하고, 기한이 된 작업 타임스탬프를 갱신하고, 세션 idle 타임스탬프를 복원하고, 외부 경고 payload는 억제할 수 있습니다. -- 하트비트 전용 응답은 세션을 활성 상태로 유지하지 않습니다. 마지막 `updatedAt` + `target: "last"`일 때는 해당 세션의 마지막 외부 채널을 사용해 전달합니다. +- Heartbeat 전달은 기본적으로 직접/DM 대상을 허용합니다. 직접 대상 전송을 억제하면서 heartbeat 턴은 계속 실행하려면 `directPolicy: "block"`을 설정하세요. +- 메인 큐가 바쁘면 heartbeat는 건너뛰어지고 나중에 다시 시도됩니다. +- `target`이 외부 대상으로 resolve되지 않으면 실행은 계속되지만 + 외부로 보내는 메시지는 전송되지 않습니다. +- `showOk`, `showAlerts`, `useIndicator`가 모두 비활성화되어 있으면 실행은 사전에 `reason=alerts-disabled`로 건너뛰어집니다. +- 알림 전달만 비활성화된 경우에도 OpenClaw는 heartbeat를 실행하고, due-task 타임스탬프를 업데이트하고, 세션 idle 타임스탬프를 복원하며, 외부 알림 payload는 억제할 수 있습니다. +- resolve된 heartbeat 대상이 타이핑을 지원하면 OpenClaw는 + heartbeat 실행이 활성 상태인 동안 타이핑 표시를 보여줍니다. 이는 heartbeat가 + 채팅 출력을 보낼 것과 동일한 대상을 사용하며, `typingMode: "never"`로 비활성화됩니다. +- Heartbeat 전용 응답은 세션을 활성 상태로 유지하지 않습니다. 마지막 `updatedAt` 값이 복원되므로 idle 만료는 정상적으로 동작합니다. -- 분리된 [background tasks](/ko/automation/tasks)는 시스템 이벤트를 큐에 넣고 메인 세션이 무언가를 빨리 인지해야 할 때 하트비트를 깨울 수 있습니다. 이 깨우기 동작이 하트비트 실행을 background task로 만들지는 않습니다. +- 분리된 [백그라운드 작업](/ko/automation/tasks)은 시스템 이벤트를 큐에 넣어 메인 세션이 무언가를 빠르게 알아차려야 할 때 heartbeat를 깨울 수 있습니다. 이 wake는 heartbeat 실행을 백그라운드 작업으로 만들지는 않습니다. ## 가시성 제어 -기본적으로 `HEARTBEAT_OK` 확인 응답은 숨겨지고 경고 콘텐츠는 -전달됩니다. 채널별 또는 계정별로 이를 조정할 수 있습니다: +기본적으로 `HEARTBEAT_OK` 확인 응답은 숨겨지고, 알림 콘텐츠는 +전달됩니다. 이를 채널별 또는 계정별로 조정할 수 있습니다: ```yaml channels: defaults: heartbeat: showOk: false # HEARTBEAT_OK 숨기기 (기본값) - showAlerts: true # 경고 메시지 표시 (기본값) - useIndicator: true # 인디케이터 이벤트 내보내기 (기본값) + showAlerts: true # 알림 메시지 표시 (기본값) + useIndicator: true # indicator 이벤트 발생 (기본값) telegram: heartbeat: showOk: true # Telegram에서 OK 확인 응답 표시 @@ -292,7 +296,7 @@ channels: accounts: work: heartbeat: - showAlerts: false # 이 계정에 대한 경고 전달 억제 + showAlerts: false # 이 계정의 알림 전달 억제 ``` 우선순위: 계정별 → 채널별 → 채널 기본값 → 내장 기본값. @@ -300,10 +304,10 @@ channels: ### 각 플래그의 역할 - `showOk`: 모델이 OK 전용 응답을 반환할 때 `HEARTBEAT_OK` 확인 응답을 전송합니다. -- `showAlerts`: 모델이 OK가 아닌 응답을 반환할 때 경고 콘텐츠를 전송합니다. -- `useIndicator`: UI 상태 화면용 인디케이터 이벤트를 내보냅니다. +- `showAlerts`: 모델이 비-OK 응답을 반환할 때 알림 콘텐츠를 전송합니다. +- `useIndicator`: UI 상태 표시 영역용 indicator 이벤트를 발생시킵니다. -**세 값이 모두** false이면 OpenClaw는 하트비트 실행 자체를 건너뜁니다(모델 호출 없음). +**세 가지가 모두** false이면 OpenClaw는 heartbeat 실행 자체를 건너뜁니다(모델 호출 없음). ### 채널별 vs 계정별 예시 @@ -320,7 +324,7 @@ channels: accounts: ops: heartbeat: - showAlerts: false # ops 계정에 대해서만 경고 억제 + showAlerts: false # ops 계정에 대해서만 알림 억제 telegram: heartbeat: showOk: true @@ -328,44 +332,45 @@ channels: ### 일반적인 패턴 -| 목표 | 구성 | -| --- | --- | -| 기본 동작 (OK는 숨김, 경고는 표시) | _(구성 불필요)_ | -| 완전히 무음 (메시지 없음, 인디케이터 없음) | `channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: false }` | -| 인디케이터만 사용 (메시지 없음) | `channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: true }` | +| 목표 | Config | +| ---------------------------------------- | ---------------------------------------------------------------------------------------- | +| 기본 동작 (조용한 OK, 알림 켜짐) | _(config 불필요)_ | +| 완전히 조용하게 (메시지 없음, indicator 없음) | `channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: false }` | +| indicator만 사용 (메시지 없음) | `channels.defaults.heartbeat: { showOk: false, showAlerts: false, useIndicator: true }` | | 한 채널에서만 OK 표시 | `channels.telegram.heartbeat: { showOk: true }` | ## HEARTBEAT.md (선택 사항) -워크스페이스에 `HEARTBEAT.md` 파일이 있으면 기본 프롬프트는 -에이전트가 이를 읽도록 지시합니다. 이를 “하트비트 체크리스트”라고 생각하면 됩니다: 작고, 안정적이며, +작업 공간에 `HEARTBEAT.md` 파일이 있으면 기본 프롬프트는 +에이전트에게 해당 파일을 읽으라고 지시합니다. 이를 “heartbeat 체크리스트”로 생각하세요: 작고, 안정적이며, 30분마다 포함해도 안전한 내용입니다. -일반 실행에서는 기본 에이전트에 대해 하트비트 지침이 -활성화된 경우에만 `HEARTBEAT.md`가 주입됩니다. `0m`으로 하트비트 주기를 비활성화하거나 -`includeSystemPromptSection: false`를 설정하면 일반 bootstrap +일반 실행에서는 기본 에이전트에 대해 heartbeat 지침이 +활성화된 경우에만 `HEARTBEAT.md`가 주입됩니다. heartbeat 주기를 `0m`으로 비활성화하거나 +`includeSystemPromptSection: false`를 설정하면 일반 부트스트랩 컨텍스트에서 제외됩니다. `HEARTBEAT.md`가 존재하지만 사실상 비어 있는 경우(빈 줄과 `# Heading` 같은 markdown -헤더만 있는 경우), OpenClaw는 API 호출을 절약하기 위해 하트비트 실행을 건너뜁니다. -이 건너뜀은 `reason=empty-heartbeat-file`로 보고됩니다. -파일이 없으면 하트비트는 계속 실행되며 모델이 무엇을 할지 결정합니다. +헤더만 있는 경우), OpenClaw는 API 호출을 절약하기 위해 heartbeat 실행을 건너뜁니다. +이 건너뛰기는 `reason=empty-heartbeat-file`로 보고됩니다. +파일이 없으면 heartbeat는 여전히 실행되며 모델이 무엇을 할지 결정합니다. -프롬프트 팽창을 피하려면 작게 유지하세요(짧은 체크리스트 또는 리마인더). +프롬프트가 불필요하게 커지지 않도록 작게 유지하세요(짧은 체크리스트나 미리 알림). 예시 `HEARTBEAT.md`: ```md -# Heartbeat checklist +# Heartbeat 체크리스트 -- Quick scan: anything urgent in inboxes? -- If it’s daytime, do a lightweight check-in if nothing else is pending. -- If a task is blocked, write down _what is missing_ and ask Peter next time. +- 빠른 확인: 받은편지함에 긴급한 것이 있나요? +- 낮 시간이라면 다른 일이 없을 때 가볍게 안부를 확인하세요. +- 작업이 막혀 있으면 _무엇이 부족한지_ 적어두고 다음에 Peter에게 물어보세요. ``` ### `tasks:` 블록 -`HEARTBEAT.md`는 하트비트 내부에서 간격 기반 점검을 수행하기 위한 작은 구조화된 `tasks:` 블록도 지원합니다. +`HEARTBEAT.md`는 heartbeat 내부의 간격 기반 +확인을 위한 작은 구조화된 `tasks:` 블록도 지원합니다. 예시: @@ -374,84 +379,85 @@ tasks: - name: inbox-triage interval: 30m - prompt: "Check for urgent unread emails and flag anything time sensitive." + prompt: "긴급한 읽지 않은 이메일이 있는지 확인하고 시간에 민감한 항목에 표시를 하세요." - name: calendar-scan interval: 2h - prompt: "Check for upcoming meetings that need prep or follow-up." + prompt: "준비나 후속 조치가 필요한 예정된 회의가 있는지 확인하세요." -# Additional instructions +# 추가 지침 -- Keep alerts short. -- If nothing needs attention after all due tasks, reply HEARTBEAT_OK. +- 알림은 짧게 유지하세요. +- 기한이 지난 모든 작업을 확인한 뒤에도 주의가 필요한 것이 없으면 HEARTBEAT_OK로 응답하세요. ``` -동작: +동작 방식: -- OpenClaw는 `tasks:` 블록을 파싱하고 각 작업을 자체 `interval`에 따라 검사합니다. -- 해당 틱에서 **기한이 된** 작업만 하트비트 프롬프트에 포함됩니다. -- 기한이 된 작업이 없으면 하트비트는 낭비되는 모델 호출을 피하기 위해 완전히 건너뜁니다(`reason=no-tasks-due`). -- `HEARTBEAT.md`의 작업 외 콘텐츠는 유지되며 기한이 된 작업 목록 뒤에 추가 컨텍스트로 덧붙여집니다. -- 작업 마지막 실행 타임스탬프는 세션 상태(`heartbeatTaskState`)에 저장되므로 일반적인 재시작 후에도 간격이 유지됩니다. -- 작업 타임스탬프는 하트비트 실행이 정상 응답 경로를 완료한 뒤에만 갱신됩니다. 건너뛴 `empty-heartbeat-file` / `no-tasks-due` 실행은 작업을 완료된 것으로 표시하지 않습니다. +- OpenClaw는 `tasks:` 블록을 파싱하고 각 작업을 자체 `interval` 기준으로 확인합니다. +- 해당 틱에서 **기한이 지난** 작업만 heartbeat 프롬프트에 포함됩니다. +- 기한이 지난 작업이 없으면 불필요한 모델 호출을 피하기 위해 heartbeat 전체가 건너뛰어집니다(`reason=no-tasks-due`). +- `HEARTBEAT.md`의 작업이 아닌 콘텐츠는 보존되며, 기한이 지난 작업 목록 뒤에 추가 컨텍스트로 덧붙여집니다. +- 작업의 마지막 실행 타임스탬프는 세션 상태(`heartbeatTaskState`)에 저장되므로 간격 정보는 일반적인 재시작 후에도 유지됩니다. +- 작업 타임스탬프는 heartbeat 실행이 정상 응답 경로를 완료한 뒤에만 갱신됩니다. 건너뛴 `empty-heartbeat-file` / `no-tasks-due` 실행은 작업을 완료로 표시하지 않습니다. -작업 모드는 모든 틱에서 비용을 지불하지 않으면서 하나의 하트비트 파일에 여러 주기적 점검을 담고 싶을 때 유용합니다. +작업 모드는 하나의 heartbeat 파일에 여러 주기적 확인을 담고 싶지만, 매 틱마다 그 전부에 대한 비용을 지불하고 싶지 않을 때 유용합니다. ### 에이전트가 HEARTBEAT.md를 업데이트할 수 있나요? -네 — 그렇게 하라고 요청하면 가능합니다. +네 — 그렇게 하라고 요청하면 됩니다. -`HEARTBEAT.md`는 에이전트 워크스페이스에 있는 일반 파일일 뿐이므로, -일반 채팅에서 에이전트에게 다음과 같이 말할 수 있습니다: +`HEARTBEAT.md`는 에이전트 작업 공간의 일반 파일일 뿐이므로, 일반 채팅에서 +에이전트에게 다음과 같이 말할 수 있습니다: -- “매일 캘린더 확인을 추가하도록 `HEARTBEAT.md`를 업데이트해.” -- “더 짧고 받은편지함 후속 작업에 집중되도록 `HEARTBEAT.md`를 다시 작성해.” +- “매일 캘린더 확인을 추가하도록 `HEARTBEAT.md`를 업데이트해줘.” +- “더 짧고 받은편지함 후속 조치에 집중하도록 `HEARTBEAT.md`를 다시 작성해줘.” -이를 더 능동적으로 수행하게 하려면 하트비트 프롬프트에 다음과 같은 명시적 문장을 포함할 수도 있습니다: -“체크리스트가 오래되면 더 나은 것으로 HEARTBEAT.md를 업데이트해.” +이를 선제적으로 수행하게 하고 싶다면, heartbeat 프롬프트에 +“체크리스트가 오래되면 더 나은 내용으로 HEARTBEAT.md를 업데이트하라” +같은 명시적 문장을 포함할 수도 있습니다. -안전 참고: `HEARTBEAT.md`에는 비밀 정보(API 키, 전화번호, 개인 토큰)를 넣지 마세요. -이 파일은 프롬프트 컨텍스트의 일부가 됩니다. +안전 참고: 비밀 정보(API 키, 전화번호, 비공개 토큰)는 +`HEARTBEAT.md`에 넣지 마세요. 프롬프트 컨텍스트의 일부가 됩니다. -## 수동 깨우기 (온디맨드) +## 수동 wake(온디맨드) -다음 명령으로 시스템 이벤트를 큐에 넣고 즉시 하트비트를 트리거할 수 있습니다: +다음 명령으로 시스템 이벤트를 큐에 넣고 즉시 heartbeat를 트리거할 수 있습니다: ```bash -openclaw system event --text "Check for urgent follow-ups" --mode now +openclaw system event --text "긴급한 후속 조치가 있는지 확인" --mode now ``` -여러 에이전트에 `heartbeat`가 구성되어 있으면 수동 깨우기는 그 에이전트들의 -하트비트를 즉시 각각 실행합니다. +여러 에이전트에 `heartbeat`가 구성되어 있으면 수동 wake는 해당 +에이전트들의 heartbeat를 즉시 각각 실행합니다. 다음 예약 틱까지 기다리려면 `--mode next-heartbeat`를 사용하세요. -## reasoning 전달 (선택 사항) +## Reasoning 전달 (선택 사항) -기본적으로 하트비트는 최종 “응답” payload만 전달합니다. +기본적으로 heartbeat는 최종 “answer” payload만 전달합니다. -투명성을 원한다면 다음을 활성화하세요: +투명성이 필요하다면 다음을 활성화하세요: - `agents.defaults.heartbeat.includeReasoning: true` -활성화하면 하트비트는 `Reasoning:` 접두사가 붙은 별도 메시지도 전달합니다 -(`reasoning on`과 동일한 형태). 이는 에이전트가 여러 세션/codex를 관리하고 있을 때 -왜 사용자에게 알림을 보내기로 결정했는지 보고 싶을 때 유용할 수 있습니다. -하지만 원하지 않는 더 많은 내부 세부 정보가 드러날 수도 있습니다. 그룹 채팅에서는 -끄는 편이 좋습니다. +활성화되면 heartbeat는 `Reasoning:` 접두사가 붙은 별도의 메시지도 전달합니다 +(` /reasoning on`과 동일한 형식). 에이전트가 여러 세션/codex를 관리하고 있어 +왜 나에게 ping을 보내기로 결정했는지 보고 싶을 때 유용할 수 있습니다. +하지만 원치 않는 내부 세부 정보가 더 많이 노출될 수도 있습니다. 그룹 채팅에서는 +끄는 것을 권장합니다. ## 비용 고려 -하트비트는 전체 에이전트 턴을 실행합니다. 간격이 짧을수록 토큰을 더 많이 사용합니다. 비용을 줄이려면: +Heartbeat는 전체 에이전트 턴을 실행합니다. 간격이 짧을수록 더 많은 토큰이 소모됩니다. 비용을 줄이려면: -- 전체 대화 기록 전송을 피하기 위해 `isolatedSession: true`를 사용하세요(실행당 약 100K 토큰에서 약 2~5K로 감소). -- bootstrap 파일을 `HEARTBEAT.md`로만 제한하려면 `lightContext: true`를 사용하세요. +- 전체 대화 기록 전송을 피하려면 `isolatedSession: true`를 사용하세요(실행당 약 100K 토큰에서 약 2-5K로 감소). +- 부트스트랩 파일을 `HEARTBEAT.md`만으로 제한하려면 `lightContext: true`를 사용하세요. - 더 저렴한 `model`을 설정하세요(예: `ollama/llama3.2:1b`). - `HEARTBEAT.md`를 작게 유지하세요. - 내부 상태 업데이트만 원한다면 `target: "none"`을 사용하세요. ## 관련 항목 -- [Automation & Tasks](/ko/automation) — 모든 자동화 메커니즘 한눈에 보기 -- [Background Tasks](/ko/automation/tasks) — 분리된 작업이 추적되는 방식 -- [Timezone](/ko/concepts/timezone) — 시간대가 하트비트 예약에 미치는 영향 -- [Troubleshooting](/ko/automation/cron-jobs#troubleshooting) — 자동화 문제 디버깅 +- [자동화 및 작업](/ko/automation) — 모든 자동화 메커니즘 한눈에 보기 +- [백그라운드 작업](/ko/automation/tasks) — 분리된 작업이 추적되는 방식 +- [시간대](/ko/concepts/timezone) — 시간대가 heartbeat 일정에 미치는 영향 +- [문제 해결](/ko/automation/cron-jobs#troubleshooting) — 자동화 문제 디버깅 diff --git a/docs/ko/plugins/codex-harness.md b/docs/ko/plugins/codex-harness.md index 832ac34f4..b3d606d95 100644 --- a/docs/ko/plugins/codex-harness.md +++ b/docs/ko/plugins/codex-harness.md @@ -1,65 +1,68 @@ --- read_when: - - 번들 Codex app-server 하네스를 사용하려고 함 - - Codex 모델 참조와 구성 예제가 필요함 - - Codex 전용 배포를 위해 Pi fallback을 비활성화하려고 함 -summary: 번들 Codex app-server 하네스를 통해 OpenClaw 임베디드 에이전트 턴 실행 -title: Codex 하네스 + - 번들된 Codex 앱-서버 하니스를 사용하려고 합니다. + - Codex 모델 참조와 구성 예제가 필요합니다. + - Codex 전용 배포를 위해 Pi 폴백을 비활성화하려고 합니다. +summary: 번들된 Codex 앱-서버 하니스를 통해 OpenClaw 임베디드 에이전트 턴을 실행합니다 +title: Codex 하니스 x-i18n: - generated_at: "2026-04-21T06:05:03Z" + generated_at: "2026-04-22T06:00:35Z" model: gpt-5.4 provider: openai - source_hash: 3f0cdaf68be3b2257de1046103ff04f53f9d3a65ffc15ab7af5ab1f425643d6c + source_hash: d45dbd39a7d8ebb3a39d8dca3a5125c07b7168d1658ca07b85792645fb98613c source_path: plugins/codex-harness.md workflow: 15 --- -# Codex 하네스 +# Codex 하니스 -번들 `codex` Plugin을 사용하면 OpenClaw가 내장 PI 하네스 대신 -Codex app-server를 통해 임베디드 에이전트 턴을 실행할 수 있습니다. +번들된 `codex` Plugin을 사용하면 OpenClaw가 내장된 PI 하니스 대신 +Codex 앱-서버를 통해 임베디드 에이전트 턴을 실행할 수 있습니다. -이는 Codex가 하위 수준 에이전트 세션을 직접 관리하도록 하고 싶을 때 사용합니다: 모델 -검색, 네이티브 스레드 재개, 네이티브 Compaction, 그리고 app-server 실행입니다. -OpenClaw는 여전히 채팅 채널, 세션 파일, 모델 선택, 도구, -승인, 미디어 전달, 그리고 표시되는 transcript 미러를 관리합니다. +이는 Codex가 저수준 에이전트 세션, 즉 모델 검색, 네이티브 스레드 재개, +네이티브 Compaction, 앱-서버 실행을 담당하도록 하려는 경우에 사용합니다. +OpenClaw는 여전히 채팅 채널, 세션 파일, 모델 선택, 도구, 승인, +미디어 전달, 그리고 사용자에게 보이는 트랜스크립트 미러를 담당합니다. -이 하네스는 기본적으로 꺼져 있습니다. `codex` Plugin이 -활성화되어 있고 해석된 모델이 `codex/*` 모델일 때, 또는 `embeddedHarness.runtime: "codex"`나 `OPENCLAW_AGENT_RUNTIME=codex`를 명시적으로 강제했을 때만 선택됩니다. -`codex/*`를 전혀 구성하지 않으면 기존 PI, OpenAI, Anthropic, Gemini, 로컬, -그리고 custom-provider 실행은 현재 동작을 유지합니다. +하니스는 기본적으로 꺼져 있습니다. `codex` Plugin이 활성화되어 있고 +해결된 모델이 `codex/*` 모델일 때만 선택되며, 또는 +`embeddedHarness.runtime: "codex"`나 `OPENCLAW_AGENT_RUNTIME=codex`를 +명시적으로 강제한 경우에 선택됩니다. +`codex/*`를 전혀 구성하지 않으면, 기존 PI, OpenAI, Anthropic, Gemini, local, +custom-provider 실행은 현재 동작을 그대로 유지합니다. ## 올바른 모델 접두사 선택 -OpenClaw는 OpenAI 접근과 Codex 형태 접근에 대해 별도의 경로를 가집니다: +OpenClaw는 OpenAI 접근과 Codex 형태 접근에 대해 별도의 경로를 가집니다. -| 모델 ref | 런타임 경로 | 사용 시점 | -| ---------------------- | -------------------------------------------- | ----------------------------------------------------------------------- | -| `openai/gpt-5.4` | OpenClaw/PI 경유 OpenAI provider 경로 | `OPENAI_API_KEY`로 직접 OpenAI Platform API에 접근하려는 경우 | -| `openai-codex/gpt-5.4` | PI 경유 OpenAI Codex OAuth provider | Codex app-server 하네스 없이 ChatGPT/Codex OAuth를 사용하려는 경우 | -| `codex/gpt-5.4` | 번들 Codex provider + Codex 하네스 | 임베디드 에이전트 턴에 네이티브 Codex app-server 실행을 사용하려는 경우 | +| 모델 참조 | 런타임 경로 | 사용 시점 | +| ---------------------- | ----------------------------------------- | ----------------------------------------------------------------------- | +| `openai/gpt-5.4` | OpenClaw/PI 플로우를 통한 OpenAI provider | `OPENAI_API_KEY`로 OpenAI Platform API에 직접 접근하려는 경우입니다. | +| `openai-codex/gpt-5.4` | PI를 통한 OpenAI Codex OAuth provider | Codex 앱-서버 하니스 없이 ChatGPT/Codex OAuth를 사용하려는 경우입니다. | +| `codex/gpt-5.4` | 번들된 Codex provider 및 Codex 하니스 | 임베디드 에이전트 턴에 네이티브 Codex 앱-서버 실행을 사용하려는 경우입니다. | -Codex 하네스는 `codex/*` 모델 ref만 처리합니다. 기존 `openai/*`, -`openai-codex/*`, Anthropic, Gemini, xAI, 로컬, 그리고 custom provider ref는 -정상 경로를 그대로 유지합니다. +Codex 하니스는 `codex/*` 모델 참조만 처리합니다. 기존 `openai/*`, +`openai-codex/*`, Anthropic, Gemini, xAI, local, custom provider 참조는 +기존의 일반 경로를 유지합니다. ## 요구 사항 -- 번들 `codex` Plugin을 사용할 수 있는 OpenClaw -- Codex app-server `0.118.0` 이상 -- app-server 프로세스에서 사용할 수 있는 Codex 인증 +- 번들된 `codex` Plugin을 사용할 수 있는 OpenClaw. +- Codex 앱-서버 `0.118.0` 이상. +- 앱-서버 프로세스에서 사용할 수 있는 Codex 인증. -이 Plugin은 더 오래되었거나 버전이 없는 app-server 핸드셰이크를 차단합니다. 이렇게 하면 -OpenClaw가 검증된 프로토콜 surface 위에서만 동작하도록 유지할 수 있습니다. +이 Plugin은 버전이 없거나 더 오래된 앱-서버 핸드셰이크를 차단합니다. +이를 통해 OpenClaw가 검증된 프로토콜 표면에서만 동작하도록 유지합니다. -실제 환경 및 Docker 스모크 테스트에서는 인증이 보통 `OPENAI_API_KEY`와, -선택적으로 `~/.codex/auth.json` 및 -`~/.codex/config.toml` 같은 Codex CLI 파일에서 제공됩니다. 로컬 Codex app-server가 -사용하는 것과 동일한 인증 자료를 사용하세요. +라이브 및 Docker 스모크 테스트에서는 인증이 일반적으로 `OPENAI_API_KEY`와 +선택적 Codex CLI 파일(예: `~/.codex/auth.json`, +`~/.codex/config.toml`)에서 제공됩니다. 로컬 Codex 앱-서버가 사용하는 것과 +같은 인증 자료를 사용하세요. ## 최소 구성 -`codex/gpt-5.4`를 사용하고, 번들 Plugin을 활성화하고, `codex` 하네스를 강제합니다: +`codex/gpt-5.4`를 사용하고, 번들된 Plugin을 활성화하고, `codex` 하니스를 +강제합니다. ```json5 { @@ -82,7 +85,7 @@ OpenClaw가 검증된 프로토콜 surface 위에서만 동작하도록 유지 } ``` -구성에서 `plugins.allow`를 사용한다면, 거기에도 `codex`를 포함하세요: +구성에서 `plugins.allow`를 사용한다면, 거기에도 `codex`를 포함하세요. ```json5 { @@ -97,13 +100,14 @@ OpenClaw가 검증된 프로토콜 surface 위에서만 동작하도록 유지 } ``` -`agents.defaults.model` 또는 에이전트 모델을 `codex/`로 설정하면 -번들 `codex` Plugin도 자동 활성화됩니다. 명시적인 Plugin 항목은 -공유 구성에서 여전히 유용한데, 배포 의도를 더 명확하게 보여주기 때문입니다. +`agents.defaults.model` 또는 에이전트 모델을 `codex/`로 설정해도 +번들된 `codex` Plugin이 자동으로 활성화됩니다. 그래도 명시적인 Plugin 항목은 +공유 구성에서 배포 의도를 분명히 드러내므로 여전히 유용합니다. ## 다른 모델을 대체하지 않고 Codex 추가 -`codex/*` 모델에는 Codex를, 그 외 모든 경우에는 PI를 사용하려면 `runtime: "auto"`를 유지하세요: +`codex/*` 모델에는 Codex를 사용하고, 나머지에는 PI를 사용하려면 +`runtime: "auto"`를 유지하세요. ```json5 { @@ -135,17 +139,17 @@ OpenClaw가 검증된 프로토콜 surface 위에서만 동작하도록 유지 } ``` -이 형태에서는: +이 구성에서는 다음과 같습니다. -- `/model codex` 또는 `/model codex/gpt-5.4`는 Codex app-server 하네스를 사용합니다. +- `/model codex` 또는 `/model codex/gpt-5.4`는 Codex 앱-서버 하니스를 사용합니다. - `/model gpt` 또는 `/model openai/gpt-5.4`는 OpenAI provider 경로를 사용합니다. - `/model opus`는 Anthropic provider 경로를 사용합니다. -- Codex가 아닌 모델이 선택되면 PI가 호환성 하네스로 유지됩니다. +- Codex가 아닌 모델이 선택되면, PI가 호환성 하니스로 유지됩니다. ## Codex 전용 배포 -모든 임베디드 에이전트 턴이 Codex 하네스를 사용한다는 점을 보장해야 한다면 -PI fallback을 비활성화하세요: +모든 임베디드 에이전트 턴이 Codex 하니스를 사용한다는 점을 증명해야 한다면 +PI 폴백을 비활성화하세요. ```json5 { @@ -161,7 +165,7 @@ PI fallback을 비활성화하세요: } ``` -환경 변수 override: +환경 변수 재정의: ```bash OPENCLAW_AGENT_RUNTIME=codex \ @@ -169,14 +173,14 @@ OPENCLAW_AGENT_HARNESS_FALLBACK=none \ openclaw gateway run ``` -fallback이 비활성화되면, `codex` Plugin이 비활성화되어 있거나, -요청한 모델이 `codex/*` ref가 아니거나, app-server가 너무 오래되었거나, -app-server를 시작할 수 없는 경우 OpenClaw는 초기에 실패합니다. +폴백이 비활성화되면, Codex Plugin이 비활성화되어 있거나, +요청된 모델이 `codex/*` 참조가 아니거나, 앱-서버가 너무 오래되었거나, +앱-서버를 시작할 수 없는 경우 OpenClaw는 초기에 실패합니다. ## 에이전트별 Codex -기본 에이전트는 일반 auto-selection을 유지하면서 특정 에이전트 하나만 -Codex 전용으로 만들 수 있습니다: +기본 에이전트는 일반적인 자동 선택을 유지하면서, 특정 에이전트 하나만 +Codex 전용으로 만들 수 있습니다. ```json5 { @@ -207,20 +211,21 @@ Codex 전용으로 만들 수 있습니다: } ``` -일반 세션 명령으로 에이전트와 모델을 전환하세요. `/new`는 새 -OpenClaw 세션을 만들고, Codex 하네스는 필요에 따라 sidecar app-server -스레드를 생성하거나 재개합니다. `/reset`은 해당 스레드에 대한 OpenClaw 세션 바인딩을 지웁니다. +일반적인 세션 명령으로 에이전트와 모델을 전환하세요. `/new`는 새로운 +OpenClaw 세션을 만들고, Codex 하니스는 필요에 따라 해당 사이드카 앱-서버 +스레드를 생성하거나 재개합니다. `/reset`은 해당 스레드에 대한 OpenClaw 세션 +바인딩을 지웁니다. ## 모델 검색 -기본적으로 Codex Plugin은 app-server에 사용 가능한 모델을 요청합니다. 검색이 -실패하거나 시간 초과되면 번들 fallback 카탈로그를 사용합니다: +기본적으로 Codex Plugin은 앱-서버에 사용 가능한 모델을 요청합니다. +검색이 실패하거나 시간 초과되면, 번들된 폴백 카탈로그를 사용합니다. - `codex/gpt-5.4` - `codex/gpt-5.4-mini` - `codex/gpt-5.2` -`plugins.entries.codex.config.discovery` 아래에서 검색을 조정할 수 있습니다: +`plugins.entries.codex.config.discovery` 아래에서 검색 동작을 조정할 수 있습니다. ```json5 { @@ -240,8 +245,7 @@ OpenClaw 세션을 만들고, Codex 하네스는 필요에 따라 sidecar app-se } ``` -시작 시 Codex 프로브를 피하고 -fallback 카탈로그만 사용하려면 검색을 비활성화하세요: +시작 시 Codex 탐지를 피하고 폴백 카탈로그만 사용하려면 검색을 비활성화하세요. ```json5 { @@ -260,17 +264,17 @@ fallback 카탈로그만 사용하려면 검색을 비활성화하세요: } ``` -## App-server 연결 및 정책 +## 앱-서버 연결 및 정책 -기본적으로 Plugin은 다음과 같이 로컬에서 Codex를 시작합니다: +기본적으로 Plugin은 다음과 같이 로컬에서 Codex를 시작합니다. ```bash codex app-server --listen stdio:// ``` -기본적으로 OpenClaw는 Codex에 네이티브 승인을 요청하도록 지시합니다. 이 -정책은 더 세부적으로 조정할 수 있으며, 예를 들어 더 엄격하게 만들고 검토를 -guardian을 통해 라우팅할 수 있습니다: +기본적으로 OpenClaw는 Codex에 네이티브 승인을 요청하도록 지시합니다. +예를 들어 정책을 더 엄격하게 하고 검토를 guardian으로 라우팅하는 등, +이 정책을 추가로 조정할 수 있습니다. ```json5 { @@ -292,7 +296,7 @@ guardian을 통해 라우팅할 수 있습니다: } ``` -이미 실행 중인 app-server에는 WebSocket 전송을 사용하세요: +이미 실행 중인 앱-서버에는 WebSocket 전송을 사용하세요. ```json5 { @@ -316,22 +320,22 @@ guardian을 통해 라우팅할 수 있습니다: 지원되는 `appServer` 필드: -| 필드 | 기본값 | 의미 | +| 필드 | 기본값 | 의미 | | ------------------- | ---------------------------------------- | ------------------------------------------------------------------------ | -| `transport` | `"stdio"` | `"stdio"`는 Codex를 시작하고, `"websocket"`은 `url`에 연결합니다. | -| `command` | `"codex"` | stdio 전송용 실행 파일 | -| `args` | `["app-server", "--listen", "stdio://"]` | stdio 전송용 인수 | -| `url` | unset | WebSocket app-server URL | -| `authToken` | unset | WebSocket 전송용 Bearer 토큰 | -| `headers` | `{}` | 추가 WebSocket 헤더 | -| `requestTimeoutMs` | `60000` | app-server control-plane 호출 시간 제한 | -| `approvalPolicy` | `"on-request"` | 스레드 시작/재개/턴에 전송되는 네이티브 Codex 승인 정책 | -| `sandbox` | `"workspace-write"` | 스레드 시작/재개 시 전송되는 네이티브 Codex 샌드박스 모드 | -| `approvalsReviewer` | `"user"` | 네이티브 승인을 Codex guardian이 검토하게 하려면 `"guardian_subagent"` 사용 | -| `serviceTier` | unset | 선택적 Codex 서비스 계층, 예: `"priority"` | +| `transport` | `"stdio"` | `"stdio"`는 Codex를 시작하고, `"websocket"`은 `url`에 연결합니다. | +| `command` | `"codex"` | stdio 전송용 실행 파일입니다. | +| `args` | `["app-server", "--listen", "stdio://"]` | stdio 전송용 인수입니다. | +| `url` | unset | WebSocket 앱-서버 URL입니다. | +| `authToken` | unset | WebSocket 전송용 Bearer 토큰입니다. | +| `headers` | `{}` | 추가 WebSocket 헤더입니다. | +| `requestTimeoutMs` | `60000` | 앱-서버 제어 플레인 호출의 시간 초과입니다. | +| `approvalPolicy` | `"on-request"` | 스레드 시작/재개/턴 시 전송되는 네이티브 Codex 승인 정책입니다. | +| `sandbox` | `"workspace-write"` | 스레드 시작/재개 시 전송되는 네이티브 Codex 샌드박스 모드입니다. | +| `approvalsReviewer` | `"user"` | Codex guardian이 네이티브 승인을 검토하도록 하려면 `"guardian_subagent"`를 사용합니다. | +| `serviceTier` | unset | 선택적 Codex 서비스 등급입니다. 예: `"priority"`. | -기존 환경 변수도 일치하는 구성 필드가 설정되지 않은 경우 -로컬 테스트용 fallback으로 계속 작동합니다: +이전 환경 변수도, 일치하는 구성 필드가 설정되지 않은 경우 로컬 테스트용 폴백으로 +계속 사용할 수 있습니다. - `OPENCLAW_CODEX_APP_SERVER_BIN` - `OPENCLAW_CODEX_APP_SERVER_ARGS` @@ -339,7 +343,7 @@ guardian을 통해 라우팅할 수 있습니다: - `OPENCLAW_CODEX_APP_SERVER_SANDBOX` - `OPENCLAW_CODEX_APP_SERVER_GUARDIAN=1` -반복 가능한 배포에는 구성이 더 적합합니다. +반복 가능한 배포를 위해서는 구성을 사용하는 것이 좋습니다. ## 일반적인 레시피 @@ -357,7 +361,7 @@ guardian을 통해 라우팅할 수 있습니다: } ``` -PI fallback이 비활성화된 Codex 전용 하네스 검증: +PI 폴백을 비활성화한 Codex 전용 하니스 검증: ```json5 { @@ -395,7 +399,7 @@ guardian이 검토하는 Codex 승인: } ``` -명시적 헤더를 사용하는 원격 app-server: +명시적 헤더를 사용하는 원격 앱-서버: ```json5 { @@ -418,78 +422,85 @@ guardian이 검토하는 Codex 승인: } ``` -모델 전환은 계속 OpenClaw가 제어합니다. OpenClaw 세션이 -기존 Codex 스레드에 연결된 경우, 다음 턴은 현재 선택된 -`codex/*` 모델, provider, 승인 정책, 샌드박스, 그리고 서비스 계층을 다시 -app-server로 전송합니다. `codex/gpt-5.4`에서 `codex/gpt-5.2`로 전환해도 -스레드 바인딩은 유지되지만, Codex에는 새로 선택된 모델로 계속 진행하라고 요청합니다. +모델 전환은 계속 OpenClaw가 제어합니다. OpenClaw 세션이 기존 Codex 스레드에 +연결되어 있을 때, 다음 턴은 현재 선택된 `codex/*` 모델, provider, 승인 정책, +sandbox, service tier를 다시 앱-서버로 보냅니다. +`codex/gpt-5.4`에서 `codex/gpt-5.2`로 전환하면 스레드 바인딩은 유지되지만, +Codex에는 새로 선택된 모델로 계속 진행하도록 요청합니다. ## Codex 명령 -번들 Plugin은 인증된 슬래시 명령으로 `/codex`를 등록합니다. 이 명령은 -범용이며 OpenClaw 텍스트 명령을 지원하는 모든 채널에서 동작합니다. +번들된 Plugin은 `/codex`를 승인된 슬래시 명령으로 등록합니다. +이는 일반적이며 OpenClaw 텍스트 명령을 지원하는 모든 채널에서 동작합니다. -일반적인 형태: +일반적인 형식: -- `/codex status`는 app-server 실시간 연결 상태, 모델, account, rate limit, MCP 서버, 그리고 Skills를 표시합니다. -- `/codex models`는 실시간 Codex app-server 모델을 나열합니다. +- `/codex status`는 실시간 앱-서버 연결 상태, 모델, 계정, rate limit, MCP 서버, Skills를 표시합니다. +- `/codex models`는 실시간 Codex 앱-서버 모델 목록을 표시합니다. - `/codex threads [filter]`는 최근 Codex 스레드를 나열합니다. - `/codex resume `는 현재 OpenClaw 세션을 기존 Codex 스레드에 연결합니다. -- `/codex compact`는 Codex app-server에 연결된 스레드의 Compaction을 요청합니다. +- `/codex compact`는 연결된 스레드에 대해 Codex 앱-서버에 Compaction을 요청합니다. - `/codex review`는 연결된 스레드에 대해 Codex 네이티브 검토를 시작합니다. -- `/codex account`는 account 및 rate-limit 상태를 표시합니다. -- `/codex mcp`는 Codex app-server MCP 서버 상태를 나열합니다. -- `/codex skills`는 Codex app-server Skills를 나열합니다. +- `/codex account`는 계정 및 rate-limit 상태를 표시합니다. +- `/codex mcp`는 Codex 앱-서버 MCP 서버 상태를 나열합니다. +- `/codex skills`는 Codex 앱-서버 Skills를 나열합니다. -`/codex resume`는 하네스가 일반 턴에 사용하는 것과 동일한 sidecar 바인딩 파일을 기록합니다. -다음 메시지에서 OpenClaw는 해당 Codex 스레드를 재개하고, 현재 선택된 OpenClaw `codex/*` 모델을 app-server에 전달하며, -확장 기록을 계속 활성화된 상태로 유지합니다. +`/codex resume`는 하니스가 일반 턴에 사용하는 것과 동일한 사이드카 바인딩 파일을 +씁니다. 다음 메시지에서 OpenClaw는 해당 Codex 스레드를 재개하고, 현재 선택된 +OpenClaw `codex/*` 모델을 앱-서버에 전달하며, 확장된 기록을 계속 활성화된 +상태로 유지합니다. -이 명령 surface는 Codex app-server `0.118.0` 이상이 필요합니다. 개별 -제어 메서드는 미래 버전 또는 custom app-server가 해당 JSON-RPC 메서드를 노출하지 않는 경우 +이 명령 표면은 Codex 앱-서버 `0.118.0` 이상이 필요합니다. 향후 버전 또는 +커스텀 앱-서버가 해당 JSON-RPC 메서드를 노출하지 않는 경우, 개별 제어 메서드는 `unsupported by this Codex app-server`로 보고됩니다. -## 도구, 미디어, 그리고 Compaction +## 도구, 미디어, Compaction -Codex 하네스는 하위 수준 임베디드 에이전트 실행기만 변경합니다. +Codex 하니스는 저수준 임베디드 에이전트 실행기만 변경합니다. -OpenClaw는 여전히 도구 목록을 구성하고 하네스로부터 동적 도구 결과를 받습니다. -텍스트, 이미지, 비디오, 음악, TTS, 승인, 그리고 메시징 도구 출력은 -계속 일반 OpenClaw 전달 경로를 통해 처리됩니다. +OpenClaw는 여전히 도구 목록을 만들고 하니스로부터 동적 도구 결과를 받습니다. +텍스트, 이미지, 비디오, 음악, TTS, 승인, 메시징 도구 출력은 계속해서 일반적인 +OpenClaw 전달 경로를 통해 처리됩니다. -선택된 모델이 Codex 하네스를 사용할 때, 네이티브 스레드 Compaction은 -Codex app-server에 위임됩니다. OpenClaw는 채널 기록, 검색, `/new`, `/reset`, -그리고 향후 모델 또는 하네스 전환을 위해 transcript 미러를 유지합니다. 이 -미러에는 사용자 프롬프트, 최종 assistant 텍스트, 그리고 app-server가 이를 내보낼 경우 -가벼운 Codex 추론 또는 계획 기록이 포함됩니다. +선택된 모델이 Codex 하니스를 사용하는 경우, 네이티브 스레드 Compaction은 +Codex 앱-서버에 위임됩니다. OpenClaw는 채널 기록, 검색, `/new`, `/reset`, +그리고 향후 모델 또는 하니스 전환을 위해 트랜스크립트 미러를 유지합니다. +이 미러에는 사용자 프롬프트, 최종 어시스턴트 텍스트, 그리고 앱-서버가 이를 +내보낼 때 경량 Codex 추론 또는 계획 기록이 포함됩니다. -미디어 생성에는 PI가 필요하지 않습니다. 이미지, 비디오, 음악, PDF, TTS, 그리고 미디어 -이해는 계속 `agents.defaults.imageGenerationModel`, `videoGenerationModel`, `pdfModel`, -그리고 `messages.tts` 같은 해당 provider/모델 설정을 사용합니다. +미디어 생성에는 PI가 필요하지 않습니다. 이미지, 비디오, 음악, PDF, TTS, +미디어 이해는 계속해서 `agents.defaults.imageGenerationModel`, +`videoGenerationModel`, `pdfModel`, `messages.tts` 같은 해당 provider/모델 +설정을 사용합니다. ## 문제 해결 -**`/model`에 Codex가 표시되지 않음:** `plugins.entries.codex.enabled`를 활성화하고, -`codex/*` 모델 ref를 설정하거나, `plugins.allow`가 `codex`를 제외하고 있는지 확인하세요. +**`/model`에 Codex가 표시되지 않음:** `plugins.entries.codex.enabled`를 +활성화하고, `codex/*` 모델 참조를 설정하거나, `plugins.allow`에서 `codex`가 +제외되어 있는지 확인하세요. -**OpenClaw가 PI로 fallback함:** 테스트 중에는 `embeddedHarness.fallback: "none"` 또는 -`OPENCLAW_AGENT_HARNESS_FALLBACK=none`을 설정하세요. +**OpenClaw가 Codex 대신 PI를 사용함:** Codex 하니스가 실행을 처리하지 않으면, +OpenClaw는 호환성 백엔드로 PI를 사용할 수 있습니다. 테스트 중 Codex 선택을 +강제하려면 `embeddedHarness.runtime: "codex"`를 설정하고, 일치하는 Plugin +하니스가 없을 때 실패하게 하려면 `embeddedHarness.fallback: "none"`을 +설정하세요. Codex 앱-서버가 선택되면, 해당 실패는 추가 폴백 구성 없이 직접 +표면화됩니다. -**app-server가 거부됨:** app-server 핸드셰이크가 -버전 `0.118.0` 이상을 보고하도록 Codex를 업그레이드하세요. +**앱-서버가 거부됨:** 앱-서버 핸드셰이크가 버전 `0.118.0` 이상을 보고하도록 +Codex를 업그레이드하세요. -**모델 검색이 느림:** `plugins.entries.codex.config.discovery.timeoutMs`를 낮추거나 -검색을 비활성화하세요. +**모델 검색이 느림:** `plugins.entries.codex.config.discovery.timeoutMs`를 +낮추거나 검색을 비활성화하세요. -**WebSocket 전송이 즉시 실패함:** `appServer.url`, `authToken`, -그리고 원격 app-server가 동일한 Codex app-server 프로토콜 버전을 사용하는지 확인하세요. +**WebSocket 전송이 즉시 실패함:** `appServer.url`, `authToken`, 그리고 원격 +앱-서버가 동일한 Codex 앱-서버 프로토콜 버전을 사용하는지 확인하세요. -**Codex가 아닌 모델이 PI를 사용함:** 이는 예상된 동작입니다. Codex 하네스는 -`codex/*` 모델 ref만 처리합니다. +**Codex가 아닌 모델이 PI를 사용함:** 이는 예상된 동작입니다. Codex 하니스는 +`codex/*` 모델 참조만 처리합니다. ## 관련 항목 -- [Agent Harness Plugins](/ko/plugins/sdk-agent-harness) -- [Model Providers](/ko/concepts/model-providers) -- [Configuration Reference](/ko/gateway/configuration-reference) -- [Testing](/ko/help/testing#live-codex-app-server-harness-smoke) +- [에이전트 하니스 Plugin](/ko/plugins/sdk-agent-harness) +- [모델 provider](/ko/concepts/model-providers) +- [구성 참조](/ko/gateway/configuration-reference) +- [테스트](/ko/help/testing#live-codex-app-server-harness-smoke) diff --git a/docs/ko/plugins/manifest.md b/docs/ko/plugins/manifest.md index d6ebffbc8..ef0386492 100644 --- a/docs/ko/plugins/manifest.md +++ b/docs/ko/plugins/manifest.md @@ -1,76 +1,75 @@ --- read_when: - OpenClaw Plugin을 빌드하고 있습니다 - - Plugin 구성 스키마를 제공하거나 Plugin 검증 오류를 디버깅해야 합니다 + - Plugin 구성 스키마를 배포하거나 Plugin 검증 오류를 디버그해야 합니다 summary: Plugin 매니페스트 + JSON 스키마 요구 사항(엄격한 구성 검증) title: Plugin 매니페스트 x-i18n: - generated_at: "2026-04-22T04:24:10Z" + generated_at: "2026-04-22T06:00:34Z" model: gpt-5.4 provider: openai - source_hash: 52a52f7e2c78bbef2cc51ade6eb12b6edc950237bdfc478f6e82248374c687bf + source_hash: b80735690799682939e8c8c27b6a364caa3ceadcf6319155ddeb20eb0538c313 source_path: plugins/manifest.md workflow: 15 --- # Plugin 매니페스트 (`openclaw.plugin.json`) -이 페이지는 **기본 OpenClaw Plugin 매니페스트**만 다룹니다. +이 페이지는 **네이티브 OpenClaw Plugin 매니페스트**만을 다룹니다. -호환되는 번들 레이아웃은 [Plugin bundles](/ko/plugins/bundles)를 참조하세요. +호환 번들 레이아웃은 [Plugin 번들](/ko/plugins/bundles)을 참조하세요. -호환되는 번들 형식은 서로 다른 매니페스트 파일을 사용합니다: +호환 번들 형식은 서로 다른 매니페스트 파일을 사용합니다. -- Codex bundle: `.codex-plugin/plugin.json` -- Claude bundle: `.claude-plugin/plugin.json` 또는 매니페스트가 없는 기본 Claude 컴포넌트 +- Codex 번들: `.codex-plugin/plugin.json` +- Claude 번들: `.claude-plugin/plugin.json` 또는 매니페스트가 없는 기본 Claude 컴포넌트 레이아웃 -- Cursor bundle: `.cursor-plugin/plugin.json` +- Cursor 번들: `.cursor-plugin/plugin.json` OpenClaw는 이러한 번들 레이아웃도 자동 감지하지만, 여기서 설명하는 -`openclaw.plugin.json` 스키마에 대해 검증되지는 않습니다. +`openclaw.plugin.json` 스키마를 기준으로 검증되지는 않습니다. -호환 번들의 경우, OpenClaw는 현재 번들 메타데이터와 선언된 -skill 루트, Claude 명령 루트, Claude 번들 `settings.json` 기본값, -Claude 번들 LSP 기본값, 그리고 레이아웃이 OpenClaw 런타임 기대와 일치할 때 -지원되는 hook pack을 읽습니다. +호환 번들의 경우, OpenClaw는 현재 레이아웃이 OpenClaw 런타임 기대사항과 일치하면 +번들 메타데이터와 선언된 skill 루트, Claude 명령 루트, Claude 번들 +`settings.json` 기본값, Claude 번들 LSP 기본값, 지원되는 hook pack을 읽습니다. -모든 기본 OpenClaw Plugin은 **반드시** **Plugin 루트**에 `openclaw.plugin.json` -파일을 포함해야 합니다. OpenClaw는 이 매니페스트를 사용해 Plugin 코드를 **실행하지 않고도** -구성을 검증합니다. 매니페스트가 없거나 유효하지 않으면 Plugin 오류로 처리되며 -구성 검증이 차단됩니다. +모든 네이티브 OpenClaw Plugin은 **반드시** +**Plugin 루트**에 `openclaw.plugin.json` 파일을 포함해야 합니다. OpenClaw는 이 매니페스트를 사용해 +**Plugin 코드를 실행하지 않고도** 구성을 검증합니다. 매니페스트가 없거나 유효하지 않으면 +Plugin 오류로 처리되며 구성 검증이 차단됩니다. 전체 Plugin 시스템 가이드는 [Plugins](/ko/tools/plugin)를 참조하세요. -기본 capability 모델과 현재 외부 호환성 가이드는 -[Capability model](/ko/plugins/architecture#public-capability-model)을 참조하세요. +네이티브 capability 모델과 현재 외부 호환성 지침은 +[Capability 모델](/ko/plugins/architecture#public-capability-model)을 참조하세요. -## 이 파일의 역할 +## 이 파일이 하는 일 `openclaw.plugin.json`은 OpenClaw가 Plugin 코드를 로드하기 전에 읽는 메타데이터입니다. -다음 용도로 사용하세요: +용도는 다음과 같습니다. -- Plugin ID +- Plugin 식별 - 구성 검증 - Plugin 런타임을 부팅하지 않고도 사용할 수 있어야 하는 인증 및 온보딩 메타데이터 -- 런타임이 로드되기 전에 제어 플레인 표면이 검사할 수 있는 저비용 활성화 힌트 -- 런타임이 로드되기 전에 설정/온보딩 표면이 검사할 수 있는 저비용 설정 설명자 -- Plugin 런타임이 로드되기 전에 확인되어야 하는 별칭 및 자동 활성화 메타데이터 -- 런타임이 로드되기 전에 Plugin을 자동 활성화해야 하는 축약형 모델 패밀리 소유 메타데이터 -- 번들 호환 wiring 및 계약 커버리지에 사용되는 정적 capability 소유 스냅샷 -- 공유 `openclaw qa` 호스트가 Plugin 런타임을 로드하기 전에 검사할 수 있는 저비용 QA 러너 메타데이터 -- 런타임을 로드하지 않고 카탈로그 및 검증 표면에 병합되어야 하는 채널별 구성 메타데이터 +- 제어면 표면이 런타임 로드 전에 확인할 수 있는 저비용 활성화 힌트 +- 설정/온보딩 표면이 런타임 로드 전에 확인할 수 있는 저비용 설정 설명자 +- Plugin 런타임 로드 전에 해석되어야 하는 별칭 및 자동 활성화 메타데이터 +- 런타임 로드 전에 Plugin을 자동 활성화해야 하는 축약형 모델 패밀리 소유 메타데이터 +- 번들된 호환 wiring 및 계약 커버리지에 사용되는 정적 capability 소유 스냅샷 +- 공유 `openclaw qa` 호스트가 Plugin 런타임 로드 전에 확인할 수 있는 저비용 QA 러너 메타데이터 +- 런타임을 로드하지 않고도 카탈로그 및 검증 표면에 병합되어야 하는 채널별 구성 메타데이터 - 구성 UI 힌트 -다음 용도로는 사용하지 마세요: +다음 용도로는 사용하지 마세요. - 런타임 동작 등록 -- 코드 entrypoint 선언 +- 코드 엔트리포인트 선언 - npm 설치 메타데이터 이들은 Plugin 코드와 `package.json`에 속합니다. -## 최소 예시 +## 최소 예제 ```json { @@ -83,13 +82,13 @@ Claude 번들 LSP 기본값, 그리고 레이아웃이 OpenClaw 런타임 기대 } ``` -## 확장 예시 +## 확장 예제 ```json { "id": "openrouter", "name": "OpenRouter", - "description": "OpenRouter provider Plugin", + "description": "OpenRouter provider plugin", "version": "1.0.0", "providers": ["openrouter"], "modelSupport": { @@ -117,13 +116,13 @@ Claude 번들 LSP 기본값, 그리고 레이아웃이 OpenClaw 런타임 기대 "provider": "openrouter", "method": "api-key", "choiceId": "openrouter-api-key", - "choiceLabel": "OpenRouter API 키", + "choiceLabel": "OpenRouter API key", "groupId": "openrouter", "groupLabel": "OpenRouter", "optionKey": "openrouterApiKey", "cliFlag": "--openrouter-api-key", "cliOption": "--openrouter-api-key ", - "cliDescription": "OpenRouter API 키", + "cliDescription": "OpenRouter API key", "onboardingScopes": ["text-inference"] } ], @@ -148,66 +147,67 @@ Claude 번들 LSP 기본값, 그리고 레이아웃이 OpenClaw 런타임 기대 ## 최상위 필드 참조 -| 필드 | 필수 여부 | 타입 | 의미 | -| ---------------------------------- | --------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -| `id` | 예 | `string` | 정식 Plugin ID입니다. 이 ID는 `plugins.entries.`에서 사용됩니다. | -| `configSchema` | 예 | `object` | 이 Plugin 구성용 인라인 JSON 스키마입니다. | -| `enabledByDefault` | 아니요 | `true` | 번들 Plugin이 기본적으로 활성화됨을 표시합니다. 생략하거나 `true`가 아닌 값을 설정하면 Plugin은 기본적으로 비활성화된 상태로 유지됩니다. | -| `legacyPluginIds` | 아니요 | `string[]` | 이 정식 Plugin ID로 정규화되는 레거시 ID입니다. | -| `autoEnableWhenConfiguredProviders`| 아니요 | `string[]` | 인증, 구성 또는 모델 참조에서 이 provider ID가 언급될 때 이 Plugin을 자동 활성화해야 하는 경우를 지정합니다. | -| `kind` | 아니요 | `"memory"` \| `"context-engine"` | `plugins.slots.*`에서 사용되는 배타적 Plugin 종류를 선언합니다. | -| `channels` | 아니요 | `string[]` | 이 Plugin이 소유한 채널 ID입니다. 탐지 및 구성 검증에 사용됩니다. | -| `providers` | 아니요 | `string[]` | 이 Plugin이 소유한 provider ID입니다. | -| `modelSupport` | 아니요 | `object` | 런타임 전에 Plugin을 자동 로드하는 데 사용되는 매니페스트 소유 축약형 모델 패밀리 메타데이터입니다. | -| `providerEndpoints` | 아니요 | `object[]` | 코어가 provider 런타임이 로드되기 전에 분류해야 하는 provider 경로용 매니페스트 소유 endpoint host/baseUrl 메타데이터입니다. | -| `cliBackends` | 아니요 | `string[]` | 이 Plugin이 소유한 CLI 추론 백엔드 ID입니다. 명시적 구성 참조에서 시작 시 자동 활성화하는 데 사용됩니다. | -| `syntheticAuthRefs` | 아니요 | `string[]` | 런타임이 로드되기 전에 cold 모델 탐색 중 Plugin 소유 synthetic 인증 hook를 프로브해야 하는 provider 또는 CLI backend 참조입니다. | -| `nonSecretAuthMarkers` | 아니요 | `string[]` | 비밀이 아닌 로컬, OAuth 또는 주변 자격 증명 상태를 나타내는 번들 Plugin 소유 placeholder API 키 값입니다. | -| `commandAliases` | 아니요 | `object[]` | 런타임이 로드되기 전에 Plugin 인식 구성 및 CLI 진단을 생성해야 하는, 이 Plugin이 소유한 명령 이름입니다. | -| `providerAuthEnvVars` | 아니요 | `Record` | OpenClaw가 Plugin 코드를 로드하지 않고도 검사할 수 있는 저비용 provider 인증 env 메타데이터입니다. | -| `providerAuthAliases` | 아니요 | `Record` | 인증 조회에 다른 provider ID를 재사용해야 하는 provider ID입니다. 예: 기본 provider API 키와 인증 프로필을 공유하는 coding provider. | -| `channelEnvVars` | 아니요 | `Record` | OpenClaw가 Plugin 코드를 로드하지 않고도 검사할 수 있는 저비용 채널 env 메타데이터입니다. env 기반 채널 설정이나 일반적인 시작/구성 helper가 확인해야 하는 인증 표면에는 이것을 사용하세요. | -| `providerAuthChoices` | 아니요 | `object[]` | 온보딩 선택기, 선호 provider 확인, 단순 CLI 플래그 wiring을 위한 저비용 인증 선택 메타데이터입니다. | -| `activation` | 아니요 | `object` | provider, 명령, 채널, 경로, capability 트리거 로드를 위한 저비용 활성화 힌트입니다. 메타데이터 전용이며, 실제 동작은 여전히 Plugin 런타임이 소유합니다. | -| `setup` | 아니요 | `object` | 탐색 및 설정 표면이 Plugin 런타임을 로드하지 않고도 검사할 수 있는 저비용 설정/온보딩 설명자입니다. | -| `qaRunners` | 아니요 | `object[]` | 공유 `openclaw qa` 호스트가 Plugin 런타임이 로드되기 전에 사용하는 저비용 QA 러너 설명자입니다. | -| `contracts` | 아니요 | `object` | 음성, 실시간 전사, 실시간 음성, 미디어 이해, 이미지 생성, 음악 생성, 비디오 생성, 웹 가져오기, 웹 검색, 도구 소유권을 위한 정적 번들 capability 스냅샷입니다. | -| `channelConfigs` | 아니요 | `Record` | 런타임이 로드되기 전에 탐색 및 검증 표면에 병합되는 매니페스트 소유 채널 구성 메타데이터입니다. | -| `skills` | 아니요 | `string[]` | Plugin 루트를 기준으로 한, 로드할 skill 디렉터리입니다. | -| `name` | 아니요 | `string` | 사람이 읽을 수 있는 Plugin 이름입니다. | -| `description` | 아니요 | `string` | Plugin 표면에 표시되는 짧은 요약입니다. | -| `version` | 아니요 | `string` | 정보 제공용 Plugin 버전입니다. | -| `uiHints` | 아니요 | `Record` | 구성 필드용 UI 라벨, placeholder, 민감도 힌트입니다. | +| 필드 | 필수 여부 | 유형 | 의미 | +| ------------------------------------ | --------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `id` | 예 | `string` | 정식 Plugin ID입니다. `plugins.entries.`에서 사용하는 ID입니다. | +| `configSchema` | 예 | `object` | 이 Plugin 구성에 대한 인라인 JSON 스키마입니다. | +| `enabledByDefault` | 아니요 | `true` | 번들된 Plugin을 기본적으로 활성화된 상태로 표시합니다. Plugin을 기본 비활성 상태로 두려면 이 필드를 생략하거나 `true`가 아닌 값을 설정하세요. | +| `legacyPluginIds` | 아니요 | `string[]` | 이 정식 Plugin ID로 정규화되는 레거시 ID입니다. | +| `autoEnableWhenConfiguredProviders` | 아니요 | `string[]` | 인증, 구성 또는 모델 참조에서 이들을 언급할 때 이 Plugin을 자동 활성화해야 하는 provider ID입니다. | +| `kind` | 아니요 | `"memory"` \| `"context-engine"` | `plugins.slots.*`에서 사용되는 배타적 Plugin 종류를 선언합니다. | +| `channels` | 아니요 | `string[]` | 이 Plugin이 소유하는 채널 ID입니다. 검색 및 구성 검증에 사용됩니다. | +| `providers` | 아니요 | `string[]` | 이 Plugin이 소유하는 provider ID입니다. | +| `modelSupport` | 아니요 | `object` | 런타임 전에 Plugin을 자동 로드하는 데 사용되는, 매니페스트 소유의 축약형 모델 패밀리 메타데이터입니다. | +| `providerEndpoints` | 아니요 | `object[]` | provider 런타임이 로드되기 전에 코어가 분류해야 하는 provider 경로용, 매니페스트 소유의 endpoint host/baseUrl 메타데이터입니다. | +| `cliBackends` | 아니요 | `string[]` | 이 Plugin이 소유하는 CLI 추론 백엔드 ID입니다. 명시적 구성 참조로부터 시작 시 자동 활성화하는 데 사용됩니다. | +| `syntheticAuthRefs` | 아니요 | `string[]` | 런타임이 로드되기 전에 콜드 모델 검색 중 Plugin 소유의 synthetic auth hook을 프로브해야 하는 provider 또는 CLI 백엔드 참조입니다. | +| `nonSecretAuthMarkers` | 아니요 | `string[]` | 비밀이 아닌 local, OAuth 또는 ambient credential 상태를 나타내는, 번들된 Plugin 소유의 플레이스홀더 API 키 값입니다. | +| `commandAliases` | 아니요 | `object[]` | 런타임이 로드되기 전에 Plugin 인지형 구성 및 CLI 진단을 생성해야 하는, 이 Plugin이 소유하는 명령 이름입니다. | +| `providerAuthEnvVars` | 아니요 | `Record` | OpenClaw가 Plugin 코드를 로드하지 않고도 확인할 수 있는 저비용 provider 인증 env 메타데이터입니다. | +| `providerAuthAliases` | 아니요 | `Record` | 다른 provider ID를 인증 조회에 재사용해야 하는 provider ID입니다. 예를 들어 기본 provider API 키와 인증 프로필을 공유하는 coding provider가 이에 해당합니다. | +| `channelEnvVars` | 아니요 | `Record` | OpenClaw가 Plugin 코드를 로드하지 않고도 확인할 수 있는 저비용 채널 env 메타데이터입니다. 일반적인 시작/구성 헬퍼가 확인해야 하는 env 기반 채널 설정 또는 인증 표면에 사용하세요. | +| `providerAuthChoices` | 아니요 | `object[]` | 온보딩 선택기, 선호 provider 결정, 단순 CLI 플래그 연결을 위한 저비용 인증 선택 메타데이터입니다. | +| `activation` | 아니요 | `object` | provider, 명령, 채널, 경로 및 capability 트리거 로딩을 위한 저비용 활성화 힌트입니다. 메타데이터 전용이며, 실제 동작은 여전히 Plugin 런타임이 소유합니다. | +| `setup` | 아니요 | `object` | Plugin 런타임을 로드하지 않고도 검색 및 설정 표면이 확인할 수 있는 저비용 설정/온보딩 설명자입니다. | +| `qaRunners` | 아니요 | `object[]` | Plugin 런타임이 로드되기 전에 공유 `openclaw qa` 호스트가 사용하는 저비용 QA 러너 설명자입니다. | +| `contracts` | 아니요 | `object` | 음성, 실시간 전사, 실시간 음성, 미디어 이해, 이미지 생성, 음악 생성, 비디오 생성, 웹 가져오기, 웹 검색, 도구 소유권에 대한 정적 번들 capability 스냅샷입니다. | +| `mediaUnderstandingProviderMetadata` | 아니요 | `Record` | `contracts.mediaUnderstandingProviders`에 선언된 provider ID를 위한 저비용 미디어 이해 기본값입니다. | +| `channelConfigs` | 아니요 | `Record` | 런타임이 로드되기 전에 검색 및 검증 표면에 병합되는, 매니페스트 소유의 채널 구성 메타데이터입니다. | +| `skills` | 아니요 | `string[]` | Plugin 루트를 기준으로 한 Skills 디렉터리입니다. | +| `name` | 아니요 | `string` | 사람이 읽을 수 있는 Plugin 이름입니다. | +| `description` | 아니요 | `string` | Plugin 표면에 표시되는 짧은 요약입니다. | +| `version` | 아니요 | `string` | 정보 제공용 Plugin 버전입니다. | +| `uiHints` | 아니요 | `Record` | 구성 필드를 위한 UI 레이블, 플레이스홀더, 민감도 힌트입니다. | -## providerAuthChoices 참조 +## `providerAuthChoices` 참조 각 `providerAuthChoices` 항목은 하나의 온보딩 또는 인증 선택을 설명합니다. OpenClaw는 provider 런타임이 로드되기 전에 이를 읽습니다. -| 필드 | 필수 여부 | 타입 | 의미 | -| -------------------- | --------- | ----------------------------------------------- | --------------------------------------------------------------------------------------------------------- | -| `provider` | 예 | `string` | 이 선택이 속한 provider ID입니다. | -| `method` | 예 | `string` | 디스패치할 인증 메서드 ID입니다. | -| `choiceId` | 예 | `string` | 온보딩 및 CLI 흐름에서 사용하는 안정적인 인증 선택 ID입니다. | -| `choiceLabel` | 아니요 | `string` | 사용자에게 표시되는 라벨입니다. 생략하면 OpenClaw는 `choiceId`로 폴백합니다. | -| `choiceHint` | 아니요 | `string` | 선택기용 짧은 도움말 텍스트입니다. | -| `assistantPriority` | 아니요 | `number` | assistant 기반 인터랙티브 선택기에서 값이 낮을수록 먼저 정렬됩니다. | -| `assistantVisibility`| 아니요 | `"visible"` \| `"manual-only"` | assistant 선택기에서는 이 선택을 숨기되, 수동 CLI 선택은 계속 허용합니다. | -| `deprecatedChoiceIds`| 아니요 | `string[]` | 사용자를 이 대체 선택으로 리디렉션해야 하는 레거시 선택 ID입니다. | -| `groupId` | 아니요 | `string` | 관련 선택을 그룹화하기 위한 선택적 그룹 ID입니다. | -| `groupLabel` | 아니요 | `string` | 해당 그룹의 사용자 대상 라벨입니다. | -| `groupHint` | 아니요 | `string` | 그룹용 짧은 도움말 텍스트입니다. | -| `optionKey` | 아니요 | `string` | 단일 플래그 기반의 단순 인증 흐름용 내부 옵션 키입니다. | -| `cliFlag` | 아니요 | `string` | `--openrouter-api-key` 같은 CLI 플래그 이름입니다. | -| `cliOption` | 아니요 | `string` | `--openrouter-api-key ` 같은 전체 CLI 옵션 형태입니다. | -| `cliDescription` | 아니요 | `string` | CLI 도움말에 사용되는 설명입니다. | -| `onboardingScopes` | 아니요 | `Array<"text-inference" \| "image-generation">` | 이 선택이 표시되어야 하는 온보딩 표면입니다. 생략하면 기본값은 `["text-inference"]`입니다. | +| 필드 | 필수 여부 | 유형 | 의미 | +| -------------------- | --------- | ----------------------------------------------- | ----------------------------------------------------------------------------------------------------- | +| `provider` | 예 | `string` | 이 선택이 속한 provider ID입니다. | +| `method` | 예 | `string` | 디스패치할 인증 방식 ID입니다. | +| `choiceId` | 예 | `string` | 온보딩 및 CLI 흐름에서 사용하는 안정적인 auth-choice ID입니다. | +| `choiceLabel` | 아니요 | `string` | 사용자에게 표시되는 레이블입니다. 생략하면 OpenClaw는 `choiceId`를 대신 사용합니다. | +| `choiceHint` | 아니요 | `string` | 선택기에 표시되는 짧은 도움말 텍스트입니다. | +| `assistantPriority` | 아니요 | `number` | assistant 기반 대화형 선택기에서 값이 낮을수록 먼저 정렬됩니다. | +| `assistantVisibility`| 아니요 | `"visible"` \| `"manual-only"` | assistant 선택기에서는 이 선택을 숨기되, 수동 CLI 선택은 계속 허용합니다. | +| `deprecatedChoiceIds`| 아니요 | `string[]` | 사용자를 이 대체 선택으로 리디렉션해야 하는 레거시 choice ID입니다. | +| `groupId` | 아니요 | `string` | 관련 선택을 묶기 위한 선택적 그룹 ID입니다. | +| `groupLabel` | 아니요 | `string` | 해당 그룹의 사용자 표시용 레이블입니다. | +| `groupHint` | 아니요 | `string` | 그룹용 짧은 도움말 텍스트입니다. | +| `optionKey` | 아니요 | `string` | 단일 플래그 기반의 단순 인증 흐름을 위한 내부 옵션 키입니다. | +| `cliFlag` | 아니요 | `string` | `--openrouter-api-key`와 같은 CLI 플래그 이름입니다. | +| `cliOption` | 아니요 | `string` | `--openrouter-api-key `와 같은 전체 CLI 옵션 형태입니다. | +| `cliDescription` | 아니요 | `string` | CLI 도움말에 사용되는 설명입니다. | +| `onboardingScopes` | 아니요 | `Array<"text-inference" \| "image-generation">` | 이 선택이 나타나야 하는 온보딩 표면입니다. 생략하면 기본값은 `["text-inference"]`입니다. | -## commandAliases 참조 +## `commandAliases` 참조 -사용자가 실수로 런타임 명령 이름을 `plugins.allow`에 넣거나 루트 CLI 명령으로 실행하려고 할 수 있고, -그 명령을 Plugin이 소유하는 경우 `commandAliases`를 사용하세요. OpenClaw는 -Plugin 런타임 코드를 가져오지 않고도 진단에 이 메타데이터를 사용합니다. +사용자가 플러그인이 소유한 런타임 명령 이름을 실수로 `plugins.allow`에 넣거나 +루트 CLI 명령으로 실행하려고 할 수 있다면 `commandAliases`를 사용하세요. OpenClaw는 +Plugin 런타임 코드를 import하지 않고도 진단을 위해 이 메타데이터를 사용합니다. ```json { @@ -221,23 +221,23 @@ Plugin 런타임 코드를 가져오지 않고도 진단에 이 메타데이터 } ``` -| 필드 | 필수 여부 | 타입 | 의미 | -| ------------ | --------- | ----------------- | ------------------------------------------------------------------------ | -| `name` | 예 | `string` | 이 Plugin에 속한 명령 이름입니다. | -| `kind` | 아니요 | `"runtime-slash"` | 루트 CLI 명령이 아니라 chat 슬래시 명령으로 이 별칭을 표시합니다. | -| `cliCommand` | 아니요 | `string` | 존재하는 경우, CLI 작업에 대해 제안할 관련 루트 CLI 명령입니다. | +| 필드 | 필수 여부 | 유형 | 의미 | +| ------------ | --------- | ----------------- | ----------------------------------------------------------------------- | +| `name` | 예 | `string` | 이 Plugin에 속한 명령 이름입니다. | +| `kind` | 아니요 | `"runtime-slash"` | 별칭을 루트 CLI 명령이 아니라 채팅 슬래시 명령으로 표시합니다. | +| `cliCommand` | 아니요 | `string` | 존재하는 경우, CLI 작업에 대해 제안할 관련 루트 CLI 명령입니다. | -## activation 참조 +## `activation` 참조 -Plugin이 나중에 자신을 활성화해야 하는 제어 플레인 이벤트를 저비용으로 선언할 수 있을 때 -`activation`을 사용하세요. +Plugin이 나중에 무엇이 활성화되어야 하는지 제어면 이벤트를 저비용으로 +선언할 수 있다면 `activation`을 사용하세요. -## qaRunners 참조 +## `qaRunners` 참조 -Plugin이 공유 `openclaw qa` 루트 아래에 하나 이상의 전송 러너를 기여하는 경우 -`qaRunners`를 사용하세요. 이 메타데이터는 저비용이고 정적으로 유지하세요. 실제 CLI 등록은 여전히 Plugin -런타임이 `qaRunnerCliRegistrations`를 export하는 경량 -`runtime-api.ts` 표면을 통해 소유합니다. +Plugin이 공유 `openclaw qa` 루트 아래에 하나 이상의 전송 러너를 제공하는 경우 +`qaRunners`를 사용하세요. 이 메타데이터는 저비용이고 정적으로 유지해야 합니다. 실제 +CLI 등록은 여전히 `qaRunnerCliRegistrations`를 export하는 경량 +`runtime-api.ts` 표면을 통해 Plugin 런타임이 소유합니다. ```json { @@ -250,16 +250,16 @@ Plugin이 공유 `openclaw qa` 루트 아래에 하나 이상의 전송 러너 } ``` -| 필드 | 필수 여부 | 타입 | 의미 | -| ------------- | --------- | -------- | -------------------------------------------------------------------- | -| `commandName` | 예 | `string` | `openclaw qa` 아래에 마운트되는 하위 명령입니다. 예: `matrix`. | -| `description` | 아니요 | `string` | 공유 호스트에 스텁 명령이 필요할 때 사용되는 폴백 도움말 텍스트입니다. | +| 필드 | 필수 여부 | 유형 | 의미 | +| ------------- | --------- | -------- | ------------------------------------------------------------------ | +| `commandName` | 예 | `string` | `openclaw qa` 아래에 마운트되는 하위 명령입니다. 예: `matrix`. | +| `description` | 아니요 | `string` | 공유 호스트에 stub 명령이 필요할 때 사용하는 대체 도움말 텍스트입니다. | 이 블록은 메타데이터 전용입니다. 런타임 동작을 등록하지 않으며, -`register(...)`, `setupEntry` 또는 다른 런타임/Plugin entrypoint를 대체하지도 않습니다. -현재 소비자는 더 넓은 Plugin 로드 전에 이를 좁히기 힌트로 사용하므로, -activation 메타데이터가 없으면 일반적으로 성능 비용만 발생하며, -레거시 매니페스트 소유권 폴백이 여전히 존재하는 동안에는 정확성이 바뀌면 안 됩니다. +`register(...)`, `setupEntry` 또는 다른 런타임/Plugin 엔트리포인트를 대체하지도 않습니다. +현재 소비자는 이를 더 넓은 Plugin 로딩 전에 범위를 좁히는 힌트로 사용하므로, +활성화 메타데이터가 없으면 보통 성능 비용만 발생합니다. 레거시 매니페스트 소유권 폴백이 +여전히 존재하는 동안에는 정확성이 바뀌지 않아야 합니다. ```json { @@ -273,28 +273,27 @@ activation 메타데이터가 없으면 일반적으로 성능 비용만 발생 } ``` -| 필드 | 필수 여부 | 타입 | 의미 | +| 필드 | 필수 여부 | 유형 | 의미 | | ---------------- | --------- | ---------------------------------------------------- | ----------------------------------------------------------------- | | `onProviders` | 아니요 | `string[]` | 요청될 때 이 Plugin을 활성화해야 하는 provider ID입니다. | | `onCommands` | 아니요 | `string[]` | 이 Plugin을 활성화해야 하는 명령 ID입니다. | | `onChannels` | 아니요 | `string[]` | 이 Plugin을 활성화해야 하는 채널 ID입니다. | | `onRoutes` | 아니요 | `string[]` | 이 Plugin을 활성화해야 하는 경로 종류입니다. | -| `onCapabilities` | 아니요 | `Array<"provider" \| "channel" \| "tool" \| "hook">` | 제어 플레인 활성화 계획에 사용되는 광범위한 capability 힌트입니다. | +| `onCapabilities` | 아니요 | `Array<"provider" \| "channel" \| "tool" \| "hook">` | 제어면 활성화 계획에 사용되는 광범위한 capability 힌트입니다. | 현재 실제 소비자: - 명령 트리거 CLI 계획은 레거시 `commandAliases[].cliCommand` 또는 `commandAliases[].name`으로 폴백합니다 -- 채널 트리거 설정/채널 계획은 명시적 채널 activation 메타데이터가 없을 때 +- 채널 트리거 설정/채널 계획은 명시적 채널 활성화 메타데이터가 없을 때 레거시 `channels[]` 소유권으로 폴백합니다 -- provider 트리거 설정/런타임 계획은 명시적 provider - activation 메타데이터가 없을 때 레거시 - `providers[]` 및 최상위 `cliBackends[]` 소유권으로 폴백합니다 +- provider 트리거 설정/런타임 계획은 명시적 provider 활성화 메타데이터가 없을 때 + 레거시 `providers[]` 및 최상위 `cliBackends[]` 소유권으로 폴백합니다 -## setup 참조 +## `setup` 참조 -런타임이 로드되기 전에 설정 및 온보딩 표면에 저비용 Plugin 소유 메타데이터가 필요할 때 -`setup`을 사용하세요. +런타임이 로드되기 전에 설정 및 온보딩 표면에 저비용의 Plugin 소유 메타데이터가 +필요한 경우 `setup`을 사용하세요. ```json { @@ -314,39 +313,40 @@ activation 메타데이터가 없으면 일반적으로 성능 비용만 발생 ``` 최상위 `cliBackends`는 계속 유효하며 CLI 추론 -백엔드를 계속 설명합니다. `setup.cliBackends`는 메타데이터 전용으로 유지되어야 하는 -제어 플레인/설정 흐름용 설정 전용 설명자 표면입니다. +백엔드를 설명합니다. `setup.cliBackends`는 메타데이터 전용으로 유지되어야 하는 +제어면/설정 흐름을 위한 설정 전용 설명자 표면입니다. 존재하는 경우 `setup.providers`와 `setup.cliBackends`는 -설정 탐색을 위한 선호되는 설명자 우선 lookup 표면입니다. 설명자가 후보 Plugin만 좁히고 -설정에 여전히 더 풍부한 설정 시점 런타임 hook가 필요하면 `requiresRuntime: true`를 설정하고 -폴백 실행 경로로 `setup-api`를 유지하세요. +설정 검색을 위한 우선 설명자 우선 조회 표면입니다. 설명자가 후보 Plugin만 +좁히고 설정에 더 풍부한 설정 시점 런타임 hook이 여전히 필요하다면 +`requiresRuntime: true`로 설정하고 폴백 실행 경로로 `setup-api`를 +유지하세요. -설정 lookup은 Plugin 소유 `setup-api` 코드를 실행할 수 있으므로, -정규화된 `setup.providers[].id`와 `setup.cliBackends[]` 값은 -탐지된 Plugin 전체에서 고유해야 합니다. 소유권이 모호하면 탐지 순서에서 승자를 고르는 대신 -fail-closed합니다. +설정 조회는 Plugin 소유의 `setup-api` 코드를 실행할 수 있으므로, +정규화된 `setup.providers[].id` 및 `setup.cliBackends[]` 값은 +검색된 Plugin 전체에서 고유해야 합니다. 소유권이 모호하면 검색 순서에서 +승자를 고르는 대신 닫힌 방식으로 실패합니다. -### setup.providers 참조 +### `setup.providers` 참조 -| 필드 | 필수 여부 | 타입 | 의미 | -| ------------- | --------- | ---------- | -------------------------------------------------------------------- | +| 필드 | 필수 여부 | 유형 | 의미 | +| ------------- | --------- | ---------- | ------------------------------------------------------------------------------------ | | `id` | 예 | `string` | 설정 또는 온보딩 중 노출되는 provider ID입니다. 정규화된 ID는 전역적으로 고유하게 유지하세요. | -| `authMethods` | 아니요 | `string[]` | 전체 런타임을 로드하지 않고도 이 provider가 지원하는 설정/인증 메서드 ID입니다. | -| `envVars` | 아니요 | `string[]` | 일반적인 설정/상태 표면이 Plugin 런타임이 로드되기 전에 확인할 수 있는 env 변수입니다. | +| `authMethods` | 아니요 | `string[]` | 전체 런타임을 로드하지 않고도 이 provider가 지원하는 설정/인증 방식 ID입니다. | +| `envVars` | 아니요 | `string[]` | Plugin 런타임이 로드되기 전에 일반 설정/상태 표면이 확인할 수 있는 env var입니다. | -### setup 필드 +### `setup` 필드 -| 필드 | 필수 여부 | 타입 | 의미 | +| 필드 | 필수 여부 | 유형 | 의미 | | ------------------ | --------- | ---------- | --------------------------------------------------------------------------------------------- | | `providers` | 아니요 | `object[]` | 설정 및 온보딩 중 노출되는 provider 설정 설명자입니다. | -| `cliBackends` | 아니요 | `string[]` | 설명자 우선 설정 lookup에 사용되는 설정 시점 backend ID입니다. 정규화된 ID는 전역적으로 고유하게 유지하세요. | -| `configMigrations` | 아니요 | `string[]` | 이 Plugin의 설정 표면이 소유한 구성 마이그레이션 ID입니다. | -| `requiresRuntime` | 아니요 | `boolean` | 설명자 lookup 후에도 설정에 `setup-api` 실행이 필요한지 여부입니다. | +| `cliBackends` | 아니요 | `string[]` | 설명자 우선 설정 조회에 사용되는 설정 시점 백엔드 ID입니다. 정규화된 ID는 전역적으로 고유하게 유지하세요. | +| `configMigrations` | 아니요 | `string[]` | 이 Plugin의 설정 표면이 소유하는 구성 마이그레이션 ID입니다. | +| `requiresRuntime` | 아니요 | `boolean` | 설명자 조회 후에도 설정에 `setup-api` 실행이 여전히 필요한지 여부입니다. | -## uiHints 참조 +## `uiHints` 참조 -`uiHints`는 구성 필드 이름에서 작은 렌더링 힌트로의 맵입니다. +`uiHints`는 구성 필드 이름에서 작은 렌더링 힌트로의 매핑입니다. ```json { @@ -361,21 +361,21 @@ fail-closed합니다. } ``` -각 필드 힌트에는 다음이 포함될 수 있습니다: +각 필드 힌트에는 다음이 포함될 수 있습니다. -| 필드 | 타입 | 의미 | -| ------------- | ---------- | ------------------------------------- | -| `label` | `string` | 사용자 대상 필드 라벨입니다. | +| 필드 | 유형 | 의미 | +| ------------- | ---------- | ----------------------------------- | +| `label` | `string` | 사용자에게 표시되는 필드 레이블입니다. | | `help` | `string` | 짧은 도움말 텍스트입니다. | | `tags` | `string[]` | 선택적 UI 태그입니다. | -| `advanced` | `boolean` | 이 필드를 고급 항목으로 표시합니다. | -| `sensitive` | `boolean` | 이 필드를 비밀 또는 민감 항목으로 표시합니다. | -| `placeholder` | `string` | 폼 입력용 placeholder 텍스트입니다. | +| `advanced` | `boolean` | 필드를 고급 항목으로 표시합니다. | +| `sensitive` | `boolean` | 필드를 비밀 또는 민감 정보로 표시합니다. | +| `placeholder` | `string` | 폼 입력용 플레이스홀더 텍스트입니다. | -## contracts 참조 +## `contracts` 참조 -OpenClaw가 Plugin 런타임을 가져오지 않고도 읽을 수 있는 -정적 capability 소유 메타데이터에만 `contracts`를 사용하세요. +OpenClaw가 Plugin 런타임을 import하지 않고도 읽을 수 있는 정적 capability +소유 메타데이터에만 `contracts`를 사용하세요. ```json { @@ -393,23 +393,60 @@ OpenClaw가 Plugin 런타임을 가져오지 않고도 읽을 수 있는 } ``` -각 목록은 모두 선택 사항입니다: +각 목록은 선택 사항입니다. -| 필드 | 타입 | 의미 | -| ------------------------------- | ---------- | ---------------------------------------------------------------- | -| `speechProviders` | `string[]` | 이 Plugin이 소유한 음성 provider ID입니다. | -| `realtimeTranscriptionProviders`| `string[]` | 이 Plugin이 소유한 실시간 전사 provider ID입니다. | -| `realtimeVoiceProviders` | `string[]` | 이 Plugin이 소유한 실시간 음성 provider ID입니다. | -| `mediaUnderstandingProviders` | `string[]` | 이 Plugin이 소유한 미디어 이해 provider ID입니다. | -| `imageGenerationProviders` | `string[]` | 이 Plugin이 소유한 이미지 생성 provider ID입니다. | -| `videoGenerationProviders` | `string[]` | 이 Plugin이 소유한 비디오 생성 provider ID입니다. | -| `webFetchProviders` | `string[]` | 이 Plugin이 소유한 웹 가져오기 provider ID입니다. | -| `webSearchProviders` | `string[]` | 이 Plugin이 소유한 웹 검색 provider ID입니다. | -| `tools` | `string[]` | 번들 계약 검사에 사용되는, 이 Plugin이 소유한 에이전트 도구 이름입니다. | +| 필드 | 유형 | 의미 | +| -------------------------------- | ---------- | -------------------------------------------------------------- | +| `speechProviders` | `string[]` | 이 Plugin이 소유하는 음성 provider ID입니다. | +| `realtimeTranscriptionProviders` | `string[]` | 이 Plugin이 소유하는 실시간 전사 provider ID입니다. | +| `realtimeVoiceProviders` | `string[]` | 이 Plugin이 소유하는 실시간 음성 provider ID입니다. | +| `mediaUnderstandingProviders` | `string[]` | 이 Plugin이 소유하는 미디어 이해 provider ID입니다. | +| `imageGenerationProviders` | `string[]` | 이 Plugin이 소유하는 이미지 생성 provider ID입니다. | +| `videoGenerationProviders` | `string[]` | 이 Plugin이 소유하는 비디오 생성 provider ID입니다. | +| `webFetchProviders` | `string[]` | 이 Plugin이 소유하는 웹 가져오기 provider ID입니다. | +| `webSearchProviders` | `string[]` | 이 Plugin이 소유하는 웹 검색 provider ID입니다. | +| `tools` | `string[]` | 번들 계약 검사에서 이 Plugin이 소유하는 에이전트 도구 이름입니다. | -## channelConfigs 참조 +## `mediaUnderstandingProviderMetadata` 참조 -채널 Plugin이 런타임이 로드되기 전에 저비용 구성 메타데이터를 필요로 할 때 +미디어 이해 provider에 기본 모델, 자동 인증 폴백 우선순위 또는 네이티브 문서 지원이 있어 +일반 코어 헬퍼가 런타임 로드 전에 이를 필요로 하는 경우 +`mediaUnderstandingProviderMetadata`를 사용하세요. 키는 반드시 +`contracts.mediaUnderstandingProviders`에도 선언되어야 합니다. + +```json +{ + "contracts": { + "mediaUnderstandingProviders": ["example"] + }, + "mediaUnderstandingProviderMetadata": { + "example": { + "capabilities": ["image", "audio"], + "defaultModels": { + "image": "example-vision-latest", + "audio": "example-transcribe-latest" + }, + "autoPriority": { + "image": 40 + }, + "nativeDocumentInputs": ["pdf"] + } + } +} +``` + +각 provider 항목에는 다음이 포함될 수 있습니다. + +| 필드 | 유형 | 의미 | +| ---------------------- | ----------------------------------- | ----------------------------------------------------------------------- | +| `capabilities` | `("image" \| "audio" \| "video")[]` | 이 provider가 노출하는 미디어 capability입니다. | +| `defaultModels` | `Record` | 구성에서 모델을 지정하지 않았을 때 사용하는 capability-대-모델 기본값입니다. | +| `autoPriority` | `Record` | 자격 증명 기반 provider 자동 폴백에서 숫자가 낮을수록 먼저 정렬됩니다. | +| `nativeDocumentInputs` | `"pdf"[]` | provider가 지원하는 네이티브 문서 입력입니다. | + +## `channelConfigs` 참조 + +채널 Plugin이 런타임 로드 전에 저비용 구성 메타데이터를 필요로 하는 경우 `channelConfigs`를 사용하세요. ```json @@ -430,28 +467,28 @@ OpenClaw가 Plugin 런타임을 가져오지 않고도 읽을 수 있는 } }, "label": "Matrix", - "description": "Matrix homeserver 연결", + "description": "Matrix 홈서버 연결", "preferOver": ["matrix-legacy"] } } } ``` -각 채널 항목에는 다음이 포함될 수 있습니다: +각 채널 항목에는 다음이 포함될 수 있습니다. -| 필드 | 타입 | 의미 | -| ------------- | ------------------------ | ------------------------------------------------------------------------------------- | -| `schema` | `object` | `channels.`용 JSON 스키마입니다. 선언된 각 채널 구성 항목에 필수입니다. | -| `uiHints` | `Record` | 해당 채널 구성 섹션용 선택적 UI 라벨/placeholder/민감도 힌트입니다. | -| `label` | `string` | 런타임 메타데이터가 준비되지 않았을 때 선택기 및 검사 표면에 병합되는 채널 라벨입니다. | -| `description` | `string` | 검사 및 카탈로그 표면용 짧은 채널 설명입니다. | -| `preferOver` | `string[]` | 선택 표면에서 이 채널이 더 우선해야 하는 레거시 또는 낮은 우선순위 Plugin ID입니다. | +| 필드 | 유형 | 의미 | +| ------------- | ------------------------ | ---------------------------------------------------------------------------------------- | +| `schema` | `object` | `channels.`용 JSON 스키마입니다. 선언된 각 채널 구성 항목에 필수입니다. | +| `uiHints` | `Record` | 해당 채널 구성 섹션에 대한 선택적 UI 레이블/플레이스홀더/민감도 힌트입니다. | +| `label` | `string` | 런타임 메타데이터가 준비되지 않았을 때 선택기와 검사 표면에 병합되는 채널 레이블입니다. | +| `description` | `string` | 검사 및 카탈로그 표면용 짧은 채널 설명입니다. | +| `preferOver` | `string[]` | 선택 표면에서 이 채널이 우선해야 하는 레거시 또는 낮은 우선순위 Plugin ID입니다. | -## modelSupport 참조 +## `modelSupport` 참조 -OpenClaw가 `gpt-5.4` 또는 `claude-sonnet-4.6` 같은 -축약형 모델 ID에서 Plugin 런타임이 로드되기 전에 -provider Plugin을 추론해야 하는 경우 `modelSupport`를 사용하세요. +Plugin 런타임이 로드되기 전에 OpenClaw가 `gpt-5.4` 또는 `claude-sonnet-4.6` 같은 +축약형 모델 ID에서 provider Plugin을 추론해야 하는 경우 +`modelSupport`를 사용하세요. ```json { @@ -462,17 +499,17 @@ provider Plugin을 추론해야 하는 경우 `modelSupport`를 사용하세요. } ``` -OpenClaw는 다음 우선순위를 적용합니다: +OpenClaw는 다음 우선순위를 적용합니다. - 명시적 `provider/model` 참조는 소유 `providers` 매니페스트 메타데이터를 사용합니다 - `modelPatterns`가 `modelPrefixes`보다 우선합니다 -- 번들되지 않은 Plugin 하나와 번들 Plugin 하나가 모두 일치하면 번들되지 않은 +- 번들되지 않은 Plugin 하나와 번들된 Plugin 하나가 모두 일치하면 번들되지 않은 Plugin이 우선합니다 -- 남은 모호성은 사용자가 또는 구성이 provider를 지정할 때까지 무시됩니다 +- 남은 모호성은 사용자가 provider를 지정하거나 구성이 provider를 지정할 때까지 무시됩니다 필드: -| 필드 | 타입 | 의미 | +| 필드 | 유형 | 의미 | | --------------- | ---------- | ----------------------------------------------------------------------------- | | `modelPrefixes` | `string[]` | 축약형 모델 ID에 대해 `startsWith`로 일치시키는 접두사입니다. | | `modelPatterns` | `string[]` | 프로필 접미사 제거 후 축약형 모델 ID에 대해 일치시키는 정규식 소스입니다. | @@ -481,69 +518,70 @@ OpenClaw는 다음 우선순위를 적용합니다: `speechProviders`, `realtimeTranscriptionProviders`, `realtimeVoiceProviders`, `mediaUnderstandingProviders`, `imageGenerationProviders`, `videoGenerationProviders`, -`webFetchProviders`, `webSearchProviders`를 `contracts` 아래로 이동하세요. -일반 매니페스트 로드는 더 이상 이러한 최상위 필드를 capability -소유권으로 취급하지 않습니다. +`webFetchProviders`, `webSearchProviders`를 `contracts` 아래로 +이동하세요. 일반 매니페스트 로딩은 더 이상 이러한 최상위 필드를 capability +소유권으로 처리하지 않습니다. -## 매니페스트와 package.json 비교 +## 매니페스트와 `package.json` -두 파일은 서로 다른 역할을 합니다: +두 파일은 서로 다른 역할을 합니다. | 파일 | 용도 | | ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- | -| `openclaw.plugin.json` | Plugin 코드가 실행되기 전에 존재해야 하는 탐지, 구성 검증, 인증 선택 메타데이터, UI 힌트 | -| `package.json` | npm 메타데이터, 의존성 설치, entrypoint, 설치 게이트, 설정, 카탈로그 메타데이터에 사용되는 `openclaw` 블록 | +| `openclaw.plugin.json` | Plugin 코드가 실행되기 전에 반드시 존재해야 하는 검색, 구성 검증, 인증 선택 메타데이터, UI 힌트 | +| `package.json` | npm 메타데이터, 의존성 설치, 엔트리포인트, 설치 게이팅, 설정 또는 카탈로그 메타데이터에 사용되는 `openclaw` 블록 | -어떤 메타데이터를 어디에 넣어야 할지 확실하지 않다면 다음 규칙을 사용하세요: +어떤 메타데이터를 어디에 둘지 확실하지 않다면 다음 규칙을 사용하세요. -- OpenClaw가 Plugin 코드를 로드하기 전에 알아야 하면 `openclaw.plugin.json`에 넣으세요 -- 패키징, 엔트리 파일, npm 설치 동작에 관한 것이면 `package.json`에 넣으세요 +- OpenClaw가 Plugin 코드를 로드하기 전에 반드시 알아야 하면 `openclaw.plugin.json`에 넣으세요 +- 패키징, 엔트리 파일 또는 npm 설치 동작에 관한 것이라면 `package.json`에 넣으세요 -### 탐지에 영향을 주는 package.json 필드 +### 검색에 영향을 주는 `package.json` 필드 일부 사전 런타임 Plugin 메타데이터는 의도적으로 `openclaw.plugin.json`이 아니라 `package.json`의 `openclaw` 블록 아래에 있습니다. 중요한 예시: -| 필드 | 의미 | -| ---------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `openclaw.extensions` | 기본 Plugin entrypoint를 선언합니다. Plugin 패키지 디렉터리 내부에 있어야 합니다. | -| `openclaw.runtimeExtensions` | 설치된 패키지용 빌드된 JavaScript 런타임 entrypoint를 선언합니다. Plugin 패키지 디렉터리 내부에 있어야 합니다. | -| `openclaw.setupEntry` | 온보딩, 지연 채널 시작, 읽기 전용 채널 상태/SecretRef 탐지 중에 사용하는 경량 설정 전용 entrypoint입니다. Plugin 패키지 디렉터리 내부에 있어야 합니다. | -| `openclaw.runtimeSetupEntry` | 설치된 패키지용 빌드된 JavaScript 설정 entrypoint를 선언합니다. Plugin 패키지 디렉터리 내부에 있어야 합니다. | -| `openclaw.channel` | 라벨, 문서 경로, 별칭, 선택용 문구 같은 저비용 채널 카탈로그 메타데이터입니다. | -| `openclaw.channel.configuredState` | 전체 채널 런타임을 로드하지 않고도 "환경 변수 전용 설정이 이미 존재하는가?"를 답할 수 있는 경량 configured-state 검사기 메타데이터입니다. | -| `openclaw.channel.persistedAuthState` | 전체 채널 런타임을 로드하지 않고도 "이미 로그인된 항목이 있는가?"를 답할 수 있는 경량 persisted-auth 검사기 메타데이터입니다. | -| `openclaw.install.npmSpec` / `openclaw.install.localPath` | 번들 Plugin 및 외부 게시 Plugin용 설치/업데이트 힌트입니다. | -| `openclaw.install.defaultChoice` | 여러 설치 소스를 사용할 수 있을 때 선호되는 설치 경로입니다. | -| `openclaw.install.minHostVersion` | `>=2026.3.22` 같은 semver 하한을 사용하는 최소 지원 OpenClaw 호스트 버전입니다. | -| `openclaw.install.allowInvalidConfigRecovery` | 구성이 유효하지 않을 때 제한적인 번들 Plugin 재설치 복구 경로를 허용합니다. | -| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen`| 시작 중 전체 채널 Plugin보다 먼저 설정 전용 채널 표면이 로드되도록 합니다. | +| 필드 | 의미 | +| ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | +| `openclaw.extensions` | 네이티브 Plugin 엔트리포인트를 선언합니다. 반드시 Plugin 패키지 디렉터리 내부에 있어야 합니다. | +| `openclaw.runtimeExtensions` | 설치된 패키지에 대한 빌드된 JavaScript 런타임 엔트리포인트를 선언합니다. 반드시 Plugin 패키지 디렉터리 내부에 있어야 합니다. | +| `openclaw.setupEntry` | 온보딩, 지연된 채널 시작, 읽기 전용 채널 상태/SecretRef 검색 중 사용되는 경량 설정 전용 엔트리포인트입니다. 반드시 Plugin 패키지 디렉터리 내부에 있어야 합니다. | +| `openclaw.runtimeSetupEntry` | 설치된 패키지에 대한 빌드된 JavaScript 설정 엔트리포인트를 선언합니다. 반드시 Plugin 패키지 디렉터리 내부에 있어야 합니다. | +| `openclaw.channel` | 레이블, 문서 경로, 별칭, 선택용 설명문 같은 저비용 채널 카탈로그 메타데이터입니다. | +| `openclaw.channel.configuredState` | 전체 채널 런타임을 로드하지 않고도 "env 전용 설정이 이미 존재하는가?"에 답할 수 있는 경량 configured-state 검사기 메타데이터입니다. | +| `openclaw.channel.persistedAuthState` | 전체 채널 런타임을 로드하지 않고도 "이미 로그인된 것이 있는가?"에 답할 수 있는 경량 persisted-auth 검사기 메타데이터입니다. | +| `openclaw.install.npmSpec` / `openclaw.install.localPath` | 번들된 Plugin과 외부 게시 Plugin을 위한 설치/업데이트 힌트입니다. | +| `openclaw.install.defaultChoice` | 여러 설치 소스를 사용할 수 있을 때 선호되는 설치 경로입니다. | +| `openclaw.install.minHostVersion` | `>=2026.3.22` 같은 semver 하한을 사용하는 최소 지원 OpenClaw 호스트 버전입니다. | +| `openclaw.install.allowInvalidConfigRecovery` | 구성이 유효하지 않을 때 제한적인 번들 Plugin 재설치 복구 경로를 허용합니다. | +| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | 시작 중 전체 채널 Plugin보다 먼저 설정 전용 채널 표면이 로드되도록 합니다. | -`openclaw.install.minHostVersion`은 설치 및 매니페스트 -레지스트리 로드 중에 강제됩니다. 잘못된 값은 거부되며, 더 새롭지만 유효한 값은 -오래된 호스트에서 Plugin을 건너뜁니다. +`openclaw.install.minHostVersion`은 설치와 매니페스트 +레지스트리 로딩 중에 적용됩니다. 유효하지 않은 값은 거부되며, 더 최신이지만 유효한 값은 +구형 호스트에서 Plugin을 건너뜁니다. -채널 Plugin은 상태, 채널 목록, -또는 SecretRef 스캔이 전체 런타임을 로드하지 않고도 구성된 계정을 식별해야 하는 경우 `openclaw.setupEntry`를 제공해야 합니다. -setup entry는 채널 메타데이터와 setup-safe 구성, -상태, secrets 어댑터를 노출해야 하며, 네트워크 클라이언트, gateway 리스너, -전송 런타임은 메인 extension entrypoint에 유지하세요. +채널 Plugin은 상태, 채널 목록 또는 SecretRef 스캔에서 전체 +런타임을 로드하지 않고도 구성된 계정을 식별해야 하는 경우 `openclaw.setupEntry`를 제공해야 합니다. +설정 엔트리는 채널 메타데이터와 설정에 안전한 구성, +상태, 시크릿 어댑터를 노출해야 합니다. 네트워크 클라이언트, Gateway 리스너, +전송 런타임은 메인 extension 엔트리포인트에 유지하세요. -런타임 entrypoint 필드는 소스 -entrypoint 필드에 대한 패키지 경계 검사를 재정의하지 않습니다. 예를 들어, `openclaw.runtimeExtensions`는 -경계를 벗어나는 `openclaw.extensions` 경로를 로드 가능하게 만들 수 없습니다. +런타임 엔트리포인트 필드는 소스 +엔트리포인트 필드에 대한 패키지 경계 검사를 무시하지 않습니다. 예를 들어 +`openclaw.runtimeExtensions`는 경계를 벗어나는 `openclaw.extensions` 경로를 +로드 가능하게 만들 수 없습니다. -`openclaw.install.allowInvalidConfigRecovery`는 의도적으로 제한적입니다. 이 설정이 -임의의 깨진 구성을 설치 가능하게 만들지는 않습니다. 현재는 -누락된 번들 Plugin 경로나 동일한 -번들 Plugin에 대한 오래된 `channels.` 항목 같은 특정한 오래된 번들 Plugin 업그레이드 실패에서만 -설치 흐름이 복구되도록 허용합니다. 관련 없는 구성 오류는 여전히 설치를 차단하고 운영자를 -`openclaw doctor --fix`로 안내합니다. +`openclaw.install.allowInvalidConfigRecovery`는 의도적으로 범위가 좁습니다. +임의의 손상된 구성을 설치 가능하게 만들지는 않습니다. 현재는 특정 오래된 번들 Plugin +업그레이드 실패(예: 누락된 번들 Plugin 경로나 동일한 번들 Plugin에 대한 오래된 +`channels.` 항목)에서만 설치 흐름이 복구되도록 허용합니다. +관련 없는 구성 오류는 여전히 설치를 차단하며 운영자를 `openclaw doctor --fix`로 +안내합니다. -`openclaw.channel.persistedAuthState`는 작은 검사기 -모듈을 위한 패키지 메타데이터입니다: +`openclaw.channel.persistedAuthState`는 아주 작은 검사기 +모듈을 위한 패키지 메타데이터입니다. ```json { @@ -559,13 +597,13 @@ entrypoint 필드에 대한 패키지 경계 검사를 재정의하지 않습니 } ``` -설정, doctor, 또는 configured-state 흐름이 전체 -채널 Plugin이 로드되기 전에 저비용 yes/no 인증 프로브를 필요로 할 때 사용하세요. 대상 export는 -지속된 상태만 읽는 작은 함수여야 하며, 전체 -채널 런타임 배럴을 통해 연결하지 마세요. +전체 채널 Plugin이 로드되기 전에 설정, doctor 또는 configured-state 흐름에 +저비용의 yes/no 인증 프로브가 필요한 경우 이것을 사용하세요. 대상 export는 +저장된 상태만 읽는 작은 함수여야 하며, 전체 채널 런타임 배럴을 통해 +라우팅하지 마세요. -`openclaw.channel.configuredState`는 저비용 환경 변수 전용 -configured-state 검사를 위한 동일한 형태를 따릅니다: +`openclaw.channel.configuredState`는 저비용 env 전용 +configured 검사에 대해 같은 형태를 따릅니다. ```json { @@ -581,31 +619,31 @@ configured-state 검사를 위한 동일한 형태를 따릅니다: } ``` -채널이 환경 변수 또는 기타 작은 -비런타임 입력에서 configured-state를 답할 수 있을 때 사용하세요. 검사가 전체 구성 확인 또는 실제 -채널 런타임을 필요로 한다면, 그 로직은 대신 Plugin `config.hasConfiguredState` -hook에 유지하세요. +채널이 env 또는 기타 작은 +비런타임 입력만으로 configured-state에 응답할 수 있는 경우 이것을 사용하세요. 검사에 전체 +구성 해석이나 실제 채널 런타임이 필요하다면, 그 로직은 대신 Plugin `config.hasConfiguredState` +hook에 두세요. -## 탐지 우선순위(중복 Plugin ID) +## 검색 우선순위(중복 Plugin ID) -OpenClaw는 여러 루트(번들, 전역 설치, 워크스페이스, 명시적 구성 선택 경로)에서 Plugin을 탐지합니다. 두 탐지 항목이 동일한 `id`를 공유하면, **가장 높은 우선순위**의 매니페스트만 유지되고 더 낮은 우선순위의 중복 항목은 나란히 로드되지 않고 제거됩니다. +OpenClaw는 여러 루트(번들, 전역 설치, 워크스페이스, 명시적으로 구성에서 선택된 경로)에서 Plugin을 검색합니다. 두 검색 결과가 같은 `id`를 공유하면 **가장 높은 우선순위**의 매니페스트만 유지되고, 더 낮은 우선순위의 중복 항목은 나란히 로드되는 대신 제거됩니다. -우선순위, 높은 순서부터 낮은 순서까지: +우선순위, 높은 순서에서 낮은 순서: 1. **구성 선택됨** — `plugins.entries.`에 명시적으로 고정된 경로 2. **번들됨** — OpenClaw와 함께 제공되는 Plugin 3. **전역 설치** — 전역 OpenClaw Plugin 루트에 설치된 Plugin -4. **워크스페이스** — 현재 워크스페이스를 기준으로 탐지된 Plugin +4. **워크스페이스** — 현재 워크스페이스를 기준으로 검색된 Plugin -의미: +영향: - 워크스페이스에 있는 번들 Plugin의 포크 또는 오래된 복사본은 번들 빌드를 가리지 못합니다. -- 번들 Plugin을 실제로 로컬 Plugin으로 재정의하려면, 워크스페이스 탐지에 의존하지 말고 `plugins.entries.`를 통해 고정하여 우선순위로 이기도록 하세요. -- 중복 제거는 로그에 기록되므로 Doctor 및 시작 진단이 제거된 복사본을 가리킬 수 있습니다. +- 번들 Plugin을 로컬 Plugin으로 실제로 재정의하려면 워크스페이스 검색에 의존하지 말고 `plugins.entries.`를 통해 고정해 우선순위에서 이기게 하세요. +- 제거된 중복 항목은 로그에 기록되므로 Doctor와 시작 진단이 버려진 복사본을 가리킬 수 있습니다. ## JSON 스키마 요구 사항 -- **모든 Plugin은 JSON 스키마를 포함해야 하며**, 구성을 전혀 받지 않는 경우에도 마찬가지입니다. +- **모든 Plugin은 JSON 스키마를 반드시 포함해야 하며**, 구성을 전혀 받지 않는 경우도 예외가 아닙니다. - 빈 스키마도 허용됩니다(예: `{ "type": "object", "additionalProperties": false }`). - 스키마는 런타임이 아니라 구성 읽기/쓰기 시점에 검증됩니다. @@ -614,62 +652,62 @@ OpenClaw는 여러 루트(번들, 전역 설치, 워크스페이스, 명시적 - 알 수 없는 `channels.*` 키는 **오류**입니다. 단, 해당 채널 ID가 Plugin 매니페스트에 선언된 경우는 예외입니다. - `plugins.entries.`, `plugins.allow`, `plugins.deny`, `plugins.slots.*`는 - **탐지 가능한** Plugin ID를 참조해야 합니다. 알 수 없는 ID는 **오류**입니다. -- Plugin이 설치되어 있지만 매니페스트나 스키마가 손상되었거나 없으면, + **검색 가능한** Plugin ID를 참조해야 합니다. 알 수 없는 ID는 **오류**입니다. +- Plugin이 설치되어 있지만 매니페스트나 스키마가 손상되었거나 없으면 검증이 실패하고 Doctor가 Plugin 오류를 보고합니다. -- Plugin 구성이 존재하지만 Plugin이 **비활성화**되어 있으면, 구성은 유지되고 +- Plugin 구성이 존재하지만 Plugin이 **비활성화**되어 있으면 해당 구성은 유지되며 Doctor + 로그에 **경고**가 표시됩니다. 전체 `plugins.*` 스키마는 [구성 참조](/ko/gateway/configuration)를 참조하세요. ## 참고 -- 매니페스트는 로컬 파일 시스템 로드를 포함한 **기본 OpenClaw Plugin에 필수**입니다. -- 런타임은 여전히 Plugin 모듈을 별도로 로드하며, 매니페스트는 - 탐지 + 검증 전용입니다. -- 기본 매니페스트는 JSON5로 파싱되므로, 최종 값이 여전히 객체이기만 하면 - 주석, 후행 쉼표, 따옴표 없는 키를 사용할 수 있습니다. -- 매니페스트 로더는 문서화된 매니페스트 필드만 읽습니다. 여기에 - 사용자 정의 최상위 키를 추가하지 마세요. +- 매니페스트는 로컬 파일시스템 로드를 포함해 **네이티브 OpenClaw Plugin에 필수**입니다. +- 런타임은 여전히 Plugin 모듈을 별도로 로드합니다. 매니페스트는 + 검색 + 검증 전용입니다. +- 네이티브 매니페스트는 JSON5로 파싱되므로, 최종 값이 여전히 객체이기만 하면 + 주석, 후행 쉼표, 따옴표 없는 키가 허용됩니다. +- 매니페스트 로더는 문서화된 매니페스트 필드만 읽습니다. 여기에 사용자 정의 + 최상위 키를 추가하지 마세요. - `providerAuthEnvVars`는 인증 프로브, env-marker - 검증 및 env 이름을 검사하기 위해 Plugin - 런타임을 부팅해서는 안 되는 유사 provider 인증 표면을 위한 저비용 메타데이터 경로입니다. + 검증 및 유사한 provider 인증 표면을 위한 저비용 메타데이터 경로이며, + env 이름을 확인하기 위해 Plugin 런타임을 부팅하지 않아야 하는 경우에 사용합니다. - `providerAuthAliases`는 provider 변형이 다른 provider의 인증 - env 변수, 인증 프로필, 구성 기반 인증, API 키 온보딩 선택을 - 코어에 해당 관계를 하드코딩하지 않고 재사용할 수 있게 합니다. + env var, 인증 프로필, config 기반 인증, API 키 온보딩 선택을 + 코어에 그 관계를 하드코딩하지 않고 재사용할 수 있게 합니다. - `providerEndpoints`는 provider Plugin이 단순 endpoint host/baseUrl - 일치 메타데이터를 소유할 수 있게 합니다. 코어가 이미 지원하는 endpoint 클래스에만 - 사용하세요. 런타임 동작은 여전히 Plugin이 소유합니다. + 매칭 메타데이터를 소유할 수 있게 합니다. 코어가 이미 지원하는 endpoint class에만 + 사용하세요. 실제 런타임 동작은 여전히 Plugin이 소유합니다. - `syntheticAuthRefs`는 provider 소유 synthetic - 인증 hook를 위한 저비용 메타데이터 경로이며, 런타임 - 레지스트리가 존재하기 전에 cold 모델 탐색에서 보여야 합니다. 런타임 provider 또는 CLI backend가 실제로 + auth hook을 위한 저비용 메타데이터 경로이며, 런타임 + 레지스트리가 존재하기 전에 콜드 모델 검색에서 보여야 하는 경우에 사용합니다. 런타임 provider 또는 CLI 백엔드가 실제로 `resolveSyntheticAuth`를 구현하는 참조만 나열하세요. -- `nonSecretAuthMarkers`는 번들 Plugin 소유 - placeholder API 키(예: 로컬, OAuth 또는 주변 자격 증명 마커)를 위한 저비용 메타데이터 경로입니다. - 코어는 소유 provider를 하드코딩하지 않고도 - 인증 표시와 비밀 감사에서 이를 비비밀로 취급합니다. -- `channelEnvVars`는 쉘 환경 변수 폴백, 설정 - 프롬프트 및 env 이름을 검사하기 위해 Plugin 런타임을 부팅해서는 안 되는 유사 채널 표면을 위한 저비용 메타데이터 경로입니다. - 환경 변수 이름은 메타데이터이며, 그 자체로 활성화는 아닙니다. 상태, 감사, Cron 전달 검증 및 기타 읽기 전용 - 표면은 여전히 Plugin 신뢰 및 유효 활성화 정책을 적용한 후에야 - 환경 변수를 구성된 채널로 취급합니다. +- `nonSecretAuthMarkers`는 번들 Plugin 소유의 + local, OAuth 또는 ambient credential marker 같은 플레이스홀더 API 키를 위한 저비용 메타데이터 경로입니다. + 코어는 소유 provider를 하드코딩하지 않고도 인증 표시 및 시크릿 감사에서 + 이를 비시크릿으로 처리합니다. +- `channelEnvVars`는 셸 env 폴백, 설정 + 프롬프트 및 env 이름을 확인하기 위해 Plugin 런타임을 부팅하지 않아야 하는 유사한 채널 표면을 위한 저비용 메타데이터 경로입니다. + env 이름은 메타데이터일 뿐, 그 자체로 활성화는 아닙니다. + 상태, 감사, Cron 전달 검증 및 기타 읽기 전용 + 표면은 여전히 env var를 구성된 채널로 처리하기 전에 Plugin 신뢰와 유효 활성화 정책을 적용합니다. - `providerAuthChoices`는 인증 선택 선택기, - `--auth-choice` 확인, 선호 provider 매핑, 단순 온보딩 - CLI 플래그 등록을 위한 저비용 메타데이터 경로이며 provider 런타임이 로드되기 전에 사용됩니다. provider 코드가 필요한 런타임 wizard + `--auth-choice` 해석, 선호 provider 매핑, 단순 온보딩 + CLI 플래그 등록을 provider 런타임 로드 전에 처리하기 위한 저비용 메타데이터 경로입니다. provider 코드가 필요한 런타임 wizard 메타데이터는 - [Provider runtime hooks](/ko/plugins/architecture#provider-runtime-hooks)를 참조하세요. + [Provider 런타임 hooks](/ko/plugins/architecture#provider-runtime-hooks)를 참조하세요. - 배타적 Plugin 종류는 `plugins.slots.*`를 통해 선택됩니다. - `kind: "memory"`는 `plugins.slots.memory`로 선택됩니다. - `kind: "context-engine"`는 `plugins.slots.contextEngine`으로 선택됩니다 (기본값: 내장 `legacy`). -- Plugin에 필요하지 않다면 `channels`, `providers`, `cliBackends`, `skills`는 - 생략할 수 있습니다. -- Plugin이 기본 모듈에 의존하는 경우 빌드 단계와 - 패키지 관리자 허용 목록 요구 사항(예: pnpm `allow-build-scripts` - - `pnpm rebuild `)을 문서화하세요. +- `channels`, `providers`, `cliBackends`, `skills`는 + Plugin에 필요하지 않으면 생략할 수 있습니다. +- Plugin이 네이티브 모듈에 의존한다면 빌드 단계와 + 패키지 관리자 허용 목록 요구 사항을 문서화하세요(예: pnpm `allow-build-scripts` + - `pnpm rebuild `). ## 관련 항목 -- [Plugin 빌드하기](/ko/plugins/building-plugins) — Plugin 시작하기 +- [Plugin 빌드하기](/ko/plugins/building-plugins) — Plugin 시작 가이드 - [Plugin 아키텍처](/ko/plugins/architecture) — 내부 아키텍처 - [SDK 개요](/ko/plugins/sdk-overview) — Plugin SDK 참조 diff --git a/docs/ko/plugins/sdk-agent-harness.md b/docs/ko/plugins/sdk-agent-harness.md index 365727584..424e1e4b3 100644 --- a/docs/ko/plugins/sdk-agent-harness.md +++ b/docs/ko/plugins/sdk-agent-harness.md @@ -1,55 +1,55 @@ --- read_when: - 내장 에이전트 런타임 또는 하네스 레지스트리를 변경하고 있습니다 - - 번들되었거나 신뢰할 수 있는 플러그인에서 에이전트 하네스를 등록하고 있습니다 - - Codex 플러그인이 모델 제공자와 어떤 관련이 있는지 이해해야 합니다 + - 번들되었거나 신뢰할 수 있는 Plugin에서 에이전트 하네스를 등록하고 있습니다 + - Codex Plugin이 모델 provider와 어떤 관련이 있는지 이해해야 합니다 sidebarTitle: Agent Harness -summary: 낮은 수준의 내장 에이전트 실행기를 대체하는 플러그인을 위한 실험적 SDK 표면 -title: 에이전트 하네스 플러그인 +summary: 저수준 내장 에이전트 실행기를 대체하는 Plugin용 실험적 SDK 표면 +title: 에이전트 하네스 Plugin x-i18n: - generated_at: "2026-04-12T00:18:56Z" + generated_at: "2026-04-22T06:00:30Z" model: gpt-5.4 provider: openai - source_hash: 62b88fd24ce8b600179db27e16e8d764a2cd7a14e5c5df76374c33121aa5e365 + source_hash: 728fef59ae3cce29a3348842820f1f71a2eac98ae6b276179bce6c85d16613df source_path: plugins/sdk-agent-harness.md workflow: 15 --- -# 에이전트 하네스 플러그인 +# 에이전트 하네스 Plugin -**에이전트 하네스**는 준비된 OpenClaw 에이전트 턴 하나를 위한 낮은 수준의 실행기입니다. 이는 모델 제공자도, 채널도, 도구 레지스트리도 아닙니다. +**에이전트 하네스**는 준비된 OpenClaw 에이전트 한 턴을 위한 저수준 실행기입니다. 이것은 모델 provider도, channel도, tool registry도 아닙니다. -이 표면은 번들되었거나 신뢰할 수 있는 네이티브 플러그인에만 사용하세요. 이 계약은 매개변수 타입이 의도적으로 현재 내장 러너를 그대로 반영하므로 아직 실험적입니다. +이 표면은 번들되었거나 신뢰할 수 있는 네이티브 Plugin에만 사용하세요. 이 계약은 여전히 실험적이며, 그 이유는 파라미터 타입이 의도적으로 현재 내장 러너를 반영하기 때문입니다. -## 하네스를 사용하는 경우 +## 하네스를 사용해야 하는 경우 -모델 계열이 자체 네이티브 세션 런타임을 가지고 있고 일반적인 OpenClaw 제공자 전송이 잘못된 추상화일 때 에이전트 하네스를 등록하세요. +모델 패밀리에 자체 네이티브 세션 런타임이 있고 일반적인 OpenClaw provider 전송이 잘못된 추상화인 경우 에이전트 하네스를 등록하세요. 예시: -- 스레드와 compaction을 직접 관리하는 네이티브 코딩 에이전트 서버 -- 네이티브 plan/reasoning/tool 이벤트를 스트리밍해야 하는 로컬 CLI 또는 데몬 -- OpenClaw 세션 transcript에 더해 자체 resume id가 필요한 모델 런타임 +- 스레드와 Compaction을 자체적으로 관리하는 네이티브 코딩 에이전트 서버 +- 네이티브 계획/추론/tool 이벤트를 스트리밍해야 하는 로컬 CLI 또는 데몬 +- OpenClaw 세션 transcript 외에 자체 resume id가 필요한 모델 런타임 -새 LLM API를 추가하기 위해 하네스를 등록해서는 **안 됩니다**. 일반적인 HTTP 또는 WebSocket 모델 API의 경우 [provider plugin](/ko/plugins/sdk-provider-plugins)을 빌드하세요. +새로운 LLM API를 추가하기 위해 하네스를 등록해서는 **안 됩니다**. 일반적인 HTTP 또는 WebSocket 모델 API의 경우 [provider Plugin](/ko/plugins/sdk-provider-plugins)을 만드세요. -## 코어가 계속 소유하는 것 +## 여전히 코어가 담당하는 것 -하네스가 선택되기 전에 OpenClaw는 이미 다음을 해석합니다: +하네스가 선택되기 전에 OpenClaw는 이미 다음을 해결했습니다: -- 제공자와 모델 -- 런타임 인증 상태 +- provider와 모델 +- 런타임 auth 상태 - thinking level과 context budget - OpenClaw transcript/session 파일 -- workspace, sandbox, 도구 정책 -- 채널 응답 콜백과 스트리밍 콜백 -- 모델 폴백과 라이브 모델 전환 정책 +- workspace, sandbox, 그리고 tool 정책 +- channel reply callback과 streaming callback +- 모델 fallback 및 live 모델 전환 정책 -이 분리는 의도된 것입니다. 하네스는 준비된 시도를 실행할 뿐이며, 제공자를 선택하거나, 채널 전달을 대체하거나, 모델을 조용히 전환하지 않습니다. +이 분리는 의도된 것입니다. 하네스는 준비된 시도를 실행하며, provider를 선택하거나, channel 전달을 대체하거나, 모델을 조용히 전환하지 않습니다. -## 하네스 등록 +## 하네스 등록하기 -**가져오기:** `openclaw/plugin-sdk/agent-harness` +**Import:** `openclaw/plugin-sdk/agent-harness` ```typescript import type { AgentHarness } from "openclaw/plugin-sdk/agent-harness"; @@ -85,49 +85,49 @@ export default definePluginEntry({ ## 선택 정책 -OpenClaw는 제공자/모델 해석 후 하네스를 선택합니다: +OpenClaw는 provider/모델 해석 후 하네스를 선택합니다: 1. `OPENCLAW_AGENT_RUNTIME=`는 해당 id를 가진 등록된 하네스를 강제합니다. 2. `OPENCLAW_AGENT_RUNTIME=pi`는 내장 PI 하네스를 강제합니다. -3. `OPENCLAW_AGENT_RUNTIME=auto`는 등록된 하네스에 해석된 제공자/모델을 지원하는지 묻습니다. -4. 등록된 하네스가 일치하지 않으면, PI 폴백이 비활성화되지 않은 한 OpenClaw는 PI를 사용합니다. +3. `OPENCLAW_AGENT_RUNTIME=auto`는 등록된 하네스들에 해석된 provider/모델을 지원하는지 질의합니다. +4. 일치하는 등록된 하네스가 없으면, PI fallback이 비활성화되지 않은 한 OpenClaw는 PI를 사용합니다. -강제된 플러그인 하네스 실패는 실행 실패로 표시됩니다. `auto` 모드에서는 선택된 플러그인 하네스가 턴이 부작용을 만들기 전에 실패하면 OpenClaw가 PI로 폴백할 수 있습니다. 대신 그 폴백을 하드 실패로 만들려면 `OPENCLAW_AGENT_HARNESS_FALLBACK=none` 또는 `embeddedHarness.fallback: "none"`을 설정하세요. +Plugin 하네스 실패는 실행 실패로 표면화됩니다. `auto` 모드에서 PI fallback은 해석된 provider/모델을 지원하는 등록된 Plugin 하네스가 없을 때만 사용됩니다. Plugin 하네스가 한번 실행을 맡으면, OpenClaw는 같은 턴을 PI를 통해 다시 실행하지 않습니다. 그렇게 하면 auth/런타임 의미가 바뀌거나 부작용이 중복될 수 있기 때문입니다. -번들된 Codex 플러그인은 `codex`를 하네스 id로 등록합니다. 코어는 이를 일반적인 플러그인 하네스 id로 취급합니다. Codex 전용 별칭은 공유 런타임 선택기가 아니라 플러그인 또는 운영자 설정에 속해야 합니다. +번들된 Codex Plugin은 `codex`를 하네스 id로 등록합니다. 코어는 이를 일반적인 Plugin 하네스 id로 취급합니다. Codex 전용 alias는 공유 런타임 선택자가 아니라 Plugin 또는 운영자 config에 속합니다. -## 제공자와 하네스 페어링 +## provider와 하네스 페어링 -대부분의 하네스는 제공자도 함께 등록해야 합니다. 제공자는 모델 ref, 인증 상태, 모델 메타데이터, `/model` 선택을 OpenClaw의 나머지 부분에서 볼 수 있게 합니다. 그런 다음 하네스는 `supports(...)`에서 해당 제공자를 claim합니다. +대부분의 하네스는 provider도 함께 등록해야 합니다. provider는 모델 ref, auth 상태, 모델 메타데이터, 그리고 `/model` 선택을 OpenClaw의 나머지 부분에 보이게 합니다. 그 다음 하네스는 `supports(...)`에서 해당 provider를 맡습니다. -번들된 Codex 플러그인은 이 패턴을 따릅니다: +번들된 Codex Plugin은 이 패턴을 따릅니다: - provider id: `codex` -- 사용자 모델 ref: `codex/gpt-5.4`, `codex/gpt-5.2`, 또는 Codex app server가 반환하는 다른 모델 +- 사용자 모델 ref: `codex/gpt-5.4`, `codex/gpt-5.2`, 또는 Codex 앱 서버가 반환한 다른 모델 - harness id: `codex` -- auth: 합성 제공자 가용성. Codex 하네스가 네이티브 Codex 로그인/세션을 소유하기 때문입니다 -- app-server request: OpenClaw는 bare model id를 Codex에 보내고 하네스가 네이티브 app-server 프로토콜과 통신하도록 둡니다 +- auth: 합성된 provider 가용성. Codex 하네스가 네이티브 Codex 로그인/세션을 관리하기 때문입니다 +- app-server 요청: OpenClaw는 순수 모델 id를 Codex에 보내고, 하네스가 네이티브 app-server 프로토콜과 통신하도록 둡니다 -Codex 플러그인은 추가적입니다. 일반 `openai/gpt-*` ref는 계속 OpenAI provider ref로 남으며 일반 OpenClaw provider 경로를 계속 사용합니다. Codex 관리 인증, Codex 모델 검색, 네이티브 스레드, Codex app-server 실행을 원할 때는 `codex/gpt-*`를 선택하세요. `/model`은 OpenAI provider 자격 증명이 없어도 Codex app server가 반환한 Codex 모델들 사이를 전환할 수 있습니다. +Codex Plugin은 가산적입니다. 일반 `openai/gpt-*` ref는 여전히 OpenAI provider ref이며 정상적인 OpenClaw provider 경로를 계속 사용합니다. Codex가 관리하는 auth, Codex 모델 검색, 네이티브 스레드, 그리고 Codex app-server 실행을 원할 때 `codex/gpt-*`를 선택하세요. `/model`은 OpenAI provider 자격 증명을 요구하지 않고도 Codex 앱 서버가 반환한 Codex 모델 사이를 전환할 수 있습니다. -운영자 설정, 모델 접두사 예시, Codex 전용 구성은 [Codex Harness](/ko/plugins/codex-harness)를 참조하세요. +운영자 설정, 모델 prefix 예시, 그리고 Codex 전용 config는 [Codex Harness](/ko/plugins/codex-harness)를 참고하세요. -OpenClaw는 Codex app-server `0.118.0` 이상을 요구합니다. Codex 플러그인은 app-server initialize 핸드셰이크를 검사하고 더 오래되었거나 버전이 없는 서버를 차단하여 OpenClaw가 테스트된 프로토콜 표면에 대해서만 실행되도록 합니다. +OpenClaw는 Codex app-server `0.118.0` 이상을 요구합니다. Codex Plugin은 app-server 초기화 handshake를 확인하고, 버전이 더 낮거나 버전 정보가 없는 서버를 차단하여 OpenClaw가 테스트된 프로토콜 표면에서만 실행되도록 합니다. ### 네이티브 Codex 하네스 모드 -번들된 `codex` 하네스는 내장 OpenClaw 에이전트 턴을 위한 네이티브 Codex 모드입니다. 먼저 번들된 `codex` 플러그인을 활성화하고, 구성이 제한적인 allowlist를 사용한다면 `plugins.allow`에 `codex`를 포함하세요. 이것은 `openai-codex/*`와 다릅니다: +번들된 `codex` 하네스는 내장 OpenClaw 에이전트 턴을 위한 네이티브 Codex 모드입니다. 먼저 번들된 `codex` Plugin을 활성화하고, config에서 제한적인 allowlist를 사용한다면 `plugins.allow`에 `codex`를 포함하세요. 이것은 `openai-codex/*`와 다릅니다: -- `openai-codex/*`는 일반 OpenClaw provider 경로를 통해 ChatGPT/Codex OAuth를 사용합니다. +- `openai-codex/*`는 일반적인 OpenClaw provider 경로를 통해 ChatGPT/Codex OAuth를 사용합니다. - `codex/*`는 번들된 Codex provider를 사용하고 턴을 Codex app-server를 통해 라우팅합니다. -이 모드가 실행되면 Codex는 네이티브 thread id, resume 동작, compaction, app-server 실행을 소유합니다. OpenClaw는 여전히 채팅 채널, 표시되는 transcript mirror, 도구 정책, 승인, 미디어 전달, 세션 선택을 소유합니다. Codex app-server 경로가 사용되고 있고 PI 폴백이 고장 난 네이티브 하네스를 숨기지 않음을 증명해야 한다면 `embeddedHarness.runtime: "codex"`와 `embeddedHarness.fallback: "none"`을 사용하세요. +이 모드가 실행되면 Codex는 네이티브 thread id, resume 동작, Compaction, 그리고 app-server 실행을 관리합니다. OpenClaw는 여전히 chat channel, 표시되는 transcript 미러, tool 정책, 승인, media 전달, 그리고 session 선택을 관리합니다. 오직 Codex app-server 경로만 실행을 맡을 수 있음을 증명해야 한다면 `embeddedHarness.runtime: "codex"`와 `embeddedHarness.fallback: "none"`을 사용하세요. 이 config는 선택 가드일 뿐입니다. Codex app-server 실패는 이미 PI를 통해 재시도하지 않고 직접 실패하기 때문입니다. -## PI 폴백 비활성화 +## PI fallback 비활성화 -기본적으로 OpenClaw는 `agents.defaults.embeddedHarness`를 `{ runtime: "auto", fallback: "pi" }`로 설정하여 내장 에이전트를 실행합니다. `auto` 모드에서 등록된 플러그인 하네스는 제공자/모델 쌍을 claim할 수 있습니다. 일치하는 것이 없거나 자동 선택된 플러그인 하네스가 출력을 만들기 전에 실패하면 OpenClaw는 PI로 폴백합니다. +기본적으로 OpenClaw는 `agents.defaults.embeddedHarness`를 `{ runtime: "auto", fallback: "pi" }`로 설정하여 내장 에이전트를 실행합니다. `auto` 모드에서는 등록된 Plugin 하네스가 provider/모델 쌍을 맡을 수 있습니다. 일치하는 것이 없으면 OpenClaw는 PI로 fallback합니다. -플러그인 하네스가 유일하게 실행되는 런타임임을 증명해야 할 때는 `fallback: "none"`을 설정하세요. 이렇게 하면 자동 PI 폴백이 비활성화됩니다. 명시적인 `runtime: "pi"` 또는 `OPENCLAW_AGENT_RUNTIME=pi`는 차단하지 않습니다. +Plugin 하네스 선택이 누락됐을 때 PI를 사용하는 대신 실패하도록 해야 한다면 `fallback: "none"`을 설정하세요. 선택된 Plugin 하네스의 실패는 이미 즉시 실패합니다. 이것은 명시적인 `runtime: "pi"` 또는 `OPENCLAW_AGENT_RUNTIME=pi`를 막지 않습니다. Codex 전용 내장 실행의 경우: @@ -145,7 +145,7 @@ Codex 전용 내장 실행의 경우: } ``` -등록된 어떤 플러그인 하네스라도 일치하는 모델을 claim하게 하되 OpenClaw가 절대로 조용히 PI로 폴백하지 않게 하려면 `runtime: "auto"`를 유지하고 폴백을 비활성화하세요: +등록된 어떤 Plugin 하네스든 일치하는 모델을 맡게 하고 싶지만 OpenClaw가 절대로 조용히 PI로 fallback하지 않게 하려면 `runtime: "auto"`를 유지하고 fallback을 비활성화하세요: ```json { @@ -160,7 +160,7 @@ Codex 전용 내장 실행의 경우: } ``` -에이전트별 재정의도 같은 형태를 사용합니다: +에이전트별 override도 같은 형태를 사용합니다: ```json { @@ -185,7 +185,7 @@ Codex 전용 내장 실행의 경우: } ``` -`OPENCLAW_AGENT_RUNTIME`는 여전히 구성된 runtime보다 우선합니다. 환경에서 PI 폴백을 비활성화하려면 `OPENCLAW_AGENT_HARNESS_FALLBACK=none`을 사용하세요. +`OPENCLAW_AGENT_RUNTIME`는 여전히 config된 runtime을 override합니다. 환경에서 PI fallback을 비활성화하려면 `OPENCLAW_AGENT_HARNESS_FALLBACK=none`을 사용하세요. ```bash OPENCLAW_AGENT_RUNTIME=codex \ @@ -193,39 +193,39 @@ OPENCLAW_AGENT_HARNESS_FALLBACK=none \ openclaw gateway run ``` -폴백이 비활성화되면 요청된 하네스가 등록되지 않았거나, 해석된 제공자/모델을 지원하지 않거나, 턴 부작용을 만들기 전에 실패할 때 세션은 초기에 실패합니다. 이는 Codex 전용 배포와 Codex app-server 경로가 실제로 사용 중임을 증명해야 하는 라이브 테스트를 위한 의도된 동작입니다. +fallback이 비활성화되면 요청된 하네스가 등록되지 않았거나, 해석된 provider/모델을 지원하지 않거나, 턴 부작용을 생성하기 전에 실패하는 경우 session은 조기에 실패합니다. 이것은 Codex 전용 배포와 실제로 Codex app-server 경로가 사용 중임을 증명해야 하는 live 테스트를 위한 의도된 동작입니다. -이 설정은 내장 에이전트 하네스만 제어합니다. 이미지, 비디오, 음악, TTS, PDF 또는 다른 제공자별 모델 라우팅은 비활성화하지 않습니다. +이 설정은 내장 에이전트 하네스만 제어합니다. image, video, music, TTS, PDF, 또는 기타 provider별 모델 라우팅은 비활성화하지 않습니다. -## 네이티브 세션과 transcript mirror +## 네이티브 세션과 transcript 미러 -하네스는 네이티브 session id, thread id 또는 데몬 측 resume token을 유지할 수 있습니다. 그 바인딩을 OpenClaw 세션과 명시적으로 연결해 두고, 사용자에게 보이는 assistant/tool 출력을 OpenClaw transcript에 계속 미러링하세요. +하네스는 네이티브 session id, thread id, 또는 데몬 측 resume token을 유지할 수 있습니다. 그 바인딩을 OpenClaw session과 명시적으로 연결된 상태로 유지하고, 사용자에게 보이는 assistant/tool 출력을 계속 OpenClaw transcript에 미러링하세요. OpenClaw transcript는 다음을 위한 호환성 계층으로 남아 있습니다: -- 채널에 표시되는 세션 기록 +- channel에 보이는 session 기록 - transcript 검색 및 인덱싱 - 이후 턴에서 내장 PI 하네스로 다시 전환 -- 일반 `/new`, `/reset`, 세션 삭제 동작 +- 일반적인 `/new`, `/reset`, 그리고 session 삭제 동작 -하네스가 사이드카 바인딩을 저장한다면 소유한 OpenClaw 세션이 재설정될 때 OpenClaw가 이를 지울 수 있도록 `reset(...)`을 구현하세요. +하네스가 사이드카 바인딩을 저장한다면, 소유한 OpenClaw session이 reset될 때 OpenClaw가 이를 지울 수 있도록 `reset(...)`을 구현하세요. -## 도구 및 미디어 결과 +## tool 및 media 결과 -코어는 OpenClaw 도구 목록을 구성하고 이를 준비된 시도에 전달합니다. 하네스가 동적 도구 호출을 실행할 때는 채널 미디어를 직접 보내는 대신 하네스 결과 형태를 통해 도구 결과를 반환하세요. +코어는 OpenClaw tool 목록을 구성하고 이를 준비된 시도에 전달합니다. 하네스가 동적 tool 호출을 실행할 때는 channel media를 직접 보내지 말고, 하네스 결과 shape를 통해 tool 결과를 반환하세요. -이렇게 하면 텍스트, 이미지, 비디오, 음악, TTS, 승인, 메시징 도구 출력이 PI 기반 실행과 동일한 전달 경로를 유지합니다. +이렇게 하면 text, image, video, music, TTS, 승인, 그리고 메시징 tool 출력이 PI 기반 실행과 동일한 전달 경로를 유지할 수 있습니다. ## 현재 제한 사항 -- 공개 import 경로는 일반적이지만, 일부 attempt/result 타입 별칭은 호환성을 위해 여전히 `Pi` 이름을 사용합니다. -- 서드파티 하네스 설치는 실험적입니다. 네이티브 세션 런타임이 필요해질 때까지는 provider plugin을 우선 사용하세요. -- 턴 간 하네스 전환은 지원됩니다. 네이티브 도구, 승인, assistant 텍스트 또는 메시지 전송이 시작된 뒤에는 턴 중간에 하네스를 전환하지 마세요. +- 공개 import 경로는 일반적이지만, 일부 시도/결과 타입 alias는 호환성을 위해 여전히 `Pi` 이름을 갖고 있습니다. +- 서드파티 하네스 설치는 실험적입니다. 네이티브 세션 런타임이 필요해질 때까지는 provider Plugin을 선호하세요. +- 턴 간 하네스 전환은 지원됩니다. 네이티브 tool, 승인, assistant 텍스트, 또는 메시지 전송이 시작된 후에는 턴 도중 하네스를 전환하지 마세요. ## 관련 항목 - [SDK 개요](/ko/plugins/sdk-overview) - [런타임 헬퍼](/ko/plugins/sdk-runtime) -- [제공자 플러그인](/ko/plugins/sdk-provider-plugins) +- [provider Plugin](/ko/plugins/sdk-provider-plugins) - [Codex Harness](/ko/plugins/codex-harness) -- [모델 제공자](/ko/concepts/model-providers) +- [모델 provider](/ko/concepts/model-providers) diff --git a/docs/ko/plugins/sdk-channel-plugins.md b/docs/ko/plugins/sdk-channel-plugins.md index 88758d2dd..2139efc06 100644 --- a/docs/ko/plugins/sdk-channel-plugins.md +++ b/docs/ko/plugins/sdk-channel-plugins.md @@ -1,114 +1,94 @@ --- read_when: - - 새 메시징 채널 Plugin을 구축하고 있습니다 - - OpenClaw을 메시징 플랫폼에 연결하려고 합니다 + - 새 메시징 채널 Plugin을 빌드하고 있습니다 + - OpenClaw를 메시징 플랫폼에 연결하려고 합니다 - ChannelPlugin 어댑터 표면을 이해해야 합니다 sidebarTitle: Channel Plugins -summary: OpenClaw용 메시징 채널 Plugin 구축 단계별 가이드 -title: 채널 Plugin 구축 +summary: OpenClaw용 메시징 채널 Plugin을 빌드하는 단계별 가이드 +title: 채널 Plugin 빌드하기 x-i18n: - generated_at: "2026-04-22T04:24:43Z" + generated_at: "2026-04-22T06:00:33Z" model: gpt-5.4 provider: openai - source_hash: f08bf785cd2e16ed6ce0317f4fd55c9eccecf7476d84148ad47e7be516dd71fb + source_hash: e67d8c4be8cc4a312e5480545497b139c27bed828304de251e6258a3630dd9b5 source_path: plugins/sdk-channel-plugins.md workflow: 15 --- -# 채널 Plugin 구축 +# 채널 Plugin 빌드하기 -이 가이드는 OpenClaw을 메시징 플랫폼에 연결하는 채널 Plugin을 구축하는 과정을 안내합니다. 이 가이드를 마치면 DM 보안, pairing, 답장 스레딩, 아웃바운드 메시징을 갖춘 작동하는 채널을 만들 수 있습니다. +이 가이드는 OpenClaw를 메시징 플랫폼에 연결하는 채널 Plugin을 빌드하는 과정을 안내합니다. 이 가이드를 마치면 DM 보안, 페어링, 답장 스레딩, 아웃바운드 메시징을 갖춘 작동하는 채널을 만들 수 있습니다. - 아직 OpenClaw Plugin을 한 번도 만들어 본 적이 없다면, 먼저 - 기본 패키지 구조와 manifest 설정을 다루는 + 아직 OpenClaw Plugin을 한 번도 만들어본 적이 없다면, 기본 패키지 + 구조와 manifest 설정을 위해 먼저 [시작하기](/ko/plugins/building-plugins)를 읽으세요. ## 채널 Plugin의 작동 방식 -채널 Plugin은 자체 send/edit/react 도구가 필요하지 않습니다. OpenClaw는 -코어에 하나의 공통 `message` 도구를 유지합니다. Plugin이 담당하는 영역은 다음과 같습니다: +채널 Plugin에는 자체 send/edit/react 도구가 필요하지 않습니다. OpenClaw는 코어에 공유 `message` 도구 하나를 유지합니다. Plugin은 다음을 담당합니다. - **Config** — 계정 확인 및 설정 마법사 -- **보안** — DM 정책 및 허용 목록 +- **Security** — DM 정책 및 허용 목록 - **Pairing** — DM 승인 흐름 -- **세션 문법** — provider별 대화 ID를 기본 채팅, 스레드 ID, 부모 대체 경로에 매핑하는 방식 -- **아웃바운드** — 플랫폼으로 텍스트, 미디어, poll 보내기 -- **스레딩** — 답장을 스레드로 연결하는 방식 +- **Session grammar** — provider별 대화 ID가 기본 채팅, 스레드 ID, 부모 대체 경로에 어떻게 매핑되는지 +- **Outbound** — 플랫폼으로 텍스트, 미디어, 투표 보내기 +- **Threading** — 답장이 어떻게 스레드로 연결되는지 +- **Heartbeat typing** — heartbeat 전달 대상에 대한 선택적 typing/busy 신호 -코어는 공통 메시지 도구, prompt 연결, 바깥쪽 세션 키 형태, -일반적인 `:thread:` bookkeeping, dispatch를 소유합니다. +코어는 공유 메시지 도구, 프롬프트 연결, 바깥쪽 세션 키 형태, 일반적인 `:thread:` 기록 관리, 그리고 디스패치를 담당합니다. -채널이 미디어 소스를 담는 message-tool 파라미터를 추가한다면, 해당 -파라미터 이름을 `describeMessageTool(...).mediaSourceParams`를 통해 노출하세요. -코어는 sandbox 경로 정규화와 아웃바운드 미디어 액세스 -정책을 위해 이 명시적 목록을 사용하므로, Plugin은 provider별 -avatar, attachment, cover-image 파라미터에 대해 공유 코어 특수 처리가 필요하지 않습니다. +채널이 인바운드 답장 외부에서 typing indicator를 지원한다면, 채널 Plugin에 `heartbeat.sendTyping(...)`을 노출하세요. 코어는 heartbeat 모델 실행이 시작되기 전에 확인된 heartbeat 전달 대상과 함께 이를 호출하고, 공유 typing keepalive/cleanup 수명주기를 사용합니다. 플랫폼에 명시적인 중지 신호가 필요하다면 `heartbeat.clearTyping(...)`도 추가하세요. + +채널이 미디어 소스를 전달하는 message-tool 파라미터를 추가한다면, 해당 파라미터 이름을 `describeMessageTool(...).mediaSourceParams`를 통해 노출하세요. 코어는 이 명시적 목록을 sandbox 경로 정규화와 아웃바운드 미디어 접근 정책에 사용하므로, Plugin에 provider별 avatar, attachment, cover-image 파라미터를 위한 공유 코어 특수 처리가 필요하지 않습니다. 가능하면 -`{ "set-profile": ["avatarUrl", "avatarPath"] }`처럼 action 키 기반 맵을 반환하여, -관련 없는 action이 다른 action의 미디어 인수를 상속하지 않도록 하세요. 평면 배열도 -의도적으로 모든 노출 action에서 공유되는 파라미터에는 여전히 사용할 수 있습니다. +`{ "set-profile": ["avatarUrl", "avatarPath"] }` +처럼 action 키 기반 맵을 반환하여 관련 없는 action이 다른 action의 미디어 인자를 상속하지 않도록 하세요. 모든 노출된 action에서 의도적으로 공유되는 파라미터라면 flat array도 여전히 사용할 수 있습니다. -플랫폼이 대화 ID 안에 추가 scope를 저장한다면, 해당 파싱은 -`messaging.resolveSessionConversation(...)`을 통해 Plugin 내부에 유지하세요. 이것이 -`rawId`를 기본 대화 ID, 선택적 스레드 -ID, 명시적 `baseConversationId`, 그리고 `parentConversationCandidates`에 매핑하는 -정식 훅입니다. -`parentConversationCandidates`를 반환할 때는, -가장 좁은 부모에서 가장 넓은/기본 대화 순으로 정렬해 유지하세요. +플랫폼이 대화 ID 내부에 추가 범위를 저장한다면, 그 파싱은 Plugin 안에서 `messaging.resolveSessionConversation(...)`으로 처리하세요. 이는 `rawId`를 기본 대화 ID, 선택적 스레드 ID, 명시적 `baseConversationId`, 그리고 모든 `parentConversationCandidates`에 매핑하기 위한 표준 hook입니다. +`parentConversationCandidates`를 반환할 때는 가장 좁은 부모부터 가장 넓은/기본 대화 순서로 정렬하세요. -채널 레지스트리가 부팅되기 전에 동일한 파싱이 필요한 번들 Plugin은 -일치하는 -`resolveSessionConversation(...)` export가 있는 최상위 `session-key-api.ts` 파일도 노출할 수 있습니다. -코어는 런타임 Plugin 레지스트리를 아직 사용할 수 없을 때만 -이 bootstrap-safe 표면을 사용합니다. +채널 레지스트리가 부팅되기 전에 동일한 파싱이 필요한 번들 Plugin은 일치하는 `resolveSessionConversation(...)` export가 있는 최상위 `session-key-api.ts` 파일도 노출할 수 있습니다. 코어는 런타임 Plugin 레지스트리를 아직 사용할 수 없을 때만 이 bootstrap-safe 표면을 사용합니다. -`messaging.resolveParentConversationCandidates(...)`는 -Plugin이 일반/raw ID 위에 부모 대체 경로만 필요로 하는 경우를 위한 레거시 호환성 대체 수단으로 -여전히 사용할 수 있습니다. 두 훅이 모두 존재하면 코어는 -먼저 `resolveSessionConversation(...).parentConversationCandidates`를 사용하고, -정식 훅이 이를 생략한 경우에만 `resolveParentConversationCandidates(...)`로 -대체합니다. +`messaging.resolveParentConversationCandidates(...)`는 Plugin이 generic/raw ID 위에 부모 대체 경로만 필요로 하는 경우를 위한 레거시 호환성 대체 수단으로 계속 사용할 수 있습니다. 두 hook이 모두 존재하면, 코어는 먼저 +`resolveSessionConversation(...).parentConversationCandidates`를 사용하고, 표준 hook이 이를 생략한 경우에만 `resolveParentConversationCandidates(...)`로 대체합니다. -## 승인 및 채널 기능 +## 승인과 채널 기능 -대부분의 채널 Plugin은 승인 전용 코드가 필요하지 않습니다. +대부분의 채널 Plugin에는 승인 전용 코드가 필요하지 않습니다. -- 코어는 동일 채팅 `/approve`, 공통 승인 버튼 payload, 일반적인 대체 전송을 소유합니다. -- 채널에 승인 전용 동작이 필요할 때는 채널 Plugin에 하나의 `approvalCapability` 객체를 두는 방식을 우선하세요. -- `ChannelPlugin.approvals`는 제거되었습니다. 승인 전송/기본 동작/렌더링/인증 관련 사실은 `approvalCapability`에 두세요. -- `plugin.auth`는 login/logout 전용이며, 코어는 더 이상 그 객체에서 승인 인증 훅을 읽지 않습니다. -- `approvalCapability.authorizeActorAction` 및 `approvalCapability.getActionAvailabilityState`가 정식 승인 인증 seam입니다. +- 코어는 동일 채팅 `/approve`, 공유 승인 버튼 payload, 일반적인 대체 전달을 담당합니다. +- 채널에 승인 전용 동작이 필요할 때는 채널 Plugin에 `approvalCapability` 객체 하나를 두는 방식을 선호하세요. +- `ChannelPlugin.approvals`는 제거되었습니다. 승인 전달/네이티브/렌더링/인증 관련 정보는 `approvalCapability`에 넣으세요. +- `plugin.auth`는 login/logout 전용입니다. 코어는 더 이상 그 객체에서 승인 인증 hook을 읽지 않습니다. +- `approvalCapability.authorizeActorAction`과 `approvalCapability.getActionAvailabilityState`가 표준 승인 인증 seam입니다. - 동일 채팅 승인 인증 가용성에는 `approvalCapability.getActionAvailabilityState`를 사용하세요. -- 채널이 기본 exec 승인을 노출한다면, 동일 채팅 승인 인증과 시작 표면/기본 클라이언트 상태가 다를 때 `approvalCapability.getExecInitiatingSurfaceState`를 사용하세요. 코어는 이 exec 전용 훅을 사용해 `enabled`와 `disabled`를 구분하고, 시작 채널이 기본 exec 승인을 지원하는지 판단하며, 기본 클라이언트 대체 안내에 해당 채널을 포함합니다. `createApproverRestrictedNativeApprovalCapability(...)`는 일반적인 경우 이를 채워 줍니다. -- 중복된 로컬 승인 프롬프트 숨김이나 전송 전 타이핑 표시 같은 채널별 payload 수명주기 동작에는 `outbound.shouldSuppressLocalPayloadPrompt` 또는 `outbound.beforeDeliverPayload`를 사용하세요. -- `approvalCapability.delivery`는 기본 승인 라우팅 또는 대체 억제에만 사용하세요. -- 채널 소유 기본 승인 관련 사실에는 `approvalCapability.nativeRuntime`을 사용하세요. 핫 채널 엔트리포인트에서는 `createLazyChannelApprovalNativeRuntimeAdapter(...)`로 이를 지연 로드 상태로 유지하세요. 이 어댑터는 필요 시 런타임 모듈을 import하면서도 코어가 승인 수명주기를 조립할 수 있게 해 줍니다. -- 채널이 공통 렌더러 대신 정말로 사용자 지정 승인 payload가 필요한 경우에만 `approvalCapability.render`를 사용하세요. -- 채널이 비활성화 경로 답장에서 기본 exec 승인을 활성화하는 데 필요한 정확한 config 노브를 설명하려면 `approvalCapability.describeExecApprovalSetup`을 사용하세요. 이 훅은 `{ channel, channelLabel, accountId }`를 받습니다. 이름이 지정된 계정 채널은 최상위 기본값 대신 `channels..accounts..execApprovals.*` 같은 계정 범위 경로를 렌더링해야 합니다. -- 채널이 기존 config에서 안정적인 소유자 유사 DM identity를 추론할 수 있다면, 승인 전용 코어 로직을 추가하지 말고 `openclaw/plugin-sdk/approval-runtime`의 `createResolvedApproverActionAuthAdapter`를 사용해 동일 채팅 `/approve`를 제한하세요. -- 채널에 기본 승인 전송이 필요하다면, 채널 코드는 대상 정규화와 전송/표시 관련 사실에 집중하세요. `openclaw/plugin-sdk/approval-runtime`의 `createChannelExecApprovalProfile`, `createChannelNativeOriginTargetResolver`, `createChannelApproverDmTargetResolver`, `createApproverRestrictedNativeApprovalCapability`를 사용하세요. 채널별 사실은 `approvalCapability.nativeRuntime` 뒤에 두고, 가능하면 `createChannelApprovalNativeRuntimeAdapter(...)` 또는 `createLazyChannelApprovalNativeRuntimeAdapter(...)`를 사용해 코어가 핸들러를 조립하고 요청 필터링, 라우팅, dedupe, 만료, Gateway 구독, 다른 곳으로 라우팅됨 알림을 소유하게 하세요. `nativeRuntime`은 몇 개의 더 작은 seam으로 나뉩니다: +- 채널이 네이티브 exec 승인을 노출한다면, 시작 표면/네이티브 클라이언트 상태가 동일 채팅 승인 인증과 다를 때 `approvalCapability.getExecInitiatingSurfaceState`를 사용하세요. 코어는 이 exec 전용 hook을 사용해 `enabled`와 `disabled`를 구분하고, 시작 채널이 네이티브 exec 승인을 지원하는지 판단하며, 네이티브 클라이언트 대체 안내에 해당 채널을 포함합니다. `createApproverRestrictedNativeApprovalCapability(...)`는 일반적인 경우 이를 채워줍니다. +- 중복 로컬 승인 프롬프트 숨기기 또는 전달 전 typing indicator 보내기 같은 채널 전용 payload 수명주기 동작에는 `outbound.shouldSuppressLocalPayloadPrompt` 또는 `outbound.beforeDeliverPayload`를 사용하세요. +- 네이티브 승인 라우팅 또는 대체 전달 억제에만 `approvalCapability.delivery`를 사용하세요. +- 채널 소유의 네이티브 승인 관련 정보에는 `approvalCapability.nativeRuntime`을 사용하세요. 핫 채널 진입점에서는 `createLazyChannelApprovalNativeRuntimeAdapter(...)`로 이를 lazy하게 유지하세요. 그러면 런타임 모듈을 필요 시 import하면서도 코어가 승인 수명주기를 조합할 수 있습니다. +- 채널에 공유 렌더러 대신 진짜로 커스텀 승인 payload가 필요할 때만 `approvalCapability.render`를 사용하세요. +- 채널이 비활성 경로 응답에서 네이티브 exec 승인을 활성화하는 데 필요한 정확한 config knob을 설명하고 싶다면 `approvalCapability.describeExecApprovalSetup`을 사용하세요. 이 hook은 `{ channel, channelLabel, accountId }`를 받습니다. 이름 있는 계정 채널은 최상위 기본값 대신 `channels..accounts..execApprovals.*` 같은 계정 범위 경로를 렌더링해야 합니다. +- 채널이 기존 config에서 안정적인 owner 유사 DM 신원을 추론할 수 있다면, 승인 전용 코어 로직을 추가하지 않고 동일 채팅 `/approve`를 제한하기 위해 `openclaw/plugin-sdk/approval-runtime`의 `createResolvedApproverActionAuthAdapter`를 사용하세요. +- 채널에 네이티브 승인 전달이 필요하다면, 채널 코드는 대상 정규화와 전송/표시 관련 사실에만 집중하도록 유지하세요. `openclaw/plugin-sdk/approval-runtime`의 `createChannelExecApprovalProfile`, `createChannelNativeOriginTargetResolver`, `createChannelApproverDmTargetResolver`, `createApproverRestrictedNativeApprovalCapability`를 사용하세요. 채널별 사실은 `approvalCapability.nativeRuntime` 뒤에 두고, 이상적으로는 `createChannelApprovalNativeRuntimeAdapter(...)` 또는 `createLazyChannelApprovalNativeRuntimeAdapter(...)`를 통해 노출하세요. 그러면 코어가 핸들러를 조합하고 요청 필터링, 라우팅, 중복 제거, 만료, gateway 구독, 다른 곳으로 라우팅되었음 알림을 담당할 수 있습니다. `nativeRuntime`은 몇 개의 더 작은 seam으로 나뉩니다. - `availability` — 계정이 구성되었는지, 요청을 처리해야 하는지 여부 -- `presentation` — 공통 승인 view model을 pending/resolved/expired 기본 payload 또는 최종 action으로 매핑 -- `transport` — 대상 준비 및 기본 승인 메시지 send/update/delete -- `interactions` — 기본 버튼 또는 반응을 위한 선택적 bind/unbind/clear-action 훅 -- `observe` — 선택적 전송 진단 훅 -- 채널에 client, token, Bolt app, Webhook receiver 같은 런타임 소유 객체가 필요하다면 `openclaw/plugin-sdk/channel-runtime-context`를 통해 등록하세요. 일반적인 runtime-context 레지스트리를 사용하면 코어가 승인 전용 wrapper glue를 추가하지 않고도 채널 시작 상태에서 capability 기반 핸들러를 bootstrap할 수 있습니다. -- capability 기반 seam이 아직 충분히 표현력이 없을 때만 더 저수준인 `createChannelApprovalHandler` 또는 `createChannelNativeApprovalRuntime`을 사용하세요. -- 기본 승인 채널은 `accountId`와 `approvalKind`를 모두 이 헬퍼들을 통해 라우팅해야 합니다. `accountId`는 다중 계정 승인 정책을 올바른 bot 계정 범위로 유지하고, `approvalKind`는 코어에 하드코딩된 분기 없이 채널에서 exec 대 plugin 승인 동작을 사용할 수 있게 합니다. -- 이제 코어가 승인 재라우팅 알림도 소유합니다. 채널 Plugin은 `createChannelNativeApprovalRuntime`에서 자체적으로 "승인이 DM / 다른 채널로 이동했다" 같은 후속 메시지를 보내지 말고, 공통 승인 capability 헬퍼를 통해 정확한 origin + 승인자 DM 라우팅을 노출한 뒤, 코어가 실제 전송 결과를 집계하여 시작 채팅으로 알림을 게시하게 하세요. -- 전달된 승인 ID 종류를 끝까지 보존하세요. 기본 클라이언트는 - 채널 로컬 상태를 바탕으로 exec 대 plugin 승인 라우팅을 - 추측하거나 다시 쓰면 안 됩니다. -- 서로 다른 승인 종류는 의도적으로 서로 다른 기본 표면을 노출할 수 있습니다. - 현재 번들 예시: - - Slack은 exec 및 plugin ID 모두에 대해 기본 승인 라우팅을 유지합니다. - - Matrix는 exec 및 plugin 승인 모두에 대해 동일한 기본 DM/채널 라우팅과 반응 UX를 유지하면서도, 승인 종류별로 인증은 다르게 둘 수 있습니다. -- `createApproverRestrictedNativeApprovalAdapter`는 여전히 호환성 wrapper로 존재하지만, 새 코드는 capability builder를 우선 사용하고 Plugin에 `approvalCapability`를 노출해야 합니다. +- `presentation` — 공유 승인 뷰 모델을 대기 중/해결됨/만료됨 네이티브 payload 또는 최종 action으로 매핑 +- `transport` — 대상 준비 및 네이티브 승인 메시지 전송/업데이트/삭제 +- `interactions` — 네이티브 버튼 또는 reaction을 위한 선택적 bind/unbind/clear-action hook +- `observe` — 선택적 전달 진단 hook +- 채널에 client, token, Bolt app, Webhook receiver 같은 런타임 소유 객체가 필요하다면, `openclaw/plugin-sdk/channel-runtime-context`를 통해 등록하세요. 일반적인 runtime-context 레지스트리는 코어가 승인 전용 wrapper glue를 추가하지 않고도 채널 시작 상태에서 capability 기반 핸들러를 bootstrap할 수 있게 해줍니다. +- capability 기반 seam이 아직 충분히 표현력이 없을 때만 더 저수준의 `createChannelApprovalHandler` 또는 `createChannelNativeApprovalRuntime`을 사용하세요. +- 네이티브 승인 채널은 `accountId`와 `approvalKind`를 모두 그 helper들을 통해 라우팅해야 합니다. `accountId`는 멀티 계정 승인 정책이 올바른 bot 계정 범위로 유지되도록 하고, `approvalKind`는 코어의 하드코딩된 분기 없이 채널이 exec와 Plugin 승인 동작을 사용할 수 있도록 합니다. +- 이제 코어가 승인 재라우팅 알림도 담당합니다. 채널 Plugin은 `createChannelNativeApprovalRuntime`에서 자체적인 "승인이 DM / 다른 채널로 갔습니다" 후속 메시지를 보내지 말고, 대신 공유 승인 capability helper를 통해 정확한 origin + approver-DM 라우팅을 노출하고, 시작 채팅으로 알림을 게시하기 전에 코어가 실제 전달을 집계하도록 하세요. +- 전달된 승인 ID 종류를 처음부터 끝까지 보존하세요. 네이티브 클라이언트는 채널 로컬 상태에서 exec와 Plugin 승인 라우팅을 추측하거나 다시 작성해서는 안 됩니다. +- 서로 다른 승인 종류는 의도적으로 서로 다른 네이티브 표면을 노출할 수 있습니다. + 현재 번들 예시는 다음과 같습니다. + - Slack은 exec와 Plugin ID 모두에 대해 네이티브 승인 라우팅을 계속 사용할 수 있게 유지합니다. + - Matrix는 exec와 Plugin 승인 모두에 대해 동일한 네이티브 DM/채널 라우팅과 reaction UX를 유지하면서도, 승인 종류별로 auth가 달라지도록 허용합니다. +- `createApproverRestrictedNativeApprovalAdapter`는 여전히 호환성 wrapper로 존재하지만, 새 코드는 capability builder를 선호하고 Plugin에 `approvalCapability`를 노출해야 합니다. -핫 채널 엔트리포인트에서는 이 계열 전체가 아니라 한 부분만 -필요할 때 더 좁은 런타임 하위 경로를 우선 사용하세요: +핫 채널 진입점의 경우, 그 계열 중 한 부분만 필요하다면 더 좁은 런타임 하위 경로를 선호하세요. - `openclaw/plugin-sdk/approval-auth-runtime` - `openclaw/plugin-sdk/approval-client-runtime` @@ -120,104 +100,92 @@ Plugin이 일반/raw ID 위에 부모 대체 경로만 필요로 하는 경우 - `openclaw/plugin-sdk/approval-reply-runtime` - `openclaw/plugin-sdk/channel-runtime-context` -마찬가지로, 더 넓은 umbrella -표면이 필요하지 않을 때는 `openclaw/plugin-sdk/setup-runtime`, +마찬가지로, 더 넓은 umbrella 표면이 필요하지 않다면 +`openclaw/plugin-sdk/setup-runtime`, `openclaw/plugin-sdk/setup-adapter-runtime`, `openclaw/plugin-sdk/reply-runtime`, `openclaw/plugin-sdk/reply-dispatch-runtime`, -`openclaw/plugin-sdk/reply-reference`, -`openclaw/plugin-sdk/reply-chunking`을 우선 사용하세요. +`openclaw/plugin-sdk/reply-reference`, 그리고 +`openclaw/plugin-sdk/reply-chunking`을 선호하세요. -설정 관련으로는 구체적으로: +설정과 관련해서는 특히 다음과 같습니다. -- `openclaw/plugin-sdk/setup-runtime`은 런타임 안전 설정 헬퍼를 다룹니다: +- `openclaw/plugin-sdk/setup-runtime`은 런타임 안전 설정 helper를 다룹니다: import-safe setup patch adapter (`createPatchedAccountSetupAdapter`, `createEnvPatchedAccountSetupAdapter`, `createSetupInputPresenceValidator`), lookup-note 출력, - `promptResolvedAllowFrom`, `splitSetupEntries`, 위임된 + `promptResolvedAllowFrom`, `splitSetupEntries`, 그리고 위임된 setup-proxy builder -- `openclaw/plugin-sdk/setup-adapter-runtime`은 - `createEnvPatchedAccountSetupAdapter`를 위한 좁은 env 인식 adapter +- `openclaw/plugin-sdk/setup-adapter-runtime`은 `createEnvPatchedAccountSetupAdapter`를 위한 좁은 env 인식 adapter seam입니다 -- `openclaw/plugin-sdk/channel-setup`은 선택적 설치 setup +- `openclaw/plugin-sdk/channel-setup`은 선택적 설치 설정 builder와 몇 가지 setup-safe 기본 요소를 다룹니다: `createOptionalChannelSetupSurface`, `createOptionalChannelSetupAdapter`, -채널이 env 기반 설정이나 인증을 지원하고, 일반적인 시작/config -흐름이 런타임 로드 전에 해당 env 이름을 알아야 한다면, -Plugin manifest에 `channelEnvVars`로 선언하세요. 채널 런타임 `envVars`나 로컬 -상수는 운영자 대상 복사용으로만 유지하세요. +채널이 env 기반 설정 또는 auth를 지원하고, 일반적인 시작/config 흐름이 런타임이 로드되기 전에 해당 env 이름을 알아야 한다면, Plugin manifest에 `channelEnvVars`로 선언하세요. 채널 런타임 `envVars` 또는 로컬 상수는 운영자 대상 복사용으로만 유지하세요. -채널이 Plugin 런타임이 시작되기 전에 `status`, `channels list`, `channels status`, 또는 -SecretRef 스캔에 나타날 수 있다면 `package.json`에 `openclaw.setupEntry`를 추가하세요. -이 엔트리포인트는 읽기 전용 명령 경로에서 안전하게 import될 수 있어야 하며, -채널 메타데이터, setup-safe config adapter, status -adapter, 채널 secret target 메타데이터를 반환해야 합니다. setup 엔트리에서는 -client, listener, transport runtime을 시작하지 마세요. +채널이 Plugin 런타임이 시작되기 전에 `status`, `channels list`, `channels status`, 또는 SecretRef 스캔에 나타날 수 있다면, `package.json`에 `openclaw.setupEntry`를 추가하세요. 이 진입점은 읽기 전용 명령 경로에서 안전하게 import할 수 있어야 하며, 해당 요약에 필요한 채널 메타데이터, setup-safe config adapter, status adapter, 채널 secret target 메타데이터를 반환해야 합니다. 설정 진입점에서 client, listener, transport runtime을 시작하지 마세요. `createOptionalChannelSetupWizard`, `DEFAULT_ACCOUNT_ID`, `createTopLevelChannelDmPolicy`, `setSetupChannelEnabled`, 그리고 `splitSetupEntries` -- 다음과 같은 더 무거운 공통 설정/config 헬퍼도 함께 필요할 때만 - 더 넓은 `openclaw/plugin-sdk/setup` seam을 사용하세요: +- 더 무거운 공유 설정/config helper도 함께 필요할 때만 더 넓은 + `openclaw/plugin-sdk/setup` seam을 사용하세요. 예: `moveSingleAccountChannelSectionToDefaultAccount(...)` -채널이 설정 표면에 "먼저 이 Plugin을 설치하세요"만 -광고하려는 경우에는 `createOptionalChannelSetupSurface(...)`를 우선 사용하세요. -생성된 adapter/wizard는 config 쓰기와 finalize에서 fail-closed로 동작하며, -검증, finalize, docs-link 복사 전반에서 동일한 설치 필요 메시지를 재사용합니다. +채널이 설정 표면에서 단지 "먼저 이 Plugin을 설치하세요"만 안내하려는 경우라면, `createOptionalChannelSetupSurface(...)`를 선호하세요. 생성된 adapter/wizard는 config 쓰기와 마무리에서 fail closed 방식으로 동작하며, 검증, finalize, docs-link 복사 전반에서 동일한 설치 필요 메시지를 재사용합니다. -다른 핫 채널 경로에서도, 더 넓은 레거시 표면보다는 좁은 헬퍼를 우선 사용하세요: +다른 핫 채널 경로에서도 더 넓은 레거시 표면보다 좁은 helper를 선호하세요: -- 다중 계정 config 및 - 기본 계정 대체 경로에는 `openclaw/plugin-sdk/account-core`, +- 멀티 계정 config와 기본 계정 대체 경로에는 + `openclaw/plugin-sdk/account-core`, `openclaw/plugin-sdk/account-id`, - `openclaw/plugin-sdk/account-resolution`, + `openclaw/plugin-sdk/account-resolution`, 그리고 `openclaw/plugin-sdk/account-helpers`를 사용하세요 -- 인바운드 route/envelope 및 - record-and-dispatch 연결에는 `openclaw/plugin-sdk/inbound-envelope`와 +- 인바운드 route/envelope와 + record-and-dispatch 연결에는 + `openclaw/plugin-sdk/inbound-envelope`와 `openclaw/plugin-sdk/inbound-reply-dispatch`를 사용하세요 - 대상 파싱/매칭에는 `openclaw/plugin-sdk/messaging-targets`를 사용하세요 -- 미디어 로딩과 아웃바운드 - identity/send delegate 및 payload planning에는 `openclaw/plugin-sdk/outbound-media`와 +- 미디어 로딩과 아웃바운드 신원/전송 delegate 및 payload 계획에는 + `openclaw/plugin-sdk/outbound-media`와 `openclaw/plugin-sdk/outbound-runtime`을 사용하세요 -- 명시적 `replyToId`/`threadId`를 유지하거나, - 기본 세션 키가 여전히 일치한 뒤 현재 `:thread:` 세션을 복구해야 하는 아웃바운드 route에는 +- 아웃바운드 route가 명시적 `replyToId`/`threadId`를 보존하거나, + 기본 세션 키가 여전히 일치한 뒤 현재 `:thread:` 세션을 복구해야 한다면 `openclaw/plugin-sdk/channel-core`의 `buildThreadAwareOutboundSessionRoute(...)`를 사용하세요. - Provider Plugin은 플랫폼에 기본 스레드 전송 의미 체계가 있을 경우 + provider Plugin은 플랫폼에 네이티브 스레드 전달 의미 체계가 있을 때 우선순위, suffix 동작, 스레드 ID 정규화를 재정의할 수 있습니다. -- 스레드 바인딩 수명주기 - 및 adapter 등록에는 `openclaw/plugin-sdk/thread-bindings-runtime`을 사용하세요 -- 레거시 agent/media - payload 필드 레이아웃이 여전히 필요할 때만 `openclaw/plugin-sdk/agent-media-payload`를 사용하세요 -- Telegram 사용자 지정 명령 - 정규화, 중복/충돌 검증, 대체 경로 안정 명령 +- thread-binding 수명주기와 adapter 등록에는 + `openclaw/plugin-sdk/thread-bindings-runtime`을 사용하세요 +- 레거시 agent/media payload 필드 레이아웃이 여전히 필요할 때만 + `openclaw/plugin-sdk/agent-media-payload`를 사용하세요 +- Telegram 커스텀 명령 정규화, 중복/충돌 검증, 대체 경로 안정적 명령 config 계약에는 `openclaw/plugin-sdk/telegram-command-config`를 사용하세요 -인증 전용 채널은 보통 기본 경로에서 멈출 수 있습니다. 코어가 승인을 처리하고 Plugin은 아웃바운드/인증 기능만 노출하면 됩니다. Matrix, Slack, Telegram, 사용자 지정 채팅 전송 계층처럼 기본 승인을 지원하는 채널은 자체 승인 수명주기를 구현하지 말고 공통 기본 헬퍼를 사용해야 합니다. +인증 전용 채널은 보통 기본 경로에서 멈출 수 있습니다. 코어가 승인을 처리하고 Plugin은 아웃바운드/인증 기능만 노출하면 됩니다. Matrix, Slack, Telegram, 커스텀 채팅 전송 같은 네이티브 승인 채널은 자체 승인 수명주기를 구현하지 말고 공유 네이티브 helper를 사용해야 합니다. ## 인바운드 멘션 정책 -인바운드 멘션 처리는 두 계층으로 나누어 유지하세요: +인바운드 멘션 처리는 두 계층으로 나누어 유지하세요. - Plugin이 소유하는 증거 수집 -- 공통 정책 평가 +- 공유 정책 평가 멘션 정책 결정에는 `openclaw/plugin-sdk/channel-mention-gating`을 사용하세요. -더 넓은 인바운드 -헬퍼 barrel이 필요할 때만 `openclaw/plugin-sdk/channel-inbound`를 사용하세요. +더 넓은 인바운드 helper barrel이 필요할 때만 +`openclaw/plugin-sdk/channel-inbound`를 사용하세요. -Plugin 로컬 로직에 잘 맞는 항목: +Plugin 로컬 로직에 잘 맞는 경우: -- bot에 대한 답장 감지 +- bot에 대한 reply 감지 - bot 인용 감지 - 스레드 참여 여부 확인 - 서비스/시스템 메시지 제외 -- bot 참여를 증명하는 데 필요한 플랫폼 기본 캐시 +- bot 참여를 입증하는 데 필요한 플랫폼 네이티브 캐시 -공통 헬퍼에 잘 맞는 항목: +공유 helper에 잘 맞는 경우: - `requireMention` - 명시적 멘션 결과 @@ -228,7 +196,7 @@ Plugin 로컬 로직에 잘 맞는 항목: 권장 흐름: 1. 로컬 멘션 사실을 계산합니다. -2. 해당 사실을 `resolveInboundMentionDecision({ facts, policy })`에 전달합니다. +2. 그 사실을 `resolveInboundMentionDecision({ facts, policy })`에 전달합니다. 3. 인바운드 게이트에서 `decision.effectiveWasMentioned`, `decision.shouldBypassMention`, `decision.shouldSkip`를 사용합니다. ```typescript @@ -268,8 +236,8 @@ const decision = resolveInboundMentionDecision({ if (decision.shouldSkip) return; ``` -`api.runtime.channel.mentions`는 이미 런타임 주입에 의존하는 -번들 채널 Plugin을 위해 동일한 공통 멘션 헬퍼를 노출합니다: +`api.runtime.channel.mentions`는 런타임 주입에 이미 의존하는 +번들 채널 Plugin을 위해 동일한 공유 멘션 helper를 노출합니다. - `buildMentionRegexes` - `matchesMentionPatterns` @@ -279,21 +247,22 @@ if (decision.shouldSkip) return; `implicitMentionKindWhen`과 `resolveInboundMentionDecision`만 필요하다면, -관련 없는 인바운드 -런타임 헬퍼를 로드하지 않도록 `openclaw/plugin-sdk/channel-mention-gating`에서 import하세요. +관련 없는 인바운드 런타임 helper까지 로드하지 않도록 +`openclaw/plugin-sdk/channel-mention-gating`에서 import하세요. -이전 `resolveMentionGating*` 헬퍼는 -`openclaw/plugin-sdk/channel-inbound`에 호환성 export로만 남아 있습니다. 새 코드는 -`resolveInboundMentionDecision({ facts, policy })`를 사용해야 합니다. +이전의 `resolveMentionGating*` helper는 +`openclaw/plugin-sdk/channel-inbound`에 호환성 export로만 남아 있습니다. +새 코드는 `resolveInboundMentionDecision({ facts, policy })`를 사용해야 합니다. ## 단계별 안내 - + 표준 Plugin 파일을 만드세요. `package.json`의 `channel` 필드는 - 이 패키지가 채널 Plugin임을 나타냅니다. 전체 패키지 메타데이터 표면은 - [Plugin 설정 및 config](/ko/plugins/sdk-setup#openclaw-channel)를 참고하세요: + 이것이 채널 Plugin임을 나타냅니다. 전체 패키지 메타데이터 표면은 + [Plugin 설정 및 Config](/ko/plugins/sdk-setup#openclaw-channel)를 + 참고하세요. ```json package.json @@ -342,9 +311,8 @@ if (decision.shouldSkip) return; - - `ChannelPlugin` 인터페이스에는 많은 선택적 adapter 표면이 있습니다. 먼저 - 최소 구성인 `id`와 `setup`부터 시작하고, 필요에 따라 adapter를 추가하세요. + + `ChannelPlugin` 인터페이스에는 선택적인 adapter 표면이 많이 있습니다. 최소 구성인 `id`와 `setup`부터 시작해서 필요할 때 adapter를 추가하세요. `src/channel.ts`를 만드세요: @@ -439,23 +407,23 @@ if (decision.shouldSkip) return; }); ``` - - 저수준 adapter 인터페이스를 직접 구현하는 대신 - 선언형 옵션을 전달하면 builder가 이를 조합합니다: + + 저수준 adapter 인터페이스를 수동으로 구현하는 대신, + 선언적 옵션을 전달하면 builder가 이를 조합합니다. - | 옵션 | 연결되는 항목 | + | Option | 연결되는 항목 | | --- | --- | - | `security.dm` | config 필드 기반 범위 지정 DM 보안 resolver | - | `pairing.text` | 코드 교환이 있는 텍스트 기반 DM pairing 흐름 | - | `threading` | reply-to-mode resolver(고정, 계정 범위, 또는 사용자 지정) | - | `outbound.attachedResults` | 결과 메타데이터(message ID)를 반환하는 send 함수 | + | `security.dm` | config 필드에서 범위가 지정된 DM 보안 resolver | + | `pairing.text` | 코드 교환이 있는 텍스트 기반 DM 페어링 흐름 | + | `threading` | reply-to-mode resolver(고정, 계정 범위, 또는 커스텀) | + | `outbound.attachedResults` | 결과 메타데이터(메시지 ID)를 반환하는 send 함수 | - 완전한 제어가 필요하면 선언형 옵션 대신 원시 adapter 객체를 전달할 수도 있습니다. + 완전한 제어가 필요하다면 선언적 옵션 대신 원시 adapter 객체를 전달할 수도 있습니다. - + `index.ts`를 만드세요: ```typescript index.ts @@ -491,21 +459,21 @@ if (decision.shouldSkip) return; }); ``` - 채널 소유 CLI descriptor는 `registerCliMetadata(...)`에 두세요. 이렇게 하면 OpenClaw가 - 전체 채널 런타임을 활성화하지 않고도 루트 도움말에 이를 표시할 수 있으며, - 일반적인 전체 로드에서는 실제 명령 - 등록을 위해 동일한 descriptor를 계속 가져올 수 있습니다. `registerFull(...)`은 런타임 전용 작업에 유지하세요. - `registerFull(...)`이 Gateway RPC 메서드를 등록한다면, - Plugin 전용 접두사를 사용하세요. 코어 관리자 네임스페이스(`config.*`, - `exec.approvals.*`, `wizard.*`, `update.*`)는 예약되어 있으며 항상 - `operator.admin`으로 확인됩니다. - `defineChannelPluginEntry`는 등록 모드 분기를 자동으로 처리합니다. - 전체 옵션은 [엔트리포인트](/ko/plugins/sdk-entrypoints#definechannelpluginentry)를 참고하세요. + 채널이 소유하는 CLI descriptor는 `registerCliMetadata(...)`에 두어, + OpenClaw가 전체 채널 런타임을 활성화하지 않고도 루트 도움말에 이를 표시할 수 있게 하세요. + 일반적인 전체 로드에서도 실제 명령 등록을 위해 동일한 descriptor를 계속 가져옵니다. + `registerFull(...)`은 런타임 전용 작업에만 유지하세요. + `registerFull(...)`이 gateway RPC 메서드를 등록한다면, + Plugin 전용 prefix를 사용하세요. 코어 관리 네임스페이스 + (`config.*`, `exec.approvals.*`, `wizard.*`, `update.*`)는 예약되어 있으며 + 항상 `operator.admin`으로 확인됩니다. + `defineChannelPluginEntry`는 등록 모드 분리를 자동으로 처리합니다. 모든 + 옵션은 [진입점](/ko/plugins/sdk-entrypoints#definechannelpluginentry)을 참고하세요. - - 온보딩 중 경량 로드를 위해 `setup-entry.ts`를 만드세요: + + 온보딩 중 경량 로딩을 위해 `setup-entry.ts`를 만드세요: ```typescript setup-entry.ts import { defineSetupPluginEntry } from "openclaw/plugin-sdk/channel-core"; @@ -514,34 +482,33 @@ if (decision.shouldSkip) return; export default defineSetupPluginEntry(acmeChatPlugin); ``` - 채널이 비활성화되었거나 구성되지 않았을 때 OpenClaw는 - 전체 엔트리 대신 이를 로드합니다. 설정 흐름 중 무거운 런타임 코드를 불러오는 것을 방지합니다. - 자세한 내용은 [설정 및 config](/ko/plugins/sdk-setup#setup-entry)를 참고하세요. + OpenClaw는 채널이 비활성화되었거나 설정되지 않았을 때 전체 진입점 대신 이것을 로드합니다. + 이렇게 하면 설정 흐름 중에 무거운 런타임 코드를 끌어오지 않게 됩니다. + 자세한 내용은 [설정 및 Config](/ko/plugins/sdk-setup#setup-entry)를 참고하세요. - setup-safe export를 sidecar - 모듈로 분리하는 번들 workspace 채널은, - 명시적인 setup 시점 런타임 setter도 필요할 경우 + setup-safe export를 사이드카 모듈로 분리하는 번들 워크스페이스 채널은 `openclaw/plugin-sdk/channel-entry-contract`의 `defineBundledChannelSetupEntry(...)`를 사용할 수 있습니다. + 이는 설정 시점의 명시적 runtime setter도 함께 필요할 때 유용합니다. - - Plugin은 플랫폼에서 메시지를 수신해 이를 - OpenClaw로 전달해야 합니다. 일반적인 패턴은 요청을 검증하고 - 채널의 인바운드 핸들러를 통해 dispatch하는 Webhook입니다: + + Plugin은 플랫폼에서 메시지를 받아 OpenClaw로 전달해야 합니다. + 일반적인 패턴은 요청을 검증하고 채널의 인바운드 핸들러를 통해 + 디스패치하는 Webhook입니다: ```typescript registerFull(api) { api.registerHttpRoute({ path: "/acme-chat/webhook", - auth: "plugin", // plugin-managed auth (verify signatures yourself) + auth: "plugin", // plugin-managed auth (서명 검증은 직접 수행) handler: async (req, res) => { const event = parseWebhookPayload(req); - // Your inbound handler dispatches the message to OpenClaw. - // The exact wiring depends on your platform SDK — - // see a real example in the bundled Microsoft Teams or Google Chat plugin package. + // 인바운드 핸들러가 메시지를 OpenClaw로 디스패치합니다. + // 정확한 연결 방식은 플랫폼 SDK에 따라 다릅니다 — + // 실제 예시는 번들 Microsoft Teams 또는 Google Chat Plugin 패키지를 참고하세요. await handleAcmeChatInbound(api, event); res.statusCode = 200; @@ -553,7 +520,7 @@ if (decision.shouldSkip) return; ``` - 인바운드 메시지 처리는 채널별로 다릅니다. 각 채널 Plugin은 + 인바운드 메시지 처리는 채널마다 다릅니다. 각 채널 Plugin은 자체 인바운드 파이프라인을 소유합니다. 실제 패턴은 번들 채널 Plugin (예: Microsoft Teams 또는 Google Chat Plugin 패키지)을 참고하세요. @@ -562,14 +529,14 @@ if (decision.shouldSkip) return; -`src/channel.test.ts`에 colocated 테스트를 작성하세요: +`src/channel.test.ts`에 테스트를 함께 작성하세요: ```typescript src/channel.test.ts import { describe, it, expect } from "vitest"; import { acmeChatPlugin } from "./channel.js"; describe("acme-chat plugin", () => { - it("resolves account from config", () => { + it("config에서 계정을 확인한다", () => { const cfg = { channels: { "acme-chat": { token: "test-token", allowFrom: ["user1"] }, @@ -579,7 +546,7 @@ if (decision.shouldSkip) return; expect(account.token).toBe("test-token"); }); - it("inspects account without materializing secrets", () => { + it("보안 정보를 구체화하지 않고 계정을 검사한다", () => { const cfg = { channels: { "acme-chat": { token: "test-token" } }, } as any; @@ -588,7 +555,7 @@ if (decision.shouldSkip) return; expect(result.tokenStatus).toBe("available"); }); - it("reports missing config", () => { + it("누락된 config를 보고한다", () => { const cfg = { channels: {} } as any; const result = acmeChatPlugin.setup!.inspectAccount!(cfg, undefined); expect(result.configured).toBe(false); @@ -600,7 +567,7 @@ if (decision.shouldSkip) return; pnpm test -- /acme-chat/ ``` - 공통 테스트 헬퍼는 [테스트](/ko/plugins/sdk-testing)를 참고하세요. + 공유 테스트 helper는 [테스트](/ko/plugins/sdk-testing)를 참고하세요. @@ -609,8 +576,8 @@ if (decision.shouldSkip) return; ``` /acme-chat/ -├── package.json # openclaw.channel metadata -├── openclaw.plugin.json # config schema가 포함된 Manifest +├── package.json # openclaw.channel 메타데이터 +├── openclaw.plugin.json # config 스키마가 포함된 Manifest ├── index.ts # defineChannelPluginEntry ├── setup-entry.ts # defineSetupPluginEntry ├── api.ts # 공개 export (선택 사항) @@ -618,7 +585,7 @@ if (decision.shouldSkip) return; └── src/ ├── channel.ts # createChatChannelPlugin을 통한 ChannelPlugin ├── channel.test.ts # 테스트 - ├── client.ts # 플랫폼 API client + ├── client.ts # 플랫폼 API 클라이언트 └── runtime.ts # 런타임 저장소(필요한 경우) ``` @@ -626,29 +593,29 @@ if (decision.shouldSkip) return; - 고정, 계정 범위, 또는 사용자 지정 답장 모드 + 고정, 계정 범위, 또는 커스텀 reply 모드 - describeMessageTool 및 action 검색 + describeMessageTool와 action 검색 inferTargetChatType, looksLikeId, resolveTarget - - api.runtime를 통한 TTS, STT, 미디어, 하위 에이전트 + + api.runtime를 통한 TTS, STT, 미디어, 하위 agent -일부 번들 헬퍼 seam은 번들 Plugin 유지 관리와 -호환성을 위해 여전히 존재합니다. 하지만 새 채널 Plugin에 권장되는 패턴은 아닙니다. -해당 번들 Plugin 계열을 직접 유지 관리하는 경우가 아니라면, -일반 SDK 표면의 공통 channel/setup/reply/runtime 하위 경로를 우선 사용하세요. +일부 번들 helper seam은 번들 Plugin 유지보수와 +호환성을 위해 여전히 존재합니다. 이는 새 채널 Plugin에 권장되는 패턴이 아닙니다. +해당 번들 Plugin 계열을 직접 유지보수하는 경우가 아니라면, +공통 SDK 표면의 일반적인 channel/setup/reply/runtime 하위 경로를 우선 사용하세요. ## 다음 단계 -- [Provider Plugin](/ko/plugins/sdk-provider-plugins) — Plugin이 모델도 제공하는 경우 -- [SDK 개요](/ko/plugins/sdk-overview) — 전체 하위 경로 import 참조 -- [SDK 테스트](/ko/plugins/sdk-testing) — 테스트 유틸리티 및 계약 테스트 -- [Plugin Manifest](/ko/plugins/manifest) — 전체 manifest schema +- [Provider Plugins](/ko/plugins/sdk-provider-plugins) — Plugin이 모델도 제공하는 경우 +- [SDK 개요](/ko/plugins/sdk-overview) — 전체 하위 경로 import 참고 자료 +- [SDK 테스트](/ko/plugins/sdk-testing) — 테스트 유틸리티와 계약 테스트 +- [Plugin Manifest](/ko/plugins/manifest) — 전체 manifest 스키마 diff --git a/docs/ko/providers/ollama.md b/docs/ko/providers/ollama.md index 0c58701e9..71a01442c 100644 --- a/docs/ko/providers/ollama.md +++ b/docs/ko/providers/ollama.md @@ -1,25 +1,25 @@ --- read_when: - - Ollama를 통해 클라우드 또는 로컬 모델로 OpenClaw를 실행하려고 합니다 - - Ollama 설정 및 구성 안내가 필요합니다 - - 이미지 이해를 위한 Ollama 비전 모델을 원합니다 + - Ollama를 통해 클라우드 또는 로컬 모델로 OpenClaw를 실행하려고 합니다. + - Ollama 설정 및 구성 안내가 필요합니다. + - 이미지 이해를 위해 Ollama 비전 모델을 사용하려고 합니다. summary: Ollama로 OpenClaw 실행하기(클라우드 및 로컬 모델) title: Ollama x-i18n: - generated_at: "2026-04-22T04:26:57Z" + generated_at: "2026-04-22T06:00:54Z" model: gpt-5.4 provider: openai - source_hash: 32623b6523f22930a5987fb22d2074f1e9bb274cc01ae1ad1837825cc04ec179 + source_hash: 704beed3bf988d6c2ad50b2a1533f6dcef655e44b34f23104827d2acb71b8655 source_path: providers/ollama.md workflow: 15 --- # Ollama -OpenClaw는 호스팅된 클라우드 모델과 로컬/자체 호스팅 Ollama 서버를 위해 Ollama의 네이티브 API(`/api/chat`)와 통합됩니다. Ollama는 세 가지 모드로 사용할 수 있습니다. 도달 가능한 Ollama 호스트를 통한 `Cloud + Local`, `https://ollama.com`에 대한 `Cloud only`, 도달 가능한 Ollama 호스트에 대한 `Local only`입니다. +OpenClaw는 Ollama의 네이티브 API(`/api/chat`)와 통합되어, 호스팅된 클라우드 모델과 로컬/자체 호스팅 Ollama 서버를 모두 사용할 수 있습니다. Ollama는 세 가지 모드로 사용할 수 있습니다: 연결 가능한 Ollama 호스트를 통한 `Cloud + Local`, `https://ollama.com`에 대한 `Cloud only`, 또는 연결 가능한 Ollama 호스트에 대한 `Local only`. -**원격 Ollama 사용자**: OpenClaw에서 `/v1` OpenAI 호환 URL(`http://host:11434/v1`)을 사용하지 마세요. 이렇게 하면 tool calling이 깨지고 모델이 원시 도구 JSON을 일반 텍스트로 출력할 수 있습니다. 대신 네이티브 Ollama API URL을 사용하세요: `baseUrl: "http://host:11434"` (`/v1` 없음). +**원격 Ollama 사용자**: OpenClaw에서 `/v1` OpenAI 호환 URL(`http://host:11434/v1`)을 사용하지 마세요. 이렇게 하면 도구 호출이 깨지고 모델이 원시 도구 JSON을 일반 텍스트로 출력할 수 있습니다. 대신 네이티브 Ollama API URL을 사용하세요: `baseUrl: "http://host:11434"` (`/v1` 없음). ## 시작하기 @@ -28,7 +28,7 @@ OpenClaw는 호스팅된 클라우드 모델과 로컬/자체 호스팅 Ollama - **가장 적합한 경우:** 작동하는 Ollama 클라우드 또는 로컬 설정까지 가는 가장 빠른 경로. + **적합한 경우:** 작동하는 Ollama 클라우드 또는 로컬 설정으로 가장 빠르게 시작하고 싶을 때. @@ -36,7 +36,7 @@ OpenClaw는 호스팅된 클라우드 모델과 로컬/자체 호스팅 Ollama openclaw onboard ``` - 프로바이더 목록에서 **Ollama**를 선택하세요. + 제공자 목록에서 **Ollama**를 선택하세요. - **Cloud + Local** — 로컬 Ollama 호스트와, 해당 호스트를 통해 라우팅되는 클라우드 모델 @@ -44,7 +44,7 @@ OpenClaw는 호스팅된 클라우드 모델과 로컬/자체 호스팅 Ollama - **Local only** — 로컬 모델만 사용 - `Cloud only`는 `OLLAMA_API_KEY`를 요청하고 호스팅된 클라우드 기본값을 제안합니다. `Cloud + Local`과 `Local only`는 Ollama 기본 URL을 요청하고, 사용 가능한 모델을 검색하며, 아직 사용할 수 없는 경우 선택한 로컬 모델을 자동으로 pull합니다. `Cloud + Local`은 해당 Ollama 호스트가 클라우드 액세스를 위해 로그인되어 있는지도 확인합니다. + `Cloud only`는 `OLLAMA_API_KEY`를 요청하고 호스팅된 클라우드 기본값을 제안합니다. `Cloud + Local`과 `Local only`는 Ollama 기본 URL을 요청하고, 사용 가능한 모델을 검색하며, 선택한 로컬 모델이 아직 없으면 자동으로 pull합니다. `Cloud + Local`은 해당 Ollama 호스트가 클라우드 액세스를 위해 로그인되어 있는지도 확인합니다. ```bash @@ -74,11 +74,11 @@ OpenClaw는 호스팅된 클라우드 모델과 로컬/자체 호스팅 Ollama - **가장 적합한 경우:** 클라우드 또는 로컬 설정을 완전히 제어하고 싶은 경우. + **적합한 경우:** 클라우드 또는 로컬 설정을 완전히 제어하고 싶을 때. - - **Cloud + Local**: Ollama를 설치하고 `ollama signin`으로 로그인한 뒤, 해당 호스트를 통해 클라우드 요청을 라우팅 + - **Cloud + Local**: Ollama를 설치하고, `ollama signin`으로 로그인한 뒤, 해당 호스트를 통해 클라우드 요청을 라우팅 - **Cloud only**: `OLLAMA_API_KEY`와 함께 `https://ollama.com` 사용 - **Local only**: [ollama.com/download](https://ollama.com/download)에서 Ollama 설치 @@ -92,7 +92,7 @@ OpenClaw는 호스팅된 클라우드 모델과 로컬/자체 호스팅 Ollama ``` - `Cloud only`에는 실제 `OLLAMA_API_KEY`를 사용하세요. 호스트 기반 설정에서는 아무 플레이스홀더 값이나 동작합니다. + `Cloud only`에서는 실제 `OLLAMA_API_KEY`를 사용하세요. 호스트 기반 설정에서는 아무 자리표시자 값이나 작동합니다. ```bash # Cloud @@ -132,9 +132,9 @@ OpenClaw는 호스팅된 클라우드 모델과 로컬/자체 호스팅 Ollama - `Cloud + Local`은 로컬 모델과 클라우드 모델 모두에 대해 도달 가능한 Ollama 호스트를 제어 지점으로 사용합니다. 이것이 Ollama가 권장하는 하이브리드 흐름입니다. + `Cloud + Local`은 연결 가능한 Ollama 호스트를 로컬 모델과 클라우드 모델 모두의 제어 지점으로 사용합니다. 이것이 Ollama에서 권장하는 하이브리드 흐름입니다. - 설정 중에는 **Cloud + Local**을 사용하세요. OpenClaw는 Ollama 기본 URL을 요청하고, 해당 호스트에서 로컬 모델을 검색하며, 호스트가 `ollama signin`으로 클라우드 액세스에 로그인되어 있는지 확인합니다. 호스트가 로그인되어 있으면 OpenClaw는 `kimi-k2.5:cloud`, `minimax-m2.7:cloud`, `glm-5.1:cloud` 같은 호스팅된 클라우드 기본값도 제안합니다. + 설정 중에 **Cloud + Local**을 사용하세요. OpenClaw는 Ollama 기본 URL을 요청하고, 해당 호스트에서 로컬 모델을 검색하며, 호스트가 `ollama signin`으로 클라우드 액세스에 로그인되어 있는지 확인합니다. 호스트가 로그인되어 있으면 OpenClaw는 `kimi-k2.5:cloud`, `minimax-m2.7:cloud`, `glm-5.1:cloud` 같은 호스팅된 클라우드 기본값도 제안합니다. 호스트가 아직 로그인되어 있지 않으면, `ollama signin`을 실행할 때까지 OpenClaw는 설정을 로컬 전용으로 유지합니다. @@ -143,56 +143,56 @@ OpenClaw는 호스팅된 클라우드 모델과 로컬/자체 호스팅 Ollama `Cloud only`는 `https://ollama.com`의 Ollama 호스팅 API를 대상으로 실행됩니다. - 설정 중에는 **Cloud only**를 사용하세요. OpenClaw는 `OLLAMA_API_KEY`를 요청하고, `baseUrl: "https://ollama.com"`을 설정하며, 호스팅된 클라우드 모델 목록을 시드합니다. 이 경로는 로컬 Ollama 서버나 `ollama signin`을 **필요로 하지 않습니다**. + 설정 중에 **Cloud only**를 사용하세요. OpenClaw는 `OLLAMA_API_KEY`를 요청하고, `baseUrl: "https://ollama.com"`을 설정하며, 호스팅된 클라우드 모델 목록을 시드합니다. 이 경로는 로컬 Ollama 서버나 `ollama signin`이 **필요하지 않습니다**. - `openclaw onboard` 중 표시되는 클라우드 모델 목록은 `https://ollama.com/api/tags`에서 실시간으로 채워지며, 최대 500개 항목으로 제한되므로 선택기는 정적 시드가 아니라 현재 호스팅 카탈로그를 반영합니다. 설정 시점에 `ollama.com`에 도달할 수 없거나 모델이 반환되지 않으면, OpenClaw는 이전의 하드코딩된 제안으로 폴백하여 온보딩이 계속 완료되도록 합니다. + `openclaw onboard` 중에 표시되는 클라우드 모델 목록은 `https://ollama.com/api/tags`에서 실시간으로 채워지며, 최대 500개 항목으로 제한되므로 선택기는 정적인 시드가 아니라 현재 호스팅 카탈로그를 반영합니다. 설정 시점에 `ollama.com`에 연결할 수 없거나 모델이 반환되지 않으면, 온보딩이 계속 완료되도록 OpenClaw는 이전 하드코딩된 제안값으로 대체합니다. 로컬 전용 모드에서 OpenClaw는 구성된 Ollama 인스턴스에서 모델을 검색합니다. 이 경로는 로컬 또는 자체 호스팅 Ollama 서버용입니다. - OpenClaw는 현재 로컬 기본값으로 `gemma4`를 제안합니다. + 현재 OpenClaw는 로컬 기본값으로 `gemma4`를 제안합니다. -## 모델 검색(암시적 프로바이더) +## 모델 검색(암시적 provider) -`OLLAMA_API_KEY`(또는 인증 프로필)를 설정하고 **`models.providers.ollama`를 정의하지 않으면**, OpenClaw는 `http://127.0.0.1:11434`의 로컬 Ollama 인스턴스에서 모델을 검색합니다. +`OLLAMA_API_KEY`(또는 auth profile)를 설정하고 `models.providers.ollama`를 정의하지 **않으면**, OpenClaw는 `http://127.0.0.1:11434`의 로컬 Ollama 인스턴스에서 모델을 검색합니다. -| 동작 | 세부사항 | +| 동작 | 상세 | | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| 카탈로그 쿼리 | `/api/tags` 쿼리 | -| 기능 감지 | 최선 노력 방식의 `/api/show` 조회를 사용해 `contextWindow`를 읽고 기능(비전 포함)을 감지 | -| 비전 모델 | `/api/show`가 `vision` 기능을 보고하는 모델은 이미지 가능(`input: ["text", "image"]`)으로 표시되므로, OpenClaw가 프롬프트에 이미지를 자동 주입 | -| 추론 감지 | 모델 이름 휴리스틱(`r1`, `reasoning`, `think`)으로 `reasoning` 표시 | -| 토큰 제한 | OpenClaw가 사용하는 기본 Ollama 최대 토큰 상한으로 `maxTokens` 설정 | +| 카탈로그 조회 | `/api/tags` 조회 | +| 기능 감지 | 최선형 `/api/show` 조회를 사용해 `contextWindow`를 읽고 기능(비전 포함)을 감지 | +| 비전 모델 | `/api/show`에서 `vision` 기능이 보고되는 모델은 이미지 지원(`input: ["text", "image"]`)으로 표시되므로, OpenClaw가 프롬프트에 이미지를 자동 주입 | +| reasoning 감지 | 모델 이름 휴리스틱(`r1`, `reasoning`, `think`)으로 `reasoning` 표시 | +| 토큰 제한 | OpenClaw가 사용하는 기본 Ollama 최대 토큰 제한으로 `maxTokens` 설정 | | 비용 | 모든 비용을 `0`으로 설정 | -이렇게 하면 카탈로그를 로컬 Ollama 인스턴스와 정렬된 상태로 유지하면서도 수동 모델 항목 입력을 피할 수 있습니다. +이렇게 하면 수동 모델 항목 없이도 카탈로그를 로컬 Ollama 인스턴스와 일치된 상태로 유지할 수 있습니다. ```bash -# 사용 가능한 모델 보기 +# 사용 가능한 모델 확인 ollama list openclaw models list ``` -새 모델을 추가하려면 Ollama로 pull하기만 하면 됩니다. +새 모델을 추가하려면 Ollama로 간단히 pull하면 됩니다. ```bash ollama pull mistral ``` -새 모델은 자동으로 검색되어 바로 사용할 수 있습니다. +새 모델은 자동으로 검색되어 사용할 수 있게 됩니다. -`models.providers.ollama`를 명시적으로 설정하면 자동 검색은 건너뛰어지며, 모델을 수동으로 정의해야 합니다. 아래의 명시적 구성 섹션을 참고하세요. +`models.providers.ollama`를 명시적으로 설정하면 자동 검색은 건너뛰며, 모델을 수동으로 정의해야 합니다. 아래의 명시적 구성 섹션을 참고하세요. ## 비전 및 이미지 설명 -번들 Ollama Plugin은 Ollama를 이미지 가능 미디어 이해 프로바이더로 등록합니다. 이를 통해 OpenClaw는 명시적 이미지 설명 요청과 구성된 이미지 모델 기본값을 로컬 또는 호스팅된 Ollama 비전 모델을 통해 라우팅할 수 있습니다. +번들된 Ollama Plugin은 Ollama를 이미지 지원 미디어 이해 provider로 등록합니다. 이를 통해 OpenClaw는 명시적인 이미지 설명 요청과 구성된 이미지 모델 기본값을 로컬 또는 호스팅된 Ollama 비전 모델로 라우팅할 수 있습니다. 로컬 비전의 경우 이미지를 지원하는 모델을 pull하세요. @@ -201,7 +201,7 @@ ollama pull qwen2.5vl:7b export OLLAMA_API_KEY="ollama-local" ``` -그런 다음 infer CLI로 확인하세요. +그다음 infer CLI로 확인하세요. ```bash openclaw infer image describe \ @@ -210,9 +210,9 @@ openclaw infer image describe \ --json ``` -`--model`은 전체 `` ref여야 합니다. 이 값을 설정하면 `openclaw infer image describe`는 해당 모델이 네이티브 비전을 지원한다는 이유로 설명을 건너뛰지 않고, 그 모델을 직접 실행합니다. +`--model`은 전체 `` 참조여야 합니다. 이 값이 설정되면 `openclaw infer image describe`는 해당 모델이 네이티브 비전을 지원해서 설명을 건너뛰는 대신, 그 모델을 직접 실행합니다. -인바운드 미디어의 기본 이미지 이해 모델로 Ollama를 사용하려면 `agents.defaults.imageModel`을 구성하세요. +수신 미디어에 대한 기본 이미지 이해 모델로 Ollama를 사용하려면 `agents.defaults.imageModel`을 구성하세요. ```json5 { @@ -238,7 +238,7 @@ openclaw infer image describe \ } ``` -OpenClaw는 이미지 가능으로 표시되지 않은 모델에 대한 이미지 설명 요청을 거부합니다. 암시적 검색에서는 `/api/show`가 비전 기능을 보고할 때 OpenClaw가 이를 Ollama에서 읽어옵니다. +OpenClaw는 이미지 지원으로 표시되지 않은 모델에 대한 이미지 설명 요청을 거부합니다. 암시적 검색을 사용할 때는 `/api/show`가 비전 기능을 보고하면 OpenClaw가 이를 Ollama에서 읽어옵니다. ## 구성 @@ -251,13 +251,13 @@ OpenClaw는 이미지 가능으로 표시되지 않은 모델에 대한 이미 ``` - `OLLAMA_API_KEY`가 설정되어 있으면 프로바이더 항목에서 `apiKey`를 생략할 수 있으며, OpenClaw가 가용성 확인을 위해 이를 채워 넣습니다. + `OLLAMA_API_KEY`가 설정되어 있으면 provider 항목에서 `apiKey`를 생략할 수 있으며, OpenClaw가 사용 가능 여부 확인을 위해 이를 채웁니다. - 호스팅된 클라우드 설정이 필요하거나, Ollama가 다른 호스트/포트에서 실행되거나, 특정 컨텍스트 윈도우 또는 모델 목록을 강제하고 싶거나, 완전히 수동 모델 정의를 원할 때는 명시적 구성을 사용하세요. + 호스팅된 클라우드 설정을 원하거나, Ollama가 다른 호스트/포트에서 실행되거나, 특정 컨텍스트 윈도우 또는 모델 목록을 강제하고 싶거나, 완전 수동 모델 정의를 원할 때는 명시적 구성을 사용하세요. ```json5 { @@ -287,7 +287,7 @@ OpenClaw는 이미지 가능으로 표시되지 않은 모델에 대한 이미 - Ollama가 다른 호스트 또는 포트에서 실행 중인 경우(명시적 구성은 자동 검색을 비활성화하므로 모델을 수동으로 정의해야 함): + Ollama가 다른 호스트나 포트에서 실행 중인 경우(명시적 구성은 자동 검색을 비활성화하므로 모델을 수동으로 정의해야 함): ```json5 { @@ -296,7 +296,7 @@ OpenClaw는 이미지 가능으로 표시되지 않은 모델에 대한 이미 ollama: { apiKey: "ollama-local", baseUrl: "http://ollama-host:11434", // /v1 없음 - 네이티브 Ollama API URL 사용 - api: "ollama", // 네이티브 tool-calling 동작을 보장하기 위해 명시적으로 설정 + api: "ollama", // 네이티브 도구 호출 동작을 보장하려면 명시적으로 설정 }, }, }, @@ -304,7 +304,7 @@ OpenClaw는 이미지 가능으로 표시되지 않은 모델에 대한 이미 ``` - URL에 `/v1`을 추가하지 마세요. `/v1` 경로는 OpenAI 호환 모드를 사용하므로 tool calling이 신뢰할 수 없습니다. 경로 접미사 없이 기본 Ollama URL을 사용하세요. + URL에 `/v1`을 추가하지 마세요. `/v1` 경로는 OpenAI 호환 모드를 사용하므로 도구 호출이 안정적이지 않습니다. 경로 접미사 없이 기본 Ollama URL을 사용하세요. @@ -312,7 +312,7 @@ OpenClaw는 이미지 가능으로 표시되지 않은 모델에 대한 이미 ### 모델 선택 -구성되면 모든 Ollama 모델을 사용할 수 있습니다. +구성이 완료되면 모든 Ollama 모델을 사용할 수 있습니다. ```json5 { @@ -329,15 +329,15 @@ OpenClaw는 이미지 가능으로 표시되지 않은 모델에 대한 이미 ## Ollama Web Search -OpenClaw는 번들 `web_search` 프로바이더로 **Ollama Web Search**를 지원합니다. +OpenClaw는 번들된 `web_search` provider로 **Ollama Web Search**를 지원합니다. -| 속성 | 세부사항 | +| 속성 | 상세 | | ----------- | ----------------------------------------------------------------------------------------------------------------- | -| 호스트 | 구성된 Ollama 호스트를 사용(`models.providers.ollama.baseUrl`이 설정된 경우 해당 값, 아니면 `http://127.0.0.1:11434`) | +| 호스트 | 구성된 Ollama 호스트 사용(`models.providers.ollama.baseUrl`이 설정된 경우 해당 값, 그렇지 않으면 `http://127.0.0.1:11434`) | | 인증 | 키 불필요 | | 요구 사항 | Ollama가 실행 중이어야 하며 `ollama signin`으로 로그인되어 있어야 함 | -`openclaw onboard` 또는 `openclaw configure --section web` 중에 **Ollama Web Search**를 선택하거나 다음을 설정하세요. +`openclaw onboard` 또는 `openclaw configure --section web` 중에 **Ollama Web Search**를 선택하거나, 다음을 설정하세요: ```json5 { @@ -352,7 +352,7 @@ OpenClaw는 번들 `web_search` 프로바이더로 **Ollama Web Search**를 지 ``` -전체 설정 및 동작 세부사항은 [Ollama Web Search](/ko/tools/ollama-search)를 참고하세요. +전체 설정 및 동작 세부 정보는 [Ollama Web Search](/ko/tools/ollama-search)를 참고하세요. ## 고급 구성 @@ -360,10 +360,10 @@ OpenClaw는 번들 `web_search` 프로바이더로 **Ollama Web Search**를 지 - **OpenAI 호환 모드에서는 tool calling이 신뢰할 수 없습니다.** 프록시에 OpenAI 형식이 필요하고 네이티브 tool calling 동작에 의존하지 않는 경우에만 이 모드를 사용하세요. + **OpenAI 호환 모드에서는 도구 호출이 안정적이지 않습니다.** 프록시에 OpenAI 형식이 필요한 경우에만 이 모드를 사용하고, 네이티브 도구 호출 동작에 의존하지 마세요. - 대신 OpenAI 호환 엔드포인트를 사용해야 한다면(예: OpenAI 형식만 지원하는 프록시 뒤에 있는 경우), `api: "openai-completions"`를 명시적으로 설정하세요. + 대신 OpenAI 호환 엔드포인트를 사용해야 하는 경우(예: OpenAI 형식만 지원하는 프록시 뒤에 있는 경우), `api: "openai-completions"`를 명시적으로 설정하세요. ```json5 { @@ -381,9 +381,9 @@ OpenClaw는 번들 `web_search` 프로바이더로 **Ollama Web Search**를 지 } ``` - 이 모드는 스트리밍과 tool calling을 동시에 지원하지 않을 수 있습니다. 모델 구성의 `params: { streaming: false }`로 스트리밍을 비활성화해야 할 수 있습니다. + 이 모드에서는 스트리밍과 도구 호출을 동시에 지원하지 않을 수 있습니다. 모델 구성에서 `params: { streaming: false }`로 스트리밍을 비활성화해야 할 수도 있습니다. - Ollama에서 `api: "openai-completions"`를 사용할 때, OpenClaw는 기본적으로 `options.num_ctx`를 주입하여 Ollama가 조용히 4096 컨텍스트 윈도우로 폴백하지 않도록 합니다. 프록시/업스트림이 알 수 없는 `options` 필드를 거부한다면 이 동작을 비활성화하세요. + Ollama와 함께 `api: "openai-completions"`를 사용할 때 OpenClaw는 기본적으로 `options.num_ctx`를 주입하여 Ollama가 조용히 4096 컨텍스트 윈도우로 대체되지 않도록 합니다. 프록시/업스트림이 알 수 없는 `options` 필드를 거부한다면 이 동작을 비활성화하세요. ```json5 { @@ -404,9 +404,9 @@ OpenClaw는 번들 `web_search` 프로바이더로 **Ollama Web Search**를 지 - 자동 검색된 모델의 경우, OpenClaw는 가능하면 Ollama가 보고한 컨텍스트 윈도우를 사용하고, 그렇지 않으면 OpenClaw가 사용하는 기본 Ollama 컨텍스트 윈도우로 폴백합니다. + 자동 검색된 모델의 경우 OpenClaw는 가능하면 Ollama가 보고한 컨텍스트 윈도우를 사용하고, 그렇지 않으면 OpenClaw가 사용하는 기본 Ollama 컨텍스트 윈도우로 대체합니다. - 명시적 프로바이더 구성에서는 `contextWindow`와 `maxTokens`를 재정의할 수 있습니다. + 명시적 provider 구성에서 `contextWindow`와 `maxTokens`를 재정의할 수 있습니다. ```json5 { @@ -428,32 +428,30 @@ OpenClaw는 번들 `web_search` 프로바이더로 **Ollama Web Search**를 지 - - OpenClaw는 기본적으로 `deepseek-r1`, `reasoning`, `think` 같은 이름을 가진 모델을 추론 가능 모델로 처리합니다. + + OpenClaw는 기본적으로 `deepseek-r1`, `reasoning`, `think` 같은 이름을 가진 모델을 reasoning 지원 모델로 취급합니다. ```bash ollama pull deepseek-r1:32b ``` - 추가 구성은 필요하지 않습니다. OpenClaw가 자동으로 이를 표시합니다. + 추가 구성은 필요하지 않습니다. OpenClaw가 자동으로 표시합니다. - Ollama는 무료이며 로컬에서 실행되므로, 모든 모델 비용은 $0으로 설정됩니다. 이는 자동 검색 모델과 수동 정의 모델 모두에 적용됩니다. + Ollama는 무료이며 로컬에서 실행되므로 모든 모델 비용은 $0으로 설정됩니다. 이는 자동 검색된 모델과 수동으로 정의된 모델 모두에 적용됩니다. - 번들 Ollama Plugin은 - [메모리 검색](/ko/concepts/memory)을 위한 메모리 임베딩 프로바이더를 등록합니다. 구성된 Ollama 기본 URL - 및 API 키를 사용합니다. + 번들된 Ollama Plugin은 [메모리 검색](/ko/concepts/memory)을 위한 메모리 임베딩 provider를 등록합니다. 구성된 Ollama 기본 URL과 API 키를 사용합니다. | 속성 | 값 | | ------------- | ------------------- | | 기본 모델 | `nomic-embed-text` | - | 자동 pull | 예 — 임베딩 모델이 로컬에 없으면 자동으로 pull됩니다 | + | 자동 pull | 예 — 로컬에 없으면 임베딩 모델을 자동으로 pull합니다 | - 메모리 검색 임베딩 프로바이더로 Ollama를 선택하려면: + 메모리 검색 임베딩 provider로 Ollama를 선택하려면 다음과 같이 설정하세요. ```json5 { @@ -468,10 +466,12 @@ OpenClaw는 번들 `web_search` 프로바이더로 **Ollama Web Search**를 지 - OpenClaw의 Ollama 통합은 기본적으로 **네이티브 Ollama API**(`/api/chat`)를 사용하며, 이 API는 스트리밍과 tool calling을 동시에 완전히 지원합니다. 특별한 구성이 필요하지 않습니다. + OpenClaw의 Ollama 통합은 기본적으로 **네이티브 Ollama API**(`/api/chat`)를 사용하며, 이 API는 스트리밍과 도구 호출을 동시에 완전히 지원합니다. 별도의 특별한 구성은 필요하지 않습니다. + + 네이티브 `/api/chat` 요청의 경우 OpenClaw는 thinking 제어도 Ollama에 직접 전달합니다. `/think off`와 `openclaw agent --thinking off`는 최상위 `think: false`를 보내고, `off`가 아닌 thinking 수준은 `think: true`를 보냅니다. - OpenAI 호환 엔드포인트를 사용해야 한다면 위의 "레거시 OpenAI 호환 모드" 섹션을 참고하세요. 해당 모드에서는 스트리밍과 tool calling이 동시에 작동하지 않을 수 있습니다. + OpenAI 호환 엔드포인트를 사용해야 한다면 위의 "레거시 OpenAI 호환 모드" 섹션을 참고하세요. 해당 모드에서는 스트리밍과 도구 호출이 동시에 작동하지 않을 수 있습니다. @@ -481,7 +481,7 @@ OpenClaw는 번들 `web_search` 프로바이더로 **Ollama Web Search**를 지 - Ollama가 실행 중인지, `OLLAMA_API_KEY`(또는 인증 프로필)를 설정했는지, 그리고 명시적인 `models.providers.ollama` 항목을 **정의하지 않았는지** 확인하세요. + Ollama가 실행 중인지, `OLLAMA_API_KEY`(또는 auth profile)를 설정했는지, 그리고 명시적인 `models.providers.ollama` 항목을 정의하지 **않았는지** 확인하세요. ```bash ollama serve @@ -496,10 +496,10 @@ OpenClaw는 번들 `web_search` 프로바이더로 **Ollama Web Search**를 지 - 모델이 목록에 없다면, 해당 모델을 로컬에서 pull하거나 `models.providers.ollama`에 명시적으로 정의하세요. + 모델이 목록에 없으면 로컬에서 해당 모델을 pull하거나 `models.providers.ollama`에 명시적으로 정의하세요. ```bash - ollama list # 설치된 항목 보기 + ollama list # 설치된 항목 확인 ollama pull gemma4 ollama pull gpt-oss:20b ollama pull llama3.3 # 또는 다른 모델 @@ -522,20 +522,20 @@ OpenClaw는 번들 `web_search` 프로바이더로 **Ollama Web Search**를 지 -추가 도움말: [Troubleshooting](/ko/help/troubleshooting) 및 [FAQ](/ko/help/faq). +추가 도움말: [문제 해결](/ko/help/troubleshooting) 및 [FAQ](/ko/help/faq). ## 관련 항목 - - 모든 프로바이더, 모델 ref, failover 동작 개요. + + 모든 provider, 모델 참조, 장애 조치 동작 개요. 모델 선택 및 구성 방법. - Ollama 기반 웹 검색의 전체 설정 및 동작 세부사항. + Ollama 기반 웹 검색의 전체 설정 및 동작 세부 정보. 전체 구성 참조. diff --git a/docs/ko/providers/tencent.md b/docs/ko/providers/tencent.md new file mode 100644 index 000000000..6b024567d --- /dev/null +++ b/docs/ko/providers/tencent.md @@ -0,0 +1,64 @@ +--- +read_when: + - OpenClaw에서 Tencent Hy 모델을 사용하려고 합니다. + - TokenHub API 키 설정이 필요합니다. +summary: Tencent Cloud TokenHub 설정 +title: Tencent Cloud (TokenHub) +x-i18n: + generated_at: "2026-04-22T06:01:08Z" + model: gpt-5.4 + provider: openai + source_hash: 04da073973792c55dc0c2d287bfc51187bb2128bbbd5c4a483f850adeea50ab5 + source_path: providers/tencent.md + workflow: 15 +--- + +# Tencent Cloud (TokenHub) + +Tencent Cloud provider는 TokenHub 엔드포인트(`tencent-tokenhub`)를 통해 Tencent Hy 모델에 접근할 수 있게 해줍니다. + +이 provider는 OpenAI 호환 API를 사용합니다. + +## 빠른 시작 + +```bash +openclaw onboard --auth-choice tokenhub-api-key +``` + +## 비대화형 예시 + +```bash +openclaw onboard --non-interactive \ + --mode local \ + --auth-choice tokenhub-api-key \ + --tokenhub-api-key "$TOKENHUB_API_KEY" \ + --skip-health \ + --accept-risk +``` + +## Provider 및 엔드포인트 + +| Provider | 엔드포인트 | 사용 사례 | +| ------------------ | ----------------------------- | ------------------------ | +| `tencent-tokenhub` | `tokenhub.tencentmaas.com/v1` | Tencent TokenHub를 통한 Hy | + +## 사용 가능한 모델 + +### tencent-tokenhub + +- **hy3-preview** — Hy3 프리뷰(256K 컨텍스트, 추론, 기본값) + +## 참고 + +- TokenHub 모델 ref는 `tencent-tokenhub/`를 사용합니다. +- 필요한 경우 `models.providers`에서 가격 및 컨텍스트 메타데이터를 재정의하세요. + +## 환경 참고 + +Gateway가 데몬(launchd/systemd)으로 실행되는 경우, `TOKENHUB_API_KEY`가 해당 프로세스에서 사용 가능하도록 해야 합니다(예: `~/.openclaw/.env` 또는 `env.shellEnv`를 통해). + +## 관련 문서 + +- [OpenClaw Configuration](/ko/gateway/configuration) +- [Model Providers](/ko/concepts/model-providers) +- [Tencent TokenHub](https://cloud.tencent.com/document/product/1823/130050)