chore(i18n): refresh ko translations

This commit is contained in:
openclaw-docs-i18n[bot] 2026-04-09 01:33:40 +00:00
parent f1a153b632
commit a0d596177d
21 changed files with 3987 additions and 4847 deletions

View File

@ -4,66 +4,66 @@ read_when:
summary: Discord 봇 지원 상태, 기능 및 구성
title: Discord
x-i18n:
generated_at: "2026-04-06T03:08:11Z"
generated_at: "2026-04-09T01:30:04Z"
model: gpt-5.4
provider: openai
source_hash: 54af2176a1b4fa1681e3f07494def0c652a2730165058848000e71a59e2a9d08
source_hash: 3cd2886fad941ae2129e681911309539e9a65a2352b777b538d7f4686a68f73f
source_path: channels/discord.md
workflow: 15
---
# Discord (Bot API)
상태: 공식 Discord gateway를 통해 DM 및 길드 채널에서 사용할 준비가 되어 있습니다.
상태: 공식 Discord 게이트웨이를 통해 DM 및 길드 채널에서 사용할 준비가 되었습니다.
<CardGroup cols={3}>
<Card title="페어링" icon="link" href="/ko/channels/pairing">
Discord DM은 기본적으로 페어링 모드입니다.
</Card>
<Card title="슬래시 명령어" icon="terminal" href="/ko/tools/slash-commands">
기본 명령 동작 및 명령 카탈로그.
기본 명령 동작 및 명령 카탈로그입니다.
</Card>
<Card title="채널 문제 해결" icon="wrench" href="/ko/channels/troubleshooting">
채널 전반의 진단 및 복구 흐름.
채널 전반의 진단 및 복구 흐름입니다.
</Card>
</CardGroup>
## 빠른 설정
새 애플리케이션과 봇을 만들고, 봇을 서버에 추가한 뒤, OpenClaw와 페어링해야 합니다. 봇은 본인 전용 비공개 서버에 추가하는 것을 권장합니다. 아직 서버가 없다면 먼저 [서버를 만드세요](https://support.discord.com/hc/en-us/articles/204849977-How-do-I-create-a-server) (**Create My Own > For me and my friends** 선택).
새 애플리케이션과 봇을 만들고, 봇을 서버에 추가한 뒤, OpenClaw와 페어링해야 합니다. 봇은 본인만 사용하는 비공개 서버에 추가하는 것을 권장합니다. 아직 서버가 없다면 먼저 [서버를 만드세요](https://support.discord.com/hc/en-us/articles/204849977-How-do-I-create-a-server) (**Create My Own > For me and my friends** 선택).
<Steps>
<Step title="Discord 애플리케이션과 봇 만들기">
[Discord Developer Portal](https://discord.com/developers/applications)로 이동한 **New Application**을 클릭합니다. 이름은 "OpenClaw"처럼 지정합니다.
[Discord Developer Portal](https://discord.com/developers/applications)로 이동한 다음 **New Application**을 클릭합니다. 이름은 "OpenClaw"처럼 지정합니다.
사이드바에서 **Bot**을 클릭합니다. **Username**은 OpenClaw 에이전트를 부르는 이름으로 설정합니다.
</Step>
<Step title="권한이 필요한 인텐트 활성화">
계속해서 **Bot** 페이지에서 아래로 스크롤하여 **Privileged Gateway Intents**로 이동한 다음을 활성화합니다.
<Step title="권한 있는 인텐트 활성화">
계속해서 **Bot** 페이지에서 아래로 스크롤하여 **Privileged Gateway Intents**로 이동한 다음, 다음을 활성화합니다.
- **Message Content Intent** (필수)
- **Server Members Intent** (권장; 역할 허용 목록 및 이름-대-ID 매칭에 필요)
- **Presence Intent** (선택 사항; 프레즌스 업데이트가 필요한 경우에만 필요)
- **Server Members Intent** (권장; 역할 allowlist 및 이름→ID 매칭에 필요)
- **Presence Intent** (선택 사항; 프레즌스 업데이트가 필요할 때만 사용)
</Step>
<Step title="봇 토큰 복사">
**Bot** 페이지 상단으로 다시 올라가 **Reset Token**을 클릭합니다.
다시 **Bot** 페이지 상단으로 올라가 **Reset Token**을 클릭합니다.
<Note>
이름과 달리, 이는 첫 번째 토큰을 생성하는 동작이며 "재설정"되는 것은 없습니다.
이름과 달리, 이것은 첫 번째 토큰을 생성하는 동작이며 실제로 무언가를 "재설정"하는 것은 아닙니다.
</Note>
토큰을 복사해 어딘가에 저장합니다. 이것이 **Bot Token**이며, 곧 필요합니다.
토큰을 복사하여 안전한 곳에 저장합니다. 이것이 **Bot Token**이며, 곧 필요합니다.
</Step>
<Step title="초대 URL 생성 후 서버에 봇 추가">
사이드바에서 **OAuth2**를 클릭합니다. 서버에 봇을 추가할 수 있도록 적절한 권한이 포함된 초대 URL을 생성합니다.
<Step title="초대 URL 생성 및 봇을 서버에 추가">
사이드바에서 **OAuth2**를 클릭합니다. 봇을 서버에 추가할 수 있도록 적절한 권한이 포함된 초대 URL을 생성합니다.
아래로 스크롤 **OAuth2 URL Generator**에서 다음을 활성화합니다.
아래로 스크롤하여 **OAuth2 URL Generator**에서 다음을 활성화합니다.
- `bot`
- `applications.commands`
@ -77,30 +77,30 @@ x-i18n:
- Attach Files
- Add Reactions (선택 사항)
맨 아래에 생성된 URL을 복사해 브라우저에 붙여넣고, 서버를 선택한 뒤 **Continue**를 클릭하여 연결합니다. 이제 Discord 서버에서 봇이 보여야 합니다.
하단에서 생성된 URL을 복사해 브라우저에 붙여넣고, 서버를 선택한 다음 **Continue**를 클릭해 연결합니다. 이제 Discord 서버에서 봇이 보여야 합니다.
</Step>
<Step title="Developer Mode 활성화 및 ID 수집">
Discord 앱으로 돌아가 내부 ID를 복사할 수 있도록 Developer Mode를 활성화해야 합니다.
다시 Discord 앱으로 돌아가 내부 ID를 복사할 수 있도록 Developer Mode를 활성화해야 합니다.
1. **User Settings**(아바타 옆 톱니바퀴 아이콘) → **Advanced****Developer Mode** 켜기
2. 사이드바에서 **서버 아이콘** 우클릭 → **Copy Server ID**
3. **본인 아바타** 우클릭 → **Copy User ID**
2. 사이드바에서 **server icon**을 우클릭 → **Copy Server ID**
3. 자신의 **avatar**를 우클릭 → **Copy User ID**
**Server ID**와 **User ID**를 Bot Token과 함께 저장하세요. 다음 단계에서 이 세 가지를 모두 OpenClaw에 보내게 됩니다.
**Server ID**와 **User ID**를 Bot Token과 함께 저장하세요. 다음 단계에서 이 세 가지 모두를 OpenClaw에 전달합니다.
</Step>
<Step title="서버 멤버의 DM 허용">
페어링이 작동하려면 Discord에서 봇이 사용자에게 DM을 보낼 수 있어야 합니다. **서버 아이콘**을 우클릭 → **Privacy Settings** → **Direct Messages** 켜기.
페어링이 작동하려면 Discord에서 봇이 사용자에게 DM을 보낼 수 있어야 합니다. **server icon**을 우클릭 → **Privacy Settings** → **Direct Messages** 켜기.
이렇게 하면 서버 멤버(봇 포함)가 사용자에게 DM을 보낼 수 있습니다. OpenClaw와 Discord DM을 사용하려면 이 설정을 계속 켜 두세요. 길드 채널만 사용할 계획이라면 페어링 후 DM을 비활성화해도 됩니다.
이렇게 하면 서버 멤버(봇 포함)가 사용자에게 DM을 보낼 수 있습니다. OpenClaw에서 Discord DM을 사용하려면 이 설정을 켜 둡니다. 길드 채널만 사용할 계획이라면, 페어링 후 DM을 비활성화해도 됩니다.
</Step>
<Step title="봇 토큰을 안전하게 설정하기(채팅 보내지 마세요)">
Discord 봇 토큰은 비밀 정보입니다(비밀번호와 유사). 에이전트에 메시지를 보내기 전에 OpenClaw를 실행하는 머신에 설정하세요.
<Step title="봇 토큰을 안전하게 설정하기(채팅으로 보내지 마세요)">
Discord 봇 토큰은 비밀 정보입니다(비밀번호와 유사). 에이전트에 메시지를 보내기 전에 OpenClaw가 실행 중인 머신에 설정하세요.
```bash
export DISCORD_BOT_TOKEN="YOUR_BOT_TOKEN"
@ -110,7 +110,7 @@ openclaw config set channels.discord.enabled true --strict-json
openclaw gateway
```
OpenClaw가 이미 백그라운드 서비스로 실행 중이라면 OpenClaw Mac 앱에서 다시 시작하거나 `openclaw gateway run` 프로세스를 중지 후 다시 시작하세요.
OpenClaw가 이미 백그라운드 서비스로 실행 중이면 OpenClaw Mac 앱에서 재시작하거나 `openclaw gateway run` 프로세스를 중지했다가 다시 시작하세요.
</Step>
@ -118,12 +118,12 @@ openclaw gateway
<Tabs>
<Tab title="에이전트에게 요청">
기존 채널(예: Telegram)에서 OpenClaw 에이전트와 대화하며 이렇게 요청하세요. Discord가 첫 번째 채널이라면 대신 CLI / config 탭을 사용하세요.
기존 채널(예: Telegram)에서 OpenClaw 에이전트와 대화하며 알려주세요. Discord가 첫 번째 채널이라면 대신 CLI / config 탭을 사용하세요.
> "이미 Discord 봇 토큰을 config에 설정했습니다. User ID `<user_id>`와 Server ID `<server_id>`로 Discord 설정을 완료해 주세요."
> "이미 Discord 봇 토큰을 config에 설정했습니다. User ID `<user_id>`와 Server ID `<server_id>`로 Discord 설정을 마무리해 주세요."
</Tab>
<Tab title="CLI / config">
파일 기반 config를 선호한다면 다음과 같이 설정하세요.
파일 기반 구성을 선호한다면 다음을 설정합니다.
```json5
{
@ -146,19 +146,19 @@ openclaw gateway
DISCORD_BOT_TOKEN=...
```
일반 텍스트 `token` 값도 지원됩니다. `channels.discord.token` env/file/exec provider 전반에서 SecretRef 값도 지원됩니다. 자세한 내용은 [Secrets Management](/ko/gateway/secrets)를 참고하세요.
일반 텍스트 `token` 값도 지원됩니다. `channels.discord.token` 대해 env/file/exec provider 전반에서 SecretRef 값도 지원됩니다. 자세한 내용은 [Secrets Management](/ko/gateway/secrets)를 참고하세요.
</Tab>
</Tabs>
</Step>
<Step title="첫 DM 페어링 승인">
gateway가 실행 중이 될 때까지 기다린 뒤 Discord에서 봇에게 DM을 보내세요. 봇이 페어링 코드를 응답합니다.
<Step title="첫 번째 DM 페어링 승인">
게이트웨이가 실행될 때까지 기다린 다음 Discord에서 봇에 DM을 보내세요. 봇이 페어링 코드로 응답합니다.
<Tabs>
<Tab title="에이전트에게 요청">
기존 채널의 에이전트에게 페어링 코드를 보내세요.
기존 채널에서 에이전트에게 페어링 코드를 보냅니다.
> "이 Discord 페어링 코드를 승인해 주세요: `<CODE>`"
</Tab>
@ -174,27 +174,27 @@ openclaw pairing approve discord <CODE>
페어링 코드는 1시간 후 만료됩니다.
이제 Discord DM을 통해 에이전트와 대화할 수 있어야 합니다.
이제 Discord에서 DM을 통해 에이전트와 대화할 수 있습니다.
</Step>
</Steps>
<Note>
토큰 확인은 계정을 인식합니다. config의 토큰 값이 env 대체값보다 우선합니다. `DISCORD_BOT_TOKEN`은 기본 계정에만 사용됩니다.
고급 아웃바운드 호출(메시지 도구/채널 작업)의 경우, 명시적인 호출별 `token`이 해당 호출에 사용됩니다. 이는 전송 및 읽기/프로브 계열 작업(예: read/search/fetch/thread/pins/permissions)에 적용됩니다. 계정 정책/재시도 설정은 여전히 활성 런타임 스냅샷에서 선택된 계정에서 가져옵니다.
토큰 해석은 계정을 인식합니다. config의 토큰 값이 env 대체값보다 우선합니다. `DISCORD_BOT_TOKEN`은 기본 계정에만 사용됩니다.
고급 아웃바운드 호출(message tool/channel actions)의 경우, 명시적 호출별 `token`이 해당 호출에 사용됩니다. 이는 send 및 read/probe 계열 작업(예: read/search/fetch/thread/pins/permissions)에 적용됩니다. 계정 정책/재시도 설정은 여전히 활성 런타임 스냅샷에서 선택된 계정에서 가져옵니다.
</Note>
## 권장: 길드 워크스페이스 설정
DM이 작동하면 Discord 서버를 전체 워크스페이스로 설정할 수 있습니다. 이렇게 하면 각 채널이 자체 컨텍스트를 가진 독립적인 에이전트 세션을 갖게 됩니다. 본인과 봇만 있는 비공개 서버에 권장됩니다.
DM이 작동하면 Discord 서버를 전체 워크스페이스로 설정할 수 있습니다. 이 경우 각 채널은 자체 컨텍스트를 가진 별도의 에이전트 세션을 갖습니다. 자신과 봇만 있는 비공개 서버에 권장됩니다.
<Steps>
<Step title="서버를 길드 허용 목록에 추가">
<Step title="서버를 길드 allowlist에 추가">
이렇게 하면 에이전트가 DM뿐 아니라 서버의 모든 채널에서 응답할 수 있습니다.
<Tabs>
<Tab title="에이전트에게 요청">
> "내 Discord Server ID `<server_id>`를 길드 허용 목록에 추가해 주세요"
> "내 Discord Server ID `<server_id>`를 길드 allowlist에 추가해 주세요"
</Tab>
<Tab title="Config">
@ -219,15 +219,15 @@ DM이 작동하면 Discord 서버를 전체 워크스페이스로 설정할 수
</Step>
<Step title="@mention 없이 응답 허용">
기본적으로 에이전트는 길드 채널에서 @mention 되었을 때만 응답합니다. 비공개 서버라면 모든 메시지에 응답하도록 설정하는 것이 일반적니다.
<Step title="@mention 없이 응답 허용">
기본적으로 에이전트는 길드 채널에서 @mention 되었을 때만 응답합니다. 비공개 서버라면 모든 메시지에 응답하도록 설정하는 것이 일반적으로 더 편리합니다.
<Tabs>
<Tab title="에이전트에게 요청">
> "이 서버에서 내 에이전트가 @mentioned 되지 않아도 응답하도록 해 주세요"
> "이 서버에서 @mentioned 되지 않아도 내 에이전트가 응답하도록 해 주세요"
</Tab>
<Tab title="Config">
길드 config에서 `requireMention: false` 설정하세요.
길드 config에서 `requireMention: false` 설정하세요.
```json5
{
@ -249,39 +249,39 @@ DM이 작동하면 Discord 서버를 전체 워크스페이스로 설정할 수
</Step>
<Step title="길드 채널의 메모리 계획">
기본적으로 장기 메모리(MEMORY.md)는 DM 세션에서만 로드됩니다. 길드 채널에서는 MEMORY.md를 자동 로드하지 않습니다.
기본적으로 장기 메모리(`MEMORY.md`)는 DM 세션에서만 로드됩니다. 길드 채널`MEMORY.md`를 자동 로드하지 않습니다.
<Tabs>
<Tab title="에이전트에게 요청">
> "Discord 채널에서 질문할 때 MEMORY.md의 장기 컨텍스트가 필요하면 memory_search 또는 memory_get을 사용해 주세요."
> "Discord 채널에서 질문할 때 `MEMORY.md`의 장기 컨텍스트가 필요하면 memory_search 또는 memory_get을 사용해 주세요."
</Tab>
<Tab title="수동">
모든 채널에서 공유 컨텍스트가 필요하다면 안정적인 지침은 `AGENTS.md` 또는 `USER.md`두세요(모든 세션에 주입됨). 장기 메모는 `MEMORY.md`에 두고 필요할 때 메모리 도구로 접근하세요.
모든 채널에서 공유 컨텍스트가 필요하다면 안정적인 지침은 `AGENTS.md` 또는 `USER.md`넣으세요(모든 세션에 주입됨). 장기 메모는 `MEMORY.md`에 보관하고, 필요할 때 memory 도구로 접근하세요.
</Tab>
</Tabs>
</Step>
</Steps>
이제 Discord 서버에 몇 개의 채널을 만들고 대화를 시작하세요. 에이전트는 채널 이름을 볼 수 있으며, 각 채널은 자체적으로 격리된 세션을 갖습니다. 따라서 `#coding`, `#home`, `#research` 또는 워크플로에 맞는 어떤 구성이든 만들 수 있습니다.
이제 Discord 서버에 몇 개의 채널을 만들고 대화를 시작하세요. 에이전트는 채널 이름을 볼 수 있으며, 각 채널은 자체적으로 격리된 세션을 갖습니다. 따라서 워크플로에 맞게 `#coding`, `#home`, `#research` 등을 설정할 수 있습니다.
## 런타임 모델
- Gateway가 Discord 연결을 소유합니다.
- 게이트웨이가 Discord 연결을 소유합니다.
- 응답 라우팅은 결정적입니다. Discord 인바운드 응답은 다시 Discord로 돌아갑니다.
- 기본값(`session.dmScope=main`)에서는 직접 채팅이 에이전트 메인 세션(`agent:main:main`)을 공유합니다.
- 길드 채널은 격리된 세션 키(`agent:<agentId>:discord:channel:<channelId>`)를 사용합니다.
- 그룹 DM은 기본적으로 무시됩니다(`channels.discord.dm.groupEnabled=false`).
- 기본 슬래시 명령은 격리된 명령 세션(`agent:<agentId>:discord:slash:<userId>`)에서 실행되지만, 라우팅된 대화 세션에는 계속 `CommandTargetSessionKey`가 전달됩니다.
- 기본 슬래시 명령은 격리된 명령 세션(`agent:<agentId>:discord:slash:<userId>`)에서 실행되며, 동시에 라우팅된 대화 세션에 대한 `CommandTargetSessionKey`도 전달합니다.
## 포럼 채널
Discord 포럼 및 미디어 채널은 스레드 게시물만 허용합니다. OpenClaw는 이를 생성하는 두 가지 방법을 지원합니다.
Discord 포럼 및 미디어 채널은 스레드 게시물만 허용합니다. OpenClaw는 이를 만드는 두 가지 방법을 지원합니다.
- 포럼 부모 채널(`channel:<forumId>`) 메시지를 보내 스레드를 자동 생성합니다. 스레드 제목은 메시지의 첫 번째 비어 있지 않은 줄을 사용합니다.
- `openclaw message thread create`를 사용하여 스레드를 직접 생성합니다. 포럼 채널에서는 `--message-id`를 전달하지 마세요.
- 포럼 부모(`channel:<forumId>`) 메시지를 보내 스레드를 자동 생성합니다. 스레드 제목은 메시지의 첫 번째 비어 있지 않은 줄을 사용합니다.
- `openclaw message thread create`를 사용 스레드를 직접 생성합니다. 포럼 채널에서는 `--message-id`를 전달하지 마세요.
예시: 포럼 부모 채널로 보내 스레드 생성
예시: 포럼 부모로 보내 스레드 생성
```bash
openclaw message send --channel discord --target channel:<forumId> \
@ -295,35 +295,35 @@ openclaw message thread create --channel discord --target channel:<forumId> \
--thread-name "Topic title" --message "Body of the post"
```
포럼 부모 채널은 Discord 컴포넌트를 허용하지 않습니다. 컴포넌트가 필요하면 스레드 자체(`channel:<threadId>`)로 보내세요.
포럼 부모 Discord 컴포넌트를 허용하지 않습니다. 컴포넌트가 필요하면 스레드 자체(`channel:<threadId>`)로 보내세요.
## 인터랙티브 컴포넌트
OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지원합니다. `components` payload와 함께 메시지 도구를 사용하세요. 상호작용 결과는 일반 인바운드 메시지처럼 다시 에이전트로 라우팅되며, 기존 Discord `replyToMode` 설정을 따릅니다.
OpenClaw는 에이전트 메시지에 대해 Discord components v2 컨테이너를 지원합니다. message tool에서 `components` 페이로드를 사용하세요. 인터랙션 결과는 일반적인 인바운드 메시지처럼 에이전트로 다시 라우팅되며, 기존 Discord `replyToMode` 설정을 따릅니다.
지원되는 블록:
- `text`, `section`, `separator`, `actions`, `media-gallery`, `file`
- 액션 행은 최대 5개의 버튼 또는 하나의 선택 메뉴를 허용합니다
- 액션 행은 최대 5개의 버튼 또는 단일 선택 메뉴를 허용합니다.
- 선택 유형: `string`, `user`, `role`, `mentionable`, `channel`
기본적으로 컴포넌트는 한 번만 사용할 수 있습니다. 만료될 때까지 버튼, 선택, 폼을 여러 번 사용할 수 있도록 하려면 `components.reusable=true` 설정하세요.
기본적으로 컴포넌트는 한 번만 사용할 수 있습니다. 버튼, 선택 항목, 폼을 만료될 때까지 여러 번 사용 가능하게 하려면 `components.reusable=true` 설정하세요.
누가 버튼을 클릭할 수 있는지 제한하려면 해당 버튼에 `allowedUsers`를 설정하세요(Discord 사용자 ID, 태그 또는 `*`). 설정된 경우, 일치하지 않는 사용자는 ephemeral 거부 응답을 받습니다.
버튼을 클릭할 수 있는 사용자를 제한하려면 해당 버튼에 `allowedUsers`를 설정하세요(Discord 사용자 ID, 태그 또는 `*`). 구성된 경우, 일치하지 않는 사용자는 ephemeral 거부 응답을 받습니다.
`/model``/models` 슬래시 명령은 provider와 model 드롭다운, 그리고 Submit 단계를 포함한 인터랙티브 모델 선택기를 엽니다. 선택기 응답은 ephemeral이며 호출한 사용자만 사용할 수 있습니다.
`/model``/models` 슬래시 명령은 provider 및 모델 드롭다운과 Submit 단계가 포함된 인터랙티브 모델 선택기를 엽니다. 선택기 응답은 ephemeral이며, 호출한 사용자만 사용할 수 있습니다.
파일 첨부:
- `file` 블록은 첨부 참조(`attachment://<filename>`)를 가리켜야 합니다
- 첨부는 `media`/`path`/`filePath`(단일 파일)로 제공하세요. 여러 파일에는 `media-gallery`를 사용하세요
- 업로드 이름이 첨부 참조와 일치해야 할 경우 `filename`을 사용해 덮어쓸 수 있습니다
- `file` 블록은 첨부 참조(`attachment://<filename>`)를 가리켜야 합니다.
- 첨부는 `media`/`path`/`filePath`(단일 파일)를 통해 제공하세요. 여러 파일은 `media-gallery`를 사용하세요.
- 첨부 참조와 업로드 이름이 일치해야 할 때는 `filename`으로 업로드 이름을 재정의하세요.
모달 폼:
- 최대 5개 필드와 함께 `components.modal`을 추가하세요
- 최대 5개 필드`components.modal`을 추가합니다.
- 필드 유형: `text`, `checkbox`, `radio`, `select`, `role-select`, `user-select`
- OpenClaw가 자동으로 트리거 버튼을 추가합니다
- OpenClaw가 트리거 버튼을 자동으로 추가합니다.
예시:
@ -379,20 +379,20 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
}
```
## 접근 제어 및 라우팅
## 액세스 제어 및 라우팅
<Tabs>
<Tab title="DM 정책">
`channels.discord.dmPolicy`는 DM 접근을 제어합니다(레거시: `channels.discord.dm.policy`).
`channels.discord.dmPolicy`는 DM 액세스를 제어합니다(레거시: `channels.discord.dm.policy`).
- `pairing` (기본값)
- `allowlist`
- `open` (`channels.discord.allowFrom`에 `"*"`가 포함되어야 함; 레거시: `channels.discord.dm.allowFrom`)
- `open` (`channels.discord.allowFrom`에 `"*"` 포함 필요, 레거시: `channels.discord.dm.allowFrom`)
- `disabled`
DM 정책이 open이 아니면 알 수 없는 사용자는 차단됩니다(`pairing` 모드에서는 페어링 안내가 표시될 수 있음).
DM 정책이 open이 아니면, 알 수 없는 사용자는 차단되거나(`pairing` 모드에서는) 페어링이 요청됩니다.
멀티 계정 우선순위:
다중 계정 우선순위:
- `channels.discord.accounts.default.allowFrom``default` 계정에만 적용됩니다.
- 이름이 있는 계정은 자체 `allowFrom`이 설정되지 않은 경우 `channels.discord.allowFrom`을 상속합니다.
@ -403,7 +403,7 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
- `user:<id>`
- `<@id>` 멘션
숫자만 있는 ID는 모호하므로, 명시적인 user/channel 대상 종류가 제공되지 않으면 거부됩니다.
숫자 ID만 단독으로 사용하 형식은 모호하므로, 명시적인 user/channel 대상 종류가 제공되지 않으면 거부됩니다.
</Tab>
@ -418,12 +418,12 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
`allowlist` 동작:
- 길드는 `channels.discord.guilds`와 일치해야 함(`id` 권장, slug도 허용)
- 선택적 발신자 허용 목록: `users`(안정적인 ID 권장) 및 `roles`(역할 ID만); 둘 중 하나라도 구성되면 발신자는 `users` 또는 `roles` 중 하나와 일치하면 허용됨
- 직접적인 이름/태그 매칭은 기본적으로 비활성화되어 있음. 비상 호환 모드로만 `channels.discord.dangerouslyAllowNameMatching: true`를 활성화하세요
- `users`는 이름/태그도 지원되지만 ID가 더 안전합니다. 이름/태그 항목이 사용되면 `openclaw security audit`가 경고합니다
- 길드에 `channels`가 구성되어 있으면 목록에 없는 채널은 거부됩니다
- 길드에 `channels` 블록이 없으면 해당 허용 목록 길드 내의 모든 채널이 허용됩니다
- 길드는 `channels.discord.guilds`와 일치해야 합니다(`id` 권장, slug 허용)
- 선택적 발신자 allowlist: `users`(안정적인 ID 권장) 및 `roles`(역할 ID만). 둘 중 하나라도 구성되어 있으면 발신자는 `users` 또는 `roles` 중 하나와 일치할 때 허용됩니다.
- 직접적인 이름/태그 매칭은 기본적으로 비활성화됩니다. 비상 호환 모드로만 `channels.discord.dangerouslyAllowNameMatching: true`를 사용하세요.
- `users` 이름/태그를 사용할 수는 있지만 ID가 더 안전합니다. 이름/태그 항목이 사용되면 `openclaw security audit`가 경고합니다.
- 길드에 `channels`가 구성되어 있으면 목록에 없는 채널은 거부됩니다.
- 길드에 `channels` 블록이 없으면 allowlist에 포함된 해당 길드의 모든 채널이 허용됩니다.
예시:
@ -449,7 +449,7 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
}
```
`DISCORD_BOT_TOKEN`만 설정하고 `channels.discord` 블록을 생성하지 않으면, 런타임 대체값은 `groupPolicy="allowlist"`입니다(로그에 경고 표시). 이는 `channels.defaults.groupPolicy``open`이어도 동일합니다.
`DISCORD_BOT_TOKEN`만 설정하고 `channels.discord` 블록을 만들지 않으면, 런타임 대체값은 `groupPolicy="allowlist"`입니다(로그에 경고 표시). 이는 `channels.defaults.groupPolicy``open`이어도 동일합니다.
</Tab>
@ -463,19 +463,19 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
- 지원되는 경우의 암시적 reply-to-bot 동작
`requireMention`은 길드/채널별로 구성됩니다(`channels.discord.guilds...`).
`ignoreOtherMentions`봇이 아닌 다른 사용자/역할을 멘션한 메시지(@everyone/@here 제외)를 선택적으로 버립니다.
`ignoreOtherMentions`다른 사용자/역할을 멘션했지만 봇은 멘션하지 않은 메시지를 선택적으로 버립니다(@everyone/@here 제외).
그룹 DM:
- 기본값: 무시(`dm.groupEnabled=false`)
- 선택적 허용 목록: `dm.groupChannels`(채널 ID 또는 slug)
- 기본값: 무시(`dm.groupEnabled=false`)
- 선택적 allowlist: `dm.groupChannels`(채널 ID 또는 slug)
</Tab>
</Tabs>
### 역할 기반 에이전트 라우팅
`bindings[].match.roles`를 사용하면 Discord 길드 멤버를 역할 ID 기준으로 서로 다른 에이전트에 라우팅할 수 있습니다. 역할 기반 바인딩은 역할 ID만 허용하며, peer 또는 parent-peer 바인딩 이후, guild-only 바인딩 이전에 평가됩니다. 바인딩이 다른 match 필드도 함께 설정한 경우(예: `peer` + `guildId` + `roles`), 구성된 모든 필드가 일치해야 합니다.
`bindings[].match.roles`를 사용해 Discord 길드 멤버를 역할 ID 기준으로 다른 에이전트로 라우팅합니다. 역할 기반 바인딩은 역할 ID만 허용하며, peer 또는 parent-peer 바인딩 이후이면서 guild-only 바인딩 이전에 평가됩니다. 바인딩이 다른 match 필드도 설정한 경우(예: `peer` + `guildId` + `roles`), 구성된 모든 필드가 일치해야 합니다.
```json5
{
@ -502,7 +502,7 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
## Developer Portal 설정
<AccordionGroup>
<Accordion title="앱 봇 만들기">
<Accordion title="앱 봇 만들기">
1. Discord Developer Portal -> **Applications** -> **New Application**
2. **Bot** -> **Add Bot**
@ -510,7 +510,7 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
</Accordion>
<Accordion title="권한이 필요한 인텐트">
<Accordion title="권한 있는 인텐트">
**Bot -> Privileged Gateway Intents**에서 다음을 활성화합니다.
- Message Content Intent
@ -523,7 +523,7 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
<Accordion title="OAuth 범위 및 기본 권한">
OAuth URL 생성기:
- 범위: `bot`, `applications.commands`
- scopes: `bot`, `applications.commands`
일반적인 기본 권한:
@ -539,26 +539,26 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
</Accordion>
<Accordion title="ID 복사">
Discord Developer Mode를 활성화한 다음을 복사합니다.
Discord Developer Mode를 활성화한 다음 다음을 복사합니다.
- server ID
- channel ID
- user ID
신뢰성 있는 감사 및 프로브를 위해 OpenClaw config에서는 숫자 ID를 권장합니다.
안정적인 감사 및 probe를 위해 OpenClaw config에서는 숫자 ID 사용을 권장합니다.
</Accordion>
</AccordionGroup>
## 기본 명령 명령 인증
## 기본 명령 명령 인증
- `commands.native`의 기본값은 `"auto"`이며 Discord에서 활성화됩니다.
- 채널별 재정의: `channels.discord.commands.native`.
- `commands.native=false`는 이전에 등록된 Discord 기본 명령을 명시적으로 제거합니다.
- 기본 명령 인증은 일반 메시지 처리와 동일한 Discord 허용 목록/정책을 사용합니다.
- Discord UI에서는 권한이 없는 사용자에게도 명령이 보일 수 있지만, 실행 시에는 여전히 OpenClaw 인증이 적용되며 "not authorized"가 반환됩니다.
- 기본 명령 인증은 일반 메시지 처리와 동일한 Discord allowlist/정책을 사용합니다.
- 권한이 없는 사용자에게도 명령이 Discord UI에 표시될 수 있지만, 실행 시에는 여전히 OpenClaw 인증이 적용되며 "not authorized"를 반환합니다.
명령 카탈로그 동작은 [Slash commands](/ko/tools/slash-commands)를 참고하세요.
명령 카탈로그 동작은 [Slash commands](/ko/tools/slash-commands)를 참고하세요.
기본 슬래시 명령 설정:
@ -580,23 +580,24 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
- `all`
- `batched`
참고: `off`는 암시적 응답 스레드 연결을 비활성화합니다. 명시적 `[[reply_to_*]]` 태그는 여전히 적용됩니다.
`first`는 해당 턴의 첫 번째 아웃바운드 Discord 메시지에 항상 암시적인 기본 응답 참조를 첨부합니다.
`batched`는 인바운드 턴이 여러 메시지의 디바운스된 배치였을 때만 Discord의 암시적인 기본 응답 참조를 첨부합니다. 이는 모든 단일 메시지 턴이 아니라 모호한 연속 대화에서만 주로 기본 응답을 사용하고 싶을 때 유용합니다.
참고: `off`는 암시적 응답 스레딩을 비활성화합니다. 명시적인 `[[reply_to_*]]` 태그는 여전히 적용됩니다.
`first`는 해당 턴의 첫 번째 아웃바운드 Discord 메시지에 암시적 기본 응답 참조를 항상 붙입니다.
`batched`
인바운드 턴이 여러 메시지의 디바운스된 배치였을 때만 Discord의 암시적 기본 응답 참조를 붙입니다. 이는 모든 단일 메시지 턴이 아니라, 주로 모호한 연속 대화에만 기본 응답을 사용하고 싶을 때 유용합니다.
메시지 ID는 컨텍스트/히스토리에 표시되므로 에이전트가 특정 메시지를 대상으로 지정할 수 있습니다.
메시지 ID는 컨텍스트/기록에 노출되므로 에이전트가 특정 메시지를 대상으로 지정할 수 있습니다.
</Accordion>
<Accordion title="실시간 스트림 미리보기">
OpenClaw는 임시 메시지를 보내고 텍스트가 도착함에 따라 편집하는 방식으로 초안 응답을 스트리밍할 수 있습니다.
<Accordion title="라이브 스트림 미리보기">
OpenClaw는 임시 메시지를 보내고 텍스트가 도착할 때마다 수정하는 방식으로 초안 응답을 스트리밍할 수 있습니다.
- `channels.discord.streaming`은 미리보기 스트리밍을 제어합니다(`off` | `partial` | `block` | `progress`, 기본값: `off`).
- 기본값이 `off`인 이유는 Discord 미리보기 편집이 특히 여러 봇이나 gateway가 같은 계정 또는 길드 트래픽을 공유하는 경우 빠르게 속도 제한에 걸릴 수 있기 때문입니다.
- 기본값이 `off`인 이유는 Discord 미리보기 수정이 빠르게 rate limit에 걸릴 수 있기 때문이며, 특히 여러 봇 또는 게이트웨이가 같은 계정이나 길드 트래픽을 공유할 때 더 그렇습니다.
- `progress`는 채널 간 일관성을 위해 허용되며 Discord에서는 `partial`로 매핑됩니다.
- `channels.discord.streamMode`는 레거시 별칭이며 자동 마이그레이션됩니다.
- `partial`은 토큰이 도착할 때 하나의 미리보기 메시지를 계속 편집합니다.
- `block`은 초안 크기의 청크를 출력합니다(크기 및 구분 기준 조정에는 `draftChunk` 사용).
- `partial`은 토큰이 도착할 때 단일 미리보기 메시지를 수정합니다.
- `block`은 초안 크기의 청크를 출력합니다(크기 및 분할 기준은 `draftChunk`로 조정).
예시:
@ -610,7 +611,7 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
}
```
`block` 모드 청킹 기본값(`channels.discord.textChunkLimit` 범위로 제한됨):
`block` 모드 청크 기본값(`channels.discord.textChunkLimit`로 제한됨):
```json5
{
@ -629,44 +630,45 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
미리보기 스트리밍은 텍스트 전용이며, 미디어 응답은 일반 전달로 대체됩니다.
참고: 미리보기 스트리밍은 블록 스트리밍과 별개입니다. Discord에서 블록 스트리밍이 명시적으로 활성화되면 OpenClaw는 이중 스트리밍을 피하기 위해 미리보기 스트림을 건너뜁니다.
참고: 미리보기 스트리밍은 블록 스트리밍과 별개입니다. Discord에 대해 블록 스트리밍이 명시적으로
활성화되면 OpenClaw는 이중 스트리밍을 피하기 위해 미리보기 스트림을 건너뜁니다.
</Accordion>
<Accordion title="히스토리, 컨텍스트 및 스레드 동작">
길드 히스토리 컨텍스트:
<Accordion title="기록, 컨텍스트 및 스레드 동작">
길드 기록 컨텍스트:
- `channels.discord.historyLimit` 기본값 `20`
- 대체값: `messages.groupChat.historyLimit`
- `0`이면 비활성화
DM 히스토리 제어:
DM 기록 제어:
- `channels.discord.dmHistoryLimit`
- `channels.discord.dms["<user_id>"].historyLimit`
스레드 동작:
- Discord 스레드는 채널 세션으로 라우팅됩니다
- 부모 스레드 메타데이터는 부모 세션 연결에 사용할 수 있습니다
- 스레드별 항목이 없으면 스레드 config는 부모 채널 config를 상속합니다
- Discord 스레드는 채널 세션으로 라우팅됩니다.
- 부모 스레드 메타데이터는 부모 세션 연결에 사용할 수 있습니다.
- 스레드별 항목이 없으면 스레드 config는 부모 채널 config를 상속합니다.
채널 주제는 **신뢰되지 않는** 컨텍스트로 주입됩니다(시스템 프롬프트 아님).
채널 주제는 **신뢰할 수 없는** 컨텍스트로 주입되며(시스템 프롬프트 아님),
응답 및 인용 메시지 컨텍스트는 현재 수신된 그대로 유지됩니다.
Discord 허용 목록은 주로 누가 에이전트를 트리거할 수 있는지를 제어하며, 완전한 보조 컨텍스트 리다크션 경계는 아닙니다.
Discord allowlist는 주로 누가 에이전트를 트리거할 수 있는지를 제어하며, 완전한 보조 컨텍스트 리다크션 경계는 아닙니다.
</Accordion>
<Accordion title="서브에이전트용 스레드 바운드 세션">
Discord는 스레드를 세션 대상에 바인딩할 수 있으므로, 해당 스레드의 후속 메시지가 동일한 세션(서브에이전트 세션 포함)으로 계속 라우팅니다.
<Accordion title="서브에이전트를 위한 스레드 바인딩 세션">
Discord는 스레드를 세션 대상에 바인딩하여 해당 스레드의 후속 메시지가 동일한 세션(서브에이전트 세션 포함)으로 계속 라우팅되도록 할 수 있습니다.
명령:
- `/focus <target>` 현재/새 스레드를 서브에이전트/세션 대상에 바인딩
- `/unfocus` 현재 스레드 바인딩 제거
- `/agents` 활성 실행 및 바인딩 상태 표시
- `/session idle <duration|off>` 포커스된 바인딩의 비활성 자동 unfocus 조회/업데이트
- `/session max-age <duration|off>` 포커스된 바인딩의 최대 유지 시간 조회/업데이트
- `/session idle <duration|off>` focused 바인딩에 대한 비활성 자동 unfocus 조회/업데이트
- `/session max-age <duration|off>` focused 바인딩에 대한 하드 최대 유지 시간 조회/업데이트
Config:
@ -696,8 +698,8 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
- `session.threadBindings.*`는 전역 기본값을 설정합니다.
- `channels.discord.threadBindings.*`는 Discord 동작을 재정의합니다.
- `sessions_spawn({ thread: true })`에 대해 스레드를 자동 생성/바인딩하려면 `spawnSubagentSessions` true여야 합니다.
- ACP(` /acp spawn ... --thread ...` 또는 `sessions_spawn({ runtime: "acp", thread: true })`)에 대해 스레드를 자동 생성/바인딩하려면 `spawnAcpSessions`가 true여야 합니다.
- `spawnSubagentSessions`는 `sessions_spawn({ thread: true })`에 대해 스레드를 자동 생성/바인딩하려면 true여야 합니다.
- `spawnAcpSessions`는 ACP에 대해 스레드를 자동 생성/바인딩하려면 true여야 합니다(`(/acp spawn ... --thread ...` 또는 `sessions_spawn({ runtime: "acp", thread: true })`).
- 계정에서 스레드 바인딩이 비활성화되어 있으면 `/focus` 및 관련 스레드 바인딩 작업을 사용할 수 없습니다.
자세한 내용은 [Sub-agents](/ko/tools/subagents), [ACP Agents](/ko/tools/acp-agents), [Configuration Reference](/ko/gateway/configuration-reference)를 참고하세요.
@ -705,11 +707,11 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
</Accordion>
<Accordion title="영구 ACP 채널 바인딩">
안정적인 "항상 켜짐" ACP 워크스페이스를 위해 Discord 대화를 대상으로 하는 최상위 타입 지정 ACP 바인딩을 구성할 수 있습니다.
안정적인 "항상 켜짐" ACP 워크스페이스를 위해, Discord 대화를 대상으로 하는 최상위 typed ACP 바인딩을 구성할 수 있습니다.
Config 경로:
- `type: "acp"``match.channel: "discord"`를 사용하`bindings[]`
- `type: "acp"``match.channel: "discord"`가 있`bindings[]`
예시:
@ -761,15 +763,15 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
참고:
- `/acp spawn codex --bind here`는 현재 Discord 채널 또는 스레드를 그 자리에서 바인딩하고, 이후 메시지를 동일한 ACP 세션으로 계속 라우팅합니다.
- 이는 여전히 "새로운 Codex ACP 세션 시작"을 의미할 수 있지만, Discord 스레드를 새로 만드는 것은 아닙니다. 기존 채널이 계속 채팅 표면으로 유지됩니다.
- Codex는 여전히 자체 `cwd` 또는 디스크상의 backend 워크스페이스에서 실행될 수 있습니다. 이 워크스페이스는 런타임 상태이며 Discord 스레드가 아닙니다.
- `/acp spawn codex --bind here`는 현재 Discord 채널 또는 스레드를 그 자리에서 바인딩하며, 이후 메시지도 동일한 ACP 세션으로 계속 라우팅되도록 유지합니다.
- 이는 여전히 "새 Codex ACP 세션 시작"을 의미할 수 있지만, 그 자체로 새 Discord 스레드를 생성하지는 않습니다. 기존 채널이 그대로 채팅 표면으로 유지됩니다.
- Codex는 여전히 자체 `cwd` 또는 디스크상의 backend 워크스페이스에서 실행될 수 있습니다. 그 워크스페이스는 Discord 스레드가 아니라 런타임 상태입니다.
- 스레드 메시지는 부모 채널 ACP 바인딩을 상속할 수 있습니다.
- 바인딩된 채널 또는 스레드에서 `/new``/reset` 동일한 ACP 세션을 그 자리에서 재설정합니다.
- 임시 스레드 바인딩도 계속 작동하며 활성 상태에서는 대상 확인을 재정의할 수 있습니다.
- `spawnAcpSessions`는 OpenClaw가 `--thread auto|here`를 통해 자식 스레드를 생성/바인딩해야 하는 경우에만 필요합니다. 현재 채널에서 `/acp spawn ... --bind here`를 사용하는 데는 필요하지 않습니다.
- 바인딩된 채널 또는 스레드에서`/new``/reset` 동일한 ACP 세션을 그 자리에서 재설정합니다.
- 임시 스레드 바인딩은 여전히 작동하며 활성 상태일 때 대상 해석을 재정의할 수 있습니다.
- `spawnAcpSessions`는 OpenClaw가 `--thread auto|here`를 통해 하위 스레드를 생성/바인딩해야 할 때만 필요합니다. 현재 채널에서 `/acp spawn ... --bind here`를 사용할 때는 필요하지 않습니다.
바인딩 동작 자세한 내용은 [ACP Agents](/ko/tools/acp-agents)를 참고하세요.
바인딩 동작에 대한 자세한 내용은 [ACP Agents](/ko/tools/acp-agents)를 참고하세요.
</Accordion>
@ -785,25 +787,25 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
</Accordion>
<Accordion title="확인 리액션">
<Accordion title="Ack 리액션">
`ackReaction`은 OpenClaw가 인바운드 메시지를 처리하는 동안 확인용 이모지를 보냅니다.
확인 순서:
해석 순서:
- `channels.discord.accounts.<accountId>.ackReaction`
- `channels.discord.ackReaction`
- `messages.ackReaction`
- 에이전트 identity 이모지 대체값(`agents.list[].identity.emoji`, 없으면 "👀")
- 에이전트 identity 이모지 대체값(`agents.list[].identity.emoji`, 없으면 `"👀"`)
참고:
- Discord는 유니코드 이모지 또는 사용자 지정 이모지 이름을 허용합니다.
- 채널 또는 계정에서 리액션을 비활성화하려면 `""`를 사용하세요.
- Discord는 유니코드 이모지 또는 커스텀 이모지 이름을 허용합니다.
- 채널이나 계정에서 리액션을 비활성화하려면 `""`를 사용하세요.
</Accordion>
<Accordion title="Config 쓰기">
채널에서 시작된 config 쓰기는 기본적으로 활성화되어 있습니다.
채널에서 시작된 config 쓰기는 기본적으로 활성화니다.
이는 `/config set|unset` 흐름에 영향을 줍니다(명령 기능이 활성화된 경우).
@ -821,8 +823,8 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
</Accordion>
<Accordion title="Gateway 프록시">
`channels.discord.proxy`를 사용해 Discord gateway WebSocket 트래픽과 시작 시 REST 조회(애플리케이션 ID + 허용 목록 확인)를 HTTP(S) 프록시를 통해 라우팅합니다.
<Accordion title="게이트웨이 프록시">
`channels.discord.proxy`를 사용하면 Discord 게이트웨이 WebSocket 트래픽과 시작 시 REST 조회(application ID + allowlist 해석)를 HTTP(S) 프록시를 통해 라우팅할 수 있습니다.
```json5
{
@ -853,7 +855,7 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
</Accordion>
<Accordion title="PluralKit 지원">
프록시된 메시지를 시스템 멤버 identity에 매핑하도록 PluralKit 확인 기능을 활성화합니다.
프록시된 메시지를 시스템 멤버 identity에 매핑하기 위해 PluralKit 해석을 활성화합니다.
```json5
{
@ -870,10 +872,10 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
참고:
- 허용 목록은 `pk:<memberId>`를 사용할 수 있습니다
- 멤버 표시 이름은 `channels.discord.dangerouslyAllowNameMatching: true`일 때만 name/slug 기준으로 매칭됩니다
- 조회는 원본 메시지 ID를 사용하며 시간 창 제약이 있습니다
- 조회에 실패하면 프록시된 메시지는 봇 메시지로 처리되어 `allowBots=true`가 아닌 한 버려집니다
- allowlist에서 `pk:<memberId>`를 사용할 수 있습니다.
- 멤버 표시 이름은 `channels.discord.dangerouslyAllowNameMatching: true`일 때만 이름/slug로 매칭됩니다.
- 조회는 원본 메시지 ID를 사용하며 시간 창 제약이 있습니다.
- 조회에 실패하면 프록시된 메시지는 봇 메시지로 처리되어 `allowBots=true`가 아닌 한 버려집니다.
</Accordion>
@ -892,7 +894,7 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
}
```
활동 예시(기본 활동 유형은 사용자 지정 상태):
활동 예시(커스텀 상태가 기본 활동 유형):
```json5
{
@ -925,7 +927,7 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
- 1: Streaming (`activityUrl` 필요)
- 2: Listening
- 3: Watching
- 4: Custom (활동 텍스트를 상태 값으로 사용하며, 이모지는 선택 사항)
- 4: Custom (활동 텍스트를 상태 값으로 사용, 이모지는 선택 사항)
- 5: Competing
auto presence 예시(런타임 상태 신호):
@ -953,72 +955,78 @@ OpenClaw는 에이전트 메시지용 Discord components v2 컨테이너를 지
</Accordion>
<Accordion title="Discord 승인">
Discord는 DM에서 버튼 기반 승인 처리를 지원하며, 선택적으로 원래 채널에 승인 프롬프트를 게시할 수 있습니다.
<Accordion title="Discord에서 승인">
Discord는 DM에서 버튼 기반 승인 처리를 지원하며, 필요하면 원래 채널에 승인 프롬프트를 게시할 수 있습니다.
Config 경로:
- `channels.discord.execApprovals.enabled`
- `channels.discord.execApprovals.approvers` (선택 사항; 가능하면 `commands.ownerAllowFrom`으로 대체)
- `channels.discord.execApprovals.approvers` (선택 사항, 가능하면 `commands.ownerAllowFrom`으로 대체)
- `channels.discord.execApprovals.target` (`dm` | `channel` | `both`, 기본값: `dm`)
- `agentFilter`, `sessionFilter`, `cleanupAfterResolve`
Discord는 `enabled`가 설정되지 않았거나 `"auto"`이고, `execApprovals.approvers` 또는 `commands.ownerAllowFrom`에서 최소 한 명의 승인자를 확인할 수 있으면 기본 exec 승인을 자동 활성화합니다. Discord는 채널 `allowFrom`, 레거시 `dm.allowFrom`, 또는 direct-message `defaultTo`에서 exec 승인자를 추론하지 않습니다. Discord를 기본 승인 클라이언트로 명시적으로 비활성화하려면 `enabled: false` 설정하세요.
`enabled`가 unset 또는 `"auto"`이고 `execApprovals.approvers` 또는 `commands.ownerAllowFrom`에서 최소 하나의 approver를 해석할 수 있으면, Discord는 기본 exec approval을 자동 활성화합니다. Discord는 채널 `allowFrom`, 레거시 `dm.allowFrom`, 직접 메시지 `defaultTo`로부터 exec approver를 추론하지 않습니다. Discord를 기본 승인 클라이언트로 명시적으로 비활성화하려면 `enabled: false` 설정하세요.
`target``channel` 또는 `both`이면 승인 프롬프트가 채널에 표시됩니다. 확인된 승인자만 버튼을 사용할 수 있으며, 다른 사용자는 ephemeral 거부 응답을 받습니다. 승인 프롬프트에는 명령 텍스트가 포함되므로, 채널 전달은 신뢰할 수 있는 채널에서만 활성화하세요. 세션 키에서 채널 ID를 유도할 수 없으면 OpenClaw는 DM 전달로 대체합니다.
`target``channel` 또는 `both`이면 승인 프롬프트가 채널에 표시됩니다. 해석된 approver만 버튼을 사용할 수 있으며, 다른 사용자는 ephemeral 거부 응답을 받습니다. 승인 프롬프트에는 명령 텍스트가 포함되므로, 채널 전달은 신뢰할 수 있는 채널에서만 활성화하세요. 세션 키에서 채널 ID를 유도할 수 없으면 OpenClaw는 DM 전달로 대체합니다.
Discord는 다른 채팅 채널에서 사용하는 공용 승인 버튼도 렌더링합니다. 기본 Discord 어댑터는 주로 승인자 DM 라우팅과 채널 팬아웃을 추가합니다.
이러한 버튼이 존재할 때는 그것이 기본 승인 UX입니다. 도구 결과에서 채팅 승인이 불가능하거나 수동 승인이 유일한 경로라고 말하는 경우에만 OpenClaw는 수동 `/approve` 명령을 포함해야 합니다.
Discord는 다른 채팅 채널에서 사용하는 공용 승인 버튼도 렌더링합니다. 기본 Discord 어댑터는 주로 approver DM 라우팅과 채널 팬아웃을 추가합니다.
이러한 버튼이 मौजूद할 때는 그것이 기본 승인 UX여야 하며, OpenClaw는
도구 결과가 채팅 승인을 사용할 수 없다고 표시하거나 수동 승인이 유일한 경로일 때만 수동 `/approve` 명령을 포함해야 합니다.
이 핸들러의 gateway 인증은 다른 Gateway 클라이언트와 동일한 공용 자격 증명 확인 계약을 사용합니다.
이 핸들러의 게이트웨이 인증은 다른 게이트웨이 클라이언트와 동일한 공용 자격 증명 해석 계약을 사용합니다.
- env 우선 로컬 인증(`OPENCLAW_GATEWAY_TOKEN` / `OPENCLAW_GATEWAY_PASSWORD` 다음 `gateway.auth.*`)
- 로컬 모드에서는 `gateway.auth.*`가 설정되지 않은 경우에만 `gateway.remote.*`를 대체값으로 사용할 수 있으며, 설정되었지만 확인되지 않은 로컬 SecretRef는 fail closed 처리됩니다
- 해당하는 경우 `gateway.remote.*`를 통한 원격 모드 지원
- URL 재정의는 override-safe입니다. CLI 재정의는 암시적 자격 증명을 재사용하지 않으며, env 재정의는 env 자격 증명만 사용합니다
- env 우선 로컬 인증(`OPENCLAW_GATEWAY_TOKEN` / `OPENCLAW_GATEWAY_PASSWORD` `gateway.auth.*`)
- local 모드에서 `gateway.auth.*`가 unset인 경우에만 `gateway.remote.*`를 대체값으로 사용할 수 있으며, 구성되었지만 해석되지 않은 로컬 SecretRef는 fail closed 됩니다.
- 적용 가능한 경우 `gateway.remote.*`를 통한 remote 모드 지원
- URL 재정의는 override-safe입니다. CLI 재정의는 암시적 자격 증명을 재사용하지 않으며, env 재정의는 env 자격 증명만 사용합니다.
승인 확인 동작:
승인 해석 동작:
- `plugin:` 접두사가 있는 ID는 `plugin.approval.resolve`를 통해 확인됩니다.
- 다른 ID는 `exec.approval.resolve`를 통해 확인됩니다.
- Discord는 여기서 추가적인 exec-to-plugin 대체 확인 단계를 수행하지 않습니다. ID 접두사가 어떤 gateway 메서드를 호출할지 결정합니다.
- `plugin:` 접두사가 붙은 ID는 `plugin.approval.resolve`를 통해 해석됩니다.
- 그 외 ID는 `exec.approval.resolve`를 통해 해석됩니다.
- Discord는 여기서 추가적인 exec-to-plugin 대체 홉을 수행하지 않으며,
ID 접두사가 호출할 게이트웨이 메서드를 결정합니다.
Exec 승인은 기본적으로 30분 후 만료됩니다. 알 수 없는 approval ID 오류로 승인에 실패한다면 승인자 확인, 기능 활성화, 전달된 approval id 종류가 대기 중인 요청과 일치하는지 확인하세요.
exec approval은 기본적으로 30분 후 만료됩니다. 승인에서
알 수 없는 approval ID 오류가 발생하면 approver 해석, 기능 활성화,
그리고 전달된 approval ID 종류가 보류 중 요청과 일치하는지 확인하세요.
관련 문서: [Exec approvals](/ko/tools/exec-approvals)
</Accordion>
</AccordionGroup>
## 도구 및 작업 게이트
## 도구 및 액션 게이트
Discord 메시지 작업에는 메시징, 채널 관리, moderation, 프레즌스, 메타데이터 작업이 포함됩니다.
Discord 메시지 액션에는 메시징, 채널 관리, moderation, presence, 메타데이터 액션이 포함됩니다.
핵심 예시:
- 메시징: `sendMessage`, `readMessages`, `editMessage`, `deleteMessage`, `threadReply`
- 리액션: `react`, `reactions`, `emojiList`
- moderation: `timeout`, `kick`, `ban`
- 프레즌스: `setPresence`
- presence: `setPresence`
작업 게이트는 `channels.discord.actions.*` 아래에 있습니다.
`event-create` 액션은 예약 이벤트 커버 이미지를 설정하기 위한 선택적 `image` 매개변수(URL 또는 로컬 파일 경로)를 허용합니다.
액션 게이트는 `channels.discord.actions.*` 아래에 있습니다.
기본 게이트 동작:
| 작업 그룹 | 기본값 |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------- |
| 액션 그룹 | 기본값 |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------- |
| reactions, messages, threads, pins, polls, search, memberInfo, roleInfo, channelInfo, channels, voiceStatus, events, stickers, emojiUploads, stickerUploads, permissions | 활성화됨 |
| roles | 비활성화 |
| moderation | 비활성화 |
| presence | 비활성화 |
| roles | 비활성화 |
| moderation | 비활성화 |
| presence | 비활성화 |
## Components v2 UI
OpenClaw는 exec 승인 및 교차 컨텍스트 마커에 Discord components v2를 사용합니다. Discord 메시지 작업도 사용자 지정 UI용 `components`를 받을 수 있습니다(고급 기능; discord 도구를 통해 컴포넌트 payload를 구성해야 함). 반면 레거시 `embeds`도 계속 사용할 수 있지만 권장되지는 않습니다.
OpenClaw는 exec approval 및 cross-context marker에 Discord components v2를 사용합니다. Discord 메시지 액션도 커스텀 UI를 위해 `components`를 받을 수 있습니다(고급 기능; discord tool을 통해 컴포넌트 페이로드를 구성해야 함). 레거시 `embeds`도 계속 사용할 수 있지만 권장되지는 않습니다.
- `channels.discord.ui.components.accentColor`는 Discord 컴포넌트 컨테이너에 사용는 강조 색상을 설정합니다(hex).
- 계정별 설정: `channels.discord.accounts.<id>.ui.components.accentColor`.
- components v2가 존재하`embeds`는 무시됩니다.
- `channels.discord.ui.components.accentColor`는 Discord 컴포넌트 컨테이너에 사용는 강조 색상을 설정합니다(hex).
- 계정별 설정 `channels.discord.accounts.<id>.ui.components.accentColor`를 사용합니다.
- components v2가 있으`embeds`는 무시됩니다.
예시:
@ -1046,7 +1054,7 @@ OpenClaw는 실시간 연속 대화를 위해 Discord 음성 채널에 참여할
- `channels.discord.voice`를 구성합니다.
- 봇은 대상 음성 채널에서 Connect + Speak 권한이 필요합니다.
Discord 전용 기본 명령 `/vc join|leave|status`를 사용해 세션을 제어하세요. 이 명령은 계정 기본 에이전트를 사용하며 다른 Discord 명령과 동일한 허용 목록 및 그룹 정책 규칙을 따릅니다.
Discord 전용 기본 명령 `/vc join|leave|status`를 사용해 세션을 제어하세요. 이 명령은 계정 기본 에이전트를 사용하며, 다른 Discord 명령과 동일한 allowlist 및 길드 정책 규칙을 따릅니다.
자동 참여 예시:
@ -1076,23 +1084,23 @@ Discord 전용 기본 명령 `/vc join|leave|status`를 사용해 세션을 제
참고:
- `voice.tts`는 음성 재생에 한해 `messages.tts`를 재정의합니다.
- 음성 전사 턴은 Discord `allowFrom`(또는 `dm.allowFrom`)에서 소유자 상태를 파생합니다. 소유자가 아닌 화자는 소유자 전용 도구(예: `gateway`, `cron`)에 접근할 수 없습니다.
- 음성은 기본적으로 활성화되어 있습니다. 비활성화하려면 `channels.discord.voice.enabled=false` 설정하세요.
- `voice.daveEncryption``voice.decryptionFailureTolerance``@discordjs/voice` 참여 옵션으로 그대로 전달됩니다.
- `@discordjs/voice`의 기본값은 설정되지 않은 경우 `daveEncryption=true`, `decryptionFailureTolerance=24`입니다.
- OpenClaw는 수신 복호화 실패도 감시하며, 짧은 시간 동안 반복된 실패가 발생하면 음성 채널을 나갔다가 다시 참여해 자동 복구합니다.
- 수신 로그에 `DecryptionFailed(UnencryptedWhenPassthroughDisabled)`가 반복적으로 표시된다면, 이는 [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419)에 추적된 상위 `@discordjs/voice` 수신 버그일 수 있습니다.
- `voice.tts`는 음성 재생에 대해서만 `messages.tts`를 재정의합니다.
- 음성 전사 턴은 Discord `allowFrom`(또는 `dm.allowFrom`)에서 소유자 상태를 파생합니다. 소유자가 아닌 화자는 소유자 전용 도구(예: `gateway`, `cron`)에 접근할 수 없습니다.
- 음성은 기본적으로 활성화되어 있습니다. 비활성화하려면 `channels.discord.voice.enabled=false` 설정하세요.
- `voice.daveEncryption``voice.decryptionFailureTolerance``@discordjs/voice` 조인 옵션으로 그대로 전달됩니다.
- `@discordjs/voice`의 기본값은 설정되지 않은 경우 `daveEncryption=true` `decryptionFailureTolerance=24`입니다.
- OpenClaw는 수신 복호화 실패도 감시하며, 짧은 시간 동안 반복 실패가 발생하면 음성 채널에서 나갔다가 다시 참여하여 자동 복구합니다.
- 수신 로그에 `DecryptionFailed(UnencryptedWhenPassthroughDisabled)`가 반복해서 표시되면, 이는 [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419)에서 추적 중인 업스트림 `@discordjs/voice` 수신 버그일 수 있습니다.
## 음성 메시지
Discord 음성 메시지는 파형 미리보기를 표시하며 OGG/Opus 오디오와 메타데이터가 필요합니다. OpenClaw는 파형을 자동 생성하지만, 오디오 파일을 검사하고 변환하려면 gateway 호스트에서 `ffmpeg``ffprobe`를 사용할 수 있어야 합니다.
Discord 음성 메시지는 파형 미리보기를 표시하며 OGG/Opus 오디오와 메타데이터가 필요합니다. OpenClaw는 파형을 자동 생성하지만, 오디오 파일을 검사하고 변환하려면 게이트웨이 호스트에서 `ffmpeg``ffprobe`를 사용할 수 있어야 합니다.
요구 사항 및 제약:
- **로컬 파일 경로**를 제공해야 합니다(URL은 거부됨).
- 텍스트 콘텐츠는 생략해야 합니다(Discord는 동일 payload에서 텍스트 + 음성 메시지를 허용하지 않음).
- 어떤 오디오 형식이든 허용되며, 필요하면 OpenClaw가 OGG/Opus로 변환합니다.
- 텍스트 콘텐츠는 생략해야 합니다(Discord는 동일한 페이로드에서 텍스트 + 음성 메시지를 허용하지 않음).
- 어떤 오디오 형식이든 허용되며, 필요할 경우 OpenClaw가 OGG/Opus로 변환합니다.
예시:
@ -1106,19 +1114,19 @@ message(action="send", channel="discord", target="channel:123", path="/path/to/a
<Accordion title="허용되지 않은 인텐트를 사용했거나 봇이 길드 메시지를 보지 못함">
- Message Content Intent 활성화
- 사용자/멤버 확인에 의존한다면 Server Members Intent 활성화
- 인텐트 변경 후 gateway 재시작
- 사용자/멤버 해석에 의존하는 경우 Server Members Intent 활성화
- 인텐트를 변경한 뒤 게이트웨이 재시작
</Accordion>
<Accordion title="길드 메시지가 예상치 못하게 차단됨">
<Accordion title="길드 메시지가 예상치 게 차단됨">
- `groupPolicy` 확인
- `channels.discord.guilds` 아래 길드 허용 목록 확인
- 길드 `channels` 맵이 존재하면 목록에 있는 채널만 허용됨
- `requireMention` 동작 멘션 패턴 확인
- `channels.discord.guilds` 아래의 길드 allowlist 확인
- 길드 `channels` 맵이 있으면 목록에 있는 채널만 허용됨
- `requireMention` 동작 멘션 패턴 확인
유용한 확인 명령:
유용한 점검:
```bash
openclaw doctor
@ -1131,9 +1139,9 @@ openclaw logs --follow
<Accordion title="Require mention이 false인데도 여전히 차단됨">
일반적인 원인:
- 일치하는 길드/채널 허용 목록 없이 `groupPolicy="allowlist"` 사용
- `requireMention`이 잘못된 위치에 구성됨(`channels.discord.guilds` 또는 채널 항목 아래에 있어야 함)
- 발신자가 길드/채널 `users` 허용 목록에 의해 차단됨
- 일치하는 길드/채널 allowlist 없이 `groupPolicy="allowlist"` 설정
- `requireMention`이 잘못된 위치에 구성됨(`channels.discord.guilds` 또는 채널 항목 아래야 함)
- 발신자가 길드/채널 `users` allowlist에 의해 차단됨
</Accordion>
@ -1145,16 +1153,16 @@ openclaw logs --follow
- `Slow listener detected ...`
- `discord inbound worker timed out after ...`
Listener 예산 조정 값:
리스너 예산 설정:
- 단일 계정: `channels.discord.eventQueue.listenerTimeout`
- 멀티 계정: `channels.discord.accounts.<accountId>.eventQueue.listenerTimeout`
- 다중 계정: `channels.discord.accounts.<accountId>.eventQueue.listenerTimeout`
Worker 실행 시간 초과 조정 값:
워커 실행 시간 초과 설정:
- 단일 계정: `channels.discord.inboundWorker.runTimeoutMs`
- 멀티 계정: `channels.discord.accounts.<accountId>.inboundWorker.runTimeoutMs`
- 기본값: `1800000` (30분); 비활성화하려면 `0`으로 설정
- 다중 계정: `channels.discord.accounts.<accountId>.inboundWorker.runTimeoutMs`
- 기본값: `1800000` (30분), 비활성화하려면 `0` 설정
권장 기준값:
@ -1177,12 +1185,13 @@ openclaw logs --follow
}
```
느린 listener 설정에는 `eventQueue.listenerTimeout`을 사용하고, 대기열에 들어간 에이전트 턴에 별도의 안전장치를 두고 싶을 때만 `inboundWorker.runTimeoutMs`를 사용하세요.
느린 리스너 설정에는 `eventQueue.listenerTimeout`을 사용하고, `inboundWorker.runTimeoutMs`
큐에 들어간 에이전트 턴에 대해 별도의 안전 장치가 필요할 때만 사용하세요.
</Accordion>
<Accordion title="권한 감사 불일치">
`channels status --probe` 권한 검사는 숫자 채널 ID에서만 작동합니다.
`channels status --probe` 권한 확인은 숫자 채널 ID에 대해서만 동작합니다.
slug 키를 사용하면 런타임 매칭은 여전히 작동할 수 있지만, probe는 권한을 완전히 검증할 수 없습니다.
@ -1199,20 +1208,20 @@ openclaw logs --follow
<Accordion title="봇 간 루프">
기본적으로 봇이 작성한 메시지는 무시됩니다.
`channels.discord.allowBots=true`로 설정한 경우, 루프 동작을 피하려면 엄격한 멘션 및 허용 목록 규칙을 사용하세요.
봇을 멘션하는 봇 메시지만 허용하려면 `channels.discord.allowBots="mentions"`를 권장합니다.
`channels.discord.allowBots=true`를 설정하는 경우, 루프 동작을 피하려면 엄격한 멘션 및 allowlist 규칙을 사용하세요.
봇을 멘션 봇 메시지만 허용하려면 `channels.discord.allowBots="mentions"`를 권장합니다.
</Accordion>
<Accordion title="DecryptionFailed(...)로 음성 STT가 끊김">
- Discord 음성 수신 복구 로직이 포함되도록 OpenClaw를 최신 상태로 유지하세요(`openclaw update`)
- `channels.discord.voice.daveEncryption=true`인지 확인하세요(기본값)
- `channels.discord.voice.decryptionFailureTolerance=24`(상위 기본값)에서 시작하고 필요한 경우에만 조정하세요
- 로그에서 다음을 확인하세요.
- Discord 음성 수신 복구 로직이 포함되도록 OpenClaw를 최신 상태로 유지하세요(`openclaw update`).
- `channels.discord.voice.daveEncryption=true`인지 확인하세요(기본값).
- `channels.discord.voice.decryptionFailureTolerance=24`(업스트림 기본값)부터 시작하고 필요할 때만 조정하세요.
- 다음 로그를 확인하세요.
- `discord voice: DAVE decrypt failures detected`
- `discord voice: repeated decrypt failures; attempting rejoin`
- 자동 재참여 후에도 실패가 계속되면 로그를 수집하고 [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419)와 비교하세요
- 자동 재참여 후에도 실패가 계속되면 로그를 수집하고 [discord.js #11419](https://github.com/discordjs/discord.js/issues/11419)와 비교하세요.
</Accordion>
</AccordionGroup>
@ -1223,35 +1232,35 @@ openclaw logs --follow
- [Configuration reference - Discord](/ko/gateway/configuration-reference#discord)
신호가 강한 Discord 필드:
신호 가치가 높은 Discord 필드:
- 시작/인증: `enabled`, `token`, `accounts.*`, `allowBots`
- 정책: `groupPolicy`, `dm.*`, `guilds.*`, `guilds.*.channels.*`
- 명령: `commands.native`, `commands.useAccessGroups`, `configWrites`, `slashCommand.*`
- 이벤트 큐: `eventQueue.listenerTimeout` (listener 예산), `eventQueue.maxQueueSize`, `eventQueue.maxConcurrency`
- 인바운드 worker: `inboundWorker.runTimeoutMs`
- 응답/히스토리: `replyToMode`, `historyLimit`, `dmHistoryLimit`, `dms.*.historyLimit`
- 이벤트 큐: `eventQueue.listenerTimeout`(리스너 예산), `eventQueue.maxQueueSize`, `eventQueue.maxConcurrency`
- 인바운드 워커: `inboundWorker.runTimeoutMs`
- 응답/기록: `replyToMode`, `historyLimit`, `dmHistoryLimit`, `dms.*.historyLimit`
- 전달: `textChunkLimit`, `chunkMode`, `maxLinesPerMessage`
- 스트리밍: `streaming` (레거시 별칭: `streamMode`), `draftChunk`, `blockStreaming`, `blockStreamingCoalesce`
- 스트리밍: `streaming`(레거시 별칭: `streamMode`), `draftChunk`, `blockStreaming`, `blockStreamingCoalesce`
- 미디어/재시도: `mediaMaxMb`, `retry`
- `mediaMaxMb`는 아웃바운드 Discord 업로드를 제한합니다(기본값: `100MB`)
- 작업: `actions.*`
- 액션: `actions.*`
- 프레즌스: `activity`, `status`, `activityType`, `activityUrl`
- UI: `ui.components.accentColor`
- 기능: `threadBindings`, 최상위 `bindings[]` (`type: "acp"`), `pluralkit`, `execApprovals`, `intents`, `agentComponents`, `heartbeat`, `responsePrefix`
- 기능: `threadBindings`, 최상위 `bindings[]`(`type: "acp"`), `pluralkit`, `execApprovals`, `intents`, `agentComponents`, `heartbeat`, `responsePrefix`
## 안전 및 운영
- 봇 토큰은 비밀로 취급하세요(관리 환경에서는 `DISCORD_BOT_TOKEN` 권장).
- 봇 토큰은 비밀 정보로 취급하세요(관리 환경에서는 `DISCORD_BOT_TOKEN` 권장).
- Discord 권한은 최소 권한 원칙으로 부여하세요.
- 명령 배포/상태가 오래되었으면 gateway를 재시작하고 `openclaw channels status --probe`로 다시 확인하세요.
- 명령 배포/상태가 오래되었다면 게이트웨이를 재시작하고 `openclaw channels status --probe`로 다시 확인하세요.
## 관련 문서
## 관련 항목
- [Pairing](/ko/channels/pairing)
- [Groups](/ko/channels/groups)
- [Channel routing](/ko/channels/channel-routing)
- [Security](/ko/gateway/security)
- [Multi-agent routing](/ko/concepts/multi-agent)
- [Troubleshooting](/ko/channels/troubleshooting)
- [Slash commands](/ko/tools/slash-commands)
- [페어링](/ko/channels/pairing)
- [그룹](/ko/channels/groups)
- [채널 라우팅](/ko/channels/channel-routing)
- [보안](/ko/gateway/security)
- [다중 에이전트 라우팅](/ko/concepts/multi-agent)
- [문제 해결](/ko/channels/troubleshooting)
- [슬래시 명령어](/ko/tools/slash-commands)

File diff suppressed because it is too large Load Diff

View File

@ -1,176 +1,175 @@
---
read_when:
- 에이전트 루프 또는 수명 주기 이벤트에 대한 정확한 단계별 설명이 필요
summary: 에이전트 루프 수명 주기, 스트림 및 wait 의미론
title: Agent Loop
- 에이전트 루프 또는 수명 주기 이벤트에 대한 정확한 단계별 설명이 필요할 때
summary: 에이전트 루프 수명 주기, 스트림, 대기 의미 체계
title: 에이전트 루프
x-i18n:
generated_at: "2026-04-05T12:39:36Z"
generated_at: "2026-04-09T01:27:57Z"
model: gpt-5.4
provider: openai
source_hash: 8e562e63c494881e9c345efcb93c5f972d69aaec61445afc3d4ad026b2d26883
source_hash: 32d3a73df8dabf449211a6183a70dcfd2a9b6f584dc76d0c4c9147582b2ca6a1
source_path: concepts/agent-loop.md
workflow: 15
---
# Agent Loop (OpenClaw)
# 에이전트 루프 (OpenClaw)
에이전트 루프는 에이전트의 전체 “실제” 실행입니다: 입력 수집 → 컨텍스트 조립 → 모델 추론 →
도구 실행 → 응답 스트리밍 → 영속화. 이는 메시지를 작과 최종 응답으로
변환하면서 세션 상태의 일관성을 유지하는 권위 있는 경로입니다.
에이전트형 루프는 에이전트의 전체 "실제" 실행입니다: 입력 수집 → 컨텍스트 조립 → 모델 추론 →
도구 실행 → 스트리밍 응답 → 영속화. 이는 메시지를 작과 최종 응답으로 바꾸는 권위 있는 경로이며,
세션 상태를 일관되게 유지합니다.
OpenClaw에서 루프는 세션당 하나의 직렬화된 실행이며, 모델이 생각하고, 도구를 호출하고, 출력을 스트리밍할 때
수명 주기 및 스트림 이벤트를 발생시킵니다. 이 문서는 그 실제 루프가
엔드 투 엔드로 어떻게 연결되어 있는지 설명합니다.
수명 주기 및 스트림 이벤트를 내보냅니다. 이 문서는 이 실제 루프가 엔드 투 엔드로 어떻게 연결되는지 설명합니다.
## 진입점
- Gateway RPC: `agent``agent.wait`.
- CLI: `agent` 명령.
- CLI: `agent` 명령.
## 작동 방식(상위 수준)
1. `agent` RPC가 매개변수를 검증하고, 세션(sessionKey/sessionId)을 확인하고, 세션 메타데이터를 저장한 다음, 즉시 `{ runId, acceptedAt }`를 반환합니다.
1. `agent` RPC는 매개변수를 검증하고, 세션을 확인하며(sessionKey/sessionId), 세션 메타데이터를 영속화하고, 즉시 `{ runId, acceptedAt }`를 반환합니다.
2. `agentCommand`가 에이전트를 실행합니다:
- 모델 + thinking/verbose 기본값 확인
- Skills 스냅샷 로드
- `runEmbeddedPiAgent` 호출(pi-agent-core 런타임)
- 임베디드 루프가 수명 주기 종료/오류를 발생시키지 않으면 **lifecycle end/error** 발생
- `runEmbeddedPiAgent` 호출 (`pi-agent-core` 런타임)
- 임베디드 루프가 내보내지 않으면 **수명 주기 end/error** 내보내기
3. `runEmbeddedPiAgent`:
- 세션별 + 전역 큐를 통해 실행 직렬화
- 모델 + 인증 프로필을 확인하고 pi 세션 빌드
- 세션별 + 전역 큐를 통해 실행 직렬화
- 모델 + auth 프로필 확인 및 pi 세션 빌드
- pi 이벤트를 구독하고 assistant/tool 델타 스트리밍
- 타임아웃 강제 적용 -> 초과 시 실행 중단
- 제한 시간 강제 적용 -> 초과 시 실행 중단
- 페이로드 + 사용량 메타데이터 반환
4. `subscribeEmbeddedPiSession`이 pi-agent-core 이벤트를 OpenClaw `agent` 스트림으로 브리지합니다:
4. `subscribeEmbeddedPiSession``pi-agent-core` 이벤트를 OpenClaw `agent` 스트림으로 브리지합니다:
- 도구 이벤트 => `stream: "tool"`
- assistant 델타 => `stream: "assistant"`
- 수명 주기 이벤트 => `stream: "lifecycle"` (`phase: "start" | "end" | "error"`)
5. `agent.wait``waitForAgentRun`을 사용합니다:
- `runId`에 대한 **lifecycle end/error** 대기
- `runId`에 대한 **수명 주기 end/error** 대기
- `{ status: ok|error|timeout, startedAt, endedAt, error? }` 반환
## 큐잉 + 동시성
- 실행은 세션 키(세션 레인)별로 직렬화되며 선택적으로 전역 레인을 통과합니다.
- 이를 통해 도구/세션 경쟁 상태를 방지하고 세션 기록의 일관성을 유지합니다.
- 실행은 세션 키(세션 레인)별로 직렬화되며, 필요에 따라 전역 레인을 통해서도 직렬화됩니다.
- 이렇게 하면 도구/세션 경쟁 상태를 방지하고 세션 히스토리를 일관되게 유지할 수 있습니다.
- 메시징 채널은 이 레인 시스템에 연결되는 큐 모드(collect/steer/followup)를 선택할 수 있습니다.
자세한 내용은 [Command Queue](/concepts/queue)를 참조하세요.
[명령 큐](/ko/concepts/queue)를 참고하세요.
## 세션 + workspace 준비
## 세션 + 워크스페이스 준비
- workspace가 확인 및 생성되며, 샌드박스 실행은 샌드박스 workspace 루트로 리디렉션될 수 있습니다.
- Skills가 로드되거나(또는 스냅샷에서 재사용되며) env와 프롬프트에 주입됩니다.
- bootstrap/context 파일이 확인되어 시스템 프롬프트 보고서에 주입됩니다.
- 워크스페이스가 확인되고 생성되며, 샌드박스 실행은 샌드박스 워크스페이스 루트로 리디렉션될 수 있습니다.
- Skills가 로드되거나(또는 스냅샷에서 재사용되거나) env 및 프롬프트에 주입됩니다.
- 부트스트랩/컨텍스트 파일이 확인되고 시스템 프롬프트 보고서에 주입됩니다.
- 세션 쓰기 잠금이 획득되며, 스트리밍 전에 `SessionManager`가 열리고 준비됩니다.
## 프롬프트 조립 + 시스템 프롬프트
- 시스템 프롬프트는 OpenClaw의 기본 프롬프트, skills 프롬프트, bootstrap 컨텍스트, 실행별 재정의로 구성됩니다.
- 모델별 제한과 compaction reserve 토큰이 강제 적용됩니다.
- 모델이 실제로 보는 내용은 [System prompt](/concepts/system-prompt)를 참조하세요.
- 시스템 프롬프트는 OpenClaw의 기본 프롬프트, skills 프롬프트, 부트스트랩 컨텍스트, 실행별 오버라이드로 구성됩니다.
- 모델별 제한과 compaction 예약 토큰이 강제 적용됩니다.
- 모델이 무엇을 보는지에 대해서는 [시스템 프롬프트](/ko/concepts/system-prompt)를 참고하세요.
## Hook 지점(가로챌 수 있는 위치)
## 지점(가로챌 수 있는 위치)
OpenClaw에는 두 가지 hook 시스템이 있습니다.
OpenClaw에는 두 가지 훅 시스템이 있습니다:
- **내부 hooks**(Gateway hooks): 명령 및 수명 주기 이벤트를 위한 이벤트 기반 스크립트.
- **Plugin hooks**: 에이전트/도구 수명 주기와 gateway 파이프라인 내부의 확장 지점.
- **내부 **(Gateway hooks): 명령 및 수명 주기 이벤트를 위한 이벤트 기반 스크립트.
- **플러그인 훅**: 에이전트/도구 수명 주기 및 gateway 파이프라인 내부의 확장 지점.
### 내부 hooks (Gateway hooks)
### 내부 (Gateway hooks)
- **`agent:bootstrap`**: 시스템 프롬프트가 최종 확정되기 전에 bootstrap 파일을 빌드하는 동안 실행됩니다.
bootstrap 컨텍스트 파일을 추가/제거할 때 사용합니다.
- **명령 hooks**: `/new`, `/reset`, `/stop` 및 기타 명령 이벤트(Hooks 문서 참).
- **`agent:bootstrap`**: 시스템 프롬프트가 최종 확정되기 전에 부트스트랩 파일을 빌드하는 동안 실행됩니다.
부트스트랩 컨텍스트 파일을 추가/제거하는 데 사용합니다.
- **명령 **: `/new`, `/reset`, `/stop` 및 기타 명령 이벤트(Hooks 문서 참).
설정 및 예시는 [Hooks](/automation/hooks)를 참조하세요.
설정 및 예제는 [Hooks](/ko/automation/hooks)를 참고하세요.
### Plugin hooks (에이전트 + gateway 수명 주기)
### 플러그인 훅(에이전트 + gateway 수명 주기)
이들은 에이전트 루프 또는 gateway 파이프라인 내부에서 실행됩니다.
들은 에이전트 루프 또는 gateway 파이프라인 내부에서 실행됩니다:
- **`before_model_resolve`**: 모델 확인 전에 세션 사전 단계(`messages` 없음)에서 실행되어 provider/model을 결정적으로 재정의합니다.
- **`before_prompt_build`**: 세션 로드 후(`messages` 포함) 실행되어 프롬프트 제출 전에 `prependContext`, `systemPrompt`, `prependSystemContext`, 또는 `appendSystemContext`를 주입합니다. 턴별 동적 텍스트에는 `prependContext`를 사용하고, 시스템 프롬프트 공간에 들어가야 하는 안정적인 안내에는 system-context 필드를 사용하세요.
- **`before_agent_start`**: 레거시 호환성 hook으로 어느 단계에서든 실행될 수 있습니다. 위의 명시적 hooks를 우선 사용하세요.
- **`before_agent_reply`**: 인라인 동작 후 및 LLM 호출 전에 실행되며, plugin이 해당 턴을 점유하고 합성 응답을 반환하거나 턴 전체를 완전히 무음 처리할 수 있게 합니다.
- **`before_model_resolve`**: 세션 전(`messages` 없음)에 실행되어, 모델 확인 전에 provider/model을 결정적으로 오버라이드합니다.
- **`before_prompt_build`**: 세션 로드 후(`messages` 포함) 실행되어, 프롬프트 제출 전에 `prependContext`, `systemPrompt`, `prependSystemContext`, 또는 `appendSystemContext`를 주입합니다. 턴별 동적 텍스트에는 `prependContext`를 사용하고, 시스템 프롬프트 공간에 배치되어야 하는 안정적인 지침에는 system-context 필드를 사용하세요.
- **`before_agent_start`**: 레거시 호환성 훅으로, 두 단계 중 어느 쪽에서든 실행될 수 있습니다. 가능하면 위의 명시적 훅을 우선 사용하세요.
- **`before_agent_reply`**: 인라인 작업 후, 그리고 LLM 호출 전에 실행되어, 플러그인이 해당 턴을 가져가 합성 응답을 반환하거나 턴 자체를 완전히 무음 처리할 수 있게 합니다.
- **`agent_end`**: 완료 후 최종 메시지 목록과 실행 메타데이터를 검사합니다.
- **`before_compaction` / `after_compaction`**: compaction 주기를 관찰하거나 주석을 추가합니다.
- **`before_tool_call` / `after_tool_call`**: 도구 매개변수/결과를 가로챕니다.
- **`before_install`**: 내장 스캔 결과를 검사하고 skill 또는 plugin 설치를 선택적으로 차단합니다.
- **`before_install`**: 내장 스캔 결과를 검사하고 skill 또는 플러그인 설치를 선택적으로 차단합니다.
- **`tool_result_persist`**: 도구 결과가 세션 기록에 기록되기 전에 동기적으로 변환합니다.
- **`message_received` / `message_sending` / `message_sent`**: 수신 + 발신 메시지 hooks.
- **`message_received` / `message_sending` / `message_sent`**: 수신 + 발신 메시지 .
- **`session_start` / `session_end`**: 세션 수명 주기 경계.
- **`gateway_start` / `gateway_stop`**: gateway 수명 주기 이벤트.
발신/도구 가드에 대한 hook 결정 규칙:
발신/도구 가드에 대한 결정 규칙:
- `before_tool_call`: `{ block: true }`최종 결정이며 더 낮은 우선순위 핸들러를 중단합니다.
- `before_tool_call`: `{ block: true }`종료 동작이며 더 낮은 우선순위의 핸들러를 중단합니다.
- `before_tool_call`: `{ block: false }`는 no-op이며 이전 block을 해제하지 않습니다.
- `before_install`: `{ block: true }`최종 결정이며 더 낮은 우선순위 핸들러를 중단합니다.
- `before_install`: `{ block: true }`종료 동작이며 더 낮은 우선순위의 핸들러를 중단합니다.
- `before_install`: `{ block: false }`는 no-op이며 이전 block을 해제하지 않습니다.
- `message_sending`: `{ cancel: true }`최종 결정이며 더 낮은 우선순위 핸들러를 중단합니다.
- `message_sending`: `{ cancel: true }`종료 동작이며 더 낮은 우선순위의 핸들러를 중단합니다.
- `message_sending`: `{ cancel: false }`는 no-op이며 이전 cancel을 해제하지 않습니다.
hook API 및 등록 세부 사항은 [Plugin hooks](/plugins/architecture#provider-runtime-hooks)를 참조하세요.
훅 API와 등록 세부 정보는 [플러그인 훅](/ko/plugins/architecture#provider-runtime-hooks)을 참고하세요.
## 스트리밍 + 부분 응답
- Assistant 델타는 pi-agent-core에서 스트리밍되며 `assistant` 이벤트로 발생합니다.
- Block streaming은 `text_end` 또는 `message_end`에서 부분 응답을 발생시킬 수 있습니다.
- Reasoning streaming은 별도 스트림 또는 block reply로 발생할 수 있습니다.
- 청크 분할 및 block reply 동작은 [Streaming](/concepts/streaming)을 참조하세요.
- assistant 델타는 `pi-agent-core`에서 스트리밍되어 `assistant` 이벤트로 내보내집니다.
- 블록 스트리밍은 `text_end` 또는 `message_end`에서 부분 응답을 내보낼 수 있습니다.
- reasoning 스트리밍은 별도의 스트림으로 또는 블록 응답으로 내보낼 수 있습니다.
- 청킹 및 블록 응답 동작은 [스트리밍](/ko/concepts/streaming)을 참고하세요.
## 도구 실행 + 메시징 도구
- 도구 시작/업데이트/종료 이벤트는 `tool` 스트림에서 발생합니다.
- 도구 결과는 기록/발생 전에 크기와 이미지 페이로드 기준으로 정리됩니다.
- 메시징 도구 전송은 중복 assistant 확인 메시지를 억제하기 위해 추적됩니다.
- 도구 start/update/end 이벤트는 `tool` 스트림으로 내보내집니다.
- 도구 결과는 로깅/내보내기 전에 크기와 이미지 페이로드 기준으로 정리됩니다.
- 메시징 도구 전송은 중복 assistant 확인 메시지를 억제하기 위해 추적됩니다.
## 응답 형태 조정 + 억제
- 최종 페이로드는 다음으로 조립됩니다:
- assistant 텍스트(및 선택적 reasoning)
- 인라인 도구 요약(verbose + 허용 시)
- 모델 오류 시 assistant 오류 텍스트
- 정확`NO_REPLY` / `no_reply`인 무응답 토큰은 발신
- 모델 오류 발생 시 assistant 오류 텍스트
- 정확한 무음 토큰 `NO_REPLY` / `no_reply` 발신
페이로드에서 필터링됩니다.
- 메시징 도구 중복은 최종 페이로드 목록에서 제거됩니다.
- 렌더링 가능한 페이로드가 남지 않았고 도구 오류가 발생한 경우,
폴백 도구 오류 응답이 발생합니다
- 메시징 도구 중복 항목은 최종 페이로드 목록에서 제거됩니다.
- 렌더링 가능한 페이로드가 남지 않았고 도구에서 오류가 발생한 경우, 대체 도구 오류 응답이 내보내집니다
(단, 메시징 도구가 이미 사용자에게 보이는 응답을 보낸 경우는 제외).
## Compaction + 재시도
- 자동 compaction은 `compaction` 스트림 이벤트를 발생시키고 재시도를 트리거할 수 있습니다.
- 재시도 시 중복 출력을 피하기 위해 메모리 내 버퍼와 도구 요약이 재설정됩니다.
- compaction 파이프라인은 [Compaction](/concepts/compaction)을 참조하세요.
- 자동 compaction은 `compaction` 스트림 이벤트를 내보내고 재시도를 유발할 수 있습니다.
- 재시도 시, 중복 출력을 방지하기 위해 메모리 내 버퍼와 도구 요약이 재설정됩니다.
- compaction 파이프라인은 [Compaction](/ko/concepts/compaction)을 참고하세요.
## 이벤트 스트림(현재)
- `lifecycle`: `subscribeEmbeddedPiSession`에서 발생(그리고 폴백으로 `agentCommand`에서도 발생)
- `assistant`: pi-agent-core의 스트리밍 델타
- `tool`: pi-agent-core의 스트리밍 도구 이벤트
- `lifecycle`: `subscribeEmbeddedPiSession`에서 내보냄(`agentCommand`에서 대체용으로도 내보냄)
- `assistant`: `pi-agent-core`의 스트리밍 델타
- `tool`: `pi-agent-core`의 스트리밍 도구 이벤트
## 채팅 채널 처리
- Assistant 델타는 채팅 `delta` 메시지로 버퍼링됩니다.
- 채팅 `final`은 **lifecycle end/error**에서 발생합니다.
- assistant 델타는 채팅 `delta` 메시지로 버퍼링됩니다.
- 채팅 `final`은 **수명 주기 end/error**에서 내보내집니다.
## 타임아웃
## 제한 시간
- `agent.wait` 기본값: 30초(wait만 해당). `timeoutMs` 매개변수로 재정의 가능.
- 에이전트 런타임: `agents.defaults.timeoutSeconds` 기본값 172800초(48시간); `runEmbeddedPiAgent`의 중단 타이머에서 강제 적용.
- `agent.wait` 기본값: 30초(대기만 해당). `timeoutMs` 매개변수로 재정의합니다.
- 에이전트 런타임: `agents.defaults.timeoutSeconds` 기본값은 172800초(48시간)이며, `runEmbeddedPiAgent`의 abort 타이머에서 강제 적용됩니다.
- LLM 유휴 제한 시간: `agents.defaults.llm.idleTimeoutSeconds`는 유휴 시간 창 안에 응답 청크가 도착하지 않으면 모델 요청을 중단합니다. 느린 로컬 모델 또는 reasoning/도구 호출 provider에 대해 명시적으로 설정하세요. 비활성화하려면 0으로 설정하세요. 설정되지 않은 경우, OpenClaw는 `agents.defaults.timeoutSeconds`가 구성되어 있으면 이를 사용하고, 그렇지 않으면 60초를 사용합니다. 명시적인 LLM 또는 에이전트 제한 시간이 없는 cron 트리거 실행은 유휴 watchdog을 비활성화하고 cron 외부 제한 시간에 의존합니다.
## 조기 종료될 수 있는 위치
## 조기 종료될 수 있는 위치
- 에이전트 타임아웃(중단)
- AbortSignal(취소)
- Gateway 연결 해제 또는 RPC 타임아웃
- `agent.wait` 타임아웃(wait만 해당, 에이전트를 중지하지는 않음)
- 에이전트 제한 시간(abort)
- AbortSignal(cancel)
- Gateway 연결 해제 또는 RPC 제한 시간
- `agent.wait` 제한 시간(대기만 해당하며, 에이전트를 중지하지는 않음)
## 관련 문서
- [Tools](/tools) — 사용 가능한 에이전트 도구
- [Hooks](/automation/hooks) — 에이전트 수명 주기 이벤트에 의해 트리거되는 이벤트 기반 스크립트
- [Compaction](/concepts/compaction) — 긴 대화가 요약되는 방식
- [Exec Approvals](/tools/exec-approvals) — 셸 명령에 대한 승인 게이트
- [Thinking](/tools/thinking) — thinking/reasoning 수준 구성
- [도구](/ko/tools) — 사용 가능한 에이전트 도구
- [Hooks](/ko/automation/hooks) — 에이전트 수명 주기 이벤트에 의해 트리거되는 이벤트 기반 스크립트
- [Compaction](/ko/concepts/compaction) — 긴 대화가 요약되는 방식
- [Exec Approvals](/ko/tools/exec-approvals) — 셸 명령에 대한 승인 게이트
- [Thinking](/ko/tools/thinking) — thinking/reasoning 수준 구성

View File

@ -1,15 +1,15 @@
---
read_when:
- 메모리 승격이 자동으로 실행되길 원합니다
- 메모리 승격이 자동으로 실행되도록 하고 싶습니다
- 각 dreaming 단계가 무엇을 하는지 이해하고 싶습니다
- MEMORY.md를 오염시키지 않고 통합을 조정하고 싶습니다
summary: Dream Diary와 함께 light, deep, REM 단계로 이루어진 백그라운드 메모리 통합
summary: 가벼운 수면, 깊은 수면, REM 단계와 Dream Diary를 포함한 백그라운드 메모리 통합
title: Dreaming (실험적)
x-i18n:
generated_at: "2026-04-06T06:00:21Z"
generated_at: "2026-04-09T01:27:50Z"
model: gpt-5.4
provider: openai
source_hash: 36c4b1e70801d662090dc8ce20608c2f141c23cd7ce53c54e3dcf332c801fd4e
source_hash: 26476eddb8260e1554098a6adbb069cf7f5e284cf2e09479c6d9d8f8b93280ef
source_path: concepts/dreaming.md
workflow: 15
---
@ -18,7 +18,7 @@ x-i18n:
Dreaming은 `memory-core`의 백그라운드 메모리 통합 시스템입니다.
이 기능은 OpenClaw가 강한 단기 신호를 오래 유지되는 메모리로 옮기도록 도우면서,
그 과정이 설명 가능하고 검토 가능하도록 유지합니다.
과정을 설명 가능하고 검토 가능하게 유지합니다.
Dreaming은 **옵트인** 기능이며 기본적으로 비활성화되어 있습니다.
@ -26,40 +26,40 @@ Dreaming은 **옵트인** 기능이며 기본적으로 비활성화되어 있습
Dreaming은 두 종류의 출력을 유지합니다.
- `memory/.dreams/`**머신 상태**(리콜 저장소, 단계 신호, 수집 체크포인트, 잠금).
- `DREAMS.md`(또는 기존 `dreams.md`)의 **사람이 읽을 수 있는 출력**, 그리고 선택적으로 `memory/dreaming/<phase>/YYYY-MM-DD.md` 아래의 단계 보고서 파일.
- `memory/.dreams/`**기계 상태**(recall 저장소, 단계 신호, 수집 체크포인트, 잠금).
- `DREAMS.md`(또는 기존 `dreams.md`)의 **사람이 읽을 수 있는 출력**와 `memory/dreaming/<phase>/YYYY-MM-DD.md` 아래의 선택적 단계 보고서 파일.
장기 승격은 계속해서 `MEMORY.md`에만 기록됩니다.
## 단계 모델
Dreaming은 협력적으로 동작하는 세 단계로 이루어져 있습니다.
Dreaming은 세 가지 협력 단계로 동작합니다.
| 단계 | 목적 | 영구 기록 |
| ----- | ---- | --------- |
| Light | 최근 단기 자료를 정렬하고 준비 | 아니요 |
| Deep | 오래 유지할 후보를 점수화하고 승격 | 예 (`MEMORY.md`) |
| REM | 주제와 반복되는 아이디어를 되돌아봄 | 아니요 |
| Light | 최근 단기 자료 정렬 및 준비 | 아니요 |
| Deep | 오래 유지할 후보 점수화 및 승격 | 예 (`MEMORY.md`) |
| REM | 주제와 반복되는 아이디어 성찰 | 아니요 |
이 단계들은 별도의 사용자 설정 "모드"가 아니라 내부 구현 세부 사항입니다.
### Light 단계
Light 단계는 최근 일일 메모리 신호와 리콜 추적을 수집하고, 중복을 제거한 뒤,
후보 을 준비합니다.
Light 단계는 최근 일일 메모리 신호와 recall 추적을 수집하고, 중복을 제거한 뒤,
후보 라인을 준비합니다.
- 단기 리콜 상태와 최근 일일 메모리 파일에서 읽습니다.
- 사용 가능한 경우 단기 recall 상태, 최근 일일 메모리 파일, 그리고 민감 정보가 제거된 세션 대화록을 읽습니다.
- 저장소에 인라인 출력이 포함된 경우 관리되는 `## Light Sleep` 블록을 기록합니다.
- 이후 deep 순위 산정에 사용할 강화 신호를 기록합니다.
- 절대 `MEMORY.md`에 기록하지 않습니다.
- 이후 deep 순위 산정을 위한 강화 신호를 기록합니다.
- 절대 `MEMORY.md`에 기록하지 않습니다.
### Deep 단계
Deep 단계는 무엇이 장기 메모리가 될지 결정합니다.
- 가중치가 적용된 점수와 임계값 게이트를 사용해 후보의 순위를 매깁니다.
- `minScore`, `minRecallCount`, `minUniqueQueries`를 모두 통과해야 합니다.
- 기록 전에 실제 일일 파일에서 스니펫을 다시 불러오므로, 오래되었거나 삭제된 스니펫은 건너뜁니다.
- 가중치 기반 점수와 임계값 게이트를 사용해 후보의 순위를 매깁니다.
- 통과하려면 `minScore`, `minRecallCount`, `minUniqueQueries`가 필요합니다.
- 기록 전에 실제 일일 파일에서 스니펫을 다시 가져오므로, 오래되었거나 삭제된 스니펫은 건너뜁니다.
- 승격된 항목을 `MEMORY.md`에 추가합니다.
- `DREAMS.md``## Deep Sleep` 요약을 기록하고, 선택적으로 `memory/dreaming/deep/YYYY-MM-DD.md`도 기록합니다.
@ -67,36 +67,55 @@ Deep 단계는 무엇이 장기 메모리가 될지 결정합니다.
REM 단계는 패턴과 성찰 신호를 추출합니다.
- 최근 단기 추적에서 주제 및 성찰 요약을 만듭니다.
- 최근 단기 추적에서 주제 및 성찰 요약을 생성합니다.
- 저장소에 인라인 출력이 포함된 경우 관리되는 `## REM Sleep` 블록을 기록합니다.
- deep 순위 산정에 사용되는 REM 강화 신호를 기록합니다.
- 절대 `MEMORY.md`에 기록하지 않습니다.
- 절대로 `MEMORY.md`에 기록하지 않습니다.
## 세션 대화록 수집
Dreaming은 민감 정보가 제거된 세션 대화록을 dreaming 코퍼스에 수집할 수 있습니다.
대화록을 사용할 수 있는 경우, 일일 메모리 신호와 recall 추적과 함께 light 단계에
입력됩니다. 개인 정보와 민감한 내용은 수집 전에 제거됩니다.
## Dream Diary
Dreaming은 또한 `DREAMS.md`에 서술형 **Dream Diary**를 유지합니다.
각 단계에 충분한 자료가 쌓이면 `memory-core`는 최선 노력 방식의 백그라운드
서브에이전트 턴을 실행하고(기본 런타임 모델 사용), 짧은 일지 항목을 추가합니다.
각 단계에 충분한 자료가 쌓이면 `memory-core`는 최선형 백그라운드 서브에이전트
턴(기본 런타임 모델 사용)을 실행하고 짧은 일지 항목을 추가합니다.
이 일지는 Dreams UI에서 사람이 읽기 위한 것이며, 승격 소스는 아닙니다.
검토 및 복구 작업을 위한 근거 기반 과거 백필 경로도 있습니다.
- `memory rem-harness --path ... --grounded`는 과거 `YYYY-MM-DD.md` 노트에서 근거 기반 일지 출력을 미리 봅니다.
- `memory rem-backfill --path ...`는 되돌릴 수 있는 근거 기반 일지 항목을 `DREAMS.md`에 기록합니다.
- `memory rem-backfill --path ... --stage-short-term`은 일반 deep 단계가 이미 사용하는 것과 동일한 단기 증거 저장소에 근거 기반의 오래 유지할 후보를 준비합니다.
- `memory rem-backfill --rollback``--rollback-short-term`은 일반 일지 항목이나 실시간 단기 recall을 건드리지 않고 이렇게 준비된 백필 아티팩트를 제거합니다.
Control UI는 동일한 일지 백필/재설정 흐름을 제공하므로, 어떤 근거 기반 후보가
승격될 가치가 있는지 결정하기 전에 Dreams 장면에서 결과를 검사할 수 있습니다.
장면은 또한 별도의 근거 기반 레인도 표시하므로, 어떤 준비된 단기 항목이 과거
재생에서 왔는지, 어떤 승격된 항목이 근거 기반 주도로 이루어졌는지 확인하고,
일반 실시간 단기 상태를 건드리지 않고 근거 기반 전용 준비 항목만 지울 수 있습니다.
## Deep 순위 산정 신호
Deep 순위 산정은 6개의 가중 기본 신호와 단계 강화 신호를 사용합니다.
Deep 순위 산정은 6개의 가중치 기반 기본 신호와 단계 강화 신호를 사용합니다.
| 신호 | 가중치 | 설명 |
| ------------------- | ------ | ------------------------------------------------- |
| 빈도 | 0.24 | 항목이 누적한 단기 신호 수 |
| 관련성 | 0.30 | 해당 항목의 평균 검색 품질 |
| 쿼리 다양성 | 0.15 | 해당 항목이 드러난 서로 다른 쿼리/일 컨텍스트 |
| 최신성 | 0.15 | 시간 감쇠가 적용된 최신성 점수 |
| 통합도 | 0.10 | 여러 날에 걸친 반복 강도 |
| 개념적 풍부함 | 0.06 | 스니펫/경로의 개념 태그 밀도 |
| ---- | ------ | ---- |
| 빈도 | 0.24 | 항목이 축적한 단기 신호 수 |
| 관련성 | 0.30 | 항목의 평균 검색 품질 |
| 쿼리 다양성 | 0.15 | 해당 항목이 드러난 서로 다른 쿼리/일자 맥락 |
| 최신성 | 0.15 | 시간 감쇠 기반 신선도 점수 |
| 통합도 | 0.10 | 여러 날에 걸친 반복 강도 |
| 개념적 풍부함 | 0.06 | 스니펫/경로의 개념 태그 밀도 |
Light 및 REM 단계 적중은
`memory/.dreams/phase-signals.json`에서 작은 최신성 감쇠 부스트를 추가합니다.
`memory/.dreams/phase-signals.json`에서 작은 최신성 감쇠 기반 부스트를 추가합니다.
## 일정 관리
## 스케줄링
활성화되면 `memory-core`는 전체 dreaming 스윕을 위한 cron 작업 하나를 자동 관리합니다.
각 스윕은 단계를 순서대로 실행합니다: light -> REM -> deep.
@ -104,7 +123,7 @@ Light 및 REM 단계 적중은
기본 주기 동작:
| 설정 | 기본값 |
| -------------------- | ----------- |
| ---- | ------ |
| `dreaming.frequency` | `0 3 * * *` |
## 빠른 시작
@ -158,7 +177,7 @@ dreaming 활성화:
## CLI 워크플로
미리 보기 또는 수동 적용에는 CLI 승격을 사용하세요.
미리 보기 또는 수동 적용에는 CLI 승격을 사용합니다.
```bash
openclaw memory promote
@ -176,7 +195,7 @@ openclaw memory promote-explain "router vlan"
openclaw memory promote-explain "router vlan" --json
```
아무것도 기록하지 않고 REM 성찰, 후보 사실, deep 승격 출력을 미리 봅니다.
아무 것도 기록하지 않고 REM 성찰, 후보 사실, deep 승격 출력을 미리 봅니다.
```bash
openclaw memory rem-harness
@ -188,7 +207,7 @@ openclaw memory rem-harness --json
모든 설정은 `plugins.entries.memory-core.config.dreaming` 아래에 있습니다.
| 키 | 기본값 |
| ----------- | ----------- |
| --- | ------ |
| `enabled` | `false` |
| `frequency` | `0 3 * * *` |
@ -199,15 +218,16 @@ openclaw memory rem-harness --json
## Dreams UI
활성화되면 Gateway **Dreams** 탭에 다음이 표시됩니다.
활성화되면 Gateway **Dreams** 탭에 다음이 표시됩니다.
- 현재 dreaming 활성화 상태
- 단계별 상태와 관리형 스윕 존재 여부
- 단기, 장기, 오늘 승격된 항목 수
- 다음 예약 실행 시각
- 단기, 근거 기반, 신호, 오늘 승격 수
- 다음 예약 실행 시점
- 과거 재생 항목을 준비하는 별도의 근거 기반 장면 레인
- `doctor.memory.dreamDiary`를 기반으로 하는 확장 가능한 Dream Diary 리더
## 관련 항목
## 관련 문서
- [메모리](/ko/concepts/memory)
- [메모리 검색](/ko/concepts/memory-search)

View File

@ -1,83 +1,83 @@
---
read_when:
- 메모리가 어떻게 작동하는지 이해하고 싶을 때
- 어떤 메모리 파일 작성해야 하는지 알고 싶을 때
summary: OpenClaw가 세션 전반에 걸쳐 정보를 기억하는 방
- 어떤 메모리 파일 작성해야 하는지 알고 싶을 때
summary: OpenClaw가 세션 전반에 걸쳐 정보를 기억하는 방
title: 메모리 개요
x-i18n:
generated_at: "2026-04-08T05:55:50Z"
generated_at: "2026-04-09T01:27:57Z"
model: gpt-5.4
provider: openai
source_hash: 3bb8552341b0b651609edaaae826a22fdc535d240aed4fad4af4b069454004af
source_hash: 2fe47910f5bf1c44be379e971c605f1cb3a29befcf2a7ee11fb3833cbe3b9059
source_path: concepts/memory.md
workflow: 15
---
# 메모리 개요
OpenClaw는 에이전트의 작업 공간에 **일반 Markdown 파일**을 작성하여 정보를 기억합니다. 모델은 디스크에 저장된 내용만 "기억"하며, 숨겨진 상태는 없습니다.
OpenClaw는 에이전트의 워크스페이스에 **일반 Markdown 파일**을 작성하여 정보를 기억합니다. 모델이 "기억하는" 것은 디스크에 저장된 내용뿐이며, 숨겨진 상태는 없습니다.
## 작동 방식
에이전트에는 메모리와 관련된 파일이 세 가지 있습니다:
에이전트에는 메모리와 관련된 파일이 세 가지 있습니다.
- **`MEMORY.md`** -- 장기 메모리. 오래 유지되는 사실, 선호, 결정 사항입니다. 모든 DM 세션 시작 시 로드됩니다.
- **`memory/YYYY-MM-DD.md`** -- 일일 노트. 진행 중인 컨텍스트와 관찰 내용을 담습니다. 오늘과 어제의 노트는 자동으로 로드됩니다.
- **`DREAMS.md`** (실험적, 선택 사항) -- 사람이 검토할 수 있도록 만든 Dream Diary 및 dreaming sweep 요약입니다.
- **`MEMORY.md`** -- 장기 메모리입니다. 지속되는 사실, 선호 사항, 결정 사항을 담습니다. 모든 DM 세션이 시작될 때 로드됩니다.
- **`memory/YYYY-MM-DD.md`** -- 일일 노트입니다. 진행 중인 컨텍스트와 관찰 내용을 담습니다. 오늘과 어제의 노트는 자동으로 로드됩니다.
- **`DREAMS.md`** (실험적, 선택 사항) -- 사람의 검토를 위한 Dream Diary 및 dreaming sweep 요약을 담으며, 근거 기반의 과거 백필 항목도 포함합니다.
이 파일들은 에이전트 작업 공간(기본값: `~/.openclaw/workspace`)에 있습니다.
이 파일들은 에이전트 워크스페이스에 있습니다(기본값 `~/.openclaw/workspace`).
<Tip>
에이전트가 무언가를 기억하길 원한다면 그냥 이렇게 요청하면 됩니다: "내가 TypeScript를 선호한다고 기억해." 그러면 적절한 파일에 기록합니다.
에이전트가 무언가를 기억하길 원한다면, 그냥 이렇게 요청하면 됩니다: "내가 TypeScript를 선호한다고 기억해." 그러면 적절한 파일에 기록합니다.
</Tip>
## 메모리 도구
에이전트에는 메모리를 다루기 위한 두 가지 도구가 있습니다:
에이전트에는 메모리를 다루기 위한 두 가지 도구가 있습니다.
- **`memory_search`** -- 원문과 표현이 달라도 시맨틱 검색을 사용해 관련 노트를 찾습니다.
- **`memory_get`** -- 특정 메모리 파일 또는 줄 범위를 읽습니다.
두 도구 모두 활성 메모리 plugin(기본값: `memory-core`)에서 제공합니다.
두 도구 모두 활성 메모리 플러그인(기본값: `memory-core`)에서 제공합니다.
## Memory Wiki companion plugin
## Memory Wiki 컴패니언 플러그인
지속 메모리가 단순한 원시 노트보다 관리되는 지식 베이스처럼 동작하길 원한다면, 번들된 `memory-wiki` plugin을 사용하세요.
지속 메모리가 단순한 원시 노트가 아니라 관리되는 지식 베이스처럼 동작하길 원한다면, 번들된 `memory-wiki` 플러그인을 사용하세요.
`memory-wiki`는 지속 지식을 다음 요소를 갖춘 위키 볼트로 컴파일합니다:
`memory-wiki`는 지속 지식을 위키 볼트로 컴파일하며, 다음을 제공합니다.
- 결정론적 페이지 구조
- 구조화된 주장과
- 결정론적 페이지 구조
- 구조화된 주장과
- 모순 및 최신성 추적
- 생성된 대시보드
- 에이전트/런타임 소비자를 위한 컴파일된 다이제스트
- `wiki_search`, `wiki_get`, `wiki_apply`, `wiki_lint` 같은 위키 네이티브 도구
plugin은 활성 메모리 plugin을 대체하지 않습니다. 활성 메모리 plugin은 여전히 회상, 승격, dreaming을 담당합니다. `memory-wiki`는 그 옆에 출처 정보가 풍부한 지식 계층을 추가합니다.
플러그인은 활성 메모리 플러그인을 대체하지 않습니다. 활성 메모리 플러그인은 여전히 회상, 승격, dreaming을 담당합니다. `memory-wiki`는 그 옆에 출처가 풍부한 지식 계층을 추가합니다.
자세한 내용은 [Memory Wiki](/ko/plugins/memory-wiki)를 참조하세요.
## 메모리 검색
임베딩 provider가 구성되어 있으면 `memory_search`는 **하이브리드 검색**을 사용합니다. 즉, 벡터 유사도(의미적 의미)와 키워드 매칭(ID 및 코드 심볼 같은 정확한 용어)을 결합합니다. 지원되는 provider 중 하나의 API 키만 있으면 별도 설정 없이 바로 동작합니다.
임베딩 제공자가 구성되어 있으면 `memory_search`는 **하이브리드 검색**을 사용합니다. 즉, 벡터 유사도(의미적 의미)와 키워드 매칭(ID나 코드 심볼 같은 정확한 용어)을 결합합니다. 지원되는 제공자 중 하나의 API 키만 있으면 바로 사용할 수 있습니다.
<Info>
OpenClaw는 사용 가능한 API 키를 바탕으로 임베딩 provider를 자동 감지합니다. OpenAI, Gemini, Voyage 또는 Mistral 키가 구성되어 있으면 메모리 검색이 자동으로 활성화됩니다.
OpenClaw는 사용 가능한 API 키를 바탕으로 임베딩 제공자를 자동 감지합니다. OpenAI, Gemini, Voyage 또는 Mistral 키가 구성되어 있으면 메모리 검색이 자동으로 활성화됩니다.
</Info>
검색 작동 방식, 튜닝 옵션, provider 설정에 대한 자세한 내용은 [Memory Search](/ko/concepts/memory-search)를 참조하세요.
검색 작동 방식, 튜닝 옵션, 제공자 설정에 대한 자세한 내용은 [Memory Search](/ko/concepts/memory-search)를 참조하세요.
## 메모리 백엔드
<CardGroup cols={3}>
<Card title="내장형 (기본값)" icon="database" href="/ko/concepts/memory-builtin">
SQLite 기반입니다. 키워드 검색, 벡터 유사도, 하이브리드 검색을 별도 설정 없이 사용할 수 있습니다. 추가 의존성이 필요하지 않습니다.
SQLite 기반입니다. 키워드 검색, 벡터 유사도, 하이브리드 검색을 즉시 사용할 수 있습니다. 추가 의존성이 필요 없습니다.
</Card>
<Card title="QMD" icon="search" href="/ko/concepts/memory-qmd">
재순위 지정, 쿼리 확장, 작업 공간 외부 디렉터리 인덱싱 기능을 갖춘 로컬 우선 사이드카입니다.
재순위 지정, 쿼리 확장, 워크스페이스 외부 디렉터리 인덱싱 기능을 갖춘 로컬 우선 사이드카입니다.
</Card>
<Card title="Honcho" icon="brain" href="/ko/concepts/memory-honcho">
사용자 모델링, 시맨틱 검색, 멀티 에이전트 인식을 지원하는 AI 네이티브 교차 세션 메모리입니다. plugin 설치가 필요합니다.
사용자 모델링, 시맨틱 검색, 멀티 에이전트 인식을 갖춘 AI 네이티브 크로스세션 메모리입니다. 플러그인을 설치해야 합니다.
</Card>
</CardGroup>
@ -85,35 +85,63 @@ SQLite 기반입니다. 키워드 검색, 벡터 유사도, 하이브리드 검
<CardGroup cols={1}>
<Card title="Memory Wiki" icon="book" href="/ko/plugins/memory-wiki">
주장, 대시보드, bridge mode, Obsidian 친화적 워크플로를 갖춘 출처 정보가 풍부한 위키 볼트로 지속 메모리를 컴파일합니다.
지속 메모리를 주장, 대시보드, 브리지 모드, Obsidian 친화적 워크플로를 갖춘 출처 풍부한 위키 볼트로 컴파일합니다.
</Card>
</CardGroup>
## 자동 메모리 플러시
[compaction](/ko/concepts/compaction)이 대화를 요약하기 전에 OpenClaw는 에이전트에게 중요한 컨텍스트를 메모리 파일에 저장하라고 상기시키는 무음 턴을 실행합니다. 이것은 기본적으로 활성화되어 있으므로 별도로 설정할 필요가 없습니다.
[compaction](/ko/concepts/compaction)이 대화를 요약하기 전에, OpenClaw는 에이전트에게 중요한 컨텍스트를 메모리 파일에 저장하라고 상기시키는 조용한 턴을 실행합니다. 이 기능은 기본적으로 켜져 있으므로 별도로 설정할 필요가 없습니다.
<Tip>
메모리 플러시는 compaction 중 컨텍스트 손실을 방지합니다. 대화에 중요한 사실이 있지만 아직 파일에 기록되지 않았다면, 요약이 이루어지기 전에 자동으로 저장됩니다.
메모리 플러시는 compaction 중 컨텍스트 손실을 방지합니다. 대화에 중요한 사실이 아직 파일에 기록되지 않았다면, 요약이 이루어지기 전에 자동으로 저장됩니다.
</Tip>
## Dreaming (실험적)
Dreaming은 메모리를 위한 선택적 백그라운드 통합 패스입니다. 단기 신호를 수집하고, 후보를 점수화하며, 기준을 충족한 항목만 장기 메모리(`MEMORY.md`)로 승격합니다.
Dreaming은 메모리를 위한 선택적 백그라운드 통합 패스입니다. 단기 신호를 수집하고, 후보를 점수화하며, 자격을 충족한 항목만 장기 메모리(`MEMORY.md`)로 승격합니다.
장기 메모리의 신호 대 잡음비를 높게 유지하도록 설계되었습니다:
이 기능은 장기 메모리의 신호 대 잡음비를 높게 유지하도록 설계되었습니다.
- **옵트인**: 기본적으로 비활성화되어 있습니다.
- **Opt-in**: 기본적으로 비활성화되어 있습니다.
- **예약 실행**: 활성화되면 `memory-core`가 전체 dreaming sweep을 위한 반복 cron 작업 하나를 자동으로 관리합니다.
- **임곗값 기반**: 승격은 점수, 회상 빈도, 쿼리 다양성 게이트를 통과해야 합니다.
- **검토 가능**: 단계 요약과 다이어리 항목이 사람이 검토할 수 있도록 `DREAMS.md`에 기록됩니다.
- **임곗값 적용**: 승격은 점수, 회상 빈도, 쿼리 다양성 게이트를 통과해야 합니다.
- **검토 가능**: 단계 요약과 다이어리 항목이 사람이 검토할 수 있도록 `DREAMS.md`에 기록됩니다.
단계 동작, 점수화 신호, Dream Diary 세부 정보는 [Dreaming (experimental)](/ko/concepts/dreaming)을 참조하세요.
단계별 동작, 점수 신호, Dream Diary 세부 정보는 [Dreaming (experimental)](/ko/concepts/dreaming)을 참조하세요.
## 근거 기반 백필과 라이브 승격
dreaming 시스템에는 이제 밀접하게 연관된 두 가지 검토 경로가 있습니다.
- **라이브 dreaming**은 `memory/.dreams/` 아래의 단기 dreaming 저장소를 기반으로 작동하며, 일반적인 딥 단계가 무엇을 `MEMORY.md`로 승격할 수 있는지 결정할 때 사용하는 방식입니다.
- **근거 기반 백필**은 과거의 `memory/YYYY-MM-DD.md` 노트를 독립적인 일일 파일로 읽고, 구조화된 검토 출력을 `DREAMS.md`에 기록합니다.
근거 기반 백필은 `MEMORY.md`를 수동으로 편집하지 않고도 오래된 노트를 다시 처리하고 시스템이 무엇을 지속적인 정보로 판단하는지 확인하고 싶을 때 유용합니다.
다음 명령을 사용하면:
```bash
openclaw memory rem-backfill --path ./memory --stage-short-term
```
근거 기반의 지속 후보는 직접 승격되지 않습니다. 대신 일반적인 딥 단계가 이미 사용하는 것과 동일한 단기 dreaming 저장소에 스테이징됩니다. 즉, 다음을 의미합니다.
- `DREAMS.md`는 계속 사람 검토용 표면으로 남습니다.
- 단기 저장소는 계속 머신 대상 순위화 표면으로 남습니다.
- `MEMORY.md`는 여전히 딥 승격에 의해서만 기록됩니다.
재처리가 유용하지 않았다고 판단되면, 일반 다이어리 항목이나 정상적인 회상 상태를 건드리지 않고 스테이징된 아티팩트를 제거할 수 있습니다.
```bash
openclaw memory rem-backfill --rollback
openclaw memory rem-backfill --rollback-short-term
```
## CLI
```bash
openclaw memory status # 인덱스 상태와 provider 확인
openclaw memory status # 인덱스 상태와 제공자 확인
openclaw memory search "query" # 명령줄에서 검색
openclaw memory index --force # 인덱스 다시 빌드
```
@ -122,9 +150,9 @@ openclaw memory index --force # 인덱스 다시 빌드
- [Builtin Memory Engine](/ko/concepts/memory-builtin) -- 기본 SQLite 백엔드
- [QMD Memory Engine](/ko/concepts/memory-qmd) -- 고급 로컬 우선 사이드카
- [Honcho Memory](/ko/concepts/memory-honcho) -- AI 네이티브 교차 세션 메모리
- [Honcho Memory](/ko/concepts/memory-honcho) -- AI 네이티브 크로스세션 메모리
- [Memory Wiki](/ko/plugins/memory-wiki) -- 컴파일된 지식 볼트 및 위키 네이티브 도구
- [Memory Search](/ko/concepts/memory-search) -- 검색 파이프라인, provider, 튜닝
- [Memory Search](/ko/concepts/memory-search) -- 검색 파이프라인, 제공자 및 튜닝
- [Dreaming (experimental)](/ko/concepts/dreaming) -- 단기 회상에서 장기 메모리로의 백그라운드 승격
- [Memory configuration reference](/ko/reference/memory-config) -- 모든 구성 옵션
- [Compaction](/ko/concepts/compaction) -- compaction이 메모리와 상호작용하는 방식

View File

@ -1,40 +1,41 @@
---
read_when:
- provider별 모델 설정 참조가 필요합니다
- 모델 provider용 예시 config 또는 CLI 온보딩 명령이 필요합니다
summary: 예시 config와 CLI 흐름이 포함된 모델 provider 개요
title: 모델 provider
- 제공자별 모델 설정 참고 자료가 필요합니다
- 모델 제공자를 위한 예제 구성이나 CLI 온보딩 명령이 필요합니다
summary: 예제 구성과 CLI 흐름이 포함된 모델 제공자 개요
title: 모델 제공자
x-i18n:
generated_at: "2026-04-08T05:57:21Z"
generated_at: "2026-04-09T01:29:44Z"
model: gpt-5.4
provider: openai
source_hash: 558ac9e34b67fcc3dd6791a01bebc17e1c34152fa6c5611593d681e8cfa532d9
source_hash: 53e3141256781002bbe1d7e7b78724a18d061fcf36a203baae04a091b8c9ea1b
source_path: concepts/model-providers.md
workflow: 15
---
# 모델 provider
# 모델 제공자
이 페이지는 **LLM/모델 provider**를 다룹니다(WhatsApp/Telegram 같은 채팅 채널은 아님).
모델 선택 규칙은 [/concepts/models](/ko/concepts/models)을 참하세요.
이 페이지는 **LLM/모델 제공자**를 다룹니다(WhatsApp/Telegram 같은 채팅 채널이 아님).
모델 선택 규칙은 [/concepts/models](/ko/concepts/models)을 참하세요.
## 빠른 규칙
- 모델 ref는 `provider/model`을 사용합니다(예: `opencode/claude-opus-4-6`).
- `agents.defaults.models`를 설정하면 allowlist가 됩니다.
- 모델 참조는 `provider/model` 형식을 사용합니다(예: `opencode/claude-opus-4-6`).
- `agents.defaults.models`를 설정하면 허용 목록이 됩니다.
- CLI 도우미: `openclaw onboard`, `openclaw models list`, `openclaw models set <provider/model>`.
- 폴백 런타임 규칙, 쿨다운 프로브, 세션 override 지속성은
[/concepts/model-failover](/ko/concepts/model-failover)에 설명되어 있습니다.
- `models.providers.*.models[].contextWindow`는 네이티브 모델 메타데이터입니다.
`models.providers.*.models[].contextTokens`유효 런타임 상한입니다.
- Provider plugin은 `registerProvider({ catalog })`를 통해 모델 catalog를 주입할 수 있습니다.
- 폴백 런타임 규칙, 쿨다운 프로브, 세션 재정의 지속성은
[/concepts/model-failover](/ko/concepts/model-failover)에 문서화되어 있습니다.
- `models.providers.*.models[].contextWindow`는 네이티브 모델 메타데이터이고,
`models.providers.*.models[].contextTokens`실제 런타임 상한입니다.
- 제공자 플러그인은 `registerProvider({ catalog })`를 통해 모델 카탈로그를 주입할 수 있으며,
OpenClaw는 그 출력을 `models.providers`에 병합한 뒤
`models.json`을 기록합니다.
- Provider manifest는 `providerAuthEnvVars`를 선언할 수 있으므로 일반적인 env 기반
인증 프로브가 plugin 런타임을 로드할 필요가 없습니다. 남아 있는 코어 env-var
맵은 이제 non-plugin/core provider와 Anthropic API-key-first 온보딩 같은
일부 일반 우선순위 사례에만 사용됩니다.
- Provider plugin은 다음을 통해 provider 런타임 동작도 직접 소유할 수 있습니다.
- 제공자 매니페스트는 `providerAuthEnvVars`
`providerAuthAliases`를 선언할 수 있으므로 일반적인 env 기반 인증 프로브와 제공자 변형은
플러그인 런타임을 로드할 필요가 없습니다. 남아 있는 코어 env-var 맵은 이제
비플러그인/코어 제공자와 Anthropic API 키 우선 온보딩 같은 몇 가지 일반 우선순위 사례에만
사용됩니다.
- 제공자 플러그인은 다음을 통해 제공자 런타임 동작도 소유할 수 있습니다:
`normalizeModelId`, `normalizeTransport`, `normalizeConfig`,
`applyNativeStreamingUsageCompat`, `resolveConfigApiKey`,
`resolveSyntheticAuth`, `shouldDeferSyntheticProfileAuth`,
@ -52,219 +53,209 @@ x-i18n:
`resolveDefaultThinkingLevel`, `applyConfigDefaults`, `isModernModelRef`,
`prepareRuntimeAuth`, `resolveUsageAuth`, `fetchUsageSnapshot`, 그리고
`onModelSelected`.
- 참고: provider 런타임 `capabilities`는 공유 runner 메타데이터입니다(provider
계열, transcript/tooling 특이사항, transport/cache 힌트). 이것은
plugin이 무엇을 등록하는지 설명하는 [공개 capability 모델](/ko/plugins/architecture#public-capability-model)
과는 다릅니다(텍스트 추론, 음성 등).
- 참고: 제공자 런타임 `capabilities`는 공유 러너 메타데이터입니다(제공자
계열, 전사 기록/도구 관련 특이점, 전송/캐시 힌트). 이는
플러그인이 무엇을 등록하는지(텍스트 추론, 음성 등)를 설명하는
[공개 capability 모델](/ko/plugins/architecture#public-capability-model)과는 다릅니다.
## Plugin 소유 provider 동작
## 플러그인 소유 제공자 동작
Provider plugin은 이제 대부분의 provider별 로직을 소유할 수 있고, OpenClaw는
일반 추론 루프를 유지합니다.
제공자 플러그인은 이제 OpenClaw가 일반 추론 루프를 유지하는 동안
대부분의 제공자별 로직을 소유할 수 있습니다.
일반적인 분리는 다음과 같습니다.
일반적인 분할:
- `auth[].run` / `auth[].runNonInteractive`: provider가 `openclaw onboard`, `openclaw models auth`, 헤드리스 설정을 위한 온보딩/로그인
흐름을 소유
- `wizard.setup` / `wizard.modelPicker`: provider가 인증 선택 라벨,
레거시 alias, 온보딩 allowlist 힌트, 온보딩/모델 picker의 설정 항목을 소유
- `catalog`: provider가 `models.providers`에 표시됨
- `normalizeModelId`: provider가 조회 또는 canonicalization 전에
레거시/preview 모델 id를 정규화
- `normalizeTransport`: provider가 일반 모델 조립 전에 transport 계열 `api` / `baseUrl`
정규화합니다. OpenClaw는 먼저 일치하는 provider를 확인한 다음,
transport를 실제로 변경할 때까지 다른 hook 가능 provider plugin도 확인합니다.
- `normalizeConfig`: provider가 런타임 사용 전에 `models.providers.<id>` config를
정규화합니다. OpenClaw는 먼저 일치하는 provider를 확인한 다음,
config를 실제로 변경할 때까지 다른 hook 가능 provider plugin도 확인합니다. 어떤
provider hook도 config를 다시 쓰지 않으면, 번들된 Google 계열 도우미가 계속해서
지원되는 Google provider 항목을 정규화합니다.
- `applyNativeStreamingUsageCompat`: provider가 config provider에 대해
엔드포인트 기반 네이티브 스트리밍 사용량 호환성 재작성을 적용
- `resolveConfigApiKey`: provider가 config provider에 대해 전체 런타임 인증을 강제로 로드하지 않고
env-marker 인증을 해결합니다.
`amazon-bedrock`도 Bedrock 런타임 인증이
AWS SDK 기본 체인을 사용하더라도, 여기에서 내장 AWS env-marker resolver를 가집니다.
- `resolveSyntheticAuth`: provider가 평문 비밀을 저장하지 않고도
로컬/셀프호스트 또는 기타 config 기반 인증 가용성을 노출할 수 있음
- `shouldDeferSyntheticProfileAuth`: provider가 저장된 synthetic profile
placeholder를 env/config 기반 인증보다 낮은 우선순위로 표시할 수 있음
- `resolveDynamicModel`: provider가 로컬 정적 catalog에 아직 없는 모델 id를
허용
- `prepareDynamicModel`: provider가 동적 해결을 다시 시도하기 전에
메타데이터 새로고침이 필요
- `normalizeResolvedModel`: provider가 transport 또는 base URL 재작성이 필요
- `contributeResolvedModelCompat`: provider가 다른 호환 transport를 통해 들어온 경우에도
해당 vendor 모델에 대한 compat 플래그를 제공
- `capabilities`: provider가 transcript/tooling/provider 계열 특이사항을 게시
- `normalizeToolSchemas`: provider가 내장 runner가 보기 전에
tool schema를 정리
- `inspectToolSchemas`: provider가 정규화 후 transport별 schema 경고를 표시
- `resolveReasoningOutputMode`: provider가 네이티브 대 태그 기반
reasoning-output 계약을 선택
- `prepareExtraParams`: provider가 모델별 요청 param의 기본값을 적용하거나 정규화
- `createStreamFn`: provider가 일반 stream 경로를 완전히
커스텀 transport로 대체
- `wrapStreamFn`: provider가 요청 헤더/본문/모델 compat wrapper를 적용
- `resolveTransportTurnState`: provider가 턴별 네이티브 transport
헤더 또는 메타데이터를 제공
- `resolveWebSocketSessionPolicy`: provider가 네이티브 WebSocket 세션
헤더 또는 세션 쿨다운 정책을 제공
- `createEmbeddingProvider`: provider가 코어 embedding switchboard 대신
provider plugin에 속하는 메모리 embedding 동작을 소유
- `formatApiKey`: provider가 저장된 인증 profile을 transport가 기대하는
런타임 `apiKey` 문자열로 포맷
- `auth[].run` / `auth[].runNonInteractive`: 제공자가 `openclaw onboard`, `openclaw models auth`, 헤드리스 설정을 위한 온보딩/로그인 흐름을 소유
- `wizard.setup` / `wizard.modelPicker`: 제공자가 인증 선택 라벨,
레거시 별칭, 온보딩 허용 목록 힌트, 온보딩/모델 선택기의 설정 항목을 소유
- `catalog`: 제공자가 `models.providers`에 나타남
- `normalizeModelId`: 제공자가 조회나 정규화 전에 레거시/프리뷰 모델 id를 정규화
- `normalizeTransport`: 제공자가 일반 모델 조립 전에 전송 계열 `api` / `baseUrl`을 정규화합니다. OpenClaw는 먼저 일치한 제공자를 확인한 다음,
실제로 전송을 변경할 때까지 다른 hook 지원 제공자 플러그인을 확인합니다
- `normalizeConfig`: 제공자가 런타임이 사용하기 전에 `models.providers.<id>` 구성을 정규화합니다. OpenClaw는 먼저 일치한 제공자를 확인한 다음, 실제로 구성을 변경할 때까지 다른
hook 지원 제공자 플러그인을 확인합니다. 어떤 제공자 hook도 구성을 재작성하지 않으면,
번들된 Google 계열 도우미가 계속 지원되는 Google 제공자 항목을
정규화합니다.
- `applyNativeStreamingUsageCompat`: 제공자가 구성 제공자에 대해 엔드포인트 기반 네이티브 스트리밍 사용량 호환성 재작성을 적용
- `resolveConfigApiKey`: 제공자가 전체 런타임 인증 로딩을 강제하지 않고
구성 제공자의 env-marker 인증을 해석합니다.
`amazon-bedrock`은 Bedrock 런타임 인증이 AWS SDK 기본 체인을 사용하더라도,
여기에서 내장 AWS env-marker 해석기도 가집니다.
- `resolveSyntheticAuth`: 제공자가 평문 비밀을 저장하지 않고도
로컬/셀프호스트형 또는 기타 구성 기반 인증 가용성을 노출할 수 있음
- `shouldDeferSyntheticProfileAuth`: 제공자가 저장된 synthetic profile
플레이스홀더를 env/구성 기반 인증보다 낮은 우선순위로 표시할 수 있음
- `resolveDynamicModel`: 제공자가 아직 로컬 정적 카탈로그에 없는
모델 id를 수용
- `prepareDynamicModel`: 제공자가 동적 해석을 다시 시도하기 전에 메타데이터 새로 고침이 필요
- `normalizeResolvedModel`: 제공자에 전송 또는 base URL 재작성이 필요
- `contributeResolvedModelCompat`: 제공자가 다른 호환 전송을 통해 들어오더라도
자사 공급업체 모델에 대한 호환 플래그를 제공
- `capabilities`: 제공자가 전사 기록/도구/제공자 계열 관련 특이점을 게시
- `normalizeToolSchemas`: 제공자가 내장 러너가 보기 전에
도구 스키마를 정리
- `inspectToolSchemas`: 제공자가 정규화 후
전송별 스키마 경고를 노출
- `resolveReasoningOutputMode`: 제공자가 네이티브와 태그형
추론 출력 계약 중에서 선택
- `prepareExtraParams`: 제공자가 모델별 요청 파라미터의 기본값을 설정하거나 정규화
- `createStreamFn`: 제공자가 일반 스트림 경로를 완전히
사용자 지정된 전송으로 대체
- `wrapStreamFn`: 제공자가 요청 헤더/본문/모델 호환 래퍼를 적용
- `resolveTransportTurnState`: 제공자가 턴별 네이티브 전송
헤더나 메타데이터를 제공
- `resolveWebSocketSessionPolicy`: 제공자가 네이티브 WebSocket 세션
헤더나 세션 쿨다운 정책을 제공
- `createEmbeddingProvider`: 제공자 플러그인 쪽에 속하는 경우
제공자가 메모리 임베딩 동작을 소유하고, 코어 임베딩 스위치보드는 사용하지 않음
- `formatApiKey`: 제공자가 저장된 인증 프로필을 전송이 기대하는 런타임
`apiKey` 문자열로 형식화
- `refreshOAuth`: 공유 `pi-ai`
refresher로 충분하지 않을 때 provider가 OAuth 새로고침을 소유
- `buildAuthDoctorHint`: OAuth 새로고침이 실패할 때 provider가
복구 안내를 추가
- `matchesContextOverflowError`: provider가 일반 heuristic이 놓치는
provider별 컨텍스트 창 초과 오류를 인식
- `classifyFailoverReason`: provider가 provider별 원시 transport/API
오류를 rate limit 또는 overload 같은 failover reason으로 매핑
- `isCacheTtlEligible`: provider가 어떤 업스트림 모델 id가 prompt-cache TTL을 지원하는지 결정
- `buildMissingAuthMessage`: provider가 일반 인증 저장소 오류를
provider별 복구 힌트로 대체
- `suppressBuiltInModel`: provider가 오래된 업스트림 행을 숨기고
직접 해결 실패에 대해 vendor 소유 오류를 반환할 수 있음
- `augmentModelCatalog`: provider가 발견 및 config 병합 후
synthetic/final catalog 행을 추가
- `isBinaryThinking`: provider가 이진 on/off thinking UX를 소유
- `supportsXHighThinking`: provider가 선택한 모델에서 `xhigh`를 사용하도록 설정
- `resolveDefaultThinkingLevel`: provider가 모델 계열의 기본 `/think` 정책을 소유
- `applyConfigDefaults`: provider가 인증 모드, env 또는 모델 계열에 따라
config materialization 중 provider별 전역 기본값을 적용
- `isModernModelRef`: provider가 라이브/스모크 선호 모델 매칭을 소유
- `prepareRuntimeAuth`: provider가 구성된 자격 증명을 짧은 수명의
런타임 토큰으로 변환
- `resolveUsageAuth`: provider가 `/usage`
및 관련 상태/리포팅 화면을 위한 사용량/할당량 자격 증명을 해결
- `fetchUsageSnapshot`: provider가 사용량 엔드포인트 fetch/parsing을 소유하고
코어는 여전히 요약 셸과 포맷팅을 소유
- `onModelSelected`: provider가 텔레메트리 또는 provider 소유 세션 bookkeeping 같은
선택 후 부수 효과를 실행
리프레셔로 충분하지 않을 때 제공자가 OAuth 갱신을 소유
- `buildAuthDoctorHint`: OAuth 갱신이
실패할 때 제공자가 복구 안내를 덧붙임
- `matchesContextOverflowError`: 제공자가 일반 휴리스틱으로는 놓치는
제공자별 컨텍스트 창 초과 오류를 인식
- `classifyFailoverReason`: 제공자가 제공자별 원시 전송/API
오류를 rate limit 또는 overload 같은 페일오버 이유로 매핑
- `isCacheTtlEligible`: 제공자가 어떤 업스트림 모델 id가 프롬프트 캐시 TTL을 지원하는지 결정
- `buildMissingAuthMessage`: 제공자가 일반 인증 저장소 오류를
제공자별 복구 힌트로 대체
- `suppressBuiltInModel`: 제공자가 오래된 업스트림 행을 숨기고
직접 해석 실패에 대해 공급업체 소유 오류를 반환할 수 있음
- `augmentModelCatalog`: 제공자가 발견 및 구성 병합 후
synthetic/final 카탈로그 행을 추가
- `isBinaryThinking`: 제공자가 이진 on/off thinking UX를 소유
- `supportsXHighThinking`: 제공자가 선택된 모델에 `xhigh`를 활성화
- `resolveDefaultThinkingLevel`: 제공자가 모델 계열의 기본 `/think` 정책을 소유
- `applyConfigDefaults`: 제공자가 인증 모드, env 또는 모델 계열에 따라
구성 구체화 중 제공자별 전역 기본값을 적용
- `isModernModelRef`: 제공자가 live/smoke 선호 모델 매칭을 소유
- `prepareRuntimeAuth`: 제공자가 구성된 자격 증명을 짧은 수명의 런타임 토큰으로 변환
- `resolveUsageAuth`: 제공자가 `/usage` 및 관련 상태/보고 표면을 위한
사용량/쿼터 자격 증명을 해석
- `fetchUsageSnapshot`: 제공자가 사용량 엔드포인트 조회/파싱을 소유하고,
코어는 여전히 요약 셸과 형식화를 소유
- `onModelSelected`: 제공자가 텔레메트리 또는 제공자 소유 세션 bookkeeping 같은
모델 선택 후 부수 효과를 실행
현재 번들 예시:
현재 번들 예시:
- `anthropic`: Claude 4.6 forward-compat 폴백, 인증 복구 힌트, 사용량
엔드포인트 fetch, cache-TTL/provider 계열 메타데이터, 인증 인식 전역
config 기본값
- `amazon-bedrock`: Bedrock별 throttle/not-ready 오류에 대한 provider 소유
컨텍스트 초과 매칭 및 failover
reason 분류, 그리고 Anthropic 트래픽에서 Claude 전용 replay-policy
가드를 위한 공유 `anthropic-by-model` 재생 계열
- `anthropic`: Claude 4.6 순방향 호환 폴백, 인증 복구 힌트, 사용량
엔드포인트 조회, cache-TTL/제공자 계열 메타데이터, 인증 인지 전역
구성 기본값
- `amazon-bedrock`: Bedrock 전용 throttle/not-ready 오류에 대한 제공자 소유
컨텍스트 초과 매칭과 페일오버 이유 분류, 그리고 Anthropic 트래픽의 Claude 전용 리플레이 정책
가드를 위한 공유 `anthropic-by-model` 리플레이 계열
- `anthropic-vertex`: Anthropic-message
트래픽에서 Claude 전용 replay-policy 가드
- `openrouter`: pass-through 모델 id, 요청 wrapper, provider capability
트래픽에 대한 Claude 전용 리플레이 정책 가드
- `openrouter`: 패스스루 모델 id, 요청 래퍼, 제공자 capability
힌트, 프록시 Gemini 트래픽에서 Gemini thought-signature 정리,
`openrouter-thinking` stream 계열을 통한 프록시 reasoning 주입,
`openrouter-thinking` 스트림 계열을 통한 프록시 추론 주입,
라우팅 메타데이터 전달, cache-TTL 정책
- `github-copilot`: 온보딩/디바이스 로그인, forward-compat 모델 폴백,
Claude-thinking transcript 힌트, 런타임 토큰 교환, 사용량 엔드포인트
fetch
- `openai`: GPT-5.4 forward-compat 폴백, 직접 OpenAI transport
정규화, Codex 인식 missing-auth 힌트, Spark 숨김, synthetic
OpenAI/Codex catalog 행, thinking/live-model 정책, usage-token alias
- `github-copilot`: 온보딩/디바이스 로그인, 순방향 호환 모델 폴백,
Claude-thinking 전사 기록 힌트, 런타임 토큰 교환, 사용량 엔드포인트
조회
- `openai`: GPT-5.4 순방향 호환 폴백, 직접 OpenAI 전송
정규화, Codex 인지 누락 인증 힌트, Spark 억제, synthetic
OpenAI/Codex 카탈로그 행, thinking/live-model 정책, 사용량 토큰 별칭
정규화(`input` / `output``prompt` / `completion` 계열), 네이티브 OpenAI/Codex
wrapper를 위한 공유 `openai-responses-defaults` stream 계열,
provider 계열 메타데이터, `gpt-image-1`용 번들 이미지 생성 provider
등록, `sora-2`용 번들 비디오 생성 provider
래퍼를 위한 공유 `openai-responses-defaults` 스트림 계열,
제공자 계열 메타데이터, `gpt-image-1`용 번들 이미지 생성 제공자
등록, `sora-2`용 번들 비디오 생성 제공자
등록
- `google``google-gemini-cli`: Gemini 3.1 forward-compat 폴백,
네이티브 Gemini replay 검증, bootstrap replay 정리, 태그 기반
reasoning-output 모드, modern-model 매칭, Gemini image-preview 모델용
번들 이미지 생성 provider 등록, Veo 모델용 번들
비디오 생성 provider 등록; Gemini CLI OAuth는 또한
사용량 화면용 인증 profile 토큰 포맷팅, usage-token parsing, 할당량 엔드포인트
fetch를 소유
- `moonshot`: 공유 transport, plugin 소유 thinking payload 정규화
- `kilocode`: 공유 transport, plugin 소유 요청 헤더, reasoning payload
정규화, 프록시 Gemini thought-signature 정리, cache-TTL
- `google``google-gemini-cli`: Gemini 3.1 순방향 호환 폴백,
네이티브 Gemini 리플레이 검증, bootstrap 리플레이 정리, 태그형
추론 출력 모드, 최신 모델 매칭, Gemini 이미지 프리뷰 모델용 번들 이미지 생성
제공자 등록, Veo 모델용 번들
비디오 생성 제공자 등록; Gemini CLI OAuth는 또한
인증 프로필 토큰 형식화, 사용량 토큰 파싱, 사용량 표면용 쿼터 엔드포인트
조회를 소유
- `moonshot`: 공유 전송, 플러그인 소유 thinking 페이로드 정규화
- `kilocode`: 공유 전송, 플러그인 소유 요청 헤더, 추론 페이로드
정규화, 프록시-Gemini thought-signature 정리, cache-TTL
정책
- `zai`: GLM-5 forward-compat 폴백, `tool_stream` 기본값, cache-TTL
정책, binary-thinking/live-model 정책, 사용량 인증 + 할당량 fetch;
알 수 없는 `glm-5*` id는 번들된 `glm-4.7` 템플릿에서 합성
- `xai`: 네이티브 Responses transport 정규화, Grok fast variant
`/fast` alias 재작성, 기본 `tool_stream`, xAI별 tool-schema /
reasoning-payload 정리, `grok-imagine-video`용 번들 비디오 생성 provider
- `zai`: GLM-5 순방향 호환 폴백, `tool_stream` 기본값, cache-TTL
정책, binary-thinking/live-model 정책, 사용량 인증 + 쿼터 조회;
알 수 없는 `glm-5*` id는 번들된 `glm-4.7` 템플릿에서 synthesize
- `xai`: 네이티브 Responses 전송 정규화, Grok 빠른 변형
`/fast` 별칭 재작성, 기본 `tool_stream`, xAI 전용 도구 스키마 /
추론 페이로드 정리, `grok-imagine-video`용 번들 비디오 생성 제공자
등록
- `mistral`: plugin 소유 capability 메타데이터
- `opencode``opencode-go`: plugin 소유 capability 메타데이터와
프록시 Gemini thought-signature 정리
- `alibaba`: `alibaba/wan2.6-t2v` 같은 직접 Wan 모델 ref
plugin 소유 비디오 생성 catalog
- `byteplus`: plugin 소유 catalog와 Seedance 텍스트-비디오/이미지-비디오 모델용
번들 비디오 생성 provider 등록
- `fal`: 호스팅된 서드파티용 번들 비디오 생성 provider 등록,
FLUX 이미지 모델용 이미지 생성 provider 등록,
그리고 호스팅된 서드파티 비디오 모델용 번들
비디오 생성 provider 등록
- `mistral`: 플러그인 소유 capability 메타데이터
- `opencode``opencode-go`: 플러그인 소유 capability 메타데이터와
프록시-Gemini thought-signature 정리
- `alibaba`: `alibaba/wan2.6-t2v` 같은 직접 Wan 모델 참조
플러그인 소유 비디오 생성 카탈로그
- `byteplus`: 플러그인 소유 카탈로그와 Seedance 텍스트-비디오/이미지-비디오 모델용
번들 비디오 생성 제공자
등록
- `fal`: 호스팅된 서드파티 이미지 생성 모델용
번들 이미지 생성 제공자 등록과 호스팅된 서드파티 비디오 모델용
번들 비디오 생성 제공자 등록
- `cloudflare-ai-gateway`, `huggingface`, `kimi`, `nvidia`, `qianfan`,
`stepfun`, `synthetic`, `venice`, `vercel-ai-gateway`, `volcengine`:
plugin 소유 catalog만 제공
- `qwen`: 텍스트 모델용 plugin 소유 catalog와 멀티모달 화면용
공유 media-understanding 및 비디오 생성 provider 등록;
플러그인 소유 카탈로그 בלבד
- `qwen`: 텍스트 모델용 플러그인 소유 카탈로그와 멀티모달 표면용
공유 media-understanding 및 비디오 생성 제공자 등록;
Qwen 비디오 생성은 `wan2.6-t2v``wan2.7-r2v` 같은 번들 Wan 모델과 함께
Standard DashScope 비디오 엔드포인트를 사용
- `runway`: `gen4.5` 같은 네이티브 Runway 태스크 기반 모델용
plugin 소유 비디오 생성 provider 등록
- `minimax`: plugin 소유 catalog, Hailuo 비디오 모델용 번들 비디오 생성 provider
등록, `image-01`용 번들 이미지 생성 provider
등록, 하이브리드 Anthropic/OpenAI replay-policy
표준 DashScope 비디오 엔드포인트를 사용
- `runway`: `gen4.5` 같은 네이티브
Runway 작업 기반 모델용 플러그인 소유 비디오 생성 제공자 등록
- `minimax`: 플러그인 소유 카탈로그, Hailuo 비디오 모델용 번들 비디오 생성 제공자
등록, `image-01`용 번들 이미지 생성 제공자
등록, 하이브리드 Anthropic/OpenAI 리플레이 정책
선택, 사용량 인증/스냅샷 로직
- `together`: plugin 소유 catalog와 Wan 비디오 모델용 번들 비디오 생성 provider
등록
- `xiaomi`: plugin 소유 catalog와 사용량 인증/스냅샷 로직
- `together`: 플러그인 소유 카탈로그와 Wan 비디오 모델용
번들 비디오 생성 제공자 등록
- `xiaomi`: 플러그인 소유 카탈로그와 사용량 인증/스냅샷 로직
번들된 `openai` plugin은 이제 `openai`
`openai-codex` 두 provider id를 모두 소유합니다.
번들된 `openai` 플러그인은 이제 두 제공자 id인 `openai`
`openai-codex`를 모두 소유합니다.
여기까지는 여전히 OpenClaw의 일반 transport에 맞는 provider를 다룹니다. 완전히
커스텀 요청 실행기가 필요한 provider는 별도의 더 깊은 확장 표면입니다.
여기까지는 여전히 OpenClaw의 일반 전송에 맞는 제공자들입니다. 완전히 사용자 지정된 요청 실행기가 필요한 제공자는 별도의, 더 깊은 확장 표면입니다.
## API 키 로테이션
## API 키 순환
- 선택된 provider에 대해 일반 provider 로테이션을 지원합니다.
- 여러 키를 다음으로 구성합니다:
- `OPENCLAW_LIVE_<PROVIDER>_KEY`(단일 라이브 override, 최우선)
- 선택된 제공자에 대해 일반적인 제공자 키 순환을 지원합니다.
- 여러 키는 다음을 통해 구성합니다:
- `OPENCLAW_LIVE_<PROVIDER>_KEY`(단일 live override, 최우선)
- `<PROVIDER>_API_KEYS`(쉼표 또는 세미콜론 목록)
- `<PROVIDER>_API_KEY`(기본 키)
- `<PROVIDER>_API_KEY_*`(번호가 붙은 목록, 예: `<PROVIDER>_API_KEY_1`)
- Google provider의 경우 `GOOGLE_API_KEY`도 폴백으로 포함됩니다.
- 키 선택 순서는 우선순위를 유지하고 값을 중복 제거합니다.
- 요청은 rate-limit 응답에서만 다음 키로 재시도됩니다(예:
`429`, `rate_limit`, `quota`, `resource exhausted`, `Too many
- `<PROVIDER>_API_KEY_*`(번호가 매겨진 목록, 예: `<PROVIDER>_API_KEY_1`)
- Google 제공자의 경우 `GOOGLE_API_KEY`도 폴백으로 포함됩니다.
- 키 선택 순서는 우선순위를 보존하고 값을 중복 제거합니다.
- 요청은 rate-limit 응답에서만 다음 키로 재시도됩니다(
예: `429`, `rate_limit`, `quota`, `resource exhausted`, `Too many
concurrent requests`, `ThrottlingException`, `concurrency limit reached`,
`workers_ai ... quota limit exceeded`, 또는 주기적인 usage-limit 메시지).
- rate-limit가 아닌 실패는 즉시 실패하며 키 로테이션을 시도하지 않습니다.
`workers_ai ... quota limit exceeded`, 또는 주기적인 사용량 제한 메시지).
- rate-limit이 아닌 실패는 즉시 실패하며, 키 순환은 시도되지 않습니다.
- 모든 후보 키가 실패하면 마지막 시도의 최종 오류가 반환됩니다.
## 내장 provider (pi-ai catalog)
## 기본 제공 제공자 (pi-ai 카탈로그)
OpenClaw는 piai catalog를 함께 제공합니다. 이 provider는
`models.providers` config가 **필요하지 않습니다**.
인증만 설정하고 모델을 선택하면 됩니다.
OpenClaw에는 piai 카탈로그가 포함되어 있습니다. 이 제공자들은
`models.providers` 구성이 **필요하지 않습니다**. 인증을 설정하고 모델만 고르면 됩니다.
### OpenAI
- Provider: `openai`
- 제공자: `openai`
- 인증: `OPENAI_API_KEY`
- 선택적 로테이션: `OPENAI_API_KEYS`, `OPENAI_API_KEY_1`, `OPENAI_API_KEY_2`, 그리고 `OPENCLAW_LIVE_OPENAI_KEY`(단일 override)
- 선택적 순환: `OPENAI_API_KEYS`, `OPENAI_API_KEY_1`, `OPENAI_API_KEY_2`, 그리고 `OPENCLAW_LIVE_OPENAI_KEY`(단일 override)
- 예시 모델: `openai/gpt-5.4`, `openai/gpt-5.4-pro`
- CLI: `openclaw onboard --auth-choice openai-api-key`
- 기본 transport는 `auto`입니다(WebSocket 우선, SSE 폴백)
- 모델별 override는 `agents.defaults.models["openai/<model>"].params.transport`로 설정합니다(`"sse"`, `"websocket"`, 또는 `"auto"`)
- OpenAI Responses WebSocket 워밍업은 기본적으로 `params.openaiWsWarmup`으로 활성화됩니다(`true`/`false`)
- OpenAI priority processing은 `agents.defaults.models["openai/<model>"].params.serviceTier` 활성화할 수 있습니다
- 기본 전송은 `auto`입니다(WebSocket 우선, SSE 폴백)
- 모델별 재정의는 `agents.defaults.models["openai/<model>"].params.transport`를 통해 수행합니다(`"sse"`, `"websocket"`, 또는 `"auto"`)
- OpenAI Responses WebSocket 워밍업은 `params.openaiWsWarmup`(`true`/`false`)을 통해 기본적으로 활성화됩니다
- OpenAI priority processing은 `agents.defaults.models["openai/<model>"].params.serviceTier`를 통해 활성화할 수 있습니다
- `/fast``params.fastMode`는 직접 `openai/*` Responses 요청을 `api.openai.com``service_tier=priority`로 매핑합니다
- 공유 `/fast` 토글 대신 명시적 tier를 원하면 `params.serviceTier`를 사용하세요
- 공유 `/fast` 토글 대신 명시적 티어를 원하면 `params.serviceTier`를 사용하세요
- 숨겨진 OpenClaw attribution 헤더(`originator`, `version`,
`User-Agent`)는 일반 OpenAI 호환 프록시가 아니라
`api.openai.com`으로 가는 네이티브 OpenAI 트래픽에만 적용됩니다
- 네이티브 OpenAI 경로는 Responses `store`, prompt-cache 힌트,
OpenAI reasoning-compat payload shaping도 유지하지만,
프록시 경로는 그렇지 않습니다
- `openai/gpt-5.3-codex-spark`는 라이브 OpenAI API가 이를 거부하기 때문에 OpenClaw에서 의도적으로 숨겨집니다. Spark는 Codex 전용으로 처리됩니다
`User-Agent`)는 일반 OpenAI 호환 프록시가 아니라 `api.openai.com`으로 향하는
네이티브 OpenAI 트래픽에만 적용됩니다
- 네이티브 OpenAI 경로는 Responses `store`, 프롬프트 캐시 힌트,
OpenAI 추론 호환 페이로드 형성도 유지하지만, 프록시 경로는 그렇지 않습니다
- `openai/gpt-5.3-codex-spark`는 live OpenAI API가 이를 거부하므로 OpenClaw에서 의도적으로 숨겨져 있습니다. Spark는 Codex 전용으로 처리됩니다
```json5
{
@ -274,14 +265,14 @@ OpenClaw는 piai catalog를 함께 제공합니다. 이 provider는
### Anthropic
- Provider: `anthropic`
- 제공자: `anthropic`
- 인증: `ANTHROPIC_API_KEY`
- 선택적 로테이션: `ANTHROPIC_API_KEYS`, `ANTHROPIC_API_KEY_1`, `ANTHROPIC_API_KEY_2`, 그리고 `OPENCLAW_LIVE_ANTHROPIC_KEY`(단일 override)
- 선택적 순환: `ANTHROPIC_API_KEYS`, `ANTHROPIC_API_KEY_1`, `ANTHROPIC_API_KEY_2`, 그리고 `OPENCLAW_LIVE_ANTHROPIC_KEY`(단일 override)
- 예시 모델: `anthropic/claude-opus-4-6`
- CLI: `openclaw onboard --auth-choice apiKey`
- 직접 공개 Anthropic 요청은 공유 `/fast` 토글과 `params.fastMode`도 지원하며, 여기에는 `api.anthropic.com`으로 전송되는 API-key 및 OAuth 인증 트래픽이 포함됩니다. OpenClaw는 이를 Anthropic `service_tier`(`auto` 대 `standard_only`)로 매핑합니다
- Anthropic 참고: Anthropic 직원이 OpenClaw 스타일 Claude CLI 사용이 다시 허용된다고 알려왔으므로, Anthropic이 새 정책을 게시하지 않는 한 OpenClaw는 이 통합에 대해 Claude CLI 재사용과 `claude -p` 사용을 허용된 것으로 처리합니다.
- Anthropic setup-token은 여전히 지원되는 OpenClaw 토큰 경로로 제공되지만, OpenClaw는 이제 가능하면 Claude CLI 재사용과 `claude -p`선합니다.
- 직접 공개 Anthropic 요청은 `api.anthropic.com`으로 전송되는 API 키 및 OAuth 인증 트래픽을 포함해 공유 `/fast` 토글과 `params.fastMode`를 지원합니다. OpenClaw는 이를 Anthropic `service_tier`(`auto` 대 `standard_only`)에 매핑합니다
- Anthropic 참고: Anthropic 직원이 OpenClaw 스타일 Claude CLI 사용이 다시 허용된다고 알려주었으므로, Anthropic이 새 정책을 게시하지 않는 한 OpenClaw는 이 통합을 위해 Claude CLI 재사용과 `claude -p` 사용을 승인된 것으로 취급합니다.
- Anthropic setup-token은 계속 지원되는 OpenClaw 토큰 경로로 제공되지만, OpenClaw는 이제 가능하면 Claude CLI 재사용과 `claude -p`를 선합니다.
```json5
{
@ -291,21 +282,20 @@ OpenClaw는 piai catalog를 함께 제공합니다. 이 provider는
### OpenAI Code (Codex)
- Provider: `openai-codex`
- 제공자: `openai-codex`
- 인증: OAuth (ChatGPT)
- 예시 모델: `openai-codex/gpt-5.4`
- CLI: `openclaw onboard --auth-choice openai-codex` 또는 `openclaw models auth login --provider openai-codex`
- 기본 transport는 `auto`입니다(WebSocket 우선, SSE 폴백)
- 모델별 override는 `agents.defaults.models["openai-codex/<model>"].params.transport`로 설정합니다(`"sse"`, `"websocket"`, 또는 `"auto"`)
- `params.serviceTier`도 네이티브 Codex Responses 요청(`chatgpt.com/backend-api`)에 전달됩니다
- 기본 전송은 `auto`입니다(WebSocket 우선, SSE 폴백)
- 모델별 재정의는 `agents.defaults.models["openai-codex/<model>"].params.transport`를 통해 수행합니다(`"sse"`, `"websocket"`, 또는 `"auto"`)
- `params.serviceTier`도 네이티브 Codex Responses 요청(`chatgpt.com/backend-api`)에 전달됩니다
- 숨겨진 OpenClaw attribution 헤더(`originator`, `version`,
`User-Agent`)는 일반 OpenAI 호환 프록시가 아니라
`chatgpt.com/backend-api`로 가는 네이티브 Codex 트래픽에만
첨부됩니다
- 직접 `openai/*`와 같은 `/fast` 토글 및 `params.fastMode` config를 공유하며, OpenClaw는 이를 `service_tier=priority`로 매핑합니다
- `openai-codex/gpt-5.3-codex-spark`는 Codex OAuth catalog가 이를 노출할 때 계속 사용할 수 있습니다. entitlement에 따라 달라집니다
- `openai-codex/gpt-5.4`는 네이티브 `contextWindow = 1050000`과 기본 런타임 `contextTokens = 272000`을 유지합니다. 런타임 상한은 `models.providers.openai-codex.models[].contextTokens`로 override하세요
- 정책 참고: OpenAI Codex OAuth는 OpenClaw 같은 외부 도구/워크플로우에 대해 명시적으로 지원됩니다.
`chatgpt.com/backend-api`로 향하는 네이티브 Codex 트래픽에만 첨부됩니다
- 직접 `openai/*`와 동일한 `/fast` 토글 및 `params.fastMode` 구성을 공유하며, OpenClaw는 이를 `service_tier=priority`로 매핑합니다
- `openai-codex/gpt-5.3-codex-spark`는 Codex OAuth 카탈로그가 이를 노출할 때 계속 사용할 수 있습니다. entitlement에 따라 달라집니다
- `openai-codex/gpt-5.4`는 네이티브 `contextWindow = 1050000`과 기본 런타임 `contextTokens = 272000`을 유지합니다. 런타임 상한은 `models.providers.openai-codex.models[].contextTokens`로 재정의하세요
- 정책 참고: OpenAI Codex OAuth는 OpenClaw 같은 외부 도구/워크플로에 대해 명시적으로 지원됩니다.
```json5
{
@ -327,15 +317,15 @@ OpenClaw는 piai catalog를 함께 제공합니다. 이 provider는
### 기타 구독형 호스팅 옵션
- [Qwen Cloud](/ko/providers/qwen): Qwen Cloud provider 표면과 Alibaba DashScope 및 Coding Plan 엔드포인트 매핑
- [Qwen Cloud](/ko/providers/qwen): Qwen Cloud 제공자 표면과 Alibaba DashScope 및 Coding Plan 엔드포인트 매핑
- [MiniMax](/ko/providers/minimax): MiniMax Coding Plan OAuth 또는 API 키 액세스
- [GLM Models](/ko/providers/glm): Z.AI Coding Plan 또는 일반 API 엔드포인트
### OpenCode
- 인증: `OPENCODE_API_KEY`(또는 `OPENCODE_ZEN_API_KEY`)
- Zen 런타임 provider: `opencode`
- Go 런타임 provider: `opencode-go`
- Zen 런타임 제공자: `opencode`
- Go 런타임 제공자: `opencode-go`
- 예시 모델: `opencode/claude-opus-4-6`, `opencode-go/kimi-k2.5`
- CLI: `openclaw onboard --auth-choice opencode-zen` 또는 `openclaw onboard --auth-choice opencode-go`
@ -347,89 +337,90 @@ OpenClaw는 piai catalog를 함께 제공합니다. 이 provider는
### Google Gemini (API 키)
- Provider: `google`
- 제공자: `google`
- 인증: `GEMINI_API_KEY`
- 선택적 로테이션: `GEMINI_API_KEYS`, `GEMINI_API_KEY_1`, `GEMINI_API_KEY_2`, `GOOGLE_API_KEY` 폴백, 그리고 `OPENCLAW_LIVE_GEMINI_KEY`(단일 override)
- 선택적 순환: `GEMINI_API_KEYS`, `GEMINI_API_KEY_1`, `GEMINI_API_KEY_2`, `GOOGLE_API_KEY` 폴백, 그리고 `OPENCLAW_LIVE_GEMINI_KEY`(단일 override)
- 예시 모델: `google/gemini-3.1-pro-preview`, `google/gemini-3-flash-preview`
- 호환성: `google/gemini-3.1-flash-preview`를 사용하는 레거시 OpenClaw config는 `google/gemini-3-flash-preview`로 정규화됩니다
- 호환성: `google/gemini-3.1-flash-preview`를 사용하는 레거시 OpenClaw 구성은 `google/gemini-3-flash-preview`로 정규화됩니다
- CLI: `openclaw onboard --auth-choice gemini-api-key`
- 직접 Gemini 실행은 `agents.defaults.models["google/<model>"].params.cachedContent`
(또는 레거시 `cached_content`)도 허용하며, provider 네이티브
`cachedContents/...` 핸들을 전달합니다. Gemini cache hit는 OpenClaw `cacheRead`로 표시됩니다
- 직접 Gemini 실행은 또한 제공자 네이티브
`cachedContents/...` 핸들을 전달하기 위해 `agents.defaults.models["google/<model>"].params.cachedContent`
(또는 레거시 `cached_content`)를 받을 수 있습니다. Gemini 캐시 히트는 OpenClaw `cacheRead`로 표시됩니다
### Google Vertex 및 Gemini CLI
- Provider: `google-vertex`, `google-gemini-cli`
- 인증: Vertex는 gcloud ADC 사용, Gemini CLI는 자체 OAuth 흐름 사용
- 주의: OpenClaw에서의 Gemini CLI OAuth는 비공식 통합입니다. 일부 사용자는 서드파티 클라이언트를 사용한 뒤 Google 계정 제한을 보고했습니다. 진행하기로 선택했다면 Google 약관을 검토하고 중요하지 않은 계정을 사용하세요.
- Gemini CLI OAuth는 번들된 `google` plugin의 일부로 제공됩니다.
- 먼저 Gemini CLI를 설치하세요:
- 제공자: `google-vertex`, `google-gemini-cli`
- 인증: Vertex는 gcloud ADC 사용하고, Gemini CLI는 자체 OAuth 흐름 사용합니다
- 주의: OpenClaw의 Gemini CLI OAuth는 비공식 통합입니다. 일부 사용자는 서드파티 클라이언트 사용 후 Google 계정 제한을 보고했습니다. 진행하기로 선택한 경우 Google 약관을 검토하고 중요하지 않은 계정을 사용하세요.
- Gemini CLI OAuth는 번들된 `google` 플러그인의 일부로 제공됩니다.
- 먼저 Gemini CLI를 설치합니다:
- `brew install gemini-cli`
- 또는 `npm install -g @google/gemini-cli`
- 활성화: `openclaw plugins enable google`
- 로그인: `openclaw models auth login --provider google-gemini-cli --set-default`
- 기본 모델: `google-gemini-cli/gemini-3-flash-preview`
- 참고: `openclaw.json`에 client id나 secret을 붙여 넣**않습니다**. CLI 로그인 흐름은
게이트웨이 호스트의 인증 profile에 토큰을 저장합니다.
- 로그인 후 요청이 실패하면 게이트웨이 호스트에 `GOOGLE_CLOUD_PROJECT` 또는 `GOOGLE_CLOUD_PROJECT_ID`를 설정하세요.
- Gemini CLI JSON 응답은 `response`에서 파싱되며, 사용량은
`stats`로 폴백되고, `stats.cached`는 OpenClaw `cacheRead`로 정규화됩니다.
- 참고: `openclaw.json`에 client id나 secret을 붙여 넣**필요가 없습니다**. CLI 로그인 흐름이
게이트웨이 호스트의 인증 프로필에 토큰을 저장합니다.
- 로그인 후 요청이 실패하면 게이트웨이 호스트에 `GOOGLE_CLOUD_PROJECT` 또는 `GOOGLE_CLOUD_PROJECT_ID`를 설정하세요.
- Gemini CLI JSON 응답은 `response`에서 파싱되며, 사용량은 `stats`로 폴백되고,
`stats.cached`는 OpenClaw `cacheRead`로 정규화됩니다.
### Z.AI (GLM)
- Provider: `zai`
- 제공자: `zai`
- 인증: `ZAI_API_KEY`
- 예시 모델: `zai/glm-5.1`
- CLI: `openclaw onboard --auth-choice zai-api-key`
- Alias: `z.ai/*` `z-ai/*``zai/*`로 정규화됩니다
- `zai-api-key`는 일치하는 Z.AI 엔드포인트를 자동 감지하며, `zai-coding-global`, `zai-coding-cn`, `zai-global`, `zai-cn`은 특정 표면을 강제합니다
- 별칭: `z.ai/*` `z-ai/*``zai/*`로 정규화됩니다
- `zai-api-key`는 일치하는 Z.AI 엔드포인트를 자동 감지합니다. `zai-coding-global`, `zai-coding-cn`, `zai-global`, `zai-cn`은 특정 표면을 강제로 선택합니다
### Vercel AI Gateway
- Provider: `vercel-ai-gateway`
- 제공자: `vercel-ai-gateway`
- 인증: `AI_GATEWAY_API_KEY`
- 예시 모델: `vercel-ai-gateway/anthropic/claude-opus-4.6`
- CLI: `openclaw onboard --auth-choice ai-gateway-api-key`
### Kilo Gateway
- Provider: `kilocode`
- 제공자: `kilocode`
- 인증: `KILOCODE_API_KEY`
- 예시 모델: `kilocode/kilo/auto`
- CLI: `openclaw onboard --auth-choice kilocode-api-key`
- 기본 URL: `https://api.kilo.ai/api/gateway/`
- 정적 폴백 catalog는 `kilocode/kilo/auto`를 포함하며, 라이브
`https://api.kilo.ai/api/gateway/models` 발견을 통해 런타임
catalog가 더 확장될 수 있습니다.
- `kilocode/kilo/auto` 뒤의 정확한 업스트림 라우팅은 OpenClaw에
하드코딩되어 있지 않고 Kilo Gateway가 소유합니다.
- 정적 폴백 카탈로그는 `kilocode/kilo/auto`를 포함하며, live
`https://api.kilo.ai/api/gateway/models` 탐색은 런타임
카탈로그를 더 확장할 수 있습니다.
- `kilocode/kilo/auto` 뒤의 정확한 업스트림 라우팅은 Kilo Gateway가 소유하며,
OpenClaw에 하드코딩되어 있지 않습니다.
설정 세부 사항은 [/providers/kilocode](/ko/providers/kilocode)를 참하세요.
설정 세부 사항은 [/providers/kilocode](/ko/providers/kilocode)를 참하세요.
### 기타 번들 provider plugin
### 기타 번들 제공자 플러그인
- OpenRouter: `openrouter` (`OPENROUTER_API_KEY`)
- 예시 모델: `openrouter/auto`
- OpenClaw는 요청이 실제로 `openrouter.ai`를 대상으로 할 때만
OpenRouter 문서의 앱 attribution 헤더를 적용합니다
OpenRouter의 문서화된 앱 attribution 헤더를 적용합니다
- OpenRouter 전용 Anthropic `cache_control` 마커도
임의 프록시 URL이 아니라 검증된 OpenRouter 경로에만 적용됩니다
- OpenRouter는 프록시 스타일 OpenAI 호환 경로에 남아 있으므로 네이티브
OpenAI 전용 요청 shaping(`serviceTier`, Responses `store`,
prompt-cache 힌트, OpenAI reasoning-compat payload)은 전달되지 않습니다
- Gemini 기반 OpenRouter ref는 프록시 Gemini thought-signature 정리만
유지하며, 네이티브 Gemini replay 검증과 bootstrap 재작성은 비활성화됩니다
임의 프록시 URL이 아니라 검증된 OpenRouter 경로에만 적용됩니다
- OpenRouter는 프록시 스타일 OpenAI 호환 경로에 머무르므로, 네이티브
OpenAI 전용 요청 형성(`serviceTier`, Responses `store`,
프롬프트 캐시 힌트, OpenAI 추론 호환 페이로드)은 전달되지 않습니다
- Gemini 기반 OpenRouter 참조는 프록시-Gemini thought-signature 정리만
유지합니다. 네이티브 Gemini 리플레이 검증과 bootstrap 재작성은 비활성 상태로 유지됩니다
- Kilo Gateway: `kilocode` (`KILOCODE_API_KEY`)
- 예시 모델: `kilocode/kilo/auto`
- Gemini 기반 Kilo ref도 동일한 프록시 Gemini thought-signature
정리 경로를 유지하며, `kilocode/kilo/auto` 및 다른 proxy-reasoning-unsupported
힌트는 프록시 reasoning 주입을 건너뜁니다
- Gemini 기반 Kilo 참조는 동일한 프록시-Gemini thought-signature
정리 경로를 유지합니다. `kilocode/kilo/auto`와 기타 프록시 추론 미지원
힌트는 프록시 추론 주입을 건너뜁니다
- MiniMax: `minimax`(API 키) 및 `minimax-portal`(OAuth)
- 인증: `minimax`에는 `MINIMAX_API_KEY`; `minimax-portal`에는 `MINIMAX_OAUTH_TOKEN` 또는 `MINIMAX_API_KEY`
- 인증: `minimax`에는 `MINIMAX_API_KEY`, `minimax-portal`에는 `MINIMAX_OAUTH_TOKEN` 또는 `MINIMAX_API_KEY`
- 예시 모델: `minimax/MiniMax-M2.7` 또는 `minimax-portal/MiniMax-M2.7`
- MiniMax 온보딩/API 키 설정은 명시적인 M2.7 모델 정의를
`input: ["text", "image"]`와 함께 기록합니다. 번들된 provider catalog는 해당 provider config가 materialize될 때까지
채팅 ref를 텍스트 전용으로 유지합니다
`input: ["text", "image"]`와 함께 기록합니다. 번들된 제공자 카탈로그는
해당 제공자 구성이 구체화될 때까지 채팅 참조를
텍스트 전용으로 유지합니다
- Moonshot: `moonshot` (`MOONSHOT_API_KEY`)
- 예시 모델: `moonshot/kimi-k2.5`
- Kimi Coding: `kimi` (`KIMI_API_KEY` 또는 `KIMICODE_API_KEY`)
@ -457,8 +448,8 @@ OpenClaw는 piai catalog를 함께 제공합니다. 이 provider는
- xAI: `xai` (`XAI_API_KEY`)
- 네이티브 번들 xAI 요청은 xAI Responses 경로를 사용합니다
- `/fast` 또는 `params.fastMode: true``grok-3`, `grok-3-mini`,
`grok-4`, `grok-4-0709`를 해당 `*-fast` variant로 재작성합니다
- `tool_stream`은 기본 활성화되어 있습니다.
`grok-4`, `grok-4-0709`를 해당 `*-fast` 변형으로 재작성합니다
- `tool_stream`은 기본적으로 활성화됩니다.
비활성화하려면
`agents.defaults.models["xai/<model>"].params.tool_stream``false`로 설정하세요
- Mistral: `mistral` (`MISTRAL_API_KEY`)
@ -469,24 +460,23 @@ OpenClaw는 piai catalog를 함께 제공합니다. 이 provider는
- Cerebras의 GLM 모델은 `zai-glm-4.7``zai-glm-4.6` id를 사용합니다.
- OpenAI 호환 base URL: `https://api.cerebras.ai/v1`.
- GitHub Copilot: `github-copilot` (`COPILOT_GITHUB_TOKEN` / `GH_TOKEN` / `GITHUB_TOKEN`)
- Hugging Face Inference 예시 모델: `huggingface/deepseek-ai/DeepSeek-R1`; CLI: `openclaw onboard --auth-choice huggingface-api-key`. [Hugging Face (Inference)](/ko/providers/huggingface)를 참하세요.
- Hugging Face Inference 예시 모델: `huggingface/deepseek-ai/DeepSeek-R1`; CLI: `openclaw onboard --auth-choice huggingface-api-key`. [Hugging Face (Inference)](/ko/providers/huggingface)를 참하세요.
## `models.providers`를 통한 provider (커스텀/base URL)
## `models.providers`를 통한 제공자 (커스텀/base URL)
**커스텀** provider 또는
OpenAI/Anthropic 호환 프록시를 추가하려면 `models.providers`(또는 `models.json`)를 사용하세요.
`models.providers`(또는 `models.json`)를 사용해 **커스텀** 제공자 또는
OpenAI/Anthropic 호환 프록시를 추가할 수 있습니다.
아래의 많은 번들 provider plugin은 이미 기본 catalog를 게시합니다.
기본 base URL, 헤더 또는 모델 목록을 override하려는 경우에만
명시적인 `models.providers.<id>` 항목을 사용하세요.
아래의 많은 번들 제공자 플러그인은 이미 기본 카탈로그를 게시합니다.
기본 base URL, 헤더 또는 모델 목록을 재정의하려는 경우에만 명시적인
`models.providers.<id>` 항목을 사용하세요.
### Moonshot AI (Kimi)
Moonshot은 번들 provider plugin으로 제공됩니다. 기본적으로 내장 provider를
사용하고, base URL 또는 모델 메타데이터를 override해야 할 때만
명시적인 `models.providers.moonshot` 항목을 추가하세요.
Moonshot은 번들 제공자 플러그인으로 제공됩니다. 기본적으로는 내장 제공자를 사용하고,
base URL이나 모델 메타데이터를 재정의해야 할 때만 명시적인 `models.providers.moonshot` 항목을 추가하세요:
- Provider: `moonshot`
- 제공자: `moonshot`
- 인증: `MOONSHOT_API_KEY`
- 예시 모델: `moonshot/kimi-k2.5`
- CLI: `openclaw onboard --auth-choice moonshot-api-key` 또는 `openclaw onboard --auth-choice moonshot-api-key-cn`
@ -523,9 +513,9 @@ Kimi K2 모델 ID:
### Kimi Coding
Kimi Coding은 Moonshot AI의 Anthropic 호환 엔드포인트를 사용합니다.
Kimi Coding은 Moonshot AI의 Anthropic 호환 엔드포인트를 사용합니다:
- Provider: `kimi`
- 제공자: `kimi`
- 인증: `KIMI_API_KEY`
- 예시 모델: `kimi/kimi-code`
@ -538,13 +528,13 @@ Kimi Coding은 Moonshot AI의 Anthropic 호환 엔드포인트를 사용합니
}
```
레거시 `kimi/k2p5`는 호환 모델 id로 계속 허용됩니다.
레거시 `kimi/k2p5`계속 호환 모델 id로 허용됩니다.
### Volcano Engine (Doubao)
Volcano Engine(화산엔진)은 중국에서 Doubao 및 기타 모델에 대한 액세스를 제공합니다.
Volcano Engine(화산엔진, 火山引擎)은 중국에서 Doubao 및 기타 모델에 대한 액세스를 제공합니다.
- Provider: `volcengine` (coding: `volcengine-plan`)
- 제공자: `volcengine`(코딩: `volcengine-plan`)
- 인증: `VOLCANO_ENGINE_API_KEY`
- 예시 모델: `volcengine-plan/ark-code-latest`
- CLI: `openclaw onboard --auth-choice volcengine-api-key`
@ -557,13 +547,12 @@ Volcano Engine(화산엔진)은 중국에서 Doubao 및 기타 모델에 대한
}
```
온보딩은 기본적으로 coding 표면을 사용하지만, 일반 `volcengine/*`
catalog도 동시에 등록됩니다.
온보딩은 기본적으로 코딩 표면을 선택하지만, 일반 `volcengine/*`
카탈로그도 동시에 등록됩니다.
온보딩/모델 구성 picker에서 Volcengine 인증 선택은
`volcengine/*``volcengine-plan/*` 행을 모두 우선합니다. 해당 모델이 아직 로드되지 않았다면
OpenClaw는 provider 범위 picker가 비어 보이지 않도록
필터링되지 않은 catalog로 폴백합니다.
온보딩/모델 선택기에서 Volcengine 인증 선택은 `volcengine/*``volcengine-plan/*` 행을 모두 선호합니다. 이 모델들이 아직 로드되지 않았다면,
OpenClaw는 비어 있는 제공자 범위 선택기를 표시하는 대신
필터링되지 않은 카탈로그로 폴백합니다.
사용 가능한 모델:
@ -573,7 +562,7 @@ OpenClaw는 provider 범위 picker가 비어 보이지 않도록
- `volcengine/glm-4-7-251222` (GLM 4.7)
- `volcengine/deepseek-v3-2-251201` (DeepSeek V3.2 128K)
Coding 모델(`volcengine-plan`):
코딩 모델(`volcengine-plan`):
- `volcengine-plan/ark-code-latest`
- `volcengine-plan/doubao-seed-code`
@ -581,11 +570,11 @@ Coding 모델(`volcengine-plan`):
- `volcengine-plan/kimi-k2-thinking`
- `volcengine-plan/glm-4.7`
### BytePlus (International)
### BytePlus (국제)
BytePlus ARK는 국제 사용자를 위해 Volcano Engine과 동일한 모델에 대한 액세스를 제공합니다.
- Provider: `byteplus` (coding: `byteplus-plan`)
- 제공자: `byteplus`(코딩: `byteplus-plan`)
- 인증: `BYTEPLUS_API_KEY`
- 예시 모델: `byteplus-plan/ark-code-latest`
- CLI: `openclaw onboard --auth-choice byteplus-api-key`
@ -598,13 +587,12 @@ BytePlus ARK는 국제 사용자를 위해 Volcano Engine과 동일한 모델에
}
```
온보딩은 기본적으로 coding 표면을 사용하지만, 일반 `byteplus/*`
catalog도 동시에 등록됩니다.
온보딩은 기본적으로 코딩 표면을 선택하지만, 일반 `byteplus/*`
카탈로그도 동시에 등록됩니다.
온보딩/모델 구성 picker에서 BytePlus 인증 선택은
`byteplus/*``byteplus-plan/*` 행을 모두 우선합니다. 해당 모델이 아직 로드되지 않았다면
OpenClaw는 provider 범위 picker가 비어 보이지 않도록
필터링되지 않은 catalog로 폴백합니다.
온보딩/모델 선택기에서 BytePlus 인증 선택은 `byteplus/*``byteplus-plan/*` 행을 모두 선호합니다. 이 모델들이 아직 로드되지 않았다면,
OpenClaw는 비어 있는 제공자 범위 선택기를 표시하는 대신
필터링되지 않은 카탈로그로 폴백합니다.
사용 가능한 모델:
@ -612,7 +600,7 @@ OpenClaw는 provider 범위 picker가 비어 보이지 않도록
- `byteplus/kimi-k2-5-260127` (Kimi K2.5)
- `byteplus/glm-4-7-251222` (GLM 4.7)
Coding 모델(`byteplus-plan`):
코딩 모델(`byteplus-plan`):
- `byteplus-plan/ark-code-latest`
- `byteplus-plan/doubao-seed-code`
@ -622,9 +610,9 @@ Coding 모델(`byteplus-plan`):
### Synthetic
Synthetic는 `synthetic` provider 뒤에서 Anthropic 호환 모델을 제공합니다.
Synthetic는 `synthetic` 제공자 뒤에서 Anthropic 호환 모델을 제공합니다:
- Provider: `synthetic`
- 제공자: `synthetic`
- 인증: `SYNTHETIC_API_KEY`
- 예시 모델: `synthetic/hf:MiniMaxAI/MiniMax-M2.5`
- CLI: `openclaw onboard --auth-choice synthetic-api-key`
@ -650,39 +638,40 @@ Synthetic는 `synthetic` provider 뒤에서 Anthropic 호환 모델을 제공합
### MiniMax
MiniMax는 커스텀 엔드포인트를 사용하므로 `models.providers`를 통해 구성합니다.
MiniMax는 커스텀 엔드포인트를 사용하므로 `models.providers`를 통해 구성됩니다:
- MiniMax OAuth (Global): `--auth-choice minimax-global-oauth`
- MiniMax OAuth (CN): `--auth-choice minimax-cn-oauth`
- MiniMax API 키 (Global): `--auth-choice minimax-global-api`
- MiniMax API 키 (CN): `--auth-choice minimax-cn-api`
- 인증: `minimax`에는 `MINIMAX_API_KEY`, `minimax-portal`에는
`MINIMAX_OAUTH_TOKEN` 또는 `MINIMAX_API_KEY`
- MiniMax API key (Global): `--auth-choice minimax-global-api`
- MiniMax API key (CN): `--auth-choice minimax-cn-api`
- 인증: `minimax`에는 `MINIMAX_API_KEY`,
`minimax-portal`에는 `MINIMAX_OAUTH_TOKEN` 또는
`MINIMAX_API_KEY`
설정 세부 사항, 모델 옵션, config snippet은 [/providers/minimax](/ko/providers/minimax)를 참고하세요.
설정 세부 사항, 모델 옵션, 구성 스니펫은 [/providers/minimax](/ko/providers/minimax)를 참조하세요.
MiniMax의 Anthropic 호환 스트리밍 경로에서는 OpenClaw가 thinking을
명시적으로 설정하지 않는 한 기본적으로 비활성화하며, `/fast on`
`MiniMax-M2.7``MiniMax-M2.7-highspeed`로 재작성합니다.
MiniMax의 Anthropic 호환 스트리밍 경로에서 OpenClaw는
명시적으로 설정하지 않는 한 기본적으로 thinking을 비활성화하며,
`/fast on``MiniMax-M2.7``MiniMax-M2.7-highspeed`로 재작성합니다.
Plugin 소유 capability 분리:
플러그인 소유 capability 분할:
- 텍스트/채팅 기본값은 `minimax/MiniMax-M2.7`에 유지
- 이미지 생성은 `minimax/image-01` 또는 `minimax-portal/image-01`
- 이미지 이해는 두 MiniMax 인증 경로 모두에서 plugin 소유 `MiniMax-VL-01`
- 웹 검색은 provider id `minimax`에 유지
- 이미지 이해는 두 MiniMax 인증 경로 모두에서 플러그인 소유 `MiniMax-VL-01`
- 웹 검색은 제공자 id `minimax`에 유지
### Ollama
Ollama는 번들 provider plugin으로 제공되며 Ollama의 네이티브 API를 사용합니다.
Ollama는 번들 제공자 플러그인으로 제공되며 Ollama의 네이티브 API를 사용합니다:
- Provider: `ollama`
- 제공자: `ollama`
- 인증: 필요 없음(로컬 서버)
- 예시 모델: `ollama/llama3.3`
- 설치: [https://ollama.com/download](https://ollama.com/download)
```bash
# Ollama를 설치한 다음 모델을 pull하세요:
# Ollama를 설치한 다음 모델을 가져옵니다:
ollama pull llama3.3
```
@ -694,27 +683,27 @@ ollama pull llama3.3
}
```
Ollama는 `OLLAMA_API_KEY`로 opt in하면 로컬 `http://127.0.0.1:11434`에서
감지되며, 번들 provider plugin이 Ollama를 직접
`openclaw onboard`와 모델 picker에 추가합니다. 온보딩, cloud/local 모드,
커스텀 구성은 [/providers/ollama](/ko/providers/ollama)를 참고하세요.
Ollama는 `OLLAMA_API_KEY`로 opt in하면 로컬 `http://127.0.0.1:11434`에서
감지되며, 번들 제공자 플러그인은 Ollama를 직접
`openclaw onboard`와 모델 선택기에 추가합니다. 온보딩, 클라우드/로컬 모드, 커스텀 구성은 [/providers/ollama](/ko/providers/ollama)를
참조하세요.
### vLLM
vLLM은 로컬/셀프호스트 OpenAI 호환
서버를 위한 번들 provider plugin으로 제공됩니다.
vLLM은 로컬/셀프호스트 OpenAI 호환
서버용 번들 제공자 플러그인으로 제공됩니다:
- Provider: `vllm`
- 제공자: `vllm`
- 인증: 선택 사항(서버에 따라 다름)
- 기본 base URL: `http://127.0.0.1:8000/v1`
로컬에서 자동 감지를 opt in하려면(서버가 인증을 강제하지 않으면 아무 값이나 가능):
로컬 자동 감지를 opt in하려면(서버가 인증을 강제하지 않으면 어떤 값이든 작동):
```bash
export VLLM_API_KEY="vllm-local"
```
그런 다음 모델을 설정하세요(`/v1/models`가 반환하는 ID 중 하나로 교체):
그런 다음 모델을 설정합니다(`/v1/models`가 반환하는 ID 중 하나로 바꾸세요):
```json5
{
@ -724,25 +713,25 @@ export VLLM_API_KEY="vllm-local"
}
```
자세한 내용은 [/providers/vllm](/ko/providers/vllm)을 참고하세요.
자세한 내용은 [/providers/vllm](/ko/providers/vllm)를 참조하세요.
### SGLang
SGLang은 빠른 셀프호스트
OpenAI 호환 서버를 위한 번들 provider plugin으로 제공됩니다.
SGLang은 빠른 셀프호스트
OpenAI 호환 서버용 번들 제공자 플러그인으로 제공됩니다:
- Provider: `sglang`
- 제공자: `sglang`
- 인증: 선택 사항(서버에 따라 다름)
- 기본 base URL: `http://127.0.0.1:30000/v1`
로컬에서 자동 감지를 opt in하려면(서버가 인증을
강제하지 않으면 아무 값이나 가능):
로컬 자동 감지를 opt in하려면(서버가
인증을 강제하지 않으면 어떤 값이든 작동):
```bash
export SGLANG_API_KEY="sglang-local"
```
그런 다음 모델을 설정하세요(`/v1/models`가 반환하는 ID 중 하나로 교체):
그런 다음 모델을 설정합니다(`/v1/models`가 반환하는 ID 중 하나로 바꾸세요):
```json5
{
@ -752,9 +741,9 @@ export SGLANG_API_KEY="sglang-local"
}
```
자세한 내용은 [/providers/sglang](/ko/providers/sglang)을 참고하세요.
자세한 내용은 [/providers/sglang](/ko/providers/sglang)를 참조하세요.
### 로컬 프록시(LM Studio, vLLM, LiteLLM 등)
### 로컬 프록시 (LM Studio, vLLM, LiteLLM 등)
예시(OpenAI 호환):
@ -791,21 +780,21 @@ export SGLANG_API_KEY="sglang-local"
참고:
- 커스텀 provider의 경우 `reasoning`, `input`, `cost`, `contextWindow`, `maxTokens`는 선택 사항입니다.
생략하면 OpenClaw는 기본적으로 다음 값을 사용합니다:
- 커스텀 제공자의 경우 `reasoning`, `input`, `cost`, `contextWindow`, `maxTokens`는 선택 사항입니다.
생략하면 OpenClaw는 다음 기본값을 사용합니다:
- `reasoning: false`
- `input: ["text"]`
- `cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 }`
- `contextWindow: 200000`
- `maxTokens: 8192`
- 권장: 프록시/모델 한도에 맞는 명시적 값을 설정하세요.
- 비네이티브 엔드포인트(`api.openai.com`이 아닌 호스트를 가진 비어 있지 않은 `baseUrl`)의 `api: "openai-completions"`에 대해 OpenClaw는 지원되지 않는 `developer` 역할로 인한 provider 400 오류를 피하기 위해 `compat.supportsDeveloperRole: false`를 강제로 적용합니다.
- 프록시 스타일 OpenAI 호환 경로 네이티브 OpenAI 전용 요청
shaping을 건너뜁니다: `service_tier` 없음, Responses `store` 없음, prompt-cache 힌트 없음,
OpenAI reasoning-compat payload shaping 없음, 숨겨진 OpenClaw attribution
- 네이티브 엔드포인트가 아닌 곳(호스트가 `api.openai.com`이 아닌 비어 있지 않은 `baseUrl`)에서 `api: "openai-completions"`를 사용할 경우, OpenClaw는 지원되지 않는 `developer` 역할로 인한 제공자 400 오류를 피하기 위해 `compat.supportsDeveloperRole: false`를 강제합니다.
- 프록시 스타일 OpenAI 호환 경로 네이티브 OpenAI 전용 요청
형성도 건너뜁니다: `service_tier` 없음, Responses `store` 없음, 프롬프트 캐시 힌트 없음,
OpenAI 추론 호환 페이로드 형성 없음, 숨겨진 OpenClaw attribution
헤더 없음.
- `baseUrl`이 비어 있거나 생략되면 OpenClaw는 기본 OpenAI 동작을 유지합니다(`api.openai.com`으로 해됨).
- 안전을 위해 비네이티브 `openai-completions` 엔드포인트에서는 명시적인 `compat.supportsDeveloperRole: true`여전히 override됩니다.
- `baseUrl`이 비어 있거나 생략되면 OpenClaw는 기본 OpenAI 동작을 유지합니다(`api.openai.com`으로 해됨).
- 안전을 위해 명시적인 `compat.supportsDeveloperRole: true`비네이티브 `openai-completions` 엔드포인트에서는 여전히 재정의됩니다.
## CLI 예시
@ -815,11 +804,11 @@ openclaw models set opencode/claude-opus-4-6
openclaw models list
```
전체 구성 예시는 [/gateway/configuration](/ko/gateway/configuration)도 참고하세요.
전체 구성 예시는 [/gateway/configuration](/ko/gateway/configuration)을 참조하세요.
## 관련 항목
## 관련
- [Models](/ko/concepts/models) — 모델 구성 및 alias
- [Model Failover](/ko/concepts/model-failover) — 폴백 체인 재시도 동작
- [Configuration Reference](/ko/gateway/configuration-reference#agent-defaults) — 모델 config
- [Providers](/ko/providers) — provider별 설정 가이드
- [Models](/ko/concepts/models) — 모델 구성 및 별칭
- [Model Failover](/ko/concepts/model-failover) — 폴백 체인 재시도 동작
- [Configuration Reference](/ko/gateway/configuration-reference#agent-defaults) — 모델 구성
- [Providers](/ko/providers) — 제공자별 설정 가이드

View File

@ -2,14 +2,14 @@
read_when:
- qa-lab 또는 qa-channel 확장 시
- 리포지토리 기반 QA 시나리오 추가 시
- Gateway 대시보드 주변에 더 높은 현실성의 QA 자동화를 구축할 때
summary: qa-lab, qa-channel, 시드된 시나리오, 프로토콜 보고서를 위한 비공개 QA 자동화 구
- Gateway 대시보드를 중심으로 더 높은 현실성의 QA 자동화 구축 시
summary: qa-lab, qa-channel, 시드된 시나리오, 프로토콜 보고서를 위한 비공개 QA 자동화 구
title: QA E2E 자동화
x-i18n:
generated_at: "2026-04-08T05:55:40Z"
generated_at: "2026-04-09T01:27:48Z"
model: gpt-5.4
provider: openai
source_hash: 57da147dc06abf9620290104e01a83b42182db1806514114fd9e8467492cda99
source_hash: c922607d67e0f3a2489ac82bc9f510f7294ced039c1014c15b676d826441d833
source_path: concepts/qa-e2e-automation.md
workflow: 15
---
@ -22,16 +22,16 @@ x-i18n:
현재 구성 요소:
- `extensions/qa-channel`: DM, 채널, 스레드,
반응, 수정, 삭제 표면을 갖춘 합성 메시지 채널
- `extensions/qa-lab`: 대화 기록을 관찰하고,
리액션, 편집, 삭제 인터페이스를 갖춘 합성 메시지 채널
- `extensions/qa-lab`: 트랜스크립트를 관찰하고,
인바운드 메시지를 주입하며, Markdown 보고서를 내보내기 위한 디버거 UI 및 QA 버스
- `qa/`: 시작 작업과 기 QA
- `qa/`: 시작 작업과 기 QA
시나리오를 위한 리포지토리 기반 시드 자산
현재 QA 운영자 흐름은 2패널 QA 사이트입니다:
- 왼쪽: 에이전트가 있는 Gateway 대시보드(Control UI)
- 오른쪽: Slack과 유사한 대화 기록 및 시나리오 계획을 보여주는 QA Lab
- 오른쪽: Slack 스타일의 트랜스크립트와 시나리오 계획을 보여주는 QA Lab
다음으로 실행합니다:
@ -39,12 +39,12 @@ x-i18n:
pnpm qa:lab:up
```
이 명령은 QA 사이트를 빌드하고, Docker 기반 gateway 레인을 시작하며, 운영자 또는 자동화 루프가 에이전트에 QA
미션을 전달하고, 실제 채널 동작을 관찰하며, 무엇이 성공했고 실패했으며
무엇이 계속 막혀 있었는지 기록할 수 있는 QA Lab 페이지를 노출합니다.
이 명령은 QA 사이트를 빌드하고, Docker 기반 gateway 레인을 시작하며, 운영자 자동화 루프가 에이전트에 QA
미션을 부여하고, 실제 채널 동작을 관찰하며, 무엇이 작동했고 실패했으며
또는 계속 막혀 있었는지를 기록할 수 있는 QA Lab 페이지를 노출합니다.
매번 Docker 이미지를 다시 빌드하지 않고 더 빠르게 QA Lab UI를 반복 개발하려면,
바인드 마운트된 QA Lab 번들로 스택을 시작하세요:
매번 Docker 이미지를 다시 빌드하지 않고 QA Lab UI를 더 빠르게 반복 개발하려면,
bind mount된 QA Lab 번들로 스택을 시작하세요:
```bash
pnpm openclaw qa docker-build-image
@ -54,8 +54,8 @@ pnpm qa:lab:watch
```
`qa:lab:up:fast`는 사전 빌드된 이미지에서 Docker 서비스를 유지하고
`extensions/qa-lab/web/dist``qa-lab` 컨테이너에 바인드 마운트합니다. `qa:lab:watch`
변경 시 해당 번들을 다시 빌드하며, QA Lab 자산 해시가 바뀌면 브라우저가 자동으로 다시 로드됩니다.
`extensions/qa-lab/web/dist``qa-lab` 컨테이너에 bind mount합니다. `qa:lab:watch`
변경 시 해당 번들을 다시 빌드하고, QA Lab 자산 해시가 변경되면 브라우저가 자동으로 다시 로드됩니다.
## 리포지토리 기반 시드
@ -64,12 +64,12 @@ pnpm qa:lab:watch
- `qa/scenarios/index.md`
- `qa/scenarios/*.md`
이들은 QA 계획이 사람과
에이전트 모두에게 보이도록 의도적으로 git에 포함됩니다. 기 목록은 다음을 포괄할 만큼 충분히 넓게 유지되어야 합니다:
파일들은 QA 계획이 사람과
에이전트 모두에게 보이도록 의도적으로 git에 포함됩니다. 기 목록은 다음을 포괄할 만큼 충분히 넓게 유지되어야 합니다:
- DM 및 채널 채팅
- 스레드 동작
- 메시지 작업 수명 주기
- 메시지 액션 수명 주기
- cron 콜백
- 메모리 회상
- 모델 전환
@ -80,13 +80,61 @@ pnpm qa:lab:watch
## 보고
`qa-lab`은 관찰된 버스 타임라인에서 Markdown 프로토콜 보고서를 내보냅니다.
보고서는 다음에 답해야 합니다:
보고서는 다음에 답해야 합니다:
- 무엇이 작동했는가
- 무엇이 실패했는가
- 무엇이 계속 막혀 있었는가
- 어떤 후속 시나리오를 추가할 가치가 있는가
캐릭터 및 스타일 검사를 위해 동일한 시나리오를 여러 라이브 모델
ref에서 실행하고 판단된 Markdown 보고서를 작성하세요:
```bash
pnpm openclaw qa character-eval \
--model openai/gpt-5.4,thinking=xhigh \
--model openai/gpt-5.2,thinking=xhigh \
--model openai/gpt-5,thinking=xhigh \
--model anthropic/claude-opus-4-6,thinking=high \
--model anthropic/claude-sonnet-4-6,thinking=high \
--model zai/glm-5.1,thinking=high \
--model moonshot/kimi-k2.5,thinking=high \
--model google/gemini-3.1-pro-preview,thinking=high \
--judge-model openai/gpt-5.4,thinking=xhigh,fast \
--judge-model anthropic/claude-opus-4-6,thinking=high \
--blind-judge-models \
--concurrency 16 \
--judge-concurrency 16
```
이 명령은 Docker가 아니라 로컬 QA gateway 자식 프로세스를 실행합니다. 캐릭터 평가
시나리오는 `SOUL.md`를 통해 페르소나를 설정한 다음, 채팅, 워크스페이스 도움말, 작은 파일 작업과 같은
일반 사용자 턴을 실행해야 합니다. 후보 모델에는 자신이 평가되고 있다는 사실을 알려서는 안 됩니다.
이 명령은 각 전체 트랜스크립트를 보존하고, 기본 실행 통계를 기록한 뒤, judge 모델에 fast 모드와
`xhigh` 추론을 사용해 자연스러움, 분위기, 유머를 기준으로 실행 결과의 순위를 매기도록 요청합니다.
제공자들을 비교할 때는 `--blind-judge-models`를 사용하세요. 이 경우 judge 프롬프트는 여전히
모든 트랜스크립트와 실행 상태를 받지만, 후보 ref는 `candidate-01` 같은 중립적인
레이블로 대체됩니다. 보고서는 파싱 후 순위를 실제 ref에 다시 매핑합니다.
후보 실행은 기본적으로 `high` thinking을 사용하며, 이를 지원하는 OpenAI 모델은 `xhigh`를 사용합니다.
특정 후보를 개별적으로 재정의하려면
`--model provider/model,thinking=<level>`을 사용하세요. `--thinking <level>`은 여전히 전역 기본값을 설정하며,
기존의 `--model-thinking <provider/model=level>` 형식도 호환성을 위해 유지됩니다.
OpenAI 후보 ref는 기본적으로 fast 모드를 사용하므로, 제공자가 이를 지원하는 경우 우선 처리됩니다.
단일 후보나 judge에 재정의가 필요하면 인라인으로 `,fast`, `,no-fast`, 또는 `,fast=false`를 추가하세요.
모든 후보 모델에 fast 모드를 강제로 적용하려는 경우에만 `--fast`를 전달하세요. 후보와 judge의 실행 시간은
벤치마크 분석을 위해 보고서에 기록되지만, judge 프롬프트에는 속도로 순위를 매기지 말라고 명시되어 있습니다.
후보 및 judge 모델 실행은 모두 기본적으로 동시성 16을 사용합니다.
제공자 제한이나 로컬 gateway 부하 때문에 실행이 너무 불안정해지면
`--concurrency` 또는 `--judge-concurrency`를 낮추세요.
후보 `--model`이 전달되지 않으면 character eval은 기본적으로
`openai/gpt-5.4`, `openai/gpt-5.2`, `openai/gpt-5`, `anthropic/claude-opus-4-6`,
`anthropic/claude-sonnet-4-6`, `zai/glm-5.1`,
`moonshot/kimi-k2.5`, 그리고
`google/gemini-3.1-pro-preview`를 사용합니다.
`--judge-model`이 전달되지 않으면 judge는 기본적으로
`openai/gpt-5.4,thinking=xhigh,fast`
`anthropic/claude-opus-4-6,thinking=high`를 사용합니다.
## 관련 문서
- [테스트](/ko/help/testing)

View File

@ -1,47 +1,41 @@
---
read_when:
- API 제공자가 실패할 때 신뢰할 수 있는 대체 수단을 원할 때
- Codex CLI 또는 다른 로컬 AI CLI를 실행 중이며 이를 재사용하고 싶을 때
- CLI 백엔드 도구 접근을 위한 MCP 루프백 브리지를 이해하고 싶을 때
summary: 선택적 MCP 도구 브리지와 함께 사용하는 로컬 AI CLI 대체용 CLI 백엔드
- API 제공자가 실패할 때 안정적인 폴백이 필요합니다
- Codex CLI 또는 다른 로컬 AI CLI를 실행 중이며 이를 재사용하고 싶습니다
- CLI 백엔드 도구 액세스를 위한 MCP 루프백 브리지를 이해하고 싶습니다
summary: 'CLI 백엔드: 선택적 MCP 도구 브리지와 함께 사용하는 로컬 AI CLI 폴백'
title: CLI 백엔드
x-i18n:
generated_at: "2026-04-08T02:14:36Z"
generated_at: "2026-04-09T01:28:04Z"
model: gpt-5.4
provider: openai
source_hash: b0e8c41f5f5a8e34466f6b765e5c08585ef1788fa9e9d953257324bcc6cbc414
source_hash: 9b458f9fe6fa64c47864c8c180f3dedfd35c5647de470a2a4d31c26165663c20
source_path: gateway/cli-backends.md
workflow: 15
---
# CLI 백엔드 (대체 런타임)
# CLI 백엔드(폴백 런타임)
OpenClaw는 API 제공자가 중단되거나,
속도 제한에 걸리거나, 일시적으로 오작동할 때 **텍스트 전용 대체 수단**으로 **로컬 AI CLI**를 실행할 수 있습니다. 이는 의도적으로 보수적으로 설계되었습니다:
OpenClaw는 API 제공자가 중단되거나, 속도 제한에 걸리거나, 일시적으로 오작동할 때 **텍스트 전용 폴백**으로 **로컬 AI CLI**를 실행할 수 있습니다. 이는 의도적으로 보수적으로 설계되었습니다.
- `bundleMcp: true`가 설정된 백엔드는 루프백 MCP 브리지를 통해 gateway 도구를 받을 수 있지만, **OpenClaw 도구가 직접 주입되지는 않습니다**.
- 이를 지원하는 CLI에 대해 **JSONL 스트리밍**을 지원합니다.
- **세션이 지원되므로** 후속 턴도 일관성을 유지합니다.
- CLI가 이미지 경로를 받는다면 **이미지를 전달할 수 있습니다**.
- **OpenClaw 도구는 직접 주입되지 않지만**, `bundleMcp: true`가 설정된 백엔드는 루프백 MCP 브리지를 통해 게이트웨이 도구를 받을 수 있습니다.
- 이를 지원하는 CLI를 위한 **JSONL 스트리밍**
- **세션 지원**(후속 턴의 일관성 유지)
- CLI가 이미지 경로를 허용하면 **이미지 전달 가능**
이 기능은 기본 경로라기보다 **안전망**으로 설계되었습니다. 외부 API에 의존하지 않고
“항상 동작하는” 텍스트 응답이 필요할 때 사용하세요.
이는 기본 경로라기보다 **안전망**으로 설계되었습니다. 외부 API에 의존하지 않고 “항상 동작하는” 텍스트 응답이 필요할 때 사용하세요.
ACP 세션 제어, 백그라운드 작업,
스레드/대화 바인딩, 영구적인 외부 코딩 세션을 갖춘 전체 하네스 런타임이 필요하다면
대신 [ACP Agents](/ko/tools/acp-agents)를 사용하세요. CLI 백엔드는 ACP가 아닙니다.
ACP 세션 제어, 백그라운드 작업, 스레드/대화 바인딩, 영구적인 외부 코딩 세션을 포함한 전체 하네스 런타임이 필요하다면 대신 [ACP Agents](/ko/tools/acp-agents)를 사용하세요. CLI 백엔드는 ACP가 아닙니다.
## 초보자용 빠른 시작
Codex CLI는 **아무 설정 없이도** 사용할 수 있습니다(번들된 OpenAI plugin이
기본 백엔드를 등록합니다):
Codex CLI는 **아무 설정 없이도** 사용할 수 있습니다(번들 OpenAI plugin이 기본 백엔드를 등록합니다).
```bash
openclaw agent --message "hi" --model codex-cli/gpt-5.4
```
gateway가 launchd/systemd 아래에서 실행되고 PATH가 최소화되어 있다면,
명령 경로만 추가하세요:
게이트웨이가 launchd/systemd 아래에서 실행되고 PATH가 최소화되어 있다면 명령 경로만 추가하세요.
```json5
{
@ -57,15 +51,13 @@ gateway가 launchd/systemd 아래에서 실행되고 PATH가 최소화되어 있
}
```
이것으로 끝입니다. CLI 자체 외에 별도의 키나 추가 인증 설정은 필요하지 않습니다.
이것으로 충분합니다. CLI 자체 외에는 키도, 추가 인증 설정도 필요하지 않습니다.
gateway 호스트에서 번들된 CLI 백엔드를 **기본 메시지 제공자**로 사용하는 경우,
이제 OpenClaw는 설정이 모델 ref 또는
`agents.defaults.cliBackends` 아래에서 해당 백엔드를 명시적으로 참조하면 소유 번들 plugin을 자동으로 로드합니다.
번들 CLI 백엔드를 게이트웨이 호스트의 **기본 메시지 제공자**로 사용하는 경우, 이제 OpenClaw는 구성에서 모델 ref 또는 `agents.defaults.cliBackends` 아래에 해당 백엔드를 명시적으로 참조하면 소유 번들 plugin을 자동으로 로드합니다.
## 대체 수단으로 사용하기
## 폴백으로 사용하기
CLI 백엔드를 대체 목록에 추가하면 기본 모델이 실패할 때만 실행됩니다:
CLI 백엔드를 폴백 목록에 추가하면 기본 모델이 실패할 때만 실행됩니다.
```json5
{
@ -86,26 +78,25 @@ CLI 백엔드를 대체 목록에 추가하면 기본 모델이 실패할 때만
참고:
- `agents.defaults.models`(허용 목록)을 사용하는 경우 CLI 백엔드 모델도 여기에 포함해야 합니다.
- 기본 제공자가 실패하면(인증, 속도 제한, 타임아웃), OpenClaw가
다음으로 CLI 백엔드를 시도합니다.
- `agents.defaults.models`(허용 목록)를 사용하는 경우, CLI 백엔드 모델도 여기에 포함해야 합니다.
- 기본 제공자가 실패하면(auth, 속도 제한, 시간 초과) OpenClaw가 다음으로 CLI 백엔드를 시도합니다.
## 설정 개요
## 구성 개요
모든 CLI 백엔드는 다음 아래에 있습니다:
모든 CLI 백엔드는 다음 아래에 있습니다.
```
agents.defaults.cliBackends
```
각 항목은 **provider id**(예: `codex-cli`, `my-cli`)로 키 지정됩니다.
provider id는 모델 ref의 왼쪽 부분이 됩니다:
각 항목은 **provider id**(예: `codex-cli`, `my-cli`)를 키로 사용합니다.
provider id는 모델 ref의 왼쪽 부분이 됩니다.
```
<provider>/<model>
```
### 설정 예시
### 예시 구성
```json5
{
@ -129,6 +120,9 @@ provider id는 모델 ref의 왼쪽 부분이 됩니다:
sessionMode: "existing",
sessionIdFields: ["session_id", "conversation_id"],
systemPromptArg: "--system",
// Codex 스타일 CLI는 대신 프롬프트 파일을 가리킬 수 있습니다:
// systemPromptFileConfigArg: "-c",
// systemPromptFileConfigKey: "model_instructions_file",
systemPromptWhen: "first",
imageArg: "--image",
imageMode: "repeat",
@ -140,71 +134,63 @@ provider id는 모델 ref의 왼쪽 부분이 됩니다:
}
```
## 작 방식
## 작 방식
1. provider 접두사(`codex-cli/...`)를 기준으로 **백엔드를 선택합니다**.
2. 동일한 OpenClaw 프롬프트 + 워크스페이스 컨텍스트를 사용해 **시스템 프롬프트를 구성합니다**.
3. 기록의 일관성을 유지하기 위해 지원되는 경우 세션 id와 함께 **CLI를 실행합니다**.
4. 출력을 **파싱**(JSON 또는 일반 텍스트)하고 최종 텍스트를 반환합니다.
5. 후속 요청이 동일한 CLI 세션을 재사용할 수 있도록 백엔드별 **세션 id를 저장합니다**.
1. provider 접두사(`codex-cli/...`)를 기준으로 **백엔드를 선택**합니다.
2. 동일한 OpenClaw 프롬프트 + 워크스페이스 컨텍스트를 사용해 **시스템 프롬프트를 구성**합니다.
3. 기록의 일관성을 유지하기 위해 지원되는 경우 세션 id와 함께 **CLI를 실행**합니다.
4. **출력을 파싱**(JSON 또는 일반 텍스트)하고 최종 텍스트를 반환합니다.
5. **백엔드별로 세션 id를 유지**하여 후속 요청에서 동일한 CLI 세션을 재사용합니다.
<Note>
번들된 Anthropic `claude-cli` 백엔드가 다시 지원됩니다. Anthropic 직원이
OpenClaw 스타일의 Claude CLI 사용이 다시 허용된다고 알려주었기 때문에, Anthropic이
새 정책을 발표하지 않는 한 OpenClaw는 이 통합에 대해
`claude -p` 사용을 허용된 것으로 간주합니다.
번들 Anthropic `claude-cli` 백엔드가 다시 지원됩니다. Anthropic 직원이 OpenClaw 스타일 Claude CLI 사용이 다시 허용된다고 알려주었으므로, Anthropic이 새로운 정책을 발표하지 않는 한 OpenClaw는 이 통합에 대해 `claude -p` 사용을 허용된 것으로 간주합니다.
</Note>
번들 OpenAI `codex-cli` 백엔드는 OpenClaw의 시스템 프롬프트를 Codex의 `model_instructions_file` 구성 재정의(`-c
model_instructions_file="..."`)를 통해 전달합니다. Codex는 Claude 스타일 `--append-system-prompt` 플래그를 제공하지 않으므로, OpenClaw는 새 Codex CLI 세션마다 조합된 프롬프트를 임시 파일에 기록합니다.
## 세션
- CLI가 세션을 지원하면 `sessionArg`(예: `--session-id`) 또는
세션 ID를 여러 플래그에 삽입해야 할 때 `sessionArgs`(플레이스홀더 `{sessionId}`)를 설정하세요.
- CLI가 다른 플래그를 사용하는 **resume 하위 명령**을 사용한다면,
`resumeArgs`(`resuming` 시 `args`를 대체)와 필요하다면 `resumeOutput`
(JSON이 아닌 resume용)을 설정하세요.
- CLI가 세션을 지원하면 `sessionArg`(예: `--session-id`) 또는 여러 플래그에 ID를 삽입해야 할 때 `sessionArgs`(플레이스홀더 `{sessionId}`)를 설정하세요.
- CLI가 다른 플래그를 사용하는 **재개 서브커맨드**를 사용한다면 `resumeArgs`(`args`를 대체)를 설정하고, 선택적으로 `resumeOutput`(JSON이 아닌 재개용)을 설정하세요.
- `sessionMode`:
- `always`: 항상 세션 id를 전송합니다(저장된 값이 없으면 새 UUID 사용).
- `existing`: 이전에 저장된 세션 id가 있을 때만 전송합니다.
- `none`: 세션 id를 절대 전송하지 않습니다.
- `always`: 항상 세션 id를 보냅니다(저장된 값이 없으면 새 UUID 생성).
- `existing`: 이전에 저장된 세션 id가 있을 때만 보냅니다.
- `none`: 세션 id를 절대 보내지 않습니다.
직렬화 관련 참고:
직렬화 참고:
- `serialize: true`는 동일 레인 실행 순서를 유지합니다.
- `serialize: true`는 동일 레인에서의 실행 순서를 유지합니다.
- 대부분의 CLI는 하나의 provider 레인에서 직렬화됩니다.
- OpenClaw는 재로그인, 토큰 교체, 또는 변경된 인증 프로필 자격 증명을 포함해 백엔드 인증 상태가 바뀌면 저장된 CLI 세션 재사용을 중단합니다.
- OpenClaw는 백엔드 인증 상태가 변경되면 저장된 CLI 세션 재사용을 중단합니다. 여기에는 재로그인, 토큰 교체, 인증 프로필 자격 증명 변경이 포함됩니다.
## 이미지(전달)
CLI가 이미지 경로를 받을 수 있다면 `imageArg`를 설정하세요:
CLI가 이미지 경로를 허용하면 `imageArg`를 설정하세요.
```json5
imageArg: "--image",
imageMode: "repeat"
```
OpenClaw는 base64 이미지를 임시 파일에 씁니다. `imageArg`가 설정되어 있으면 해당
경로가 CLI 인수로 전달됩니다. `imageArg`가 없으면 OpenClaw는
파일 경로를 프롬프트에 추가합니다(경로 주입). 이는 일반 경로에서 로컬 파일을 자동으로
로드하는 CLI에는 충분합니다.
OpenClaw는 base64 이미지를 임시 파일에 기록합니다. `imageArg`가 설정되어 있으면 해당 경로가 CLI 인수로 전달됩니다. `imageArg`가 없으면 OpenClaw는 파일 경로를 프롬프트에 추가합니다(경로 주입). 이는 일반 경로에서 로컬 파일을 자동 로드하는 CLI에는 충분합니다.
## 입력 / 출력
- `output: "json"`(기본값)은 JSON을 파싱하고 텍스트 + 세션 id를 추출하려고 시도합니다.
- Gemini CLI JSON 출력의 경우, `usage`가 없거나 비어 있으면 OpenClaw는
`response`에서 응답 텍스트를, `stats`에서 사용량을 읽습니다.
- `output: "jsonl"`은 JSONL 스트림(예: Codex CLI `--json`)을 파싱하고, 존재할 경우 최종 에이전트 메시지와 세션
식별자를 추출합니다.
- Gemini CLI JSON 출력의 경우 `usage`가 없거나 비어 있으면 OpenClaw는 `response`에서 응답 텍스트를, `stats`에서 사용량을 읽습니다.
- `output: "jsonl"`은 JSONL 스트림(예: Codex CLI `--json`)을 파싱하고 존재할 경우 최종 에이전트 메시지와 세션 식별자를 추출합니다.
- `output: "text"`는 stdout을 최종 응답으로 처리합니다.
입력 모드:
- `input: "arg"`(기본값)는 프롬프트를 마지막 CLI 인수로 전달합니다.
- `input: "stdin"`프롬프트를 stdin으로 보냅니다.
- `input: "stdin"`stdin을 통해 프롬프트를 보냅니다.
- 프롬프트가 매우 길고 `maxPromptArgChars`가 설정되어 있으면 stdin이 사용됩니다.
## 기본값(plugin 소유)
번들된 OpenAI plugin은 `codex-cli`에 대한 기본값도 등록합니다:
번들 OpenAI plugin도 `codex-cli`에 대한 기본값을 등록합니다.
- `command: "codex"`
- `args: ["exec","--json","--color","never","--sandbox","workspace-write","--skip-git-repo-check"]`
@ -215,7 +201,7 @@ OpenClaw는 base64 이미지를 임시 파일에 씁니다. `imageArg`가 설정
- `imageArg: "--image"`
- `sessionMode: "existing"`
번들 Google plugin도 `google-gemini-cli`에 대한 기본값을 등록합니다:
번들 Google plugin도 `google-gemini-cli`에 대한 기본값을 등록합니다.
- `command: "gemini"`
- `args: ["--output-format", "json", "--prompt", "{prompt}"]`
@ -226,68 +212,57 @@ OpenClaw는 base64 이미지를 임시 파일에 씁니다. `imageArg`가 설정
- `sessionMode: "existing"`
- `sessionIdFields: ["session_id", "sessionId"]`
전제 조건: 로컬 Gemini CLI가 설치되어 있어야 하며
`PATH`에서 `gemini`로 사용할 수 있어야 합니다(`brew install gemini-cli` 또는
`npm install -g @google/gemini-cli`).
전제 조건: 로컬 Gemini CLI가 설치되어 있어야 하며 `PATH`에서 `gemini`로 사용할 수 있어야 합니다(`brew install gemini-cli` 또는 `npm install -g @google/gemini-cli`).
Gemini CLI JSON 관련 참고:
Gemini CLI JSON 참고:
- 응답 텍스트는 JSON `response` 필드에서 읽습니다.
- `usage`가 없거나 비어 있으면 사용량은 `stats`대체됩니다.
- `usage`가 없거나 비어 있으면 사용량은 `stats`폴백합니다.
- `stats.cached`는 OpenClaw `cacheRead`로 정규화됩니다.
- `stats.input`이 없으면 OpenClaw는
`stats.input_tokens - stats.cached`에서 입력 토큰 수를 계산합니다.
- `stats.input`이 없으면 OpenClaw는 `stats.input_tokens - stats.cached`에서 입력 토큰 수를 계산합니다.
필요한 경우에만 덮어쓰세요(일반적으로 절대 `command` 경로).
필요한 경우에만 재정의하세요(일반적으로는 절대 `command` 경로).
## plugin 소유 기본값
이제 CLI 백엔드 기본값은 plugin 표면의 일부입니다:
CLI 백엔드 기본값은 이제 plugin 표면의 일부입니다.
- plugin은 `api.registerCliBackend(...)`로 이를 등록합니다.
- 백엔드 `id`는 모델 ref의 provider 접두사가 됩니다.
- `agents.defaults.cliBackends.<id>` 아래의 사용자 설정은 여전히 plugin 기본값을 덮어씁니다.
- 백엔드별 설정 정리는 선택적 `normalizeConfig` 훅을 통해 계속 plugin 소유로 유지됩니다.
- `agents.defaults.cliBackends.<id>`의 사용자 구성은 여전히 plugin 기본값을 재정의합니다.
- 백엔드별 구성 정리는 선택적 `normalizeConfig` 훅을 통해 계속 plugin 소유로 유지됩니다.
## Bundle MCP 오버레이
## 번들 MCP 오버레이
CLI 백엔드는 **OpenClaw 도구 호출을 직접 받지 않지만**, 백엔드는
`bundleMcp: true`로 생성된 MCP 설정 오버레이를 선택적으로 사용할 수 있습니다.
CLI 백엔드는 **OpenClaw 도구 호출을 직접 받지 않지만**, 백엔드는 `bundleMcp: true`로 생성된 MCP 구성 오버레이 사용을 선택할 수 있습니다.
현재 번들 동작:
- `claude-cli`: 생성된 엄격한 MCP 설정 파일
- `codex-cli`: `mcp_servers`용 인라인 설정 오버라이드
- `claude-cli`: 생성된 strict MCP 구성 파일
- `codex-cli`: `mcp_servers`에 대한 인라인 구성 재정의
- `google-gemini-cli`: 생성된 Gemini 시스템 설정 파일
bundle MCP가 활성화되면 OpenClaw는 다음을 수행합니다:
bundle MCP가 활성화되면 OpenClaw는 다음을 수행합니다.
- CLI 프로세스에 gateway 도구를 노출하는 루프백 HTTP MCP 서버를 시작합니다
- 세션별 토큰(`OPENCLAW_MCP_TOKEN`)으로 브리지를 인증합니다
- 도구 접근 범위를 현재 세션, 계정, 채널 컨텍스트로 제한합니다
- 현재 워크스페이스에 대해 활성화된 bundle-MCP 서버를 로드합니다
- 이를 기존 백엔드 MCP 설정/설정 형태와 병합합니다
- 소유 extension의 백엔드 소유 통합 모드를 사용해 실행 설정을 다시 작성합니다
- 게이트웨이 도구를 CLI 프로세스에 노출하는 루프백 HTTP MCP 서버를 시작합니다.
- 세션별 토큰(`OPENCLAW_MCP_TOKEN`)으로 브리지를 인증합니다.
- 현재 세션, 계정, 채널 컨텍스트로 도구 액세스 범위를 제한합니다.
- 현재 워크스페이스에 활성화된 bundle-MCP 서버를 로드합니다.
- 이를 기존 백엔드 MCP 구성/설정 형태와 병합합니다.
- 소유 확장의 백엔드 소유 통합 모드를 사용해 시작 구성을 다시 작성합니다.
활성화된 MCP 서버가 없더라도, 백엔드가 bundle MCP를 선택한 경우 OpenClaw는
백그라운드 실행이 격리된 상태를 유지하도록 여전히 엄격한 설정을 주입합니다.
활성화된 MCP 서버가 없더라도, 백엔드가 bundle MCP 사용을 선택한 경우 OpenClaw는 백그라운드 실행이 격리된 상태를 유지하도록 strict 구성을 계속 주입합니다.
## 제한 사항
- **직접적인 OpenClaw 도구 호출은 없습니다.** OpenClaw는
CLI 백엔드 프로토콜에 도구 호출을 주입하지 않습니다. 백엔드는
`bundleMcp: true`를 선택한 경우에만 gateway 도구를 볼 수 있습니다.
- **스트리밍은 백엔드마다 다릅니다.** 일부 백엔드는 JSONL을 스트리밍하고, 다른 백엔드는
종료 시점까지 버퍼링합니다.
- **직접 OpenClaw 도구 호출 없음.** OpenClaw는 CLI 백엔드 프로토콜에 도구 호출을 주입하지 않습니다. 백엔드는 `bundleMcp: true`를 선택한 경우에만 게이트웨이 도구를 볼 수 있습니다.
- **스트리밍은 백엔드별입니다.** 일부 백엔드는 JSONL을 스트리밍하고, 다른 백엔드는 종료 시까지 버퍼링합니다.
- **구조화된 출력**은 CLI의 JSON 형식에 따라 달라집니다.
- **Codex CLI 세션**은 텍스트 출력으로 resume되며(JSONL 아님),
이는 초기 `--json` 실행보다 구조화가 덜 되어 있습니다. OpenClaw 세션은 여전히
정상적으로 동작합니다.
- **Codex CLI 세션**은 텍스트 출력(JSONL 아님)으로 재개되므로 초기 `--json` 실행보다 구조가 덜 엄격합니다. OpenClaw 세션 자체는 여전히 정상적으로 동작합니다.
## 문제 해결
- **CLI를 찾을 수 없음**: `command`를 전체 경로로 설정하세요.
- **잘못된 모델 이름**: `modelAliases`를 사용해 `provider/model` → CLI 모델로 매핑하세요.
- **세션 연속성 없음**: `sessionArg`가 설정되어 있고 `sessionMode`
`none`이 아닌지 확인하세요(Codex CLI는 현재 JSON 출력으로 resume할 수 없습니다).
- **이미지가 무시됨**: `imageArg`를 설정하고(그리고 CLI가 파일 경로를 지원하는지 확인하세요).
- **세션 연속성 없음**: `sessionArg`가 설정되어 있고 `sessionMode``none`이 아닌지 확인하세요(Codex CLI는 현재 JSON 출력으로 재개할 수 없음).
- **이미지가 무시됨**: `imageArg`를 설정하고(CLI가 파일 경로를 지원하는지도 확인하세요).

File diff suppressed because it is too large Load Diff

View File

@ -1,14 +1,14 @@
---
read_when:
- doctor 마이그레이션 추가 또는 수정하기
- 호환되지 않는 구성 변경 도입하기
summary: 'Doctor 명령: 상태 점검, 구성 마이그레이션, 및 복구 단계'
- doctor 마이그레이션을 추가하거나 수정하는 경우
- 호환되지 않는 설정 변경을 도입하는 경우
summary: 'Doctor 명령: 상태 점검, 설정 마이그레이션, 복구 단계'
title: Doctor
x-i18n:
generated_at: "2026-04-08T02:15:43Z"
generated_at: "2026-04-09T01:29:19Z"
model: gpt-5.4
provider: openai
source_hash: 3761a222d9db7088f78215575fa84e5896794ad701aa716e8bf9039a4424dca6
source_hash: 75d321bd1ad0e16c29f2382e249c51edfc3a8d33b55bdceea39e7dbcd4901fce
source_path: gateway/doctor.md
workflow: 15
---
@ -36,101 +36,135 @@ openclaw doctor --yes
openclaw doctor --repair
```
프롬프트 없이 권장 복구를 적용합니다(안전한 경우 복구 + 재시작).
권장 복구를 프롬프트 없이 적용합니다(안전한 경우 복구 + 재시작).
```bash
openclaw doctor --repair --force
```
공격적인 복구까지 적용합니다(사용자 지정 supervisor config를 덮어씁니다).
공격적인 복구도 적용합니다(사용자 지정 supervisor config를 덮어씀).
```bash
openclaw doctor --non-interactive
```
프롬프트 없이 실행하고 안전한 마이그레이션만 적용합니다(config 정규화 + 디스크 상태 이동). 사람의 확인이 필요한 재시작/서비스/샌드박스 작업은 건너뜁니다.
감지된 레거시 상태 마이그레이션은 자동으로 실행됩니다.
기존 상태 마이그레이션은 감지되면 자동으로 실행됩니다.
```bash
openclaw doctor --deep
```
추가 gateway 설치를 위해 시스템 서비스(launchd/systemd/schtasks)를 검사합니다.
추가 gateway 설치를 위해 시스템 서비스를 검사합니다(launchd/systemd/schtasks).
쓰기 전에 변경 사항을 검토하려면 먼저 config 파일을 여세요:
기록하기 전에 변경 사항을 검토하려면 먼저 config 파일을 여세요.
```bash
cat ~/.openclaw/openclaw.json
```
## 수행 작업(요약)
## 수행 내용(요약)
- git 설치를 위한 선택적 사전 업데이트(대화형 전용).
- UI 프로토콜 최신 상태 검사(프로토콜 스키마가 더 최신이면 Control UI를 다시 빌드).
- git 설치에 대한 선택적 사전 업데이트(대화형 전용).
- UI 프로토콜 최신 상태 점검(프로토콜 스키마가 더 새로우면 Control UI를 다시 빌드).
- 상태 점검 + 재시작 프롬프트.
- Skills 상태 요약(적격/누락/차단) 및 plugin 상태.
- 레거시 값에 대한 config 정규화.
- 레거시 평면 `talk.*` 필드에서 `talk.provider` + `talk.providers.<provider>`로의 Talk config 마이그레이션.
- 레거시 Chrome 확장 config 및 Chrome MCP 준비 상태를 위한 브라우저 마이그레이션 검사.
- 기존 값에 대한 config 정규화.
- 기존 평면 `talk.*` 필드에서 `talk.provider` + `talk.providers.<provider>`로의 Talk config 마이그레이션.
- 기존 Chrome 확장 프로그램 config 및 Chrome MCP 준비 상태에 대한 브라우저 마이그레이션 점검.
- OpenCode provider 재정의 경고(`models.providers.opencode` / `models.providers.opencode-go`).
- Codex OAuth 섀도잉 경고(`models.providers.openai-codex`).
- OpenAI Codex OAuth 프로필에 대한 OAuth TLS 선행 조건 검사.
- 레거시 디스크 상태 마이그레이션(세션/agent 디렉터리/WhatsApp 인증).
- 레거시 plugin manifest 계약 키 마이그레이션(`speechProviders`, `realtimeTranscriptionProviders`, `realtimeVoiceProviders`, `mediaUnderstandingProviders`, `imageGenerationProviders`, `videoGenerationProviders`, `webFetchProviders`, `webSearchProviders``contracts`).
- 레거시 cron 저장소 마이그레이션(`jobId`, `schedule.cron`, 최상위 delivery/payload 필드, payload `provider`, 단순 `notify: true` webhook 폴백 작업).
- Codex OAuth 가림 경고(`models.providers.openai-codex`).
- OpenAI Codex OAuth 프로필용 OAuth TLS 선행 조건 점검.
- 기존 디스크 상태 마이그레이션(세션/agent 디렉터리/WhatsApp 인증).
- 기존 plugin manifest 계약 키 마이그레이션(`speechProviders`, `realtimeTranscriptionProviders`, `realtimeVoiceProviders`, `mediaUnderstandingProviders`, `imageGenerationProviders`, `videoGenerationProviders`, `webFetchProviders`, `webSearchProviders``contracts`).
- 기존 cron 저장소 마이그레이션(`jobId`, `schedule.cron`, 최상위 delivery/payload 필드, payload `provider`, 단순 `notify: true` webhook 대체 작업).
- 세션 잠금 파일 검사 및 오래된 잠금 정리.
- 상태 무결성 및 권한 검사(세션, transcript, 상태 디렉터리).
- 로컬 실행 시 config 파일 권한 검(chmod 600).
- 모델 인증 상태: OAuth 만료를 확인하고, 만료 임박 토큰을 갱신할 수 있으며, 인증 프로필의 쿨다운/비활성 상태를 보고합니다.
- 추가 워크스페이스 디렉터리 감지(`~/openclaw`).
- 상태 무결성 및 권한 점검(세션, 대화록, 상태 디렉터리).
- 로컬 실행 시 config 파일 권한 검(chmod 600).
- 모델 인증 상태: OAuth 만료를 점검하고, 만료 예정 토큰을 갱신할 수 있으며, auth-profile cooldown/비활성 상태를 보고합니다.
- 추가 workspace 디렉터리 감지(`~/openclaw`).
- 샌드박싱이 활성화된 경우 샌드박스 이미지 복구.
- 레거시 서비스 마이그레이션 및 추가 gateway 감지.
- Matrix 채널 레거시 상태 마이그레이션(`--fix` / `--repair` 모드에서).
- Gateway 런타임 검사(서비스는 설치되었지만 실행되지 않음, 캐시된 launchd 레이블).
- 기존 서비스 마이그레이션 및 추가 gateway 감지.
- Matrix 채널 기존 상태 마이그레이션(`--fix` / `--repair` 모드에서).
- Gateway 런타임 점검(서비스는 설치되었지만 실행 중이 아님, 캐시된 launchd 레이블).
- 채널 상태 경고(실행 중인 gateway에서 프로브).
- 선택적 복구가 포함된 supervisor config 감사(launchd/systemd/schtasks).
- Gateway 런타임 모범 사례 검사(Node 대 Bun, 버전 관리자 경로).
- Gateway 런타임 모범 사례 점검(Node vs Bun, 버전 관리자 경로).
- Gateway 포트 충돌 진단(기본값 `18789`).
- 열린 DM 정책에 대한 보안 경고.
- 로컬 토큰 모드용 gateway 인증 검(토큰 소스가 없을 때 토큰 생성을 제안하며, token SecretRef config는 덮어쓰지 않음).
- Linux의 systemd linger 검사.
- 워크스페이스 bootstrap 파일 크기 검사(context 파일의 잘림/한계 근접 경고).
- 셸 completion 상태 검사 및 자동 설치/업그레이드.
- 메모리 검색 임베딩 provider 준비 상태 검(로컬 모델, 원격 API 키 또는 QMD 바이너리).
- 소스 설치 검사(pnpm 워크스페이스 불일치, 누락된 UI 자산, 누락된 tsx 바이너리).
- 로컬 토큰 모드용 gateway 인증 검(토큰 소스가 없을 때 토큰 생성을 제안하며, 토큰 SecretRef config는 덮어쓰지 않음).
- Linux에서 systemd linger 점검.
- Workspace 부트스트랩 파일 크기 점검(컨텍스트 파일에 대한 잘림/한계 근접 경고).
- 셸 자동 완성 상태 점검 및 자동 설치/업그레이드.
- 메모리 검색 임베딩 provider 준비 상태 검(로컬 모델, 원격 API 키 또는 QMD 바이너리).
- 소스 설치 점검(pnpm workspace 불일치, 누락된 UI 자산, 누락된 tsx 바이너리).
- 업데이트된 config + wizard 메타데이터 기록.
## Dreams UI 백필 및 재설정
Control UI Dreams 장면에는 근거 기반 dreaming 워크플로를 위한 **Backfill**, **Reset**, **Clear Grounded**
작업이 포함됩니다. 이러한 작업은 gateway
doctor 스타일 RPC 메서드를 사용하지만, `openclaw doctor` CLI
복구/마이그레이션의 일부는 **아닙니다**.
수행하는 작업:
- **Backfill**은 활성
workspace의 과거 `memory/YYYY-MM-DD.md` 파일을 스캔하고, 근거 기반 REM 일지 패스를 실행하며, 되돌릴 수 있는 백필
항목을 `DREAMS.md`에 기록합니다.
- **Reset**은 표시된 백필 일지 항목만 `DREAMS.md`에서 제거합니다.
- **Clear Grounded**는 과거 재생에서 온,
아직 실제 recall 또는 일일
지원이 누적되지 않은, 준비된 근거 기반 전용 단기 항목만 제거합니다.
자동으로 수행하지 않는 작업:
- `MEMORY.md`를 편집하지 않습니다
- 전체 doctor 마이그레이션을 실행하지 않습니다
- 먼저 준비 CLI 경로를 명시적으로 실행하지 않는 한, 근거 기반 후보를 실시간 단기
승격 저장소에 자동으로 준비하지 않습니다
근거 기반 과거 재생이 일반 deep 승격
경로에 영향을 주게 하려면 대신 CLI 흐름을 사용하세요.
```bash
openclaw memory rem-backfill --path ./memory --stage-short-term
```
이렇게 하면 `DREAMS.md`를 검토 표면으로 유지하면서
근거 기반의 오래 유지할 후보를 단기 dreaming 저장소에 준비합니다.
## 자세한 동작 및 근거
### 0) 선택적 업데이트(git 설치)
git 체크아웃이고 doctor가 대화형으로 실행 중이면,
doctor를 실행하기 전에 업데이트(fetch/rebase/build)할지 제안합니다.
이것이 git 체크아웃이고 doctor가 대화형으로 실행 중이면,
doctor 실행 전에 업데이트(fetch/rebase/build)할지 제안합니다.
### 1) Config 정규화
config에 레거시 값 형태가 포함되어 있으면(예: 채널별 재정의가 없는
`messages.ackReaction`) doctor는 이를 현재 스키마로 정규화합니다.
config에 기존 값 형태가 포함되어 있는 경우(예: 채널별 재정의가 없는 `messages.ackReaction`)
doctor는 이를 현재 스키마로 정규화합니다.
여기에는 레거시 Talk 평면 필드도 포함됩니다. 현재 공개 Talk config는
`talk.provider` + `talk.providers.<provider>`입니다. Doctor는 이전
여기에는 기존 Talk 평면 필드도 포함됩니다. 현재 공개 Talk config는
`talk.provider` + `talk.providers.<provider>`입니다. Doctor는 기존
`talk.voiceId` / `talk.voiceAliases` / `talk.modelId` / `talk.outputFormat` /
`talk.apiKey` 형태를 provider 맵으로 다시 씁니다.
`talk.apiKey` 형태를 provider 맵으로 다시 작성합니다.
### 2) 레거시 config 키 마이그레이션
### 2) 기존 config 키 마이그레이션
config에 더 이상 사용되지 않는 키가 포함되어 있으면, 다른 명령은 실행을 거부하고
`openclaw doctor`를 실행하라고 안내합니다.
`openclaw doctor`를 실행하라고 요청합니다.
Doctor는 다음을 수행합니다:
Doctor는 다음을 수행합니다.
- 어떤 레거시 키가 발견되었는지 설명합니다.
- 어떤 기존 키가 발견되었는지 설명합니다.
- 적용한 마이그레이션을 보여줍니다.
- 업데이트된 스키마로 `~/.openclaw/openclaw.json`을 다시 씁니다.
- 업데이트된 스키마로 `~/.openclaw/openclaw.json`을 다시 기록합니다.
Gateway도 시작 시 레거시 config 형식을 감지하면 doctor 마이그레이션을 자동 실행하므로
오래된 config가 수동 개입 없이 복구됩니다.
Cron 작업 저장소 마이그레이션은 `openclaw doctor --fix`에서 처리됩니다.
Gateway도 시작 시
기존 config 형식을 감지하면 doctor 마이그레이션을 자동 실행하므로, 오래된 config가 수동 개입 없이 복구됩니다.
Cron 작업 저장소 마이그레이션은 `openclaw doctor --fix`가 처리합니다.
현재 마이그레이션:
@ -141,7 +175,7 @@ Cron 작업 저장소 마이그레이션은 `openclaw doctor --fix`에서 처리
- `routing.queue``messages.queue`
- `routing.bindings` → 최상위 `bindings`
- `routing.agents`/`routing.defaultAgentId` → `agents.list` + `agents.list[].default`
- 레거시 `talk.voiceId`/`talk.voiceAliases`/`talk.modelId`/`talk.outputFormat`/`talk.apiKey` → `talk.provider` + `talk.providers.<provider>`
- 기존 `talk.voiceId`/`talk.voiceAliases`/`talk.modelId`/`talk.outputFormat`/`talk.apiKey` → `talk.provider` + `talk.providers.<provider>`
- `routing.agentToAgent``tools.agentToAgent`
- `routing.transcribeAudio``tools.media.audio.models`
- `messages.tts.<provider>` (`openai`/`elevenlabs`/`microsoft`/`edge`) → `messages.tts.providers.<provider>`
@ -154,19 +188,19 @@ Cron 작업 저장소 마이그레이션은 `openclaw doctor --fix`에서 처리
- `plugins.entries.voice-call.config.streaming.openaiApiKey|sttModel|silenceDurationMs|vadThreshold`
`plugins.entries.voice-call.config.streaming.providers.openai.*`
- `bindings[].match.accountID``bindings[].match.accountId`
- 이름이 지정된 `accounts`가 있는 채널에서 단일 계정용 최상위 채널 값이 남아 있는 경우, 해당 계정 범위 값을 그 채널에 대해 선택된 승격 계정으로 이동합니다(대부분 채널은 `accounts.default`; Matrix는 기존에 일치하는 이름 있는/default 대상을 유지할 수 있음)
- 이름 있는 `accounts`가 있지만 단일 계정용 최상위 채널 값이 남아 있는 채널의 경우, 해당 계정 범위 값을 그 채널에 대해 선택된 승격 대상 계정으로 이동합니다(대부분 채널은 `accounts.default`; Matrix는 기존에 일치하는 이름 있는/기본 대상을 유지할 수 있음)
- `identity``agents.list[].identity`
- `agent.*``agents.defaults` + `tools.*` (tools/elevated/exec/sandbox/subagents)
- `agent.model`/`allowedModels`/`modelAliases`/`modelFallbacks`/`imageModelFallbacks`
`agents.defaults.models` + `agents.defaults.model.primary/fallbacks` + `agents.defaults.imageModel.primary/fallbacks`
- `browser.ssrfPolicy.allowPrivateNetwork``browser.ssrfPolicy.dangerouslyAllowPrivateNetwork`
- `browser.profiles.*.driver: "extension"``"existing-session"`
- `browser.relayBindHost` 제거(레거시 확장 relay 설정)
- `browser.relayBindHost` 제거(기존 확장 프로그램 relay 설정)
Doctor 경고에는 다중 계정 채널에 대한 account 기본값 안내도 포함됩니다:
Doctor 경고에는 다중 계정 채널에 대한 계정 기본값 안내도 포함됩니다.
- `channels.<channel>.defaultAccount` 또는 `accounts.default` 없이 두 개 이상의 `channels.<channel>.accounts` 항목이 구성된 경우, doctor는 폴백 라우팅이 예상치 못한 계정을 선택할 수 있다고 경고합니다.
- `channels.<channel>.defaultAccount`가 알 수 없는 계정 ID로 설정된 경우, doctor는 경고하고 구성된 계정 ID를 나열합니다.
- `channels.<channel>.accounts` 항목이 둘 이상 구성되어 있는데 `channels.<channel>.defaultAccount` 또는 `accounts.default`가 없으면, doctor는 대체 라우팅이 예상치 못한 계정을 선택할 수 있다고 경고합니다.
- `channels.<channel>.defaultAccount`가 알 수 없는 계정 ID로 설정되어 있으면, doctor는 경고하고 구성된 계정 ID 목록을 보여줍니다.
### 2b) OpenCode provider 재정의
@ -177,328 +211,335 @@ Doctor 경고에는 다중 계정 채널에 대한 account 기본값 안내도
### 2c) 브라우저 마이그레이션 및 Chrome MCP 준비 상태
브라우저 config가 아직 제거된 Chrome 확장 경로를 가리키는 경우, doctor는
이를 현재 호스트 로컬 Chrome MCP 연결 모델로 정규화합니다:
브라우저 config가 여전히 제거된 Chrome 확장 프로그램 경로를 가리키는 경우, doctor는
이를 현재 호스트 로컬 Chrome MCP 연결 모델로 정규화합니다.
- `browser.profiles.*.driver: "extension"``"existing-session"`이 됩니다
- `browser.relayBindHost`는 제거됩니다
`defaultProfile:
"user"` 또는 구성된 `existing-session` 프로필을 사용할 때 doctor는 호스트 로컬 Chrome MCP 경로도 감사합니다:
Doctor는 또한 `defaultProfile:
"user"` 또는 구성된 `existing-session` 프로필을 사용할 때 호스트 로컬 Chrome MCP 경로를 점검합니다.
- 기본 자동 연결 프로필에 대해 동일한 호스트에 Google Chrome이 설치되어 있는지 확인
- 감지된 Chrome 버전을 확인하고 Chrome 144 미만이면 경고
- 브라우저 inspect 페이지에서 원격 디버깅을 활성화하라고 안내
(예: `chrome://inspect/#remote-debugging`, `brave://inspect/#remote-debugging`,
- 기본
자동 연결 프로필에 대해 같은 호스트에 Google Chrome이 설치되어 있는지 확인합니다
- 감지된 Chrome 버전을 확인하고 Chrome 144 미만이면 경고합니다
- 브라우저 inspect 페이지에서 원격 디버깅을 활성화하라고 알려줍니다(예:
`chrome://inspect/#remote-debugging`, `brave://inspect/#remote-debugging`,
또는 `edge://inspect/#remote-debugging`)
Doctor는 Chrome 측 설정을 대신 활성화할 수 없습니다. 호스트 로컬 Chrome MCP에는 여전히 다음이 필요합니다:
Doctor는 Chrome 측 설정을 대신 활성화할 수 없습니다. 호스트 로컬 Chrome MCP에는 여전히 다음이 필요합니다.
- gateway/node 호스트에 설치된 Chromium 기반 브라우저 144+
- 로컬에서 실행 중인 브라우저
- 해당 브라우저에서 활성화된 원격 디버깅
- 브라우저에서 첫 연결 동의 프롬프트 승인
- gateway/node 호스트에 Chromium 기반 브라우저 144+가 있어야 함
- 브라우저가 로컬에서 실행 중이어야 함
- 해당 브라우저에서 원격 디버깅이 활성화되어 있어야 함
- 브라우저에서 최초 연결 동의 프롬프트를 승인해야 함
여기서의 준비 상태는 로컬 연결 선행 조건에만 관한 것입니다. Existing-session은
현재 Chrome MCP 경로 제한을 유지합니다. `responsebody`, PDF 내보내기,
다운로드 가로채기, 배치 작업 같은 고급 경로는 여전히 관리형
여기서의 준비 상태는 로컬 연결 선행 조건에만 해당합니다. Existing-session은
현재 Chrome MCP 경로 제한을 유지합니다. `responsebody`, PDF
내보내기, 다운로드 가로채기, 배치 작업 같은 고급 경로는 여전히 관리형
브라우저 또는 원시 CDP 프로필이 필요합니다.
검사는 Docker, sandbox, remote-browser 또는 기타
헤드리스 흐름에는 **적용되지 않습니다**. 이러한 경우는 계속 원시 CDP를 사용합니다.
점검은 Docker, 샌드박스, 원격 브라우저 또는 기타
헤드리스 흐름에는 **적용되지 않습니다**. 이러한 경우는 계속해서 원시 CDP를 사용합니다.
### 2d) OAuth TLS 선행 조건
OpenAI Codex OAuth 프로필이 구성되어 있으면 doctor는 OpenAI
인증 엔드포인트를 프로브하여 로컬 Node/OpenSSL TLS 스택이 인증서 체인을
검증할 수 있는지 확인합니다. 프로브가 인증서 오류로 실패하면(예:
OpenAI Codex OAuth 프로필이 구성되어 있으면, doctor는 OpenAI
인증 엔드포인트를 프로브하여 로컬 Node/OpenSSL TLS 스택이
인증서 체인을 검증할 수 있는지 확인합니다. 프로브가 인증서 오류로 실패하면(예:
`UNABLE_TO_GET_ISSUER_CERT_LOCALLY`, 만료된 인증서 또는 자체 서명 인증서),
doctor는 플랫폼별 해결 안내를 출력합니다. Homebrew Node를 사용하는 macOS에서는
보통 `brew postinstall ca-certificates`가 해결 방법입니다. `--deep`를 사용하면
gateway가 정상이어도 프로브가 실행됩니다.
doctor는 플랫폼별 수정 안내를 출력합니다. Homebrew Node를 사용하는 macOS에서는
보통 `brew postinstall ca-certificates`로 해결합니다. `--deep`를 사용하면 gateway가 정상이어도
프로브가 실행됩니다.
### 2c) Codex OAuth provider 재정의
이전에 레거시 OpenAI 전송 설정을
`models.providers.openai-codex` 아래에 추가했다면, 이는 최신 릴리스가 자동으로 사용하는
내장 Codex OAuth provider 경로를 가릴 수 있습니다. Doctor는
Codex OAuth와 함께 이러한 오래된 전송 설정을 감지하면 경고하여,
오래된 전송 재정의를 제거하거나 다시 작성해 내장 라우팅/폴백 동작을
복원할 수 있도록 합니다. 사용자 지정 프록시와 헤더 전용 재정의는 여전히 지원되며
이 경고를 발생시키지 않습니다.
이전에
`models.providers.openai-codex` 아래에 기존 OpenAI 전송 설정을 추가했다면,
최신 릴리스가 자동으로 사용하는 내장 Codex OAuth
provider 경로를 가릴 수 있습니다. Doctor는 Codex OAuth와 함께 이러한 기존 전송 설정을 발견하면
오래된 전송 재정의를 제거하거나 다시 작성하여 내장 라우팅/대체 동작을
다시 사용할 수 있도록 경고합니다. 사용자 지정 프록시와 헤더 전용 재정의는 여전히 지원되며 이 경고를
발생시키지 않습니다.
### 3) 레거시 상태 마이그레이션(디스크 레이아웃)
### 3) 기존 상태 마이그레이션(디스크 레이아웃)
Doctor는 오래된 디스크 레이아웃을 현재 구조로 마이그레이션할 수 있습니다:
Doctor는 오래된 디스크 레이아웃을 현재 구조로 마이그레이션할 수 있습니다.
- 세션 저장소 + transcript:
- 세션 저장소 + 대화록:
- `~/.openclaw/sessions/`에서 `~/.openclaw/agents/<agentId>/sessions/`
- Agent 디렉터리:
- `~/.openclaw/agent/`에서 `~/.openclaw/agents/<agentId>/agent/`
- WhatsApp 인증 상태(Baileys):
- 레거시 `~/.openclaw/credentials/*.json` (`oauth.json` 제외)에서
- `~/.openclaw/credentials/whatsapp/<accountId>/...` (기본 account id: `default`)
- 기존 `~/.openclaw/credentials/*.json`(`oauth.json` 제외)에서
- `~/.openclaw/credentials/whatsapp/<accountId>/...`(기본 계정 ID: `default`)
이 마이그레이션은 최선의 노력 기준이며 멱등적입니다. 백업으로 남겨진 레거시 폴더가 있으면
doctor는 경고를 출력합니다. Gateway/CLI도 시작 시
레거시 세션 + agent 디렉터리를 자동 마이그레이션하므로, 수동 doctor 실행 없이
기록/인증/모델이 agent별 경로에 저장됩니다. WhatsApp 인증은 의도적으로
`openclaw doctor`를 통해서만 마이그레이션됩니다. Talk provider/provider 정규화는 이제
구조적 동등성으로 비교하므로, 키 순서만 다른 차이로
반복적인 no-op `doctor --fix` 변경이 더 이상 발생하지 않습니다.
이 마이그레이션은 최선형이며 멱등적입니다. doctor는
기존 폴더를 백업으로 남겨둘 때 경고를 출력합니다. Gateway/CLI도 시작 시
기존 세션 + agent 디렉터리를 자동 마이그레이션하므로, 기록/인증/모델이 수동 doctor 실행 없이
agent별 경로에 저장됩니다. WhatsApp 인증은 의도적으로 `openclaw doctor`를 통해서만
마이그레이션됩니다. Talk provider/provider-map 정규화는 이제
구조적 동등성으로 비교하므로, 키 순서만 다른 차이로 인해
반복적인 무의미한 `doctor --fix` 변경이 더 이상 발생하지 않습니다.
### 3a) 레거시 plugin manifest 마이그레이션
### 3a) 기존 plugin manifest 마이그레이션
Doctor는 설치된 모든 plugin manifest를 검사해 더 이상 사용되지 않는 최상위 기능
Doctor는 설치된 모든 plugin manifest를 검사하여 더 이상 사용되지 않는 최상위 capability
키(`speechProviders`, `realtimeTranscriptionProviders`,
`realtimeVoiceProviders`, `mediaUnderstandingProviders`,
`imageGenerationProviders`, `videoGenerationProviders`, `webFetchProviders`,
`webSearchProviders`)를 찾습니다. 발견되면 이를 `contracts`
객체로 이동하고 manifest 파일을 제자리에서 다시 쓸지 제안합니다. 이 마이그레이션은 멱등적이며,
`contracts` 키에 이미 동일한 값이 있으면 레거시 키만 제거되고
데이터는 중복되지 않습니다.
객체로 이동하고 manifest 파일을 제자리에서 다시 쓰도록 제안합니다. 이 마이그레이션은 멱등적입니다.
`contracts` 키에 이미 같은 값이 있으면,
기존 키는 데이터를 중복하지 않고 제거됩니다.
### 3b) 레거시 cron 저장소 마이그레이션
### 3b) 기존 cron 저장소 마이그레이션
Doctor는 cron 작업 저장소(기본값 `~/.openclaw/cron/jobs.json`,
또는 재정의된 경우 `cron.store`)에서 스케줄러가 호환성을 위해 여전히 허용하는
오래된 작업 형태도 검사합니다.
Doctor는 또한 cron 작업 저장소(기본값 `~/.openclaw/cron/jobs.json`,
또는 재정의된 경우 `cron.store`)에 대해 스케줄러가 호환성을 위해 여전히
허용하는 오래된 작업 형태가 있는지 점검합니다.
현재 cron 정리 항목은 다음과 같습니다:
현재 cron 정리 항목:
- `jobId``id`
- `schedule.cron``schedule.expr`
- 최상위 payload 필드(`message`, `model`, `thinking`, ...) → `payload`
- 최상위 delivery 필드(`deliver`, `channel`, `to`, `provider`, ...) → `delivery`
- payload `provider` delivery 별칭 → 명시적 `delivery.channel`
- 단순 레거시 `notify: true` webhook 폴백 작업 → 명시적 `delivery.mode="webhook"` `delivery.to=cron.webhook`
- 단순 기존 `notify: true` webhook 대체 작업 → 명시적 `delivery.mode="webhook"` `delivery.to=cron.webhook`
Doctor는 동작을 변경하지 않고 수행할 수 있을 때만 `notify: true` 작업을
자동 마이그레이션합니다. 작업이 레거시 notify 폴백과 기존
비-webhook delivery 모드를 함께 사용하면, doctor는 경고하고 해당 작업은
수동 검토용으로 남겨 둡니다.
Doctor는 동작을 바꾸지 않고 수행할 수 있을 때만 `notify: true` 작업을 자동 마이그레이션합니다.
작업이 기존 notify 대체와 기존의
비-webhook delivery 모드를 함께 사용하는 경우, doctor는 경고하고 해당 작업은 수동 검토용으로 남겨둡니다.
### 3c) 세션 잠금 정리
Doctor는 모든 agent 세션 디렉터리를 검사해 오래된 쓰기 잠금 파일을 찾습니다 —
세션이 비정상 종료될 때 남겨진 파일입니다. 발견된 각 잠금 파일에 대해 doctor는
다음을 보고합니다: 경로, PID, PID가 아직 살아 있는지 여부, 잠금 생성 후 경과 시간,
그리고 오래된 것으로 간주되는지 여부(죽은 PID 또는 30분 초과). `--fix` / `--repair`
Doctor는 모든 agent 세션 디렉터리를 스캔하여 오래된 쓰기 잠금 파일을 찾습니다. 이는
세션이 비정상적으로 종료될 때 남겨진 파일입니다. 발견된 각 잠금 파일에 대해 다음을 보고합니다.
경로, PID, 해당 PID가 아직 살아 있는지, 잠금 경과 시간, 그리고
오래된 것으로 간주되는지 여부(죽은 PID이거나 30분 초과). `--fix` / `--repair`
모드에서는 오래된 잠금 파일을 자동으로 제거합니다. 그렇지 않으면 메모를 출력하고
`--fix`로 다시 실행하라고 안내합니다.
### 4) 상태 무결성 검사(세션 지속성, 라우팅 및 안전성)
### 4) 상태 무결성 점검(세션 지속성, 라우팅, 안전성)
상태 디렉터리는 운영의 핵심 중추입니다. 이것이 사라지면
상태 디렉터리는 운영의 핵심 기반입니다. 이것이 사라지면
세션, 자격 증명, 로그, config를 잃게 됩니다(다른 곳에 백업이 없는 한).
Doctor는 다음을 검사합니다:
Doctor는 다음을 점검합니다.
- **상태 디렉터리 누락**: 치명적인 상태 손실을 경고하고, 디렉터리를 다시 만들지 묻고,
누락된 데이터를 복구할 수 없음을 상기시킵니다.
- **상태 디렉터리 누락**: 치명적인 상태 손실을 경고하고, 디렉터리 재생성을 제안하며,
누락된 데이터를 복구할 수 없음을 알려줍니다.
- **상태 디렉터리 권한**: 쓰기 가능 여부를 확인하고, 권한 복구를 제안합니다
(소유자/그룹 불일치가 감지되면 `chown` 힌트도 출력).
- **macOS 클라우드 동기화 상태 디렉터리**: 상태가 iCloud Drive
(`~/Library/Mobile Documents/com~apple~CloudDocs/...`) 또는
`~/Library/CloudStorage/...` 아래로 확인되면 경고합니다. 동기화 기반 경로는 느린 I/O와
잠금/동기화 경쟁 상태를 유발할 수 있기 때문입니다.
`~/Library/CloudStorage/...` 아래로 해석되면 경고합니다. 동기화 기반 경로는 느린 I/O와
잠금/동기화 경쟁 유발할 수 있기 때문입니다.
- **Linux SD 또는 eMMC 상태 디렉터리**: 상태가 `mmcblk*`
마운트 소스로 확인되면 경고합니다. SD 또는 eMMC 기반 랜덤 I/O는 세션 및 자격 증명 쓰기에서
더 느리고 마모가 빠를 수 있기 때문입니다.
- **세션 디렉터리 누락**: `sessions/` 세션 저장소 디렉터리는
마운트 소스로 해석되면 경고합니다. SD 또는 eMMC 기반 랜덤 I/O는
세션 및 자격 증명 기록에서 더 느리고 마모가 빠를 수 있기 때문입니다.
- **세션 디렉터리 누락**: `sessions/` 세션 저장소 디렉터리는
기록을 유지하고 `ENOENT` 충돌을 방지하는 데 필요합니다.
- **Transcript 불일치**: 최근 세션 항목에 누락된
transcript 파일이 있으면 경고합니다.
- **메인 세션 “1줄 JSONL”**: 메인 transcript가 한 줄뿐인 경우를 표시합니다
(기록이 누적되지 않음).
- **여러 상태 디렉터리**: 서로 다른 홈 디렉터리에 여러 `~/.openclaw` 폴더가 있거나
`OPENCLAW_STATE_DIR`이 다른 곳을 가리키면 경고합니다(기록이 설치 간에 분리될 수 있음).
- **대화록 불일치**: 최근 세션 항목에 누락된
대화록 파일이 있으면 경고합니다.
- **메인 세션 “1줄 JSONL”**: 메인 대화록에 한 줄만 있는 경우(기록이 누적되지 않음)를 표시합니다.
- **여러 상태 디렉터리**: 여러 홈 디렉터리에 `~/.openclaw` 폴더가 있거나
`OPENCLAW_STATE_DIR`이 다른 곳을 가리키면 경고합니다(기록이 설치 간에
분리될 수 있음).
- **원격 모드 알림**: `gateway.mode=remote`이면 doctor는
원격 호스트에서 실행하라고 알려줍니다(상태는 այնտեղ에 있음).
원격 호스트에서 실행하라고 알려줍니다(상태는 그곳에 있음).
- **Config 파일 권한**: `~/.openclaw/openclaw.json`
그룹/전체 읽기 가능하면 경고하고 `600`으로 강화할지 제안합니다.
그룹/전체 읽기 가능하면 경고하고 `600`으로 제한할 것을 제안합니다.
### 5) 모델 인증 상태(OAuth 만료)
Doctor는 인증 저장소의 OAuth 프로필을 검사하고, 토큰이
곧 만료되거나 이미 만료되었을 때 경고하며, 안전한 경우 갱신할 수 있습니다. Anthropic
OAuth/토큰 프로필이 오래되었으면 Anthropic API 키 또는
곧 만료되거나 이미 만료된 경우 경고하며, 안전한 경우 갱신할 수 있습니다. Anthropic
OAuth/토큰 프로필이 오래된 경우, Anthropic API 키 또는
Anthropic setup-token 경로를 제안합니다.
갱신 프롬프트는 대화형(TTY) 실행 시에만 표시되며, `--non-interactive`
갱신 프롬프트는 대화형(TTY)으로 실행할 때만 표시되며, `--non-interactive`
갱신 시도를 건너뜁니다.
Doctor는 또한 다음 이유로 일시적으로 사용할 수 없는 인증 프로필도 보고합니다:
OAuth 갱신이 영구적으로 실패하면(예: `refresh_token_reused`,
`invalid_grant`, 또는 provider가 다시 로그인하라고 알리는 경우),
doctor는 재인증이 필요하다고 보고하고 실행해야 할 정확한
`openclaw models auth login --provider ...` 명령을 출력합니다.
- 짧은 쿨다운(속도 제한/타임아웃/인증 실패)
- 더 긴 비활성화(결제/크레딧 실패)
Doctor는 또한 다음과 같은 이유로 일시적으로 사용할 수 없는 auth profile도 보고합니다.
- 짧은 cooldown(속도 제한/타임아웃/인증 실패)
- 더 긴 비활성화(청구/크레딧 실패)
### 6) Hooks 모델 검증
`hooks.gmail.model`이 설정되어 있으면 doctor는 모델 참조를
카탈로그 및 allowlist와 대조해 검증하고, 해석되지 않거나 허용되지 않으면 경고합니다.
`hooks.gmail.model`이 설정되어 있으면, doctor는 모델 참조를
카탈로그 및 허용 목록과 대조해 검증하고, 해결되지 않거나 허용되지 않으면 경고합니다.
### 7) 샌드박스 이미지 복구
샌드박싱이 활성화되어 있으면 doctor는 Docker 이미지를 확인하고
현재 이미지가 없을 때 빌드하거나 레거시 이름으로 전환할지 제안합니다.
샌드박싱이 활성화된 경우, doctor는 Docker 이미지를 점검하고 현재 이미지가 없으면
빌드하거나 기존 이름으로 전환할 것을 제안합니다.
### 7b) 번들 plugin 런타임 의존성
Doctor는 번들 plugin 런타임 의존성(예: Discord plugin 런타임 패키지)이
OpenClaw 설치 루트에 존재하는지 확인합니다.
Doctor는 번들 plugin 런타임 의존성(예:
Discord plugin 런타임 패키지)이 OpenClaw 설치 루트에 존재하는지 확인합니다.
누락된 항목이 있으면 doctor는 해당 패키지를 보고하고
`openclaw doctor --fix` / `openclaw doctor --repair` 모드에서 설치합니다.
### 8) Gateway 서비스 마이그레이션 및 정리 힌트
Doctor는 레거시 gateway 서비스(launchd/systemd/schtasks)를 감지하고
이를 제거한 뒤 현재 gateway 포트를 사용해 OpenClaw 서비스를 설치할지 제안합니다.
추가적인 gateway 유사 서비스도 검사하고 정리 힌트를 출력할 수 있습니다.
프로필 이름이 지정된 OpenClaw gateway 서비스는 1급 대상으로 간주되며 "추가"로 표시되지 않습니다.
Doctor는 기존 gateway 서비스(launchd/systemd/schtasks)를 감지하고
이를 제거한 뒤 현재 gateway
포트를 사용하는 OpenClaw 서비스를 설치할 것을 제안합니다. 또한 추가 gateway 유사 서비스를 검사하여 정리 힌트를 출력할 수 있습니다.
프로필 이름이 붙은 OpenClaw gateway 서비스는 정식 항목으로 간주되며 "추가"로 표시되지 않습니다.
### 8b) 시작 Matrix 마이그레이션
### 8b) 시작 Matrix 마이그레이션
Matrix 채널 계정에 보류 중이거나 처리 가능한 레거시 상태 마이그레이션이 있으면,
doctor(`--fix` / `--repair` 모드)는 먼저 마이그레이션 전 스냅샷을 만든 다음
최선의 노력 기준 마이그레이션 단계를 실행합니다: 레거시 Matrix 상태 마이그레이션 및
레거시 암호화 상태 준비. 두 단계 모두 치명적이지 않으며, 오류는 로그에 기록되고
시작은 계속됩니다. 읽기 전용 모드(`--fix` 없는 `openclaw doctor`)에서는 이 검사를
완전히 건너니다.
Matrix 채널 계정에 보류 중이거나 실행 가능한 기존 상태 마이그레이션이 있으면,
doctor는(`--fix` / `--repair` 모드에서) 마이그레이션 전 스냅샷을 생성한 다음
최선형 마이그레이션 단계를 실행합니다: 기존 Matrix 상태 마이그레이션과 기존
암호화 상태 준비. 두 단계 모두 치명적이지 않으며, 오류는 기록되고
시작은 계속됩니다. 읽기 전용 모드(`--fix` 없는 `openclaw doctor`)에서는 이 점검이
완전히 건너뛰어집니다.
### 9) 보안 경고
Doctor는 provider가 allowlist 없이 DM에 열려 있거나,
Doctor는 provider가 허용 목록 없이 DM에 열려 있거나,
정책이 위험한 방식으로 구성된 경우 경고를 출력합니다.
### 10) systemd linger(Linux)
systemd 사용자 서비스로 실행 중이면 doctor는 로그아웃 후에도
gateway가 계속 살아 있도록 lingering이 활성화되어 있는지 확인합니다.
systemd 사용자 서비스로 실행 중인 경우, doctor는 로그아웃 후에도
gateway가 계속 실행되도록 linger가 활성화되어 있는지 확인합니다.
### 11) 워크스페이스 상태(Skills, plugins 및 레거시 디렉터리)
### 11) Workspace 상태(Skills, plugins, 기존 디렉터리)
Doctor는 기본 agent의 워크스페이스 상태 요약을 출력합니다:
Doctor는 기본 agent에 대한 workspace 상태 요약을 출력합니다.
- **Skills 상태**: 적격, 요구 사항 누락, allowlist 차단된 skill 수를 집계합니다.
- **레거시 워크스페이스 디렉터리**: 현재 워크스페이스와 함께 `~/openclaw` 또는 기타 레거시 워크스페이스 디렉터리가
- **Skills 상태**: 적격, 요구 사항 누락, 허용 목록 차단된 skills 수를 집계합니다.
- **기존 workspace 디렉터리**: 현재 workspace와 함께 `~/openclaw` 또는 기타 기존 workspace 디렉터리가
존재하면 경고합니다.
- **Plugin 상태**: 로드됨/비활성/오류 plugin 수를 집계하고, 오류가 있는 경우 plugin ID를 나열하며,
번들 plugin 기능을 보고합니다.
- **Plugin 호환성 경고**: 현재 런타임과 호환성 문제가 있는 plugin을 표시합니다.
- **Plugin 진단**: plugin 레지스트리가 로드 시점에 출력한 경고 또는 오류를 노출합니다.
- **Plugin 상태**: 로드됨/비활성화됨/오류 plugin 수를 집계하고, 오류가 있는 경우 plugin ID를 나열하며,
번들 plugin capability를 보고합니다.
- **Plugin 호환성 경고**: 현재 런타임과 호환성 문제가 있는 plugins를 표시합니다.
- **Plugin 진단**: plugin registry가
로드 시 출력한 경고나 오류를 표시합니다.
### 11b) Bootstrap 파일 크기
### 11b) 부트스트랩 파일 크기
Doctor는 워크스페이스 bootstrap 파일(예: `AGENTS.md`,
`CLAUDE.md` 또는 기타 주입된 context 파일)이 구성된
문자 예산에 근접했거나 초과했는지 검합니다. 파일별 원본 대 주입 문자 수, 잘림
비율, 잘림 원인(`max/file` 또는 `max/total`), 그리고 전체 예산 대비 총 주입 문자 수를
보고합니다. 파일이 잘렸거나 한계에 근접하면 doctor는
`agents.defaults.bootstrapMaxChars`
Doctor는 workspace 부트스트랩 파일(예: `AGENTS.md`,
`CLAUDE.md`, 또는 기타 주입된 컨텍스트 파일)이 구성된
문자 예산에 근접했거나 초과했는지 검합니다. 파일별 원본 문자 수 대 주입 문자 수, 잘림
비율, 잘림 원인(`max/file` 또는 `max/total`), 그리고 전체 예산 대비 총 주입
문자 수를 비율로 보고합니다. 파일이 잘렸거나 한계에 근접한 경우,
doctor는 `agents.defaults.bootstrapMaxChars`
`agents.defaults.bootstrapTotalMaxChars` 조정을 위한 팁을 출력합니다.
### 11c) 셸 completion
### 11c) 셸 자동 완성
Doctor는 현재 셸에 tab completion이 설치되어 있는지 검사합니다
(zsh, bash, fish 또는 PowerShell):
Doctor는 현재 셸에 대해 탭 자동 완성이 설치되어 있는지 점검합니다
(zsh, bash, fish, 또는 PowerShell).
- 셸 프로필이 느린 동적 completion 패턴
(`source <(openclaw completion ...)`)을 사용하면, doctor는 이를 더 빠른
- 셸 프로필이 느린 동적 자동 완성 패턴을 사용하는 경우
(`source <(openclaw completion ...)`), doctor는 이를 더 빠른
캐시 파일 변형으로 업그레이드합니다.
- 프로필에 completion이 구성되어 있지만 캐시 파일이 없으면,
- 프로필에 자동 완성이 구성되어 있지만 캐시 파일이 없으면,
doctor는 캐시를 자동으로 다시 생성합니다.
- completion이 전혀 구성되어 있지 않으면, doctor는 설치를 제안합니다
(대화형 모드 전용, `--non-interactive`에서는 건너뜀).
- 자동 완성이 전혀 구성되어 있지 않으면, doctor는 설치를 제안합니다
(대화형 모드에서만, `--non-interactive`에서는 건너뜀).
캐시를 수동으로 다시 생성하려면 `openclaw completion --write-state`를 실행하세요.
### 12) Gateway 인증 검(로컬 토큰)
### 12) Gateway 인증 검(로컬 토큰)
Doctor는 로컬 gateway 토큰 인증 준비 상태를 검합니다.
Doctor는 로컬 gateway 토큰 인증 준비 상태를 검합니다.
- 토큰 모드에 토큰이 필요하지만 토큰 소스가 없으면 doctor는 토큰 생성을 제안합니다.
- `gateway.auth.token`이 SecretRef로 관리되지만 사용할 수 없으면 doctor는 경고하고 일반 텍스트로 덮어쓰지 않습니다.
- `openclaw doctor --generate-gateway-token`token SecretRef가 구성되지 않은 경우에만 생성을 강제합니다.
- 토큰 모드에 토큰이 필요하고 토큰 소스가 없으면, doctor는 토큰 생성을 제안합니다.
- `gateway.auth.token`이 SecretRef로 관리되지만 사용할 수 없으면, doctor는 경고하고 평문으로 덮어쓰지 않습니다.
- `openclaw doctor --generate-gateway-token`토큰 SecretRef가 구성되지 않았을 때만 강제로 생성합니다.
### 12b) 읽기 전용 SecretRef 인식 복구
일부 복구 흐름은 런타임 fail-fast 동작을 약화시키지 않고 구성된 자격 증명을 검사해야 합니다.
일부 복구 흐름은 런타임 fail-fast 동작을 약화시키지 않으면서
구성된 자격 증명을 검사해야 합니다.
- `openclaw doctor --fix`는 이제 상태 계열 명령과 동일한 읽기 전용 SecretRef 요약 모델을 사용해 대상 config 복구를 수행합니다.
- 예: Telegram `allowFrom` / `groupAllowFrom` `@username` 복구는 가능한 경우 구성된 봇 자격 증명을 사용하려고 시도합니다.
- Telegram 봇 토큰이 SecretRef를 통해 구성되어 있지만 현재 명령 경로에서 사용할 수 없으면, doctor는 자격 증명이 구성되었지만 현재 사용할 수 없다고 보고하고, 충돌하거나 토큰이 누락되었다고 잘못 보고하는 대신 자동 확인을 건너뜁니다.
- `openclaw doctor --fix`는 이제 대상 config 복구를 위해 상태 계열 명령과 동일한 읽기 전용 SecretRef 요약 모델을 사용합니다.
- 예: Telegram `allowFrom` / `groupAllowFrom` `@username` 복구는 가능하면 구성된 bot 자격 증명을 사용하려고 시도합니다.
- Telegram bot 토큰이 SecretRef를 통해 구성되었지만 현재 명령 경로에서 사용할 수 없으면, doctor는 해당 자격 증명이 구성되었지만 사용할 수 없다고 보고하고, 충돌하거나 토큰이 누락된 것으로 잘못 보고하는 대신 자동 해결을 건너뜁니다.
### 13) Gateway 상태 점검 + 재시작
Doctor는 상태 점검을 실행하고 gateway가
비정상으로 보이면 재시작을 제안합니다.
정상적이지 않아 보이면 재시작을 제안합니다.
### 13b) 메모리 검색 준비 상태
Doctor는 구성된 메모리 검색 임베딩 provider가 기본
agent에 대해 준비되었는지 확인합니다. 동작은 구성된 백엔드와 provider에 따라 다릅니다:
Doctor는 구성된 메모리 검색 임베딩 provider가
기본 agent에 대해 준비되어 있는지 점검합니다. 동작은 구성된 백엔드와 provider에 따라 달라집니다.
- **QMD 백엔드**: `qmd` 바이너리가 사용 가능하고 시작 가능한지 프로브합니다.
그렇지 않으면 npm 패키지와 수동 바이너리 경로 옵션을 포함한 해결 안내를 출력합니다.
- **QMD 백엔드**: `qmd` 바이너리를 사용할 수 있고 시작 가능한지 프로브합니다.
그렇지 않으면 npm 패키지 및 수동 바이너리 경로 옵션을 포함한 수정 안내를 출력합니다.
- **명시적 로컬 provider**: 로컬 모델 파일 또는 인식 가능한
원격/다운로드 가능한 모델 URL이 있는지 확인합니다. 없으면 원격 provider로 전환하라고 제안합니다.
- **명시적 원격 provider** (`openai`, `voyage` 등): 환경 또는 인증 저장소에
API 키가 있는지 검증합니다. 누락된 경우 실행 가능한 해결 힌트를 출력합니다.
- **자동 provider**: 먼저 로컬 모델 가용성을 확인한 다음 자동 선택 순서대로
각 원격 provider를 시도합니다.
원격/다운로드 가능한 모델 URL이 있는지 점검합니다. 없으면 원격 provider로 전환할 것을 제안합니다.
- **명시적 원격 provider** (`openai`, `voyage` 등): API 키가
환경 변수 또는 인증 저장소에 있는지 확인합니다. 없으면 실행 가능한 수정 힌트를 출력합니다.
- **자동 provider**: 먼저 로컬 모델 가용성을 점검한 다음, 자동 선택 순서대로 각 원격
provider를 시도합니다.
gateway 프로브 결과를 사용할 수 있는 경우(검사 시점에 gateway가 정상 상태였음),
doctor는 그 결과를 CLI에서 보이는 config와 교차 참조하고
불일치가 있으면 알려줍니다.
gateway 프로브 결과를 사용할 수 있는 경우(gateway가 점검 시점에 정상적이었던 경우),
doctor는 이를 CLI에서 보이는 config와 교차 확인하고
불일치 알려줍니다.
런타임에서 임베딩 준비 상태를 확인하려면 `openclaw memory status --deep`를 사용하세요.
### 14) 채널 상태 경고
gateway가 정상 상태이면 doctor는 채널 상태 프로브를 실행하고
권장 해결 방법과 함께 경고를 보고합니다.
gateway가 정상적이면, doctor는 채널 상태 프로브를 실행하고
권장 수정과 함께 경고를 보고합니다.
### 15) Supervisor config 감사 + 복구
Doctor는 설치된 supervisor config(launchd/systemd/schtasks)를 검사해
누락되었거나 오래된 기본값(예: systemd network-online 의존성
재시작 지연)이 있는지 확인합니다. 불일치를 찾으
업데이트를 권장하고 현재 기본값으로 서비스 파일/작업을 다시 쓸 수 있습니다.
Doctor는 설치된 supervisor config(launchd/systemd/schtasks)를 점검하여
누락되었거나 오래된 기본값(예: systemd network-online 의존성
재시작 지연)을 찾습니다. 불일치를 발견하
업데이트를 권장하고 서비스 파일/작업을 현재 기본값으로 다시 쓸 수 있습니다.
참고:
- `openclaw doctor`는 supervisor config를 다시 쓰기 전에 프롬프트를 표시합니다.
- `openclaw doctor --yes`는 기본 복구 프롬프트를 수락합니다.
- `openclaw doctor --repair`는 프롬프트 없이 권장 수정 사항을 적용합니다.
- `openclaw doctor --repair`는 프롬프트 없이 권장 수정을 적용합니다.
- `openclaw doctor --repair --force`는 사용자 지정 supervisor config를 덮어씁니다.
- 토큰 인증에 토큰이 필요하고 `gateway.auth.token`이 SecretRef로 관리되는 경우, doctor 서비스 설치/복구는 SecretRef를 검증하지만 해결된 일반 텍스트 토큰 값을 supervisor 서비스 환경 메타데이터에 유지하지 않습니다.
- 토큰 인증에 토큰이 필요하고 구성된 token SecretRef가 해결되지 않으면, doctor는 실행 가능한 안내와 함께 설치/복구 경로를 차단합니다.
- `gateway.auth.token``gateway.auth.password`가 모두 구성되어 있`gateway.auth.mode`가 설정되지 않은 경우, doctor는 mode가 명시적으로 설정될 때까지 설치/복구를 차단합니다.
- Linux user-systemd unit의 경우, doctor 토큰 드리프트 검사는 이제 서비스 인증 메타데이터를 비교할 때 `Environment=` `EnvironmentFile=` 소스를 모두 포함합니다.
- 언제든 `openclaw gateway install --force`를 통해 전체 다시 쓰기를 강제할 수 있습니다.
- 토큰 인증에 토큰이 필요하고 `gateway.auth.token`이 SecretRef로 관리되는 경우, doctor 서비스 설치/복구는 SecretRef를 검증하지만 해결된 평문 토큰 값을 supervisor 서비스 환경 메타데이터에 저장하지 않습니다.
- 토큰 인증에 토큰이 필요하고 구성된 토큰 SecretRef가 해결되지 않으면, doctor는 실행 가능한 안내와 함께 설치/복구 경로를 차단합니다.
- `gateway.auth.token``gateway.auth.password`가 모두 구성되어 있는데 `gateway.auth.mode`가 설정되지 않으면, doctor는 모드가 명시적으로 설정될 때까지 설치/복구를 차단합니다.
- Linux user-systemd 유닛의 경우, doctor 토큰 드리프트 점검은 이제 서비스 인증 메타데이터 비교 시 `Environment=` `EnvironmentFile=` 소스를 모두 포함합니다.
- 언제든`openclaw gateway install --force` 전체 다시 쓰기를 강제할 수 있습니다.
### 16) Gateway 런타임 + 포트 진단
Doctor는 서비스 런타임(PID, 마지막 종료 상태)을 검사하고,
서비스가 설치되어 있지만 실제로 실행 중이 아니면 경고합니다. 또한 gateway 포트
(기본값 `18789`)의 포트 충돌을 확인하고 가능한 원인(gateway가 이미 실행 중, SSH 터널)을 보고합니다.
서비스는 설치되었지만 실제로 실행 중이 아닐 때 경고합니다. 또한 gateway 포트(기본값 `18789`)의
포트 충돌을 점검하고 가능한 원인(gateway가 이미 실행 중, SSH 터널)을 보고합니다.
### 17) Gateway 런타임 모범 사례
Doctor는 gateway 서비스가 Bun 또는 버전 관리 Node 경로
(`nvm`, `fnm`, `volta`, `asdf` 등)에서 실행 중이면 경고합니다. WhatsApp + Telegram 채널은 Node가 필요하며,
버전 관리자 경로는 서비스가 셸 초기화를 로드하지 않기 때문에 업그레이드 후 깨질 수 있습니다.
시스템 Node 설치가 가능하면(Homebrew/apt/choco) 해당 설치로 마이그레이션할지 제안합니다.
Doctor는 gateway 서비스가 Bun 또는 버전 관리 Node 경로
(`nvm`, `fnm`, `volta`, `asdf` 등)에서 실행될 때 경고합니다. WhatsApp + Telegram 채널은 Node를 필요로 하며,
버전 관리자 경로는 서비스가 셸 초기화 스크립트를 로드하지 않기 때문에 업그레이드 후 깨질 수 있습니다.
사용 가능한 경우, doctor는 시스템 Node 설치(Homebrew/apt/choco)로 마이그레이션할 것을 제안합니다.
### 18) Config 기 + wizard 메타데이터
### 18) Config 기 + wizard 메타데이터
Doctor는 모든 config 변경 사항을 저장하고
doctor 실행을 기록하기 위해 wizard 메타데이터를 남깁니다.
Doctor는 모든 config 변경 사항을 저장하고 doctor 실행을 기록하기 위해
wizard 메타데이터를 기록합니다.
### 19) 워크스페이스 팁(백업 + 메모리 시스템)
### 19) Workspace 팁(백업 + 메모리 시스템)
Doctor는 누락된 경우 워크스페이스 메모리 시스템을 제안하고,
워크스페이스가 아직 git 아래에 없으면 백업 팁을 출력합니다.
Doctor는 workspace 메모리 시스템이 없으면 이를 제안하고, workspace가 아직 git 아래에 있지 않으면
백업 팁을 출력합니다.
워크스페이스 구조와 git 백업(권장: 비공개 GitHub 또는 GitLab)에 대한 전체 가이드는
workspace 구조와 git 백업(권장: 비공개 GitHub 또는 GitLab)에 대한 전체 가이드는
[/concepts/agent-workspace](/ko/concepts/agent-workspace)를 참조하세요.

File diff suppressed because it is too large Load Diff

View File

@ -1,507 +0,0 @@
---
date: 2026-04-05T00:00:00Z
status: active
title: '리팩터링: plugin-sdk를 점진적으로 실제 워크스페이스 패키지로 만들기'
type: refactor
x-i18n:
generated_at: "2026-04-07T05:58:03Z"
model: gpt-5.4
provider: openai
source_hash: ea1ca41846363c506a0db6dbca746e840d7c71ca82bbfc5277af9e2ae7f6b070
source_path: plans/2026-04-05-002-refactor-real-plugin-sdk-workspace-plan.md
workflow: 15
---
# 리팩터링: plugin-sdk를 점진적으로 실제 워크스페이스 패키지로 만들기
## 개요
이 계획은 `packages/plugin-sdk`에 plugin SDK용 실제 워크스페이스 패키지를 도입하고, 이를 사용해 소수의 1차 확장 세트에 컴파일러 강제 패키지 경계를 옵트인 방식으로 적용합니다. 목표는 선택된 번들 제공자 확장 세트에 대해 일반적인 `tsc`에서 불법 상대 import가 실패하도록 만드는 것이며, 저장소 전체 마이그레이션이나 거대한 병합 충돌 표면을 강제하지 않는 것입니다.
핵심적인 점진적 조치는 한동안 두 가지 모드를 병행 실행하는 것입니다.
| 모드 | import 형태 | 사용 대상 | 강제 방식 |
| ---- | ----------- | --------- | --------- |
| 레거시 모드 | `openclaw/plugin-sdk/*` | 기존의 모든 비옵트인 확장 | 현재의 관대한 동작 유지 |
| 옵트인 모드 | `@openclaw/plugin-sdk/*` | 1차 확장만 | 패키지 로컬 `rootDir` + 프로젝트 참조 |
## 문제 프레임
현재 저장소는 대규모 공개 plugin SDK 표면을 export하지만, 이는 실제 워크스페이스 패키지가 아닙니다. 대신 다음과 같습니다.
- 루트 `tsconfig.json``openclaw/plugin-sdk/*`
`src/plugin-sdk/*.ts`에 직접 매핑합니다.
- 이전 실험에 옵트인되지 않은 확장도 여전히 해당
전역 소스 별칭 동작을 공유합니다.
- 허용된 SDK import가 확장 패키지 외부의 원시 저장소 소스로 해석되지 않게 된 뒤에야
`rootDir` 추가가 동작합니다.
즉, 저장소는 원하는 경계 정책을 설명할 수는 있지만, TypeScript는 대부분의 확장에 대해 이를 깔끔하게 강제하지 못합니다.
필요한 것은 다음을 만족하는 점진적 경로입니다.
- `plugin-sdk`를 실제 패키지로 만들기
- SDK를 `@openclaw/plugin-sdk`라는 워크스페이스 패키지로 점진적으로 이동하기
- 첫 번째 PR에서는 약 10개의 확장만 변경하기
- 확장 트리의 나머지는 나중에 정리할 때까지 기존 방식에 남겨두기
- 1차 롤아웃의 주요 메커니즘으로 `tsconfig.plugin-sdk.dts.json` + postinstall 생성 선언 워크플로를 피하기
## 요구 사항 추적
- R1. `packages/` 아래에 plugin SDK용 실제 워크스페이스 패키지를 생성합니다.
- R2. 새 패키지 이름을 `@openclaw/plugin-sdk`로 지정합니다.
- R3. 새 SDK 패키지에 자체 `package.json``tsconfig.json`을 부여합니다.
- R4. 마이그레이션 기간 동안 비옵트인 확장에 대해 레거시 `openclaw/plugin-sdk/*` import가 계속 동작하도록 유지합니다.
- R5. 첫 번째 PR에서는 소규모 1차 확장 세트만 옵트인합니다.
- R6. 1차 확장에서는 패키지 루트를 벗어나는 상대 import가 fail-closed 되어야 합니다.
- R7. 1차 확장은 루트 `paths` 별칭이 아니라 패키지 의존성과 TS 프로젝트 참조를 통해 SDK를 사용해야 합니다.
- R8. 이 계획은 에디터 정합성을 위해 저장소 전체에 필수적인 postinstall 생성 단계를 피해야 합니다.
- R9. 1차 롤아웃은 저장소 전체 300개 이상 파일 리팩터링이 아니라, 리뷰 가능하고 병합 가능한 중간 규모 PR이어야 합니다.
## 범위 경계
- 첫 번째 PR에서 모든 번들 확장을 완전히 마이그레이션하지 않습니다.
- 첫 번째 PR에서 `src/plugin-sdk` 삭제를 요구하지 않습니다.
- 모든 루트 빌드 또는 테스트 경로를 즉시 새 패키지를 사용하도록 재배선할 필요는 없습니다.
- 모든 비옵트인 확장에 대해 VS Code squiggle을 강제하려고 하지 않습니다.
- 확장 트리 나머지 부분에 대한 광범위한 lint 정리를 하지 않습니다.
- 옵트인된 확장의 import 해석, 패키지 소유권, 경계 강제 외에 큰 런타임 동작 변경은 하지 않습니다.
## 컨텍스트 및 조사
### 관련 코드 및 패턴
- `pnpm-workspace.yaml`은 이미 `packages/*``extensions/*`를 포함하므로
`packages/plugin-sdk` 아래의 새 워크스페이스 패키지는 기존 저장소
레이아웃에 맞습니다.
- `packages/memory-host-sdk/package.json`
`packages/plugin-package-contract/package.json` 같은 기존 워크스페이스 패키지는 이미
`src/*.ts`를 루트로 하는 패키지 로컬 `exports` 맵을 사용합니다.
- 루트 `package.json`은 현재
`dist/plugin-sdk/*.js``dist/plugin-sdk/*.d.ts`를 기반으로 하는
`./plugin-sdk``./plugin-sdk/*` export를 통해 SDK 표면을 게시합니다.
- `src/plugin-sdk/entrypoints.ts``scripts/lib/plugin-sdk-entrypoints.json`
이미 SDK 표면의 정식 진입점 인벤토리 역할을 합니다.
- 루트 `tsconfig.json`은 현재 다음을 매핑합니다.
- `openclaw/plugin-sdk` -> `src/plugin-sdk/index.ts`
- `openclaw/plugin-sdk/*` -> `src/plugin-sdk/*.ts`
- 이전 경계 실험은 허용된 SDK import가 확장 패키지 외부의 원시 소스로 더 이상 해석되지 않게 된 이후에야
패키지 로컬 `rootDir`이 불법 상대 import에 대해 동작함을 보여주었습니다.
### 1차 확장 세트
이 계획은 1차 세트가 복잡한 채널 런타임 엣지 케이스를 끌어들일 가능성이 가장 적은, 제공자 중심 세트라고 가정합니다.
- `extensions/anthropic`
- `extensions/exa`
- `extensions/firecrawl`
- `extensions/groq`
- `extensions/mistral`
- `extensions/openai`
- `extensions/perplexity`
- `extensions/tavily`
- `extensions/together`
- `extensions/xai`
### 1차 SDK 표면 인벤토리
1차 확장은 현재 관리 가능한 SDK 서브패스 하위 집합을 import합니다.
초기 `@openclaw/plugin-sdk` 패키지는 다음만 포함하면 됩니다.
- `agent-runtime`
- `cli-runtime`
- `config-runtime`
- `core`
- `image-generation`
- `media-runtime`
- `media-understanding`
- `plugin-entry`
- `plugin-runtime`
- `provider-auth`
- `provider-auth-api-key`
- `provider-auth-login`
- `provider-auth-runtime`
- `provider-catalog-shared`
- `provider-entry`
- `provider-http`
- `provider-model-shared`
- `provider-onboard`
- `provider-stream-family`
- `provider-stream-shared`
- `provider-tools`
- `provider-usage`
- `provider-web-fetch`
- `provider-web-search`
- `realtime-transcription`
- `realtime-voice`
- `runtime-env`
- `secret-input`
- `security-runtime`
- `speech`
- `testing`
### 제도적 학습
- 이 작업 트리에는 관련 `docs/solutions/` 항목이 없었습니다.
### 외부 참고 자료
- 이 계획에는 외부 조사가 필요하지 않았습니다. 저장소에 이미 관련 워크스페이스 패키지 및 SDK export 패턴이 포함되어 있습니다.
## 핵심 기술 결정
- 새 워크스페이스 패키지로 `@openclaw/plugin-sdk`를 도입하면서
마이그레이션 동안 레거시 루트 `openclaw/plugin-sdk/*` 표면은 유지합니다.
근거: 이렇게 하면 모든 확장과 모든 루트 빌드 경로를 한 번에 바꾸지 않고도 1차 확장 세트를 실제 패키지 해석으로 이동시킬 수 있습니다.
- 모든 사람의 기존 확장 베이스를 대체하는 대신
`extensions/tsconfig.package-boundary.base.json` 같은 전용 옵트인 경계 베이스 구성을 사용합니다.
근거: 저장소는 마이그레이션 중 레거시 확장 모드와 옵트인 확장 모드를 동시에 지원해야 합니다.
- 1차 확장에서 `packages/plugin-sdk/tsconfig.json`으로의 TS 프로젝트 참조를 사용하고
옵트인 경계 모드에 대해 `disableSourceOfProjectReferenceRedirect`를 설정합니다.
근거: 이렇게 하면 `tsc`에 실제 패키지 그래프를 제공하면서, 에디터와 컴파일러가 원시 소스 순회로 되돌아가는 것을 억제할 수 있습니다.
- 1차 단계에서는 `@openclaw/plugin-sdk`를 private로 유지합니다.
근거: 즉각적인 목표는 표면이 안정되기 전 제2의 외부 SDK 계약을 게시하는 것이 아니라, 내부 경계 강제와 마이그레이션 안전성입니다.
- 첫 구현 슬라이스에서는 1차 SDK 서브패스만 이동하고,
나머지는 호환성 브리지를 유지합니다.
근거: `src/plugin-sdk/*.ts`의 315개 파일 전체를 하나의 PR에서 물리적으로 이동하는 것은
이 계획이 피하려는 바로 그 병합 충돌 표면입니다.
- 1차 단계에서는 `scripts/postinstall-bundled-plugins.mjs`에 의존해
SDK 선언을 빌드하지 않습니다.
근거: 명시적인 빌드/참조 흐름이 이해하기 쉽고 저장소 동작을 더 예측 가능하게 유지합니다.
## 열린 질문
### 계획 수립 중 해결됨
- 어떤 확장을 1차에 포함해야 하는가?
위에 나열된 10개의 provider/web-search 확장을 사용합니다. 더 무거운 채널 패키지보다 구조적으로 더 격리되어 있기 때문입니다.
- 첫 번째 PR이 전체 확장 트리를 대체해야 하는가?
아니요. 첫 번째 PR은 두 가지 모드를 병렬로 지원하고 1차 세트만 옵트인해야 합니다.
- 1차에 postinstall 선언 빌드가 필요한가?
아니요. 패키지/참조 그래프는 명시적이어야 하며, CI는 관련 패키지 로컬 타입체크를 의도적으로 실행해야 합니다.
### 구현으로 연기됨
- 1차 패키지가 프로젝트 참조만으로 패키지 로컬 `src/*.ts`를 직접 가리킬 수 있는지, 아니면 `@openclaw/plugin-sdk` 패키지에 여전히 소규모 선언 방출 단계가 필요한지 여부
이는 구현이 소유하는 TS 그래프 검증 질문입니다.
- 루트 `openclaw` 패키지가 1차 SDK 서브패스를 즉시 `packages/plugin-sdk` 출력으로 프록시해야 하는지, 아니면 계속
`src/plugin-sdk` 아래 생성된 호환성 shim을 사용할지 여부
이는 CI를 녹색 상태로 유지하는 최소 구현 경로에 따라 달라지는 호환성 및 빌드 형태 세부 사항입니다.
## 상위 수준 기술 설계
> 이는 의도된 접근 방식을 설명하는 것으로, 구현 명세가 아니라 리뷰를 위한 방향성 가이드입니다. 구현 에이전트는 이를 재현할 코드가 아니라 컨텍스트로 취급해야 합니다.
```mermaid
flowchart TB
subgraph Legacy["레거시 확장(변경 없음)"]
L1["extensions/*\nopenclaw/plugin-sdk/*"]
L2["root tsconfig paths"]
L1 --> L2
L2 --> L3["src/plugin-sdk/*"]
end
subgraph OptIn["1차 확장"]
O1["옵트인된 10개 확장"]
O2["extensions/tsconfig.package-boundary.base.json"]
O3["rootDir = '.'\nproject reference"]
O4["@openclaw/plugin-sdk"]
O1 --> O2
O2 --> O3
O3 --> O4
end
subgraph SDK["새 워크스페이스 패키지"]
P1["packages/plugin-sdk/package.json"]
P2["packages/plugin-sdk/tsconfig.json"]
P3["packages/plugin-sdk/src/<first-wave-subpaths>.ts"]
P1 --> P2
P2 --> P3
end
O4 --> SDK
```
## 구현 단위
- [ ] **단위 1: 실제 `@openclaw/plugin-sdk` 워크스페이스 패키지 도입**
**목표:** 저장소 전체 마이그레이션을 강제하지 않고도 1차 서브패스 표면을 소유할 수 있는 SDK용 실제 워크스페이스 패키지를 만듭니다.
**요구 사항:** R1, R2, R3, R8, R9
**의존성:** 없음
**파일:**
- 생성: `packages/plugin-sdk/package.json`
- 생성: `packages/plugin-sdk/tsconfig.json`
- 생성: `packages/plugin-sdk/src/index.ts`
- 생성: 1차 SDK 서브패스를 위한 `packages/plugin-sdk/src/*.ts`
- 수정: 패키지 글롭 조정이 필요한 경우에만 `pnpm-workspace.yaml`
- 수정: `package.json`
- 수정: `src/plugin-sdk/entrypoints.ts`
- 수정: `scripts/lib/plugin-sdk-entrypoints.json`
- 테스트: `src/plugins/contracts/plugin-sdk-workspace-package.contract.test.ts`
**접근 방식:**
- `@openclaw/plugin-sdk`라는 새 워크스페이스 패키지를 추가합니다.
- 전체 315개 파일 트리가 아니라 1차 SDK 서브패스만으로 시작합니다.
- 1차 진입점을 직접 이동하면 diff가 과도하게 커지는 경우,
첫 번째 PR에서는 먼저 `packages/plugin-sdk/src`에 해당 서브패스를 얇은
패키지 래퍼로 도입한 뒤, 후속 PR에서 해당 서브패스 클러스터의 source of truth를 패키지로 전환할 수 있습니다.
- 기존 진입점 인벤토리 메커니즘을 재사용하여 1차 패키지 표면이 하나의 정식 위치에 선언되도록 합니다.
- 워크스페이스 패키지가 새로운 옵트인 계약이 되는 동안 레거시 사용자를 위한 루트 패키지 export는 유지합니다.
**따를 패턴:**
- `packages/memory-host-sdk/package.json`
- `packages/plugin-package-contract/package.json`
- `src/plugin-sdk/entrypoints.ts`
**테스트 시나리오:**
- 정상 경로: 워크스페이스 패키지가 계획에 나열된 모든 1차 서브패스를 export하며 필요한 1차 export가 누락되지 않습니다.
- 엣지 케이스: 1차 진입점 목록이 재생성되거나 정식 인벤토리와 비교될 때 패키지 export 메타데이터가 안정적으로 유지됩니다.
- 통합: 새 워크스페이스 패키지를 도입한 뒤에도 루트 패키지의 레거시 SDK export가 계속 존재합니다.
**검증:**
- 저장소에 안정적인 1차 export 맵을 갖춘 유효한 `@openclaw/plugin-sdk` 워크스페이스 패키지가 존재하며, 루트 `package.json`에 레거시 export 회귀가 없습니다.
- [ ] **단위 2: 패키지 강제 확장을 위한 옵트인 TS 경계 모드 추가**
**목표:** 옵트인된 확장이 사용할 TS 구성 모드를 정의하면서, 다른 모든 확장에 대한 기존 확장 TS 동작은 변경하지 않습니다.
**요구 사항:** R4, R6, R7, R8, R9
**의존성:** 단위 1
**파일:**
- 생성: `extensions/tsconfig.package-boundary.base.json`
- 생성: `tsconfig.boundary-optin.json`
- 수정: `extensions/xai/tsconfig.json`
- 수정: `extensions/openai/tsconfig.json`
- 수정: `extensions/anthropic/tsconfig.json`
- 수정: `extensions/mistral/tsconfig.json`
- 수정: `extensions/groq/tsconfig.json`
- 수정: `extensions/together/tsconfig.json`
- 수정: `extensions/perplexity/tsconfig.json`
- 수정: `extensions/tavily/tsconfig.json`
- 수정: `extensions/exa/tsconfig.json`
- 수정: `extensions/firecrawl/tsconfig.json`
- 테스트: `src/plugins/contracts/extension-package-project-boundaries.test.ts`
- 테스트: `test/extension-package-tsc-boundary.test.ts`
**접근 방식:**
- 레거시 확장을 위해 `extensions/tsconfig.base.json`은 그대로 둡니다.
- 다음을 수행하는 새 옵트인 베이스 구성을 추가합니다.
- `rootDir: "."` 설정
- `packages/plugin-sdk` 참조
- `composite` 활성화
- 필요 시 프로젝트 참조 소스 리디렉션 비활성화
- 같은 PR에서 루트 저장소 TS 프로젝트를 재구성하는 대신,
1차 타입체크 그래프를 위한 전용 솔루션 구성을 추가합니다.
**실행 참고:** 이 패턴을 10개 전체에 적용하기 전에
옵트인된 확장 하나에 대해 실패하는 패키지 로컬 카나리 타입체크부터 시작합니다.
**따를 패턴:**
- 이전 경계 작업의 기존 패키지 로컬 확장 `tsconfig.json` 패턴
- `packages/memory-host-sdk`의 워크스페이스 패키지 패턴
**테스트 시나리오:**
- 정상 경로: 각 옵트인 확장이 패키지 경계 TS 구성을 통해 성공적으로 타입체크됩니다.
- 오류 경로: 옵트인된 확장에서 `../../src/cli/acp-cli.ts`로의 카나리 상대 import가 `TS6059`로 실패합니다.
- 통합: 비옵트인 확장은 영향을 받지 않으며 새 솔루션 구성에 참여할 필요가 없습니다.
**검증:**
- 10개의 옵트인 확장을 위한 전용 타입체크 그래프가 존재하며, 그중 하나에서 잘못된 상대 import는 일반 `tsc`를 통해 실패합니다.
- [ ] **단위 3: 1차 확장을 `@openclaw/plugin-sdk`로 마이그레이션**
**목표:** 1차 확장이 패키지 의존성 메타데이터, 프로젝트 참조, 패키지명 import를 통해 실제 SDK 패키지를 사용하도록 변경합니다.
**요구 사항:** R5, R6, R7, R9
**의존성:** 단위 2
**파일:**
- 수정: `extensions/anthropic/package.json`
- 수정: `extensions/exa/package.json`
- 수정: `extensions/firecrawl/package.json`
- 수정: `extensions/groq/package.json`
- 수정: `extensions/mistral/package.json`
- 수정: `extensions/openai/package.json`
- 수정: `extensions/perplexity/package.json`
- 수정: `extensions/tavily/package.json`
- 수정: `extensions/together/package.json`
- 수정: `extensions/xai/package.json`
- 수정: 현재 `openclaw/plugin-sdk/*`를 참조하는 각 10개 확장 루트 아래의 프로덕션 및 테스트 import
**접근 방식:**
- 1차 확장의 `devDependencies`
`@openclaw/plugin-sdk: workspace:*`를 추가합니다.
- 해당 패키지의 `openclaw/plugin-sdk/*` import를
`@openclaw/plugin-sdk/*`로 교체합니다.
- 로컬 확장 내부 import는 `./api.ts``./runtime-api.ts` 같은 로컬 배럴에 유지합니다.
- 이 PR에서는 비옵트인 확장은 변경하지 않습니다.
**따를 패턴:**
- 기존 확장 로컬 import 배럴(`api.ts`, `runtime-api.ts`)
- 다른 `@openclaw/*` 워크스페이스 패키지에서 사용하는 패키지 의존성 형태
**테스트 시나리오:**
- 정상 경로: 마이그레이션된 각 확장이 import 재작성 후에도 기존 플러그인 테스트를 통해 계속 등록/로드됩니다.
- 엣지 케이스: 옵트인 확장 세트의 테스트 전용 SDK import도 새 패키지를 통해 올바르게 해석됩니다.
- 통합: 마이그레이션된 확장은 타입체크를 위해 루트 `openclaw/plugin-sdk/*` 별칭 경로를 필요로 하지 않습니다.
**검증:**
- 1차 확장은 레거시 루트 SDK 별칭 경로 없이 `@openclaw/plugin-sdk`를 기준으로 빌드 및 테스트됩니다.
- [ ] **단위 4: 부분 마이그레이션 중 레거시 호환성 유지**
**목표:** 마이그레이션 중 SDK가 레거시와 새 패키지 형태로 공존하는 동안 저장소의 나머지 부분이 계속 동작하도록 유지합니다.
**요구 사항:** R4, R8, R9
**의존성:** 단위 1-3
**파일:**
- 수정: 필요 시 1차 호환성 shim을 위한 `src/plugin-sdk/*.ts`
- 수정: `package.json`
- 수정: SDK 아티팩트를 조립하는 빌드 또는 export 배관
- 테스트: `src/plugins/contracts/plugin-sdk-runtime-api-guardrails.test.ts`
- 테스트: `src/plugins/contracts/plugin-sdk-index.bundle.test.ts`
**접근 방식:**
- 아직 이동하지 않은 레거시 확장 및 외부 소비자를 위해
루트 `openclaw/plugin-sdk/*`를 호환성 표면으로 유지합니다.
- `packages/plugin-sdk`로 이동한 1차 서브패스에는 생성된 shim 또는 루트 export 프록시 배선을 사용합니다.
- 이 단계에서 루트 SDK 표면을 폐기하려고 하지 않습니다.
**따를 패턴:**
- `src/plugin-sdk/entrypoints.ts`를 통한 기존 루트 SDK export 생성
- 루트 `package.json`의 기존 패키지 export 호환성
**테스트 시나리오:**
- 정상 경로: 새 패키지가 존재한 뒤에도 비옵트인 확장에 대해 레거시 루트 SDK import가 계속 해석됩니다.
- 엣지 케이스: 1차 서브패스가 마이그레이션 기간 동안 레거시 루트 표면과 새 패키지 표면 모두를 통해 동작합니다.
- 통합: plugin-sdk index/bundle 계약 테스트가 계속 일관된 공개 표면을 확인합니다.
**검증:**
- 저장소는 변경되지 않은 확장을 깨뜨리지 않으면서 레거시와 옵트인 SDK 소비 모드를 모두 지원합니다.
- [ ] **단위 5: 범위 지정 강제 추가 및 마이그레이션 계약 문서화**
**목표:** 전체 확장 트리가 마이그레이션되었다고 가장하지 않으면서, 1차 세트에 대한 새 동작을 강제하는 CI 및 기여자 가이드를 도입합니다.
**요구 사항:** R5, R6, R8, R9
**의존성:** 단위 1-4
**파일:**
- 수정: `package.json`
- 수정: 옵트인 경계 타입체크를 실행해야 하는 CI 워크플로 파일
- 수정: `AGENTS.md`
- 수정: `docs/plugins/sdk-overview.md`
- 수정: `docs/plugins/sdk-entrypoints.md`
- 수정: `docs/plans/2026-04-05-001-refactor-extension-package-resolution-boundary-plan.md`
**접근 방식:**
- `packages/plugin-sdk`와 10개의 옵트인 확장에 대해 전용 `tsc -b` 솔루션 실행 같은 명시적인 1차 게이트를 추가합니다.
- 저장소가 이제 레거시와 옵트인 확장 모드를 모두 지원하며, 새 확장 경계 작업은 새 패키지 경로를 우선 사용해야 한다고 문서화합니다.
- 이후 PR이 아키텍처를 다시 논쟁하지 않고 더 많은 확장을 추가할 수 있도록 다음 웨이브 마이그레이션 규칙을 기록합니다.
**따를 패턴:**
- `src/plugins/contracts/` 아래의 기존 계약 테스트
- 단계적 마이그레이션을 설명하는 기존 문서 업데이트
**테스트 시나리오:**
- 정상 경로: 새 1차 타입체크 게이트가 워크스페이스 패키지와 옵트인 확장에 대해 통과합니다.
- 오류 경로: 옵트인 확장에 새 불법 상대 import를 도입하면 범위 지정 타입체크 게이트가 실패합니다.
- 통합: CI는 아직 비옵트인 확장에 대해 새 패키지 경계 모드를 요구하지 않습니다.
**검증:**
- 1차 강제 경로는 전체 확장 트리 마이그레이션을 강제하지 않고도 문서화되고, 테스트되며, 실행 가능합니다.
## 시스템 전반 영향
- **상호작용 그래프:** 이 작업은 SDK source of truth, 루트 패키지 export, 확장 패키지 메타데이터, TS 그래프 레이아웃, CI 검증에 영향을 줍니다.
- **오류 전파:** 주요 의도된 실패 모드는 옵트인 확장에서 사용자 지정 스크립트 전용 실패가 아니라 컴파일 타임 TS 오류(`TS6059`)가 됩니다.
- **상태 수명 주기 위험:** 이중 표면 마이그레이션은 루트 호환성 export와 새 워크스페이스 패키지 사이의 드리프트 위험을 도입합니다.
- **API 표면 동등성:** 전환 중 1차 서브패스는 `openclaw/plugin-sdk/*``@openclaw/plugin-sdk/*`를 통해 의미적으로 동일해야 합니다.
- **통합 범위:** 경계를 증명하려면 단위 테스트만으로는 충분하지 않으며, 범위 지정 패키지 그래프 타입체크가 필요합니다.
- **변경되지 않는 불변 조건:** 비옵트인 확장은 PR 1에서 현재 동작을 유지합니다. 이 계획은 저장소 전체 import 경계 강제를 주장하지 않습니다.
## 위험 및 의존성
| 위험 | 완화책 |
| ---- | ------ |
| 1차 패키지가 여전히 원시 소스로 다시 해석되어 `rootDir`이 실제로 fail-closed 되지 않음 | 첫 구현 단계를 전체 세트로 확대하기 전에, 옵트인 확장 하나에 대한 패키지 참조 카나리로 만듭니다 |
| SDK 소스를 한 번에 너무 많이 이동하여 원래의 병합 충돌 문제가 다시 생김 | 첫 번째 PR에서는 1차 서브패스만 이동하고 루트 호환성 브리지를 유지합니다 |
| 레거시 및 새 SDK 표면이 의미적으로 드리프트함 | 단일 진입점 인벤토리를 유지하고, 호환성 계약 테스트를 추가하며, 이중 표면 동등성을 명시적으로 만듭니다 |
| 루트 저장소의 빌드/테스트 경로가 통제되지 않은 방식으로 우연히 새 패키지에 의존하기 시작함 | 전용 옵트인 솔루션 구성을 사용하고, 첫 번째 PR에서는 루트 전체 TS 토폴로지 변경을 제외합니다 |
## 단계별 전달
### 1단계
- `@openclaw/plugin-sdk` 도입
- 1차 서브패스 표면 정의
- 하나의 옵트인 확장이 `rootDir`을 통해 fail-closed 될 수 있음을 증명
### 2단계
- 10개의 1차 확장을 옵트인
- 나머지 모두를 위해 루트 호환성 유지
### 3단계
- 이후 PR에서 더 많은 확장 추가
- 더 많은 SDK 서브패스를 워크스페이스 패키지로 이동
- 레거시 확장 세트가 사라진 뒤에만 루트 호환성 폐기
## 문서 / 운영 참고 사항
- 첫 번째 PR은 자신을 저장소 전체 강제 완료가 아니라, 이중 모드 마이그레이션으로 명시적으로 설명해야 합니다.
- 마이그레이션 가이드는 이후 PR이 동일한 패키지/의존성/참조 패턴을 따라 더 많은 확장을 쉽게 추가할 수 있게 해야 합니다.
## 소스 및 참고 자료
- 이전 계획: `docs/plans/2026-04-05-001-refactor-extension-package-resolution-boundary-plan.md`
- 워크스페이스 구성: `pnpm-workspace.yaml`
- 기존 SDK 진입점 인벤토리: `src/plugin-sdk/entrypoints.ts`
- 기존 루트 SDK export: `package.json`
- 기존 워크스페이스 패키지 패턴:
- `packages/memory-host-sdk/package.json`
- `packages/plugin-package-contract/package.json`

File diff suppressed because it is too large Load Diff

View File

@ -1,73 +1,64 @@
---
read_when:
- OpenClaw plugin을 빌드할 때
- plugin config schema를 배포하거나 plugin 검증 오류를 디버깅해야 할 때
summary: Plugin 매니페스트 + JSON schema 요구 사항(엄격한 config 검증)
- OpenClaw plugin을 빌드하고 있습니다
- plugin 구성 스키마를 배포하거나 plugin 검증 오류를 디버그해야 합니다
summary: Plugin 매니페스트 + JSON Schema 요구 사항(엄격한 구성 검증)
title: Plugin 매니페스트
x-i18n:
generated_at: "2026-04-07T05:58:49Z"
generated_at: "2026-04-09T01:29:23Z"
model: gpt-5.4
provider: openai
source_hash: 22d41b9f8748b1b1b066ee856be4a8f41e88b9a8bc073d74fc79d2bb0982f01a
source_hash: 9a7ee4b621a801d2a8f32f8976b0e1d9433c7810eb360aca466031fc0ffb286a
source_path: plugins/manifest.md
workflow: 15
---
# Plugin 매니페스트 (openclaw.plugin.json)
# Plugin 매니페스트(openclaw.plugin.json)
이 페이지는 **네이티브 OpenClaw plugin 매니페스트**만을 위한 문서입니다.
이 페이지는 **네이티브 OpenClaw plugin 매니페스트** 전용입니다.
호환되는 번들 레이아웃은 [Plugin bundles](/ko/plugins/bundles)를 참하세요.
호환되는 번들 레이아웃은 [Plugin bundles](/ko/plugins/bundles)를 참하세요.
호환 번들 형식은 서로 다른 매니페스트 파일을 사용합니다:
호환되는 번들 형식은 서로 다른 매니페스트 파일을 사용합니다.
- Codex 번들: `.codex-plugin/plugin.json`
- Claude 번들: `.claude-plugin/plugin.json` 또는 매니페스트가 없는 기본 Claude component
레이아웃
- Cursor 번들: `.cursor-plugin/plugin.json`
OpenClaw는 해당 번들 레이아웃도 자동 감지하지만, 여기서 설명하는
`openclaw.plugin.json` schema에 대해 검증되지는 않습니다.
OpenClaw는 이러한 번들 레이아웃도 자동 감지하지만, 여기서 설명하는 `openclaw.plugin.json` 스키마에 대해서는 검증하지 않습니다.
호환 번들의 경우 OpenClaw는 현재 번들 메타데이터와 선언된
skill 루트, Claude 명령 루트, Claude 번들 `settings.json` 기본값,
Claude 번들 LSP 기본값, 그리고 레이아웃이
OpenClaw 런타임 기대 사항과 일치할 때 지원되는 hook pack을 읽습니다.
호환 번들의 경우, OpenClaw는 현재 레이아웃이 OpenClaw 런타임 기대 사항과 일치할 때 번들 메타데이터와 선언된 skill 루트, Claude command 루트, Claude 번들 `settings.json` 기본값, Claude 번들 LSP 기본값, 지원되는 hook pack을 읽습니다.
모든 네이티브 OpenClaw plugin은 **plugin 루트**에 `openclaw.plugin.json` 파일을
반드시 포함해야 합니다. OpenClaw는 이 매니페스트를 사용해 plugin 코드를
**실행하지 않고도** 구성을 검증합니다. 매니페스트가 없거나 유효하지 않으면
plugin 오류로 처리되며 config 검증이 차단됩니다.
모든 네이티브 OpenClaw plugin은 **plugin 루트**에 `openclaw.plugin.json` 파일을 **반드시** 포함해야 합니다. OpenClaw는 이 매니페스트를 사용해 **plugin 코드를 실행하지 않고도** 구성을 검증합니다. 매니페스트가 없거나 유효하지 않으면 plugin 오류로 처리되며 구성 검증이 차단됩니다.
전체 plugin 시스템 가이드는 [Plugins](/ko/tools/plugin)를 참고하세요.
네이티브 capability 모델과 현재 외부 호환성 안내는
[Capability model](/ko/plugins/architecture#public-capability-model)을 참고하세요.
전체 plugin 시스템 가이드는 [Plugins](/ko/tools/plugin)를 참조하세요.
네이티브 capability 모델과 현재 외부 호환성 지침은 [Capability model](/ko/plugins/architecture#public-capability-model)을 참조하세요.
## 이 파일의 역할
`openclaw.plugin.json`은 OpenClaw가 plugin 코드를 로드하기 전에 읽는
메타데이터입니다.
`openclaw.plugin.json`은 OpenClaw가 plugin 코드를 로드하기 전에 읽는 메타데이터입니다.
다음 용도로 사용하세요:
다음 용도로 사용하세요.
- plugin 식별자
- config 검증
- plugin 런타임을 부팅하지 않고도 사용할 수 있어야 하는 인증 및 온보딩 메타데이터
- plugin 런타임 로드되기 전에 해석되어야 하는 별칭 및 자동 활성화 메타데이터
- 런타임이 로드되기 전에 plugin을 자동 활성화해야 하는 축약형 모델 계열 소유 메타데이터
- 번들 compat 배선과 contract 커버리지에 사용되는 정적 capability 소유 스냅샷
- 런타임을 로드하지 않고 catalog 및 검증 표면에 병합되어야 하는 채널별 config 메타데이터
- 구성 검증
- plugin 런타임을 부팅하지 않고도 사용할 수 있어야 하는 auth 및 onboarding 메타데이터
- plugin 런타임 로드 전에 해석되어야 하는 별칭 및 자동 활성화 메타데이터
- 런타임 로드 전에 plugin을 자동 활성화해야 하는 shorthand model-family 소유 메타데이터
- 번들 compat wiring 및 계약 커버리지에 사용되는 정적 capability 소유 스냅샷
- 런타임을 로드하지 않고 catalog 및 검증 표면에 병합되어야 하는 채널별 구성 메타데이터
- config UI 힌트
다음 용도로는 사용하지 마세요:
다음 용도로는 사용하지 마세요.
- 런타임 동작 등록
- 코드 엔트리포인트 선언
- 코드 entrypoint 선언
- npm 설치 메타데이터
러한 항목은 plugin 코드와 `package.json`에 속합니다.
은 plugin 코드와 `package.json`에 속합니다.
## 최소 예
## 최소 예
```json
{
@ -80,7 +71,7 @@ plugin 오류로 처리되며 config 검증이 차단됩니다.
}
```
## 상세 예시
## 자세한 예제
```json
{
@ -96,6 +87,9 @@ plugin 오류로 처리되며 config 검증이 차단됩니다.
"providerAuthEnvVars": {
"openrouter": ["OPENROUTER_API_KEY"]
},
"providerAuthAliases": {
"openrouter-coding": "openrouter"
},
"channelEnvVars": {
"openrouter-chatops": ["OPENROUTER_CHATOPS_TOKEN"]
},
@ -135,63 +129,64 @@ plugin 오류로 처리되며 config 검증이 차단됩니다.
## 최상위 필드 참조
| Field | Required | Type | What it means |
| ----------------------------------- | -------- | -------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `id` | Yes | `string` | 정식 plugin id입니다. 이 id는 `plugins.entries.<id>`에서 사용됩니다. |
| `configSchema` | Yes | `object` | 이 plugin config용 인라인 JSON Schema입니다. |
| `enabledByDefault` | No | `true` | 번들 plugin을 기본적으로 활성화된 것으로 표시합니다. 기본 비활성 상태로 두려면 생략하거나 `true`가 아닌 값을 설정하세요. |
| `legacyPluginIds` | No | `string[]` | 이 정식 plugin id로 정규화되는 레거시 id입니다. |
| `autoEnableWhenConfiguredProviders` | No | `string[]` | 인증, config 또는 모델 참조에서 해당 provider id가 언급될 때 이 plugin을 자동 활성화해야 하는 provider id입니다. |
| `kind` | No | `"memory"` \| `"context-engine"` | `plugins.slots.*`에서 사용하는 배타적 plugin kind를 선언합니다. |
| `channels` | No | `string[]` | 이 plugin이 소유하는 채널 id입니다. 검색 및 config 검증에 사용됩니다. |
| `providers` | No | `string[]` | 이 plugin이 소유하는 provider id입니다. |
| `modelSupport` | No | `object` | 런타임 전에 plugin을 자동 로드하는 데 사용되는, 매니페스트 소유 축약형 모델 계열 메타데이터입니다. |
| `cliBackends` | No | `string[]` | 이 plugin이 소유하는 CLI 추론 backend id입니다. 명시적 config 참조에 따른 시작 시 자동 활성화에 사용됩니다. |
| `providerAuthEnvVars` | No | `Record<string, string[]>` | OpenClaw가 plugin 코드를 로드하지 않고도 확인할 수 있는 저비용 provider 인증 env 메타데이터입니다. |
| `channelEnvVars` | No | `Record<string, string[]>` | OpenClaw가 plugin 코드를 로드하지 않고도 확인할 수 있는 저비용 채널 env 메타데이터입니다. 일반적인 시작/config 도우미가 확인해야 하는 env 기반 채널 설정 또는 인증 표면에 사용하세요. |
| `providerAuthChoices` | No | `object[]` | 온보딩 선택기, 선호 provider 해석, 간단한 CLI 플래그 연결을 위한 저비용 인증 선택 메타데이터입니다. |
| `contracts` | No | `object` | 음성, 실시간 전사, 실시간 음성, media-understanding, image-generation, music-generation, video-generation, web-fetch, 웹 검색, 도구 소유권에 대한 정적 번들 capability 스냅샷입니다. |
| `channelConfigs` | No | `Record<string, object>` | 런타임 로드 전에 검색 및 검증 표면에 병합되는, 매니페스트 소유 채널 config 메타데이터입니다. |
| `skills` | No | `string[]` | plugin 루트를 기준으로 한, 로드할 skill 디렉터리입니다. |
| `name` | No | `string` | 사람이 읽을 수 있는 plugin 이름입니다. |
| `description` | No | `string` | plugin 표면에 표시되는 짧은 요약입니다. |
| `version` | No | `string` | 정보 제공용 plugin 버전입니다. |
| `uiHints` | No | `Record<string, object>` | config 필드를 위한 UI 라벨, placeholder, 민감도 힌트입니다. |
| Field | Required | Type | 의미 |
| ----------------------------------- | -------- | -------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id` | Yes | `string` | 정식 plugin id입니다. 이 id는 `plugins.entries.<id>`에서 사용됩니다. |
| `configSchema` | Yes | `object` | 이 plugin 구성에 대한 인라인 JSON Schema입니다. |
| `enabledByDefault` | No | `true` | 번들 plugin을 기본적으로 활성화된 것으로 표시합니다. 기본적으로 비활성화 상태로 두려면 생략하거나 `true`가 아닌 값을 설정하세요. |
| `legacyPluginIds` | No | `string[]` | 이 정식 plugin id로 정규화되는 레거시 id입니다. |
| `autoEnableWhenConfiguredProviders` | No | `string[]` | auth, config 또는 model ref에서 해당 provider id를 언급할 때 이 plugin을 자동 활성화해야 하는 provider id입니다. |
| `kind` | No | `"memory"` \| `"context-engine"` | `plugins.slots.*`에서 사용하는 배타적 plugin kind를 선언합니다. |
| `channels` | No | `string[]` | 이 plugin이 소유한 channel id입니다. 검색 및 구성 검증에 사용됩니다. |
| `providers` | No | `string[]` | 이 plugin이 소유한 provider id입니다. |
| `modelSupport` | No | `object` | 런타임 전에 plugin을 자동 로드하는 데 사용되는 매니페스트 소유 shorthand model-family 메타데이터입니다. |
| `cliBackends` | No | `string[]` | 이 plugin이 소유한 CLI inference backend id입니다. 명시적 config ref를 기준으로 시작 시 자동 활성화하는 데 사용됩니다. |
| `providerAuthEnvVars` | No | `Record<string, string[]>` | OpenClaw가 plugin 코드를 로드하지 않고도 검사할 수 있는 저비용 provider-auth env 메타데이터입니다. |
| `providerAuthAliases` | No | `Record<string, string>` | auth 조회를 위해 다른 provider id를 재사용해야 하는 provider id입니다. 예를 들어 기본 provider API 키와 auth 프로필을 공유하는 코딩 provider가 해당됩니다. |
| `channelEnvVars` | No | `Record<string, string[]>` | OpenClaw가 plugin 코드를 로드하지 않고도 검사할 수 있는 저비용 channel env 메타데이터입니다. env 기반 channel 설정 또는 범용 startup/config helper가 확인해야 하는 auth 표면에 사용하세요. |
| `providerAuthChoices` | No | `object[]` | onboarding 선택기, 선호 provider 결정, 간단한 CLI 플래그 wiring을 위한 저비용 auth-choice 메타데이터입니다. |
| `contracts` | No | `object` | speech, realtime transcription, realtime voice, media-understanding, image-generation, music-generation, video-generation, web-fetch, web search 및 tool 소유권에 대한 정적 번들 capability 스냅샷입니다. |
| `channelConfigs` | No | `Record<string, object>` | 런타임이 로드되기 전에 검색 및 검증 표면에 병합되는 매니페스트 소유 channel config 메타데이터입니다. |
| `skills` | No | `string[]` | plugin 루트를 기준으로 로드할 skill 디렉터리입니다. |
| `name` | No | `string` | 사람이 읽을 수 있는 plugin 이름입니다. |
| `description` | No | `string` | plugin 표면에 표시되는 짧은 요약입니다. |
| `version` | No | `string` | 정보 제공용 plugin 버전입니다. |
| `uiHints` | No | `Record<string, object>` | 구성 필드에 대한 UI 레이블, placeholder, 민감도 힌트입니다. |
## providerAuthChoices 참조
`providerAuthChoices` 항목은 하나의 온보딩 또는 인증 선택을 설명합니다.
`providerAuthChoices` 항목은 하나의 onboarding 또는 auth 선택지를 설명합니다.
OpenClaw는 provider 런타임이 로드되기 전에 이를 읽습니다.
| Field | Required | Type | What it means |
| --------------------- | -------- | ----------------------------------------------- | -------------------------------------------------------------------------------------------------------- |
| `provider` | Yes | `string` | 이 선택이 속하는 provider id입니다. |
| `method` | Yes | `string` | 디스패치할 인증 방식 id입니다. |
| `choiceId` | Yes | `string` | 온보딩 및 CLI 흐름에서 사용되는 안정적인 인증 선택 id입니다. |
| `choiceLabel` | No | `string` | 사용자 대상 라벨입니다. 생략되면 OpenClaw는 `choiceId`로 폴백합니다. |
| `choiceHint` | No | `string` | 선택기를 위한 짧은 도움말 텍스트입니다. |
| `assistantPriority` | No | `number` | assistant 기반 대화형 선택기에서 값이 낮을수록 먼저 정렬됩니다. |
| `assistantVisibility` | No | `"visible"` \| `"manual-only"` | 수동 CLI 선택은 허용하면서 assistant 선택기에서는 이 선택을 숨깁니다. |
| `deprecatedChoiceIds` | No | `string[]` | 사용자를 이 대체 선택로 리디렉션해야 하는 레거시 choice id입니다. |
| `groupId` | No | `string` | 관련 선택 그룹화하기 위한 선택적 group id입니다. |
| `groupLabel` | No | `string` | 해당 그룹의 사용자 대상 라벨입니다. |
| `groupHint` | No | `string` | 그룹을 위한 짧은 도움말 텍스트입니다. |
| `optionKey` | No | `string` | 간단한 단일 플래그 인증 흐름용 내부 옵션 키입니다. |
| `cliFlag` | No | `string` | `--openrouter-api-key` 같은 CLI 플래그 이름입니다. |
| `cliOption` | No | `string` | `--openrouter-api-key <key>` 같은 전체 CLI 옵션 형태입니다. |
| `cliDescription` | No | `string` | CLI 도움말에 사용되는 설명입니다. |
| `onboardingScopes` | No | `Array<"text-inference" \| "image-generation">` | 이 선택이 표시되어야 하는 온보딩 표면입니다. 생략하면 기본값은 `["text-inference"]`입니다. |
| Field | Required | Type | 의미 |
| --------------------- | -------- | ----------------------------------------------- | ------------------------------------------------------------------------------------------------ |
| `provider` | Yes | `string` | 이 선택지가 속한 provider id입니다. |
| `method` | Yes | `string` | 전달할 auth method id입니다. |
| `choiceId` | Yes | `string` | onboarding 및 CLI 흐름에서 사용하는 안정적인 auth-choice id입니다. |
| `choiceLabel` | No | `string` | 사용자용 레이블입니다. 생략하면 OpenClaw는 `choiceId`로 폴백합니다. |
| `choiceHint` | No | `string` | 선택기에 표시할 짧은 도움말 텍스트입니다. |
| `assistantPriority` | No | `number` | assistant 기반 대화형 선택기에서 더 낮은 값이 먼저 정렬됩니다. |
| `assistantVisibility` | No | `"visible"` \| `"manual-only"` | assistant 선택기에서는 숨기되 수동 CLI 선택은 계속 허용합니다. |
| `deprecatedChoiceIds` | No | `string[]` | 사용자를 이 대체 선택로 리디렉션해야 하는 레거시 choice id입니다. |
| `groupId` | No | `string` | 관련 선택지를 그룹화하기 위한 선택적 group id입니다. |
| `groupLabel` | No | `string` | 해당 그룹의 사용자용 레이블입니다. |
| `groupHint` | No | `string` | 그룹에 대한 짧은 도움말 텍스트입니다. |
| `optionKey` | No | `string` | 간단한 단일 플래그 auth 흐름을 위한 내부 option key입니다. |
| `cliFlag` | No | `string` | `--openrouter-api-key` 같은 CLI 플래그 이름입니다. |
| `cliOption` | No | `string` | `--openrouter-api-key <key>` 같은 전체 CLI option 형태입니다. |
| `cliDescription` | No | `string` | CLI help에 사용되는 설명입니다. |
| `onboardingScopes` | No | `Array<"text-inference" \| "image-generation">` | 이 선택지를 어떤 onboarding 표면에 표시할지 지정합니다. 생략하면 기본값은 `["text-inference"]`입니다. |
## uiHints 참조
`uiHints`config 필드 이름에서 작은 렌더링 힌트로의 매핑입니다.
`uiHints`구성 필드 이름에서 작은 렌더링 힌트로 매핑되는 맵입니다.
```json
{
"uiHints": {
"apiKey": {
"label": "API key",
"help": "Used for OpenRouter requests",
"help": "OpenRouter 요청에 사용됨",
"placeholder": "sk-or-v1-...",
"sensitive": true
}
@ -199,21 +194,20 @@ OpenClaw는 provider 런타임이 로드되기 전에 이를 읽습니다.
}
```
각 필드 힌트에는 다음이 포함될 수 있습니다:
각 필드 힌트는 다음을 포함할 수 있습니다.
| Field | Type | What it means |
| ------------- | ---------- | --------------------------------------- |
| `label` | `string` | 사용자 대상 필드 라벨. |
| `help` | `string` | 짧은 도움말 텍스트. |
| `tags` | `string[]` | 선택적 UI 태그. |
| `advanced` | `boolean` | 필드를 고급 항목으로 표시합니다. |
| `sensitive` | `boolean` | 필드를 비밀값 또는 민감 항목으로 표시합니다. |
| `placeholder` | `string` | 폼 입력용 placeholder 텍스트. |
| Field | Type | 의미 |
| ------------- | ---------- | ------------------------------------- |
| `label` | `string` | 사용자용 필드 레이블입니다. |
| `help` | `string` | 짧은 도움말 텍스트입니다. |
| `tags` | `string[]` | 선택적 UI 태그입니다. |
| `advanced` | `boolean` | 필드를 고급 항목으로 표시합니다. |
| `sensitive` | `boolean` | 이 필드를 비밀 또는 민감 정보로 표시합니다. |
| `placeholder` | `string` | 양식 입력의 placeholder 텍스트입니다. |
## contracts 참조
`contracts`는 OpenClaw가 plugin 런타임을 import하지 않고도
읽을 수 있는 정적 capability 소유 메타데이터에만 사용하세요.
`contracts`는 OpenClaw가 plugin 런타임을 import하지 않고도 읽을 수 있는 정적 capability 소유 메타데이터에만 사용하세요.
```json
{
@ -231,24 +225,23 @@ OpenClaw는 provider 런타임이 로드되기 전에 이를 읽습니다.
}
```
각 목록은 선택 사항입니다:
각 목록은 선택 사항입니다.
| Field | Type | What it means |
| -------------------------------- | ---------- | -------------------------------------------------------------- |
| `speechProviders` | `string[]` | 이 plugin이 소유하는 음성 provider id입니다. |
| `realtimeTranscriptionProviders` | `string[]` | 이 plugin이 소유하는 실시간 전사 provider id입니다. |
| `realtimeVoiceProviders` | `string[]` | 이 plugin이 소유하는 실시간 음성 provider id입니다. |
| `mediaUnderstandingProviders` | `string[]` | 이 plugin이 소유하는 media-understanding provider id입니다. |
| `imageGenerationProviders` | `string[]` | 이 plugin이 소유하는 image-generation provider id입니다. |
| `videoGenerationProviders` | `string[]` | 이 plugin이 소유하는 video-generation provider id입니다. |
| `webFetchProviders` | `string[]` | 이 plugin이 소유하는 web-fetch provider id입니다. |
| `webSearchProviders` | `string[]` | 이 plugin이 소유하는 웹 검색 provider id입니다. |
| `tools` | `string[]` | 번들 contract 검사용으로 이 plugin이 소유하는 agent 도구 이름입니다. |
| Field | Type | 의미 |
| -------------------------------- | ---------- | ----------------------------------------------------------- |
| `speechProviders` | `string[]` | 이 plugin이 소유한 speech provider id입니다. |
| `realtimeTranscriptionProviders` | `string[]` | 이 plugin이 소유한 realtime-transcription provider id입니다. |
| `realtimeVoiceProviders` | `string[]` | 이 plugin이 소유한 realtime-voice provider id입니다. |
| `mediaUnderstandingProviders` | `string[]` | 이 plugin이 소유한 media-understanding provider id입니다. |
| `imageGenerationProviders` | `string[]` | 이 plugin이 소유한 image-generation provider id입니다. |
| `videoGenerationProviders` | `string[]` | 이 plugin이 소유한 video-generation provider id입니다. |
| `webFetchProviders` | `string[]` | 이 plugin이 소유한 web-fetch provider id입니다. |
| `webSearchProviders` | `string[]` | 이 plugin이 소유한 web-search provider id입니다. |
| `tools` | `string[]` | 번들 계약 검사에 사용하는 이 plugin 소유의 agent tool 이름입니다. |
## channelConfigs 참조
`channelConfigs`는 채널 plugin이 런타임 로드 전에
저비용 config 메타데이터를 필요로 할 때 사용하세요.
channel plugin이 런타임 로드 전에 저비용 config 메타데이터를 필요로 하는 경우 `channelConfigs`를 사용하세요.
```json
{
@ -268,28 +261,26 @@ OpenClaw는 provider 런타임이 로드되기 전에 이를 읽습니다.
}
},
"label": "Matrix",
"description": "Matrix homeserver connection",
"description": "Matrix homeserver 연결",
"preferOver": ["matrix-legacy"]
}
}
}
```
채널 항목에는 다음이 포함될 수 있습니다:
channel 항목은 다음을 포함할 수 있습니다.
| Field | Type | What it means |
| ------------- | ------------------------ | ----------------------------------------------------------------------------------------- |
| `schema` | `object` | `channels.<id>`용 JSON Schema입니다. 선언된 각 채널 config 항목에 필요합니다. |
| `uiHints` | `Record<string, object>` | 해당 채널 config 섹션을 위한 선택적 UI 라벨/placeholder/민감도 힌트입니다. |
| `label` | `string` | 런타임 메타데이터가 준비되지 않았을 때 선택기 및 검사 표면에 병합되는 채널 라벨입니다. |
| `description` | `string` | 검사 및 catalog 표면을 위한 짧은 채널 설명입니다. |
| `preferOver` | `string[]` | 선택 표면에서 이 채널이 우선해야 하는 레거시 또는 낮은 우선순위 plugin id입니다. |
| Field | Type | 의미 |
| ------------- | ------------------------ | -------------------------------------------------------------------------------------- |
| `schema` | `object` | `channels.<id>`용 JSON Schema입니다. 선언된 각 channel config 항목에 필수입니다. |
| `uiHints` | `Record<string, object>` | 해당 channel config 섹션에 대한 선택적 UI 레이블/placeholder/민감도 힌트입니다. |
| `label` | `string` | 런타임 메타데이터가 준비되지 않았을 때 선택기 및 검사 표면에 병합되는 channel 레이블입니다. |
| `description` | `string` | 검사 및 catalog 표면용 짧은 channel 설명입니다. |
| `preferOver` | `string[]` | 선택 표면에서 이 channel이 우선해야 하는 레거시 또는 낮은 우선순위 plugin id입니다. |
## modelSupport 참조
`modelSupport`는 OpenClaw가 `gpt-5.4` 또는 `claude-sonnet-4.6` 같은
축약형 모델 id에서 plugin 런타임이 로드되기 전에
provider plugin을 추론해야 할 때 사용하세요.
plugin 런타임이 로드되기 전에 OpenClaw가 `gpt-5.4` 또는 `claude-sonnet-4.6` 같은 shorthand model id로부터 provider plugin을 추론해야 한다면 `modelSupport`를 사용하세요.
```json
{
@ -300,76 +291,60 @@ provider plugin을 추론해야 할 때 사용하세요.
}
```
OpenClaw는 다음 우선순위를 적용합니다:
OpenClaw는 다음 우선순위를 적용합니다.
- 명시적 `provider/model` 참조는 소유 `providers` 매니페스트 메타데이터를 사용합니다
- 명시적`provider/model` ref는 소유 `providers` 매니페스트 메타데이터를 사용합니다
- `modelPatterns``modelPrefixes`보다 우선합니다
- 번들되지 않은 plugin과 번들 plugin이 각각 하나씩 모두 일치하면, 번들되지 않은
plugin이 우선합니다
- 남은 모호성은 사용자 또는 config가 provider를 지정할 때까지 무시됩니다
- 비번들 plugin 하나와 번들 plugin 하나가 모두 일치하면 비번들 plugin이 우선합니다
- 그 외의 모호성은 사용자 또는 config가 provider를 지정할 때까지 무시됩니다
필드:
| Field | Type | What it means |
| --------------- | ---------- | ------------------------------------------------------------------------------- |
| `modelPrefixes` | `string[]` | 축약형 모델 id에 대해 `startsWith`로 매칭되는 접두사입니다. |
| `modelPatterns` | `string[]` | 프로필 접미사 제거 후 축약형 모델 id에 대해 매칭되는 정규식 소스입니다. |
| Field | Type | 의미 |
| --------------- | ---------- | -------------------------------------------------------------------- |
| `modelPrefixes` | `string[]` | shorthand model id에 대해 `startsWith`로 일치시키는 접두사입니다. |
| `modelPatterns` | `string[]` | 프로필 접미사를 제거한 뒤 shorthand model id에 대해 일치시키는 정규식 소스입니다. |
레거시 최상위 capability 키는 더 이상 권장되지 않습니다. `openclaw doctor --fix`를 사용해
`speechProviders`, `realtimeTranscriptionProviders`,
`realtimeVoiceProviders`, `mediaUnderstandingProviders`,
`imageGenerationProviders`, `videoGenerationProviders`,
`webFetchProviders`, `webSearchProviders``contracts` 아래로
이동하세요. 일반 매니페스트 로딩은 더 이상 이러한 최상위 필드를
capability 소유권으로 취급하지 않습니다.
레거시 최상위 capability 키는 더 이상 권장되지 않습니다. `openclaw doctor --fix`를 사용해 `speechProviders`, `realtimeTranscriptionProviders`, `realtimeVoiceProviders`, `mediaUnderstandingProviders`, `imageGenerationProviders`, `videoGenerationProviders`, `webFetchProviders`, `webSearchProviders``contracts` 아래로 이동하세요. 일반 매니페스트 로딩은 더 이상 이러한 최상위 필드를 capability 소유권으로 취급하지 않습니다.
## 매니페스트와 package.json의 차이
두 파일은 서로 다른 역할을 합니다:
두 파일은 서로 다른 역할을 합니다.
| File | Use it for |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `openclaw.plugin.json` | 검색, config 검증, 인증 선택 메타데이터, 그리고 plugin 코드 실행 전에 존재해야 하는 UI 힌트 |
| `package.json` | npm 메타데이터, 의존성 설치, 그리고 엔트리포인트, 설치 게이팅, 설정 또는 catalog 메타데이터에 사용되는 `openclaw` 블록 |
| File | 용도 |
| ---------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `openclaw.plugin.json` | plugin 코드가 실행되기 전에 반드시 존재해야 하는 검색, 구성 검증, auth-choice 메타데이터, UI 힌트 |
| `package.json` | npm 메타데이터, 의존성 설치, 그리고 entrypoint, 설치 게이팅, 설정, catalog 메타데이터에 사용되는 `openclaw` 블록 |
어떤 메타데이터를 어디에 넣어야 할지 확실하지 않다면 다음 규칙을 사용하세요:
어떤 메타데이터를 어디에 둘지 확신이 없다면 이 규칙을 사용하세요.
- OpenClaw가 plugin 코드를 로드하기 전에 알아야 한다면 `openclaw.plugin.json`에 넣으세요
- 패키징, 엔트리 파일, npm 설치 동작에 관한 것이라`package.json`에 넣으세요
- 패키징, entry 파일, 또는 npm 설치 동작과 관련 있다`package.json`에 넣으세요
### 검색에 영향을 주는 package.json 필드
일부 사전 런타임 plugin 메타데이터는 의도적으로 `openclaw.plugin.json`이 아니라
`package.json``openclaw` 블록 아래에 위치합니다.
일부 사전 런타임 plugin 메타데이터는 의도적으로 `openclaw.plugin.json`이 아니라 `package.json``openclaw` 블록에 있습니다.
중요한 예:
중요한 예:
| Field | What it means |
| Field | 의미 |
| ----------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `openclaw.extensions` | 네이티브 plugin 엔트리포인트를 선언합니다. |
| `openclaw.setupEntry` | 온보딩 및 지연 채널 시작 중에 사용하는 가벼운 setup 전용 엔트리포인트입니다. |
| `openclaw.channel` | 라벨, 문서 경로, 별칭, 선택 복사본 같은 저비용 채널 catalog 메타데이터입니다. |
| `openclaw.channel.configuredState` | 전체 채널 런타임을 로드하지 않고도 "env만으로 된 설정이 이미 존재하는가?"에 답할 수 있는 가벼운 configured-state 검사기 메타데이터입니다. |
| `openclaw.channel.persistedAuthState` | 전체 채널 런타임을 로드하지 않고도 "이미 로그인된 항목이 있는가?"에 답할 수 있는 가벼운 persisted-auth 검사기 메타데이터입니다. |
| `openclaw.install.npmSpec` / `openclaw.install.localPath` | 번들 및 외부 게시 plugin을 위한 설치/업데이트 힌트입니다. |
| `openclaw.install.defaultChoice` | 여러 설치 소스를 사용할 수 있을 때 선호되는 설치 경로입니다. |
| `openclaw.install.minHostVersion` | `>=2026.3.22` 같은 semver 하한을 사용하는, 지원되는 최소 OpenClaw 호스트 버전입니다. |
| `openclaw.install.allowInvalidConfigRecovery` | config가 유효하지 않을 때 제한된 번들 plugin 재설치 복구 경로를 허용합니다. |
| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | 시작 중 전체 채널 plugin보다 먼저 setup 전용 채널 표면이 로드되도록 합니다. |
| `openclaw.extensions` | 네이티브 plugin entrypoint를 선언합니다. |
| `openclaw.setupEntry` | onboarding 및 지연된 channel 시작 중에 사용되는 경량 setup 전용 entrypoint입니다. |
| `openclaw.channel` | 레이블, 문서 경로, 별칭, 선택용 문구 같은 저비용 channel catalog 메타데이터입니다. |
| `openclaw.channel.configuredState` | 전체 channel 런타임을 로드하지 않고도 "env만으로 된 설정이 이미 존재하는가?"에 답할 수 있는 경량 configured-state 검사기 메타데이터입니다. |
| `openclaw.channel.persistedAuthState` | 전체 channel 런타임을 로드하지 않고도 "이미 로그인된 항목이 있는가?"에 답할 수 있는 경량 persisted-auth 검사기 메타데이터입니다. |
| `openclaw.install.npmSpec` / `openclaw.install.localPath` | 번들 및 외부 게시 plugin용 설치/업데이트 힌트입니다. |
| `openclaw.install.defaultChoice` | 여러 설치 소스를 사용할 수 있을 때 선호되는 설치 경로입니다. |
| `openclaw.install.minHostVersion` | `>=2026.3.22` 같은 semver 하한을 사용하는 최소 지원 OpenClaw 호스트 버전입니다. |
| `openclaw.install.allowInvalidConfigRecovery` | 구성이 유효하지 않을 때 제한된 번들 plugin 재설치 복구 경로를 허용합니다. |
| `openclaw.startup.deferConfiguredChannelFullLoadUntilAfterListen` | 시작 중 전체 channel plugin보다 setup 전용 channel 표면을 먼저 로드할 수 있게 합니다. |
`openclaw.install.minHostVersion`은 설치와 매니페스트
레지스트리 로드 중에 적용됩니다. 잘못된 값은 거부되며, 더 새롭지만 유효한 값은
오래된 호스트에서 plugin을 건너뜁니다.
`openclaw.install.minHostVersion`은 설치 중과 매니페스트 레지스트리 로딩 중에 적용됩니다. 유효하지 않은 값은 거부되며, 유효하지만 더 새로운 값은 오래된 호스트에서 plugin을 건너뜁니다.
`openclaw.install.allowInvalidConfigRecovery`는 의도적으로 좁은 범위로 제한됩니다. 이것이
임의의 깨진 config를 설치 가능하게 만들지는 않습니다. 현재는
번들 plugin 경로 누락 또는 동일 번들 plugin에 대한 오래된 `channels.<id>` 항목 같은,
특정한 오래된 번들 plugin 업그레이드 실패에서 설치 흐름이 복구되도록만 허용합니다.
관련 없는 config 오류는 여전히 설치를 차단하고 운영자를
`openclaw doctor --fix`로 안내합니다.
`openclaw.install.allowInvalidConfigRecovery`는 의도적으로 범위가 좁습니다. 임의의 깨진 구성을 설치 가능하게 만들지는 않습니다. 현재는 누락된 번들 plugin 경로 또는 동일 번들 plugin에 대한 오래된 `channels.<id>` 항목 같은 특정한 낡은 번들 plugin 업그레이드 실패에서만 설치 흐름이 복구되도록 허용합니다. 관련 없는 구성 오류는 여전히 설치를 차단하고 운영자를 `openclaw doctor --fix`로 안내합니다.
`openclaw.channel.persistedAuthState`는 작은 검사기
모듈을 위한 패키지 메타데이터입니다:
`openclaw.channel.persistedAuthState`는 작은 검사기 모듈을 위한 package 메타데이터입니다.
```json
{
@ -385,13 +360,9 @@ capability 소유권으로 취급하지 않습니다.
}
```
설정, doctor 또는 configured-state 흐름이 전체 채널 plugin이 로드되기 전에
저비용의 예/아니오 인증 프로브를 필요로 할 때 사용하세요. 대상 export는
저장된 상태만 읽는 작은 함수여야 하며, 전체 채널 런타임 배럴을 통해
연결하지 마세요.
설정, doctor 또는 configured-state 흐름이 전체 channel plugin이 로드되기 전에 저비용 예/아니오 auth 프로브를 필요로 할 때 사용하세요. 대상 export는 저장된 상태만 읽는 작은 함수여야 하며, 전체 channel 런타임 barrel을 통해 연결해서는 안 됩니다.
`openclaw.channel.configuredState`는 저비용 env 전용
구성 확인을 위한 동일한 형태를 따릅니다:
`openclaw.channel.configuredState`는 저비용 env 전용 configured 검사를 위해 같은 형태를 따릅니다.
```json
{
@ -407,62 +378,43 @@ capability 소유권으로 취급하지 않습니다.
}
```
채널이 env 또는 기타 작은 비런타임 입력만으로 configured-state에 답할 수 있을 때 사용하세요.
검사에 전체 config 해석 또는 실제
채널 런타임이 필요하다면, 그 로직은 대신 plugin `config.hasConfiguredState`
hook에 두세요.
channel이 env 또는 기타 작은 비런타임 입력만으로 configured-state에 답할 수 있을 때 사용하세요. 검사가 전체 config 해석이나 실제 channel 런타임을 필요로 한다면, 대신 그 로직을 plugin `config.hasConfiguredState` hook에 두세요.
## JSON Schema 요구 사항
- **모든 plugin은 JSON Schema를 반드시 포함해야 하며**, config를 전혀 받지 않는 경우에도 예외가 없습니다.
- 빈 schema도 허용됩니다(예: `{ "type": "object", "additionalProperties": false }`).
- schema는 런타임이 아니라 config 읽기/쓰기 시점에 검증됩니다.
- **모든 plugin은 JSON Schema를 반드시 포함해야 하며**, 구성을 전혀 받지 않더라도 예외는 없습니다.
- 빈 스키마도 허용됩니다(예: `{ "type": "object", "additionalProperties": false }`).
- 스키마는 런타임이 아니라 구성 읽기/쓰기 시점에 검증됩니다.
## 검증 동작
- 알 수 없는 `channels.*` 키는 **오류**입니다. 단, 해당 채널 id가
plugin 매니페스트에 선언된 경우는 예외입니다.
- `plugins.entries.<id>`, `plugins.allow`, `plugins.deny`, `plugins.slots.*`
**검색 가능한** plugin id를 참조해야 합니다. 알 수 없는 id는 **오류**입니다.
- plugin이 설치되어 있지만 매니페스트 또는 schema가 깨졌거나 없으면,
검증이 실패하고 Doctor가 plugin 오류를 보고합니다.
- plugin config가 존재하지만 plugin이 **비활성화**되어 있으면, 해당 config는 유지되고
Doctor + 로그에 **경고**가 표시됩니다.
- 알 수 없는 `channels.*` 키는 **오류**입니다. 단, 해당 channel id가 plugin 매니페스트에 선언된 경우는 예외입니다.
- `plugins.entries.<id>`, `plugins.allow`, `plugins.deny`, `plugins.slots.*`**검색 가능한** plugin id를 참조해야 합니다. 알 수 없는 id는 **오류**입니다.
- plugin이 설치되어 있지만 매니페스트나 스키마가 깨졌거나 누락된 경우 검증이 실패하고 Doctor가 plugin 오류를 보고합니다.
- plugin 구성이 존재하지만 plugin이 **비활성화**되어 있으면 구성은 유지되며 Doctor + 로그에 **경고**가 표시됩니다.
전체 `plugins.*` schema는 [Configuration reference](/ko/gateway/configuration)를 참고하세요.
전체 `plugins.*` 스키마는 [Configuration reference](/ko/gateway/configuration)를 참조하세요.
## 참고
- 매니페스트는 로컬 파일 시스템 로드를 포함한 **네이티브 OpenClaw plugin에 필수**입니다.
- 런타임은 여전히 plugin 모듈을 별도로 로드합니다. 매니페스트는
검색 + 검증 전용입니다.
- 네이티브 매니페스트는 JSON5로 파싱되므로 주석, trailing comma,
따옴표 없는 키를 사용할 수 있으며, 최종 값이 여전히 객체이기만 하면 됩니다.
- 매니페스트 로더는 문서화된 매니페스트 필드만 읽습니다. 여기에
커스텀 최상위 키를 추가하지 마세요.
- `providerAuthEnvVars`는 plugin 런타임을 부팅하지 않고도 env 이름을 확인해야 하는
인증 프로브, env-marker 검증, 기타 유사한 provider 인증 표면을 위한
저비용 메타데이터 경로입니다.
- `channelEnvVars`는 plugin 런타임을 부팅하지 않고도 env 이름을 확인해야 하는
셸 env 폴백, setup 프롬프트, 기타 유사한 채널 표면을 위한
저비용 메타데이터 경로입니다.
- `providerAuthChoices`는 provider 런타임이 로드되기 전에 인증 선택기,
`--auth-choice` 해석, 선호 provider 매핑, 단순 온보딩
CLI 플래그 등록을 위한 저비용 메타데이터 경로입니다. provider 코드가 필요한
런타임 wizard 메타데이터는
[Provider runtime hooks](/ko/plugins/architecture#provider-runtime-hooks)를 참고하세요.
- 매니페스트는 로컬 파일 시스템 로드를 포함해 **네이티브 OpenClaw plugin에 필수**입니다.
- 런타임은 여전히 plugin 모듈을 별도로 로드합니다. 매니페스트는 검색 + 검증 전용입니다.
- 네이티브 매니페스트는 JSON5로 파싱되므로 최종 값이 여전히 객체이기만 하면 주석, 후행 쉼표, 따옴표 없는 키를 허용합니다.
- 매니페스트 로더는 문서화된 매니페스트 필드만 읽습니다. 여기에 사용자 정의 최상위 키를 추가하지 마세요.
- `providerAuthEnvVars`는 env 이름을 확인하기 위해 plugin 런타임을 부팅해서는 안 되는 auth 프로브, env-marker 검증 및 유사한 provider-auth 표면을 위한 저비용 메타데이터 경로입니다.
- `providerAuthAliases`는 core에 관계를 하드코딩하지 않고도 provider 변형이 다른 provider의 auth env vars, auth 프로필, config 기반 auth, API 키 onboarding 선택지를 재사용할 수 있게 합니다.
- `channelEnvVars`는 env 이름을 확인하기 위해 plugin 런타임을 부팅해서는 안 되는 shell-env 폴백, setup 프롬프트 및 유사한 channel 표면을 위한 저비용 메타데이터 경로입니다.
- `providerAuthChoices`는 provider 런타임이 로드되기 전에 auth-choice 선택기, `--auth-choice` 해석, 선호 provider 매핑, 간단한 onboarding CLI 플래그 등록을 위한 저비용 메타데이터 경로입니다. provider 코드가 필요한 런타임 wizard 메타데이터는 [Provider runtime hooks](/ko/plugins/architecture#provider-runtime-hooks)를 참조하세요.
- 배타적 plugin kind는 `plugins.slots.*`를 통해 선택됩니다.
- `kind: "memory"``plugins.slots.memory`로 선택됩니다.
- `kind: "context-engine"``plugins.slots.contextEngine`으로 선택됩니다
(기본값: 내장 `legacy`).
- `channels`, `providers`, `cliBackends`, `skills`
plugin에 필요하지 않다면 생략할 수 있습니다.
- plugin이 네이티브 모듈에 의존한다면 빌드 단계와
패키지 관리자 허용 목록 요구 사항을 문서화하세요(예: pnpm `allow-build-scripts`
- `pnpm rebuild <package>`).
- `channels`, `providers`, `cliBackends`, `skills`는 plugin에 필요하지 않다면 생략할 수 있습니다.
- plugin이 네이티브 모듈에 의존하는 경우, 빌드 단계와 package-manager 허용 목록 요구 사항(예: pnpm `allow-build-scripts`
- `pnpm rebuild <package>`)을 문서화하세요.
## 관련 문서
- [Building Plugins](/ko/plugins/building-plugins) — plugin 시작하기
- [Building Plugins](/ko/plugins/building-plugins) — plugin 시작 가이드
- [Plugin Architecture](/ko/plugins/architecture) — 내부 아키텍처
- [SDK Overview](/ko/plugins/sdk-overview) — Plugin SDK 참조

View File

@ -5,64 +5,61 @@ read_when:
- plugin을 최신 plugin 아키텍처로 업데이트하는 경우
- 외부 OpenClaw plugin을 유지 관리하는 경우
sidebarTitle: Migrate to SDK
summary: 레거시 하위 호환성 레이어에서 최신 plugin SDK로 마이그레이션
summary: 기존 하위 호환성 계층에서 최신 plugin SDK로 마이그레이션
title: Plugin SDK 마이그레이션
x-i18n:
generated_at: "2026-04-08T02:17:32Z"
generated_at: "2026-04-09T01:30:38Z"
model: gpt-5.4
provider: openai
source_hash: 155a8b14bc345319c8516ebdb8a0ccdea2c5f7fa07dad343442996daee21ecad
source_hash: 60cbb6c8be30d17770887d490c14e3a4538563339a5206fb419e51e0558bbc07
source_path: plugins/sdk-migration.md
workflow: 15
---
# Plugin SDK 마이그레이션
OpenClaw는 폭넓은 하위 호환성 레이어에서 집중적이고 문서화된 import를 갖춘 최신 plugin
아키텍처로 이동했습니다. plugin이 새 아키텍처 이전에 만들어졌다면,
이 가이드 마이그레이션에 도움이 됩니다.
OpenClaw는 광범위한 하위 호환성 계층에서 집중적이고 문서화된 import를 사용하는 최신 plugin
아키텍처로 전환했습니다. plugin이 새 아키텍처 이전에 만들어졌다면,
이 가이드 마이그레이션에 도움이 됩니다.
## 변경 사항
## 변경되는 내용
이전 plugin 시스템은 plugin이 단일 엔트리 포인트에서 필요한 것을 무엇이든 import할 수 있도록 해주
두 개의 매우 개방된 표면을 제공했습니다.
기존 plugin 시스템은 plugin이 단일 진입점에서 필요한 거의 모든 것을 import할 수 있도록 하
두 개의 광범위한 표면을 제공했습니다.
- **`openclaw/plugin-sdk/compat`** — 수십 개의
helper를 다시 export하는 단일 import입니다. 새 plugin 아키텍처가 구축되는 동안
오래된 hook 기반 plugin이 계속 작동하도록 도입되었습니다.
- **`openclaw/extension-api`** — 내장 에이전트 실행기 같은
호스트 측 helper에 plugin이 직접 접근할 수 있게 해주는 브리지입니다.
helper를 다시 내보내는 단일 import입니다. 새 plugin 아키텍처가 구축되는 동안
기존 hook 기반 plugins가 계속 동작하도록 도입되었습니다.
- **`openclaw/extension-api`** — plugin이 내장 agent runner 같은
호스트 측 helper에 직접 접근할 수 있게 해주는 브리지입니다.
이제 두 표면 모두 **deprecated** 상태입니다. 런타임에서는 여전히 동하지만, 새
plugin은 이를 사용하면 안 되며, 기존 plugin도 다음 메이저 릴리스에서 제거되기 전에
이제 두 표면 모두 **사용 중단됨** 상태입니다. 런타임에서는 여전히 동하지만, 새
plugins는 이를 사용해서는 안 되며, 기존 plugins도 다음 메이저 릴리스에서 제거되기 전에
마이그레이션해야 합니다.
<Warning>
하위 호환성 레이어는 향후 메이저 릴리스에서 제거될 예정입니다.
이 표면에서 계속 import하는 plugin은 그 시점에 작동이 중단됩니다.
하위 호환성 계층은 향후 메이저 릴리스에서 제거될 예정입니다.
여전히 이 표면에서 import하는 plugins는 그 시점에 동작하지 않게 됩니다.
</Warning>
## 왜 변경되었나
## 왜 변경되었나
이전 접근 방식은 문제를 일으켰습니다.
기존 접근 방식은 다음과 같은 문제를 일으켰습니다.
- **느린 시작** — helper 하나를 import하면 관련 없는 수십 개 모듈이 로드됨
- **순환 의존성** — 광범위한 재-export로 import 순환이 쉽게 생김
- **불명확한 API 표면** — 어떤 export가 안정적인지, 어떤 것이 내부용인지 구분할 방법이 없음
- **느린 시작 속도** — helper 하나를 import해도 관련 없는 수십 개 모듈이 로드됨
- **순환 의존성** — 광범위한 재내보내기로 인해 import cycle이 쉽게 생김
- **불명확한 API 표면** — 어떤 export가 안정적이고 어떤 것이 내부용인지 구분할 수 없음
최신 plugin SDK는 이를 해결합니다. 각 import 경로(`openclaw/plugin-sdk/\<subpath\>`)는
명확한 목적과 문서화된 계약을 가진 작고 독립적인 모듈입니다.
작고 독립적인 모듈이며, 명확한 목적과 문서화된 계약을 가집니다.
번들 채널용 레거시 프로바이더 편의 seam도 사라졌습니다. 예를 들어
`openclaw/plugin-sdk/slack`, `openclaw/plugin-sdk/discord`,
`openclaw/plugin-sdk/signal`, `openclaw/plugin-sdk/whatsapp`,
채널 브랜드 helper seam, 그리고
`openclaw/plugin-sdk/telegram-core` 같은 import는
안정적인 plugin 계약이 아니라 private mono-repo 지름길이었습니다. 대신 더 좁고 일반적인 SDK subpath를 사용하세요. 번들
plugin workspace 내부에서는 프로바이더 소유 helper를 해당 plugin 자체의
`api.ts` 또는 `runtime-api.ts`에 유지하세요.
번들 채널용 기존 provider 편의 seam도 제거되었습니다. `openclaw/plugin-sdk/slack`, `openclaw/plugin-sdk/discord`, `openclaw/plugin-sdk/signal`, `openclaw/plugin-sdk/whatsapp`,
채널 브랜딩 helper seam, 그리고
`openclaw/plugin-sdk/telegram-core` 같은 import는 안정적인 plugin 계약이 아닌
비공개 mono-repo 지름길이었습니다. 대신 더 좁고 일반적인 SDK 하위 경로를 사용하세요. 번들 plugin workspace 내부에서는 provider 소유 helper를 해당 plugin의
자체 `api.ts` 또는 `runtime-api.ts`에 두세요.
현재 번들 프로바이더 예시:
현재 번들 provider 예시:
- Anthropic은 Claude 전용 stream helper를 자체 `api.ts` /
`contract-api.ts` seam에 유지합니다
@ -75,36 +72,36 @@ plugin workspace 내부에서는 프로바이더 소유 helper를 해당 plugin
<Steps>
<Step title="승인 네이티브 핸들러를 capability fact로 마이그레이션">
승인 가능한 채널 plugin 이제
`approvalCapability.nativeRuntime` 공유 runtime-context registry를 통해
승인 가능한 채널 plugins는 이제
`approvalCapability.nativeRuntime` 공유 runtime-context registry를 통해
네이티브 승인 동작을 노출합니다.
주요 변경 사항:
- `approvalCapability.handler.loadRuntime(...)`
`approvalCapability.nativeRuntime`로 교체
- 승인 전용 auth/delivery를 레거시 `plugin.auth` /
`plugin.approvals` wiring에서 떼어내 `approvalCapability`로 이동
- `ChannelPlugin.approvals`는 공개 채널-plugin
계약에서 제거되었습니다. delivery/native/render 필드는 `approvalCapability`로 옮기세요
- `plugin.auth`는 채널 login/logout 흐름에만 남아 있습니다. 그 안의 승인 auth
hook은 더 이상 core에서 읽지 않습니다
- 클라이언트, 토큰, Bolt
app 같은 채널 소유 runtime 객체는 `openclaw/plugin-sdk/channel-runtime-context`를 통해 등록
- 네이티브 승인 핸들러에서 plugin 소유 reroute notice를 보내지 마세요.
이제 core가 실제 delivery 결과로부터 routed-elsewhere notice를 소유합니다
- `channelRuntime``createChannelManager(...)`에 전달할 때는
실제 `createPluginRuntime().channel` 표면을 제공하세요. 부분 stub 거부됩니다.
`approvalCapability.nativeRuntime`로 교체
- 승인 관련 auth/delivery를 기존 `plugin.auth` /
`plugin.approvals` 연결에서 `approvalCapability`로 이동
- `ChannelPlugin.approvals`는 공개 채널 plugin
계약에서 제거되었으므로, delivery/native/render 필드를 `approvalCapability`로 이동
- `plugin.auth`는 채널 login/logout 흐름에만 남아 있으며, 그 안의 승인 auth
hook은 더 이상 core에서 읽지 않
- 클라이언트, 토큰 또는 Bolt
같은 채널 소유 runtime 객체는 `openclaw/plugin-sdk/channel-runtime-context`를 통해 등록
- 네이티브 승인 핸들러에서 plugin 소유의 재라우팅 알림을 보내지 마세요.
core가 이제 실제 delivery 결과에서 발생한 다른 경로 알림을 소유합니다
- `channelRuntime``createChannelManager(...)`에 전달할 때는,
실제 `createPluginRuntime().channel` 표면을 제공하세요. 부분 stub 거부됩니다.
현재 승인 capability
레이아웃은 `/plugins/sdk-channel-plugins`를 참조하세요.
</Step>
<Step title="Windows wrapper fallback 동작 점검">
<Step title="Windows wrapper 대체 동작 감사">
plugin이 `openclaw/plugin-sdk/windows-spawn`을 사용하는 경우,
해결되지 않은 Windows `.cmd`/`.bat` wrapper는 이제
`allowShellFallback: true`명시적으로 전달하지 않으면 fail closed됩니다.
해결되지 않는 Windows `.cmd`/`.bat` wrapper는 이제 명시적으로
`allowShellFallback: true`전달하지 않으면 닫힌 상태로 실패합니다.
```typescript
// 이전
@ -113,19 +110,19 @@ plugin workspace 내부에서는 프로바이더 소유 helper를 해당 plugin
// 이후
const program = applyWindowsSpawnProgramPolicy({
candidate,
// shell 매개 fallback을 의도적으로 수용하는 신뢰된 호환성 호출자
// 이것을 설정하세요.
// 신뢰된 호환성 호출자만 이 값을 설정하세요. 이러한 호출자는 의도적으로
// 셸을 통한 대체를 허용합니다.
allowShellFallback: true,
});
```
호출자가 의도적으로 shell fallback에 의존하지 않는다면
`allowShellFallback`을 설정하지 말고 대신 발생한 오류를 처리하세요.
호출자가 의도적으로 셸 대체에 의존하지 않는다면, `allowShellFallback`을 설정하지 말고
대신 발생한 오류를 처리하세요.
</Step>
<Step title="deprecated import 찾기">
plugin에서 deprecated된 두 표면 중 하나를 import하는지 검색하세요.
<Step title="사용 중단된 import 찾기">
plugin에서 사용 중단된 두 표면 중 하나에서의 import를 검색하세요.
```bash
grep -r "plugin-sdk/compat" my-plugin/
@ -135,37 +132,37 @@ plugin workspace 내부에서는 프로바이더 소유 helper를 해당 plugin
</Step>
<Step title="집중된 import로 교체">
이전 표면의 각 export는 특정 최신 import 경로에 대응됩니다.
기존 표면의 각 export는 특정 최신 import 경로에 매핑됩니다.
```typescript
// 이전(deprecated 하위 호환성 레이어)
// 이전 (사용 중단된 하위 호환성 계층)
import {
createChannelReplyPipeline,
createPluginRuntimeStore,
resolveControlCommandGate,
} from "openclaw/plugin-sdk/compat";
// 이후(최신 집중형 import)
// 이후 (최신 집중형 import)
import { createChannelReplyPipeline } from "openclaw/plugin-sdk/channel-reply-pipeline";
import { createPluginRuntimeStore } from "openclaw/plugin-sdk/runtime-store";
import { resolveControlCommandGate } from "openclaw/plugin-sdk/command-auth";
```
호스트 측 helper의 경우 직접 import하는 대신
호스트 측 helper의 경우 직접 import하지 말고,
주입된 plugin runtime을 사용하세요.
```typescript
// 이전(deprecated extension-api bridge)
// 이전 (사용 중단된 extension-api 브리지)
import { runEmbeddedPiAgent } from "openclaw/extension-api";
const result = await runEmbeddedPiAgent({ sessionId, prompt });
// 이후(주입된 runtime)
// 이후 (주입된 runtime)
const result = await api.runtime.agent.runEmbeddedPiAgent({ sessionId, prompt });
```
동일한 패턴이 다른 레거시 브리지 helper에도 적용됩니다.
동일한 패턴이 다른 기존 브리지 helper에도 적용됩니다.
| 이전 import | 최신 대응 |
| 기존 import | 최신 대응 항목 |
| --- | --- |
| `resolveAgentDir` | `api.runtime.agent.resolveAgentDir` |
| `resolveAgentWorkspaceDir` | `api.runtime.agent.resolveAgentWorkspaceDir` |
@ -173,7 +170,7 @@ plugin workspace 내부에서는 프로바이더 소유 helper를 해당 plugin
| `resolveThinkingDefault` | `api.runtime.agent.resolveThinkingDefault` |
| `resolveAgentTimeoutMs` | `api.runtime.agent.resolveAgentTimeoutMs` |
| `ensureAgentWorkspace` | `api.runtime.agent.ensureAgentWorkspace` |
| session store helpers | `api.runtime.agent.session.*` |
| session 저장소 helper | `api.runtime.agent.session.*` |
</Step>
@ -188,176 +185,178 @@ plugin workspace 내부에서는 프로바이더 소유 helper를 해당 plugin
## import 경로 참조
<Accordion title="일반적인 import 경로 표">
| Import path | 용도 | 주요 export |
| import 경로 | 목적 | 주요 export |
| --- | --- | --- |
| `plugin-sdk/plugin-entry` | 정식 plugin 엔트리 helper | `definePluginEntry` |
| `plugin-sdk/core` | 채널 엔트리 정의/builder용 레거시 umbrella 재-export | `defineChannelPluginEntry`, `createChatChannelPlugin` |
| `plugin-sdk/plugin-entry` | 정식 plugin 진입 helper | `definePluginEntry` |
| `plugin-sdk/core` | 채널 진입 정의/빌더를 위한 기존 umbrella 재내보내기 | `defineChannelPluginEntry`, `createChatChannelPlugin` |
| `plugin-sdk/config-schema` | 루트 config 스키마 export | `OpenClawSchema` |
| `plugin-sdk/provider-entry` | 단일 프로바이더 엔트리 helper | `defineSingleProviderPluginEntry` |
| `plugin-sdk/channel-core` | 집중된 채널 엔트리 정의 및 builder | `defineChannelPluginEntry`, `defineSetupPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase` |
| `plugin-sdk/setup` | 공유 setup wizard helper | allowlist prompt, setup status builder |
| `plugin-sdk/provider-entry` | 단일 provider 진입 helper | `defineSingleProviderPluginEntry` |
| `plugin-sdk/channel-core` | 집중된 채널 진입 정의 및 빌더 | `defineChannelPluginEntry`, `defineSetupPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase` |
| `plugin-sdk/setup` | 공유 setup wizard helper | 허용 목록 프롬프트, setup 상태 빌더 |
| `plugin-sdk/setup-runtime` | setup 시점 runtime helper | import-safe setup patch adapter, lookup-note helper, `promptResolvedAllowFrom`, `splitSetupEntries`, 위임 setup proxy |
| `plugin-sdk/setup-adapter-runtime` | setup adapter helper | `createEnvPatchedAccountSetupAdapter` |
| `plugin-sdk/setup-tools` | setup tooling helper | `formatCliCommand`, `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, `CONFIG_DIR` |
| `plugin-sdk/setup-tools` | setup 도구 helper | `formatCliCommand`, `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, `CONFIG_DIR` |
| `plugin-sdk/account-core` | 다중 계정 helper | 계정 목록/config/action-gate helper |
| `plugin-sdk/account-id` | account-id helper | `DEFAULT_ACCOUNT_ID`, account-id 정규화 |
| `plugin-sdk/account-resolution` | 계정 조회 helper | 계정 조회 + 기본 fallback helper |
| `plugin-sdk/account-helpers` | 좁은 범위의 계정 helper | 계정 목록/계정 액션 helper |
| `plugin-sdk/account-resolution` | 계정 조회 helper | 계정 조회 + 기본값 대체 helper |
| `plugin-sdk/account-helpers` | 좁은 계정 helper | 계정 목록/계정 작업 helper |
| `plugin-sdk/channel-setup` | setup wizard adapter | `createOptionalChannelSetupSurface`, `createOptionalChannelSetupAdapter`, `createOptionalChannelSetupWizard`, 그리고 `DEFAULT_ACCOUNT_ID`, `createTopLevelChannelDmPolicy`, `setSetupChannelEnabled`, `splitSetupEntries` |
| `plugin-sdk/channel-pairing` | DM pairing 기본 구성 요소 | `createChannelPairingController` |
| `plugin-sdk/channel-reply-pipeline` | 응답 접두사 + 타이핑 wiring | `createChannelReplyPipeline` |
| `plugin-sdk/channel-pairing` | DM 페어링 기본 구성 요소 | `createChannelPairingController` |
| `plugin-sdk/channel-reply-pipeline` | 답장 접두사 + 타이핑 연결 | `createChannelReplyPipeline` |
| `plugin-sdk/channel-config-helpers` | config adapter 팩토리 | `createHybridChannelConfigAdapter` |
| `plugin-sdk/channel-config-schema` | config 스키마 builder | 채널 config 스키마 타입 |
| `plugin-sdk/telegram-command-config` | Telegram 명령 config helper | 명령 이름 정규화, 설명 자르기, 중복/충돌 검증 |
| `plugin-sdk/channel-config-schema` | config 스키마 빌더 | 채널 config 스키마 타입 |
| `plugin-sdk/telegram-command-config` | Telegram 명령 config helper | 명령 이름 정규화, 설명 잘라내기, 중복/충돌 검증 |
| `plugin-sdk/channel-policy` | 그룹/DM 정책 해석 | `resolveChannelGroupRequireMention` |
| `plugin-sdk/channel-lifecycle` | 계정 상태 추적 | `createAccountStatusSink` |
| `plugin-sdk/inbound-envelope` | 인바운드 envelope helper | 공유 route + envelope builder helper |
| `plugin-sdk/inbound-reply-dispatch` | 인바운드 답 helper | 공유 record-and-dispatch helper |
| `plugin-sdk/messaging-targets` | 메시징 대상 파싱 | 대상 파싱/매칭 helper |
| `plugin-sdk/inbound-envelope` | 인바운드 envelope helper | 공유 route + envelope 빌더 helper |
| `plugin-sdk/inbound-reply-dispatch` | 인바운드 답 helper | 공유 record-and-dispatch helper |
| `plugin-sdk/messaging-targets` | 메시징 대상 구문 분석 | 대상 구문 분석/매칭 helper |
| `plugin-sdk/outbound-media` | 아웃바운드 미디어 helper | 공유 아웃바운드 미디어 로딩 |
| `plugin-sdk/outbound-runtime` | 아웃바운드 runtime helper | 아웃바운드 신원/send delegate helper |
| `plugin-sdk/thread-bindings-runtime` | thread-binding helper | thread-binding lifecycle 및 adapter helper |
| `plugin-sdk/agent-media-payload` | 레거시 미디어 payload helper | 레거시 필드 레이아웃용 에이전트 미디어 payload builder |
| `plugin-sdk/channel-runtime` | deprecated 호환성 shim | 레거시 채널 runtime 유틸리티 전용 |
| `plugin-sdk/channel-send-result` | send 결과 타입 | 응답 결과 타입 |
| `plugin-sdk/outbound-runtime` | 아웃바운드 runtime helper | 아웃바운드 identity/send delegate helper |
| `plugin-sdk/thread-bindings-runtime` | 스레드 바인딩 helper | 스레드 바인딩 수명 주기 및 adapter helper |
| `plugin-sdk/agent-media-payload` | 기존 미디어 payload helper | 기존 필드 레이아웃용 agent 미디어 payload 빌더 |
| `plugin-sdk/channel-runtime` | 사용 중단된 호환성 shim | 기존 채널 runtime 유틸리티 전용 |
| `plugin-sdk/channel-send-result` | 전송 결과 타입 | 답장 결과 타입 |
| `plugin-sdk/runtime-store` | 영구 plugin 저장소 | `createPluginRuntimeStore` |
| `plugin-sdk/runtime` | 광범위한 runtime helper | runtime/logging/backup/plugin-install helper |
| `plugin-sdk/runtime-env` | 좁은 범위의 runtime env helper | logger/runtime env, timeout, retry, backoff helper |
| `plugin-sdk/plugin-runtime` | 공유 plugin runtime helper | plugin 명령/hook/http/interactive helper |
| `plugin-sdk/runtime-env` | 좁은 runtime env helper | logger/runtime env, timeout, retry, backoff helper |
| `plugin-sdk/plugin-runtime` | 공유 plugin runtime helper | plugin commands/hooks/http/interactive helper |
| `plugin-sdk/hook-runtime` | hook 파이프라인 helper | 공유 webhook/internal hook 파이프라인 helper |
| `plugin-sdk/lazy-runtime` | lazy runtime helper | `createLazyRuntimeModule`, `createLazyRuntimeMethod`, `createLazyRuntimeMethodBinder`, `createLazyRuntimeNamedExport`, `createLazyRuntimeSurface` |
| `plugin-sdk/process-runtime` | process helper | 공유 exec helper |
| `plugin-sdk/cli-runtime` | CLI runtime helper | 명령 포맷팅, waits, 버전 helper |
| `plugin-sdk/gateway-runtime` | gateway helper | gateway client 및 channel-status patch helper |
| `plugin-sdk/config-runtime` | config helper | config load/write helper |
| `plugin-sdk/telegram-command-config` | Telegram 명령 helper | 번들 Telegram 계약 표면을 사용할 수 없을 때의 fallback-stable Telegram 명령 검증 helper |
| `plugin-sdk/approval-runtime` | 승인 prompt helper | exec/plugin 승인 payload, 승인 capability/profile helper, 네이티브 승인 라우팅/runtime helper |
| `plugin-sdk/approval-auth-runtime` | 승인 auth helper | approver 해석, same-chat action auth |
| `plugin-sdk/approval-client-runtime` | 승인 클라이언트 helper | 네이티브 exec 승인 profile/filter helper |
| `plugin-sdk/lazy-runtime` | 지연 runtime helper | `createLazyRuntimeModule`, `createLazyRuntimeMethod`, `createLazyRuntimeMethodBinder`, `createLazyRuntimeNamedExport`, `createLazyRuntimeSurface` |
| `plugin-sdk/process-runtime` | 프로세스 helper | 공유 exec helper |
| `plugin-sdk/cli-runtime` | CLI runtime helper | 명령 포맷팅, 대기, 버전 helper |
| `plugin-sdk/gateway-runtime` | Gateway helper | Gateway client 및 channel-status patch helper |
| `plugin-sdk/config-runtime` | Config helper | config 로드/기록 helper |
| `plugin-sdk/telegram-command-config` | Telegram 명령 helper | 번들 Telegram 계약 표면을 사용할 수 없을 때를 위한 안정적인 대체 Telegram 명령 검증 helper |
| `plugin-sdk/approval-runtime` | 승인 프롬프트 helper | exec/plugin 승인 payload, 승인 capability/profile helper, 네이티브 승인 라우팅/runtime helper |
| `plugin-sdk/approval-auth-runtime` | 승인 auth helper | approver 해석, 동일 채팅 action auth |
| `plugin-sdk/approval-client-runtime` | 승인 client helper | 네이티브 exec 승인 profile/filter helper |
| `plugin-sdk/approval-delivery-runtime` | 승인 delivery helper | 네이티브 승인 capability/delivery adapter |
| `plugin-sdk/approval-gateway-runtime` | 승인 gateway helper | 공유 승인 gateway-resolution helper |
| `plugin-sdk/approval-handler-adapter-runtime` | 승인 adapter helper | hot 채널 엔트리포인트용 경량 네이티브 승인 adapter 로딩 helper |
| `plugin-sdk/approval-handler-runtime` | 승인 핸들러 helper | 더 넓은 승인 핸들러 runtime helper. 더 좁은 adapter/gateway seam으로 충분하다면 그것을 우선 사용 |
| `plugin-sdk/approval-handler-adapter-runtime` | 승인 adapter helper | 핫 채널 진입점용 경량 네이티브 승인 adapter 로딩 helper |
| `plugin-sdk/approval-handler-runtime` | 승인 핸들러 helper | 더 광범위한 승인 핸들러 runtime helper. 더 좁은 adapter/gateway seam으로 충분하다면 그것을 우선 사용하세요 |
| `plugin-sdk/approval-native-runtime` | 승인 대상 helper | 네이티브 승인 대상/account binding helper |
| `plugin-sdk/approval-reply-runtime` | 승인 답 helper | exec/plugin 승인 답 payload helper |
| `plugin-sdk/approval-reply-runtime` | 승인 답 helper | exec/plugin 승인 답 payload helper |
| `plugin-sdk/channel-runtime-context` | 채널 runtime-context helper | 일반 채널 runtime-context register/get/watch helper |
| `plugin-sdk/security-runtime` | 보안 helper | 공유 trust, DM gating, external-content, secret-collection helper |
| `plugin-sdk/ssrf-policy` | SSRF 정책 helper | 호스트 allowlist 및 private-network 정책 helper |
| `plugin-sdk/ssrf-policy` | SSRF 정책 helper | 호스트 허용 목록 및 private-network 정책 helper |
| `plugin-sdk/ssrf-runtime` | SSRF runtime helper | pinned-dispatcher, guarded fetch, SSRF 정책 helper |
| `plugin-sdk/collection-runtime` | 경계가 있는 캐시 helper | `pruneMapToMaxSize` |
| `plugin-sdk/diagnostic-runtime` | 진단 gating helper | `isDiagnosticFlagEnabled`, `isDiagnosticsEnabled` |
| `plugin-sdk/error-runtime` | 오류 포맷 helper | `formatUncaughtError`, `isApprovalNotFoundError`, 오류 그래프 helper |
| `plugin-sdk/diagnostic-runtime` | 진단 게이팅 helper | `isDiagnosticFlagEnabled`, `isDiagnosticsEnabled` |
| `plugin-sdk/error-runtime` | 오류 포맷 helper | `formatUncaughtError`, `isApprovalNotFoundError`, 오류 그래프 helper |
| `plugin-sdk/fetch-runtime` | 래핑된 fetch/proxy helper | `resolveFetch`, proxy helper |
| `plugin-sdk/host-runtime` | 호스트 정규화 helper | `normalizeHostname`, `normalizeScpRemoteHost` |
| `plugin-sdk/retry-runtime` | 재시도 helper | `RetryConfig`, `retryAsync`, 정책 runner |
| `plugin-sdk/allow-from` | allowlist 포맷팅 | `formatAllowFromLowercase` |
| `plugin-sdk/allowlist-resolution` | allowlist 입력 매핑 | `mapAllowlistResolutionInputs` |
| `plugin-sdk/command-auth` | 명령 gating 및 명령 표면 helper | `resolveControlCommandGate`, sender-authorization helper, command registry helper |
| `plugin-sdk/secret-input` | secret 입력 파싱 | secret 입력 helper |
| `plugin-sdk/retry-runtime` | 재시도 helper | `RetryConfig`, `retryAsync`, 정책 실행기 |
| `plugin-sdk/allow-from` | 허용 목록 포맷팅 | `formatAllowFromLowercase` |
| `plugin-sdk/allowlist-resolution` | 허용 목록 입력 매핑 | `mapAllowlistResolutionInputs` |
| `plugin-sdk/command-auth` | 명령 게이팅 및 명령 표면 helper | `resolveControlCommandGate`, sender authorization helper, 명령 registry helper |
| `plugin-sdk/command-status` | 명령 상태/help 렌더러 | `buildCommandsMessage`, `buildCommandsMessagePaginated`, `buildHelpMessage` |
| `plugin-sdk/secret-input` | 비밀 입력 구문 분석 | 비밀 입력 helper |
| `plugin-sdk/webhook-ingress` | webhook 요청 helper | webhook 대상 유틸리티 |
| `plugin-sdk/webhook-request-guards` | webhook body guard helper | 요청 본문 읽기/제한 helper |
| `plugin-sdk/reply-runtime` | 공유 응답 runtime | 인바운드 dispatch, heartbeat, 응답 planner, chunking |
| `plugin-sdk/reply-dispatch-runtime` | 좁은 범위의 응답 dispatch helper | finalize + provider dispatch helper |
| `plugin-sdk/reply-history` | 답 기록 helper | `buildHistoryContext`, `buildPendingHistoryContextFromMap`, `recordPendingHistoryEntry`, `clearHistoryEntriesIfEnabled` |
| `plugin-sdk/reply-reference` | 답 참조 계획 | `createReplyReferencePlanner` |
| `plugin-sdk/reply-chunking` | 응답 chunk helper | 텍스트/markdown chunking helper |
| `plugin-sdk/session-store-runtime` | session 저장소 helper | 저장소 경로 + updated-at helper |
| `plugin-sdk/webhook-request-guards` | webhook 본문 가드 helper | 요청 본문 읽기/제한 helper |
| `plugin-sdk/reply-runtime` | 공유 답장 runtime | 인바운드 디스패치, heartbeat, 답장 planner, chunking |
| `plugin-sdk/reply-dispatch-runtime` | 좁은 답장 디스패치 helper | finalize + provider dispatch helper |
| `plugin-sdk/reply-history` | 답 기록 helper | `buildHistoryContext`, `buildPendingHistoryContextFromMap`, `recordPendingHistoryEntry`, `clearHistoryEntriesIfEnabled` |
| `plugin-sdk/reply-reference` | 답 참조 계획 | `createReplyReferencePlanner` |
| `plugin-sdk/reply-chunking` | 답장 청크 helper | 텍스트/markdown chunking helper |
| `plugin-sdk/session-store-runtime` | 세션 저장소 helper | 저장소 경로 + updated-at helper |
| `plugin-sdk/state-paths` | 상태 경로 helper | 상태 및 OAuth 디렉터리 helper |
| `plugin-sdk/routing` | 라우팅/session-key helper | `resolveAgentRoute`, `buildAgentSessionKey`, `resolveDefaultAgentBoundAccountId`, session-key 정규화 helper |
| `plugin-sdk/status-helpers` | 채널 상태 helper | 채널/계정 상태 요약 builder, runtime-state 기본값, 이슈 메타데이터 helper |
| `plugin-sdk/routing` | 라우팅/세션 키 helper | `resolveAgentRoute`, `buildAgentSessionKey`, `resolveDefaultAgentBoundAccountId`, 세션 키 정규화 helper |
| `plugin-sdk/status-helpers` | 채널 상태 helper | 채널/계정 상태 요약 빌더, runtime-state 기본값, issue 메타데이터 helper |
| `plugin-sdk/target-resolver-runtime` | 대상 resolver helper | 공유 대상 resolver helper |
| `plugin-sdk/string-normalization-runtime` | 문자열 정규화 helper | slug/문자열 정규화 helper |
| `plugin-sdk/request-url` | 요청 URL helper | request 유사 입력에서 문자열 URL 추출 |
| `plugin-sdk/run-command` | 시간 제한 명령 helper | stdout/stderr가 정규화된 시간 제한 명령 실행기 |
| `plugin-sdk/param-readers` | param reader | 공통 도구/CLI param reader |
| `plugin-sdk/tool-send` | 도구 send 추출 | 도구 인수에서 정식 send 대상 필드 추출 |
| `plugin-sdk/temp-path` | 임시 경로 helper | 공유 temp-download 경로 helper |
| `plugin-sdk/logging-core` | logging helper | 서브시스템 logger 및 redaction helper |
| `plugin-sdk/run-command` | 시간 제한 명령 helper | 정규화된 stdout/stderr를 포함한 시간 제한 명령 실행기 |
| `plugin-sdk/param-readers` | 파라미터 리더 | 공통 tool/CLI 파라미터 리더 |
| `plugin-sdk/tool-payload` | tool payload 추출 | tool 결과 객체에서 정규화된 payload 추출 |
| `plugin-sdk/tool-send` | tool send 추출 | tool 인수에서 정식 send 대상 필드 추출 |
| `plugin-sdk/temp-path` | 임시 경로 helper | 공유 임시 다운로드 경로 helper |
| `plugin-sdk/logging-core` | logging helper | 서브시스템 logger 및 민감 정보 제거 helper |
| `plugin-sdk/markdown-table-runtime` | Markdown 표 helper | Markdown 표 모드 helper |
| `plugin-sdk/reply-payload` | 메시지 응답 타입 | 응답 payload 타입 |
| `plugin-sdk/provider-setup` | 엄선된 로컬/self-hosted 프로바이더 setup helper | self-hosted 프로바이더 discovery/config helper |
| `plugin-sdk/self-hosted-provider-setup` | 집중형 OpenAI 호환 self-hosted 프로바이더 setup helper | 동일한 self-hosted 프로바이더 discovery/config helper |
| `plugin-sdk/provider-auth-runtime` | 프로바이더 runtime auth helper | runtime API-key 해석 helper |
| `plugin-sdk/provider-auth-api-key` | 프로바이더 API-key setup helper | API-key onboarding/profile-write helper |
| `plugin-sdk/provider-auth-result` | 프로바이더 auth-result helper | 표준 OAuth auth-result builder |
| `plugin-sdk/provider-auth-login` | 프로바이더 interactive login helper | 공유 interactive login helper |
| `plugin-sdk/provider-env-vars` | 프로바이더 env-var helper | 프로바이더 auth env-var 조회 helper |
| `plugin-sdk/provider-model-shared` | 공유 프로바이더 모델/replay helper | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`, 공유 replay-policy builder, provider-endpoint helper, 모델-id 정규화 helper |
| `plugin-sdk/provider-catalog-shared` | 공유 프로바이더 catalog helper | `findCatalogTemplate`, `buildSingleProviderApiKeyCatalog`, `supportsNativeStreamingUsageCompat`, `applyProviderNativeStreamingUsageCompat` |
| `plugin-sdk/provider-onboard` | 프로바이더 onboarding patch | onboarding config helper |
| `plugin-sdk/provider-http` | 프로바이더 HTTP helper | 일반 프로바이더 HTTP/endpoint capability helper |
| `plugin-sdk/provider-web-fetch` | 프로바이더 web-fetch helper | web-fetch 프로바이더 등록/캐시 helper |
| `plugin-sdk/provider-web-search-contract` | 프로바이더 web-search 계약 helper | `enablePluginInConfig`, `resolveProviderWebSearchPluginConfig`, 범위 지정 자격 증명 setter/getter 같은 좁은 web-search config/credential 계약 helper |
| `plugin-sdk/provider-web-search` | 프로바이더 web-search helper | web-search 프로바이더 등록/캐시/runtime helper |
| `plugin-sdk/provider-tools` | 프로바이더 도구/스키마 compat helper | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`, Gemini 스키마 정리 + diagnostics, 그리고 `resolveXaiModelCompatPatch` / `applyXaiModelCompat` 같은 xAI compat helper |
| `plugin-sdk/provider-usage` | 프로바이더 사용량 helper | `fetchClaudeUsage`, `fetchGeminiUsage`, `fetchGithubCopilotUsage`, 그 외 프로바이더 사용량 helper |
| `plugin-sdk/provider-stream` | 프로바이더 stream wrapper helper | `ProviderStreamFamily`, `buildProviderStreamFamilyHooks`, `composeProviderStreamWrappers`, stream wrapper 타입, 그리고 공유 Anthropic/Bedrock/Google/Kilocode/Moonshot/OpenAI/OpenRouter/Z.A.I/MiniMax/Copilot wrapper helper |
| `plugin-sdk/keyed-async-queue` | 순서 보장 async 큐 | `KeyedAsyncQueue` |
| `plugin-sdk/media-runtime` | 공유 미디어 helper | 미디어 fetch/transform/store helper와 미디어 payload builder |
| `plugin-sdk/media-generation-runtime` | 공유 미디어 생성 helper | 공유 failover helper, 후보 선택, 이미지/비디오/음악 생성용 모델 누락 메시지 |
| `plugin-sdk/media-understanding` | media-understanding helper | media understanding 프로바이더 타입 및 프로바이더 대상 image/audio helper export |
| `plugin-sdk/text-runtime` | 공유 텍스트 helper | assistant-visible-text 제거, markdown render/chunking/table helper, redaction helper, directive-tag helper, safe-text 유틸리티, 관련 text/logging helper |
| `plugin-sdk/reply-payload` | 메시지 답장 타입 | 답장 payload 타입 |
| `plugin-sdk/provider-setup` | 엄선된 로컬/self-hosted provider setup helper | self-hosted provider 검색/config helper |
| `plugin-sdk/self-hosted-provider-setup` | 집중된 OpenAI 호환 self-hosted provider setup helper | 동일한 self-hosted provider 검색/config helper |
| `plugin-sdk/provider-auth-runtime` | provider runtime auth helper | runtime API 키 해석 helper |
| `plugin-sdk/provider-auth-api-key` | provider API 키 setup helper | API 키 온보딩/profile-write helper |
| `plugin-sdk/provider-auth-result` | provider auth-result helper | 표준 OAuth auth-result 빌더 |
| `plugin-sdk/provider-auth-login` | provider 대화형 login helper | 공유 대화형 login helper |
| `plugin-sdk/provider-env-vars` | provider env-var helper | provider auth env-var 조회 helper |
| `plugin-sdk/provider-model-shared` | 공유 provider 모델/replay helper | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`, 공유 replay-policy 빌더, provider-endpoint helper, 모델 ID 정규화 helper |
| `plugin-sdk/provider-catalog-shared` | 공유 provider 카탈로그 helper | `findCatalogTemplate`, `buildSingleProviderApiKeyCatalog`, `supportsNativeStreamingUsageCompat`, `applyProviderNativeStreamingUsageCompat` |
| `plugin-sdk/provider-onboard` | provider 온보딩 패치 | 온보딩 config helper |
| `plugin-sdk/provider-http` | provider HTTP helper | 일반 provider HTTP/endpoint capability helper |
| `plugin-sdk/provider-web-fetch` | provider web-fetch helper | web-fetch provider 등록/캐시 helper |
| `plugin-sdk/provider-web-search-config-contract` | provider web-search config helper | plugin-enable 연결이 필요하지 않은 providers를 위한 좁은 web-search config/자격 증명 helper |
| `plugin-sdk/provider-web-search-contract` | provider web-search 계약 helper | `createWebSearchProviderContractFields`, `enablePluginInConfig`, `resolveProviderWebSearchPluginConfig`, 범위가 지정된 자격 증명 setter/getter 같은 좁은 web-search config/자격 증명 계약 helper |
| `plugin-sdk/provider-web-search` | provider web-search helper | web-search provider 등록/캐시/runtime helper |
| `plugin-sdk/provider-tools` | provider tool/schema 호환 helper | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`, Gemini 스키마 정리 + 진단, 그리고 `resolveXaiModelCompatPatch` / `applyXaiModelCompat` 같은 xAI 호환 helper |
| `plugin-sdk/provider-usage` | provider 사용량 helper | `fetchClaudeUsage`, `fetchGeminiUsage`, `fetchGithubCopilotUsage` 및 기타 provider 사용량 helper |
| `plugin-sdk/provider-stream` | provider stream wrapper helper | `ProviderStreamFamily`, `buildProviderStreamFamilyHooks`, `composeProviderStreamWrappers`, stream wrapper 타입, 그리고 공유 Anthropic/Bedrock/Google/Kilocode/Moonshot/OpenAI/OpenRouter/Z.A.I/MiniMax/Copilot wrapper helper |
| `plugin-sdk/keyed-async-queue` | 순서가 보장된 async 큐 | `KeyedAsyncQueue` |
| `plugin-sdk/media-runtime` | 공유 미디어 helper | 미디어 fetch/transform/store helper와 미디어 payload 빌더 |
| `plugin-sdk/media-generation-runtime` | 공유 media-generation helper | 공유 failover helper, 후보 선택, 이미지/비디오/음악 생성을 위한 모델 누락 메시지 |
| `plugin-sdk/media-understanding` | media-understanding helper | media understanding provider 타입과 provider 대상 image/audio helper export |
| `plugin-sdk/text-runtime` | 공유 텍스트 helper | assistant-visible-text 제거, markdown 렌더/chunking/표 helper, 민감 정보 제거 helper, directive-tag helper, safe-text 유틸리티, 기타 관련 text/logging helper |
| `plugin-sdk/text-chunking` | 텍스트 chunking helper | 아웃바운드 텍스트 chunking helper |
| `plugin-sdk/speech` | speech helper | speech 프로바이더 타입 및 프로바이더 대상 directive, registry, validation helper |
| `plugin-sdk/speech-core` | 공유 speech core | speech 프로바이더 타입, registry, directive, 정규화 |
| `plugin-sdk/realtime-transcription` | realtime transcription helper | 프로바이더 타입 및 registry helper |
| `plugin-sdk/realtime-voice` | realtime voice helper | 프로바이더 타입 및 registry helper |
| `plugin-sdk/speech` | speech helper | speech provider 타입과 provider 대상 directive, registry, validation helper |
| `plugin-sdk/speech-core` | 공유 speech core | speech provider 타입, registry, directive, 정규화 |
| `plugin-sdk/realtime-transcription` | realtime transcription helper | provider 타입 및 registry helper |
| `plugin-sdk/realtime-voice` | realtime voice helper | provider 타입 및 registry helper |
| `plugin-sdk/image-generation-core` | 공유 image-generation core | image-generation 타입, failover, auth, registry helper |
| `plugin-sdk/music-generation` | music-generation helper | music-generation 프로바이더/request/result 타입 |
| `plugin-sdk/music-generation-core` | 공유 music-generation core | music-generation 타입, failover helper, provider 조회, model-ref 파싱 |
| `plugin-sdk/video-generation` | video-generation helper | video-generation 프로바이더/request/result 타입 |
| `plugin-sdk/video-generation-core` | 공유 video-generation core | video-generation 타입, failover helper, provider 조회, model-ref 파싱 |
| `plugin-sdk/interactive-runtime` | interactive 답 helper | interactive 답 payload 정규화/축소 |
| `plugin-sdk/music-generation` | music-generation helper | music-generation provider/request/result 타입 |
| `plugin-sdk/music-generation-core` | 공유 music-generation core | music-generation 타입, failover helper, provider 조회, model-ref 구문 분석 |
| `plugin-sdk/video-generation` | video-generation helper | video-generation provider/request/result 타입 |
| `plugin-sdk/video-generation-core` | 공유 video-generation core | video-generation 타입, failover helper, provider 조회, model-ref 구문 분석 |
| `plugin-sdk/interactive-runtime` | interactive 답 helper | interactive 답 payload 정규화/축소 |
| `plugin-sdk/channel-config-primitives` | 채널 config 기본 구성 요소 | 좁은 채널 config-schema 기본 구성 요소 |
| `plugin-sdk/channel-config-writes` | 채널 config-write helper | 채널 config-write 권한 부여 helper |
| `plugin-sdk/channel-config-writes` | 채널 config-write helper | 채널 config-write authorization helper |
| `plugin-sdk/channel-plugin-common` | 공유 채널 prelude | 공유 채널 plugin prelude export |
| `plugin-sdk/channel-status` | 채널 상태 helper | 공유 채널 상태 snapshot/summary helper |
| `plugin-sdk/allowlist-config-edit` | allowlist config helper | allowlist config edit/read helper |
| `plugin-sdk/group-access` | 그룹 접근 helper | 공유 그룹 접근 결정 helper |
| `plugin-sdk/direct-dm` | Direct-DM helper | 공유 direct-DM auth/guard helper |
| `plugin-sdk/channel-status` | 채널 상태 helper | 공유 채널 상태 스냅샷/요약 helper |
| `plugin-sdk/allowlist-config-edit` | 허용 목록 config helper | 허용 목록 config edit/read helper |
| `plugin-sdk/group-access` | 그룹 접근 helper | 공유 group-access 결정 helper |
| `plugin-sdk/direct-dm` | 직접 DM helper | 공유 직접 DM auth/guard helper |
| `plugin-sdk/extension-shared` | 공유 extension helper | passive-channel/status 및 ambient proxy helper 기본 구성 요소 |
| `plugin-sdk/webhook-targets` | webhook 대상 helper | webhook 대상 registry 및 route-install helper |
| `plugin-sdk/webhook-path` | webhook 경로 helper | webhook 경로 정규화 helper |
| `plugin-sdk/web-media` | 공유 web media helper | 원격/로컬 미디어 로딩 helper |
| `plugin-sdk/zod` | Zod 재-export | plugin SDK 소비자를 위한 재-export된 `zod` |
| `plugin-sdk/memory-core` | 번들 memory-core helper | 메모리 manager/config/file/CLI helper 표면 |
| `plugin-sdk/memory-core-engine-runtime` | 메모리 엔진 runtime facade | 메모리 index/search runtime facade |
| `plugin-sdk/memory-core-host-engine-foundation` | 메모리 호스트 foundation 엔진 | 메모리 호스트 foundation 엔진 export |
| `plugin-sdk/memory-core-host-engine-embeddings` | 메모리 호스트 embedding 엔진 | 메모리 호스트 embedding 엔진 export |
| `plugin-sdk/zod` | Zod 재내보내기 | plugin SDK 소비자를 위한 재내보낸 `zod` |
| `plugin-sdk/memory-core` | 번들 memory-core helper | 메모리 관리자/config/파일/CLI helper 표면 |
| `plugin-sdk/memory-core-engine-runtime` | 메모리 엔진 runtime 파사드 | 메모리 인덱스/검색 runtime 파사드 |
| `plugin-sdk/memory-core-host-engine-foundation` | 메모리 호스트 기반 엔진 | 메모리 호스트 기반 엔진 export |
| `plugin-sdk/memory-core-host-engine-embeddings` | 메모리 호스트 임베딩 엔진 | 메모리 호스트 임베딩 엔진 export |
| `plugin-sdk/memory-core-host-engine-qmd` | 메모리 호스트 QMD 엔진 | 메모리 호스트 QMD 엔진 export |
| `plugin-sdk/memory-core-host-engine-storage` | 메모리 호스트 storage 엔진 | 메모리 호스트 storage 엔진 export |
| `plugin-sdk/memory-core-host-multimodal` | 메모리 호스트 multimodal helper | 메모리 호스트 multimodal helper |
| `plugin-sdk/memory-core-host-query` | 메모리 호스트 query helper | 메모리 호스트 query helper |
| `plugin-sdk/memory-core-host-secret` | 메모리 호스트 secret helper | 메모리 호스트 secret helper |
| `plugin-sdk/memory-core-host-events` | 메모리 호스트 이벤트 journal helper | 메모리 호스트 이벤트 journal helper |
| `plugin-sdk/memory-core-host-engine-storage` | 메모리 호스트 스토리지 엔진 | 메모리 호스트 스토리지 엔진 export |
| `plugin-sdk/memory-core-host-multimodal` | 메모리 호스트 멀티모달 helper | 메모리 호스트 멀티모달 helper |
| `plugin-sdk/memory-core-host-query` | 메모리 호스트 쿼리 helper | 메모리 호스트 쿼리 helper |
| `plugin-sdk/memory-core-host-secret` | 메모리 호스트 비밀 helper | 메모리 호스트 비밀 helper |
| `plugin-sdk/memory-core-host-events` | 메모리 호스트 이벤트 저널 helper | 메모리 호스트 이벤트 저널 helper |
| `plugin-sdk/memory-core-host-status` | 메모리 호스트 상태 helper | 메모리 호스트 상태 helper |
| `plugin-sdk/memory-core-host-runtime-cli` | 메모리 호스트 CLI runtime | 메모리 호스트 CLI runtime helper |
| `plugin-sdk/memory-core-host-runtime-core` | 메모리 호스트 core runtime | 메모리 호스트 core runtime helper |
| `plugin-sdk/memory-core-host-runtime-files` | 메모리 호스트 파일/runtime helper | 메모리 호스트 파일/runtime helper |
| `plugin-sdk/memory-host-core` | 메모리 호스트 core runtime alias | 메모리 호스트 core runtime helper용 vendor-neutral alias |
| `plugin-sdk/memory-host-events` | 메모리 호스트 이벤트 journal alias | 메모리 호스트 이벤트 journal helper용 vendor-neutral alias |
| `plugin-sdk/memory-host-files` | 메모리 호스트 파일/runtime alias | 메모리 호스트 파일/runtime helper용 vendor-neutral alias |
| `plugin-sdk/memory-host-markdown` | managed markdown helper | memory 인접 plugin용 공유 managed-markdown helper |
| `plugin-sdk/memory-host-search` | 활성 메모리 검색 facade | lazy active-memory search-manager runtime facade |
| `plugin-sdk/memory-host-status` | 메모리 호스트 상태 alias | 메모리 호스트 상태 helper용 vendor-neutral alias |
| `plugin-sdk/memory-host-core` | 메모리 호스트 core runtime 별칭 | 메모리 호스트 core runtime helper를 위한 vendor-neutral 별칭 |
| `plugin-sdk/memory-host-events` | 메모리 호스트 이벤트 저널 별칭 | 메모리 호스트 이벤트 저널 helper를 위한 vendor-neutral 별칭 |
| `plugin-sdk/memory-host-files` | 메모리 호스트 파일/runtime 별칭 | 메모리 호스트 파일/runtime helper를 위한 vendor-neutral 별칭 |
| `plugin-sdk/memory-host-markdown` | 관리형 markdown helper | memory 인접 plugins를 위한 공유 관리형 markdown helper |
| `plugin-sdk/memory-host-search` | 활성 메모리 검색 파사드 | 지연 로드되는 활성 메모리 search-manager runtime 파사드 |
| `plugin-sdk/memory-host-status` | 메모리 호스트 상태 별칭 | 메모리 호스트 상태 helper를 위한 vendor-neutral 별칭 |
| `plugin-sdk/memory-lancedb` | 번들 memory-lancedb helper | memory-lancedb helper 표면 |
| `plugin-sdk/testing` | 테스트 유틸리티 | 테스트 helper 및 mock |
</Accordion>
이 표는 전체 SDK
표면이 아니라 의도적으로 일반적인 마이그레이션 하위 집합만 담고 있습니다. 200개가 넘는 엔트리포인트의 전체 목록은
표면이 아니라 의도적으로 일반적인 마이그레이션 하위 집합만 포함합니다. 200개가 넘는 전체 entrypoint 목록은
`scripts/lib/plugin-sdk-entrypoints.json`에 있습니다.
목록에는 여전히
해당 목록에는 여전히
`plugin-sdk/feishu`, `plugin-sdk/feishu-setup`, `plugin-sdk/zalo`,
`plugin-sdk/zalo-setup`, `plugin-sdk/matrix*` 같은 일부 번들-plugin helper seam이 포함되어 있습니다. 이것들은
번들-plugin 유지 관리와 호환성을 위해 계속 export되지만,
일반적인 마이그레이션 표에서는 의도적으로 생략되며
새 plugin 코드의 권장 대상은 아닙니다.
`plugin-sdk/zalo-setup`, `plugin-sdk/matrix*` 같은 일부 번들-plugin helper seam도 포함되어 있습니다. 이들은 번들-plugin 유지 관리와 호환성을 위해 계속 export되지만,
의도적으로 일반 마이그레이션 표에서는 제외되어 있으며
새 plugin 코드에 권장되는 대상이 아닙니다.
동일한 규칙이 다음과 같은 다른 번들-helper 계열에도 적용됩니다.
같은 규칙은 다음과 같은 다른 번들-helper 계열에도 적용됩니다.
- browser 지원 helper: `plugin-sdk/browser-cdp`, `plugin-sdk/browser-config-runtime`, `plugin-sdk/browser-config-support`, `plugin-sdk/browser-control-auth`, `plugin-sdk/browser-node-runtime`, `plugin-sdk/browser-profiles`, `plugin-sdk/browser-security-runtime`, `plugin-sdk/browser-setup-tools`, `plugin-sdk/browser-support`
- 브라우저 지원 helper: `plugin-sdk/browser-cdp`, `plugin-sdk/browser-config-runtime`, `plugin-sdk/browser-config-support`, `plugin-sdk/browser-control-auth`, `plugin-sdk/browser-node-runtime`, `plugin-sdk/browser-profiles`, `plugin-sdk/browser-security-runtime`, `plugin-sdk/browser-setup-tools`, `plugin-sdk/browser-support`
- Matrix: `plugin-sdk/matrix*`
- LINE: `plugin-sdk/line*`
- IRC: `plugin-sdk/irc*`
@ -370,24 +369,25 @@ plugin workspace 내부에서는 프로바이더 소유 helper를 해당 plugin
`plugin-sdk/diagnostics-otel`, `plugin-sdk/diffs`, `plugin-sdk/llm-task`,
`plugin-sdk/thread-ownership`, `plugin-sdk/voice-call` 같은 번들 helper/plugin 표면
`plugin-sdk/github-copilot-token`은 현재 좁은 범위의 토큰-helper
표면인 `DEFAULT_COPILOT_API_BASE_URL`,
`deriveCopilotApiBaseUrlFromToken`, `resolveCopilotApiToken`을 노출합니다.
`plugin-sdk/github-copilot-token`은 현재
`DEFAULT_COPILOT_API_BASE_URL`,
`deriveCopilotApiBaseUrlFromToken`, `resolveCopilotApiToken`이라는 좁은 토큰-helper
표면을 노출합니다.
작업에 맞는 가장 좁은 import를 사용하세요. export를 찾을 수 없다면
작업에 맞는 가장 좁은 import를 사용하세요. export를 찾을 수 없다면,
`src/plugin-sdk/`의 소스를 확인하거나 Discord에서 문의하세요.
## 제거 일정
| 시점 | 발생 내용 |
| 시점 | 발생하는 일 |
| ---------------------- | ----------------------------------------------------------------------- |
| **지금** | deprecated 표면이 런타임 경고를 출력 |
| **다음 메이저 릴리스** | deprecated 표면이 제거되며, 계속 사용하는 plugin은 실패 |
| **지금** | 사용 중단된 표면이 런타임 경고를 출력함 |
| **다음 메이저 릴리스** | 사용 중단된 표면이 제거되며, 여전히 이를 사용하는 plugins는 실패함 |
모든 core plugin은 이미 마이그레이션되었습니다. 외부 plugin은
다음 메이저 릴리스 전에 마이그레이션해야 합니다.
모든 core plugins는 이미 마이그레이션되었습니다. 외부 plugins도 다음 메이저 릴리스 전에
마이그레이션해야 합니다.
## 경고를 임시로 숨기기
## 경고를 일시적으로 숨기기
마이그레이션 작업 중에는 다음 환경 변수를 설정하세요.
@ -396,13 +396,13 @@ OPENCLAW_SUPPRESS_PLUGIN_SDK_COMPAT_WARNING=1 openclaw gateway run
OPENCLAW_SUPPRESS_EXTENSION_API_WARNING=1 openclaw gateway run
```
이것은 임시 탈출구일 뿐이며 영구적인 해결책은 아닙니다.
이것은 임시 탈출구일 뿐, 영구적인 해결책은 아닙니다.
## 관련 문서
- [시작하기](/ko/plugins/building-plugins) — 첫 번째 plugin 만들기
- [SDK 개요](/ko/plugins/sdk-overview) — 전체 subpath import 참조
- [채널 plugin](/ko/plugins/sdk-channel-plugins) — 채널 plugin 만들기
- [프로바이더 plugin](/ko/plugins/sdk-provider-plugins) — 프로바이더 plugin 만들기
- [Plugin 내부 구조](/ko/plugins/architecture) — 아키텍처 심층 분석
- [시작하기](/ko/plugins/building-plugins) — 첫 plugin 만들기
- [SDK 개요](/ko/plugins/sdk-overview) — 전체 하위 경로 import 참조
- [채널 Plugins](/ko/plugins/sdk-channel-plugins) — 채널 plugins 만들기
- [Provider Plugins](/ko/plugins/sdk-provider-plugins) — provider plugins 만들기
- [Plugin 내부 구조](/ko/plugins/architecture) — 아키텍처 심화 설명
- [Plugin Manifest](/ko/plugins/manifest) — manifest 스키마 참조

View File

@ -1,360 +1,339 @@
---
read_when:
- 어느 SDK 하위 경로에서 import해야 하는지 알아야 할 때
- OpenClawPluginApi의 모든 registration 메서드에 대한 참조가 필요할 때
- 특정 SDK export를 찾고 있을 때
- 어떤 SDK 하위 경로에서 import해야 하는지 알아야 합니다
- OpenClawPluginApi의 모든 등록 메서드에 대한 참조가 필요합니다
- 특정 SDK export를 찾고 있습니다
sidebarTitle: SDK Overview
summary: import map, registration API 참조, 및 SDK 아키텍처
summary: import 맵, 등록 API 참조, SDK 아키텍처
title: Plugin SDK 개요
x-i18n:
generated_at: "2026-04-08T02:18:09Z"
generated_at: "2026-04-09T01:31:11Z"
model: gpt-5.4
provider: openai
source_hash: c5a41bd82d165dfbb7fbd6e4528cf322e9133a51efe55fa8518a7a0a626d9d30
source_hash: bf205af060971931df97dca4af5110ce173d2b7c12f56ad7c62d664a402f2381
source_path: plugins/sdk-overview.md
workflow: 15
---
# Plugin SDK 개요
plugin SDK는 plugins와 core 사이의 타입 지정 계약입니다. 이 페이지는
**무엇을 import할지**와 **무엇을 등록할 수 있는지**에 대한 참조입니다.
Plugin SDK는 plugins와 core 사이의 타입이 지정된 계약입니다. 이 페이지는 **무엇을 import할지**와 **무엇을 등록할 수 있는지**에 대한 참조입니다.
<Tip>
**사용 방법 가이드를 찾고 있나요?**
- 첫 plugin인가요? [Getting Started](/ko/plugins/building-plugins)부터 시작하세요
- Channel plugin인가요? [Channel Plugins](/ko/plugins/sdk-channel-plugins)를 참조하세요
- Provider plugin인가요? [Provider Plugins](/ko/plugins/sdk-provider-plugins)를 참조하세요
- 첫 plugin이라면? [Getting Started](/ko/plugins/building-plugins)부터 시작하세요
- Channel plugin이라면? [Channel Plugins](/ko/plugins/sdk-channel-plugins)를 참조하세요
- Provider plugin이라면? [Provider Plugins](/ko/plugins/sdk-provider-plugins)를 참조하세요
</Tip>
## import 규칙
항상 특정 하위 경로에서 import하세요:
항상 특정 하위 경로에서 import하세요.
```typescript
import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
import { defineChannelPluginEntry } from "openclaw/plugin-sdk/channel-core";
```
각 하위 경로는 작고 독립적인 모듈입니다. 이렇게 하면 시작 속도를 빠르게 유지하고
순환 의존성 문제를 방지할 수 있습니다. 채널별 entry/build helper의 경우
`openclaw/plugin-sdk/channel-core`를 우선 사용하고, 더 넓은 umbrella 표면과
`buildChannelConfigSchema` 같은 공통 helper에는
`openclaw/plugin-sdk/core`를 사용하세요.
각 하위 경로는 작고 독립적인 모듈입니다. 이렇게 하면 시작 속도가 빨라지고 순환 의존성 문제를 방지할 수 있습니다. channel 전용 entry/build helper의 경우 `openclaw/plugin-sdk/channel-core`를 우선 사용하고, 더 넓은 umbrella 표면과 `buildChannelConfigSchema` 같은 공용 helper에는 `openclaw/plugin-sdk/core`를 유지하세요.
`openclaw/plugin-sdk/slack`, `openclaw/plugin-sdk/discord`,
`openclaw/plugin-sdk/signal`, `openclaw/plugin-sdk/whatsapp` 같은
provider 이름이 붙은 편의 seam이나 채널 브랜딩 helper seam을 추가하거나 이에 의존하지 마세요.
번들 plugins는 generic
SDK 하위 경로를 자체 `api.ts` 또는 `runtime-api.ts` barrel 안에서 조합해야 하며, core는
그런 plugin 로컬 barrel을 사용하거나, 필요가 진정으로 cross-channel일 때에만
좁은 generic SDK 계약을 추가해야 합니다.
`openclaw/plugin-sdk/slack`, `openclaw/plugin-sdk/discord`, `openclaw/plugin-sdk/signal`, `openclaw/plugin-sdk/whatsapp` 또는 channel 브랜드 helper seam 같은 provider 이름 기반 convenience seam을 추가하거나 이에 의존하지 마세요. 번들 plugins는 자체 `api.ts` 또는 `runtime-api.ts` barrel 안에서 일반적인 SDK 하위 경로를 조합해야 하며, core는 해당 plugin 로컬 barrel을 사용하거나 필요가 진짜 cross-channel일 때 좁고 일반적인 SDK 계약을 추가해야 합니다.
생성된 export map에는 여전히 `plugin-sdk/feishu`, `plugin-sdk/feishu-setup`,
`plugin-sdk/zalo`, `plugin-sdk/zalo-setup`, `plugin-sdk/matrix*` 같은
일부 번들 plugin helper seam이 포함되어 있습니다. 이러한
하위 경로는 번들 plugin 유지 관리와 호환성만을 위해 존재하며,
아래의 일반 표에서는 의도적으로 생략되었고 새로운 서드파티 plugins에 권장되는
import 경로가 아닙니다.
생성된 export 맵에는 여전히 `plugin-sdk/feishu`, `plugin-sdk/feishu-setup`, `plugin-sdk/zalo`, `plugin-sdk/zalo-setup`, `plugin-sdk/matrix*` 같은 소수의 번들 plugin helper seam이 포함되어 있습니다. 이러한 하위 경로는 번들 plugin 유지 관리 및 호환성 전용으로 존재하며, 아래 공통 표에서는 의도적으로 생략되었고 새로운 서드파티 plugins에 권장되는 import 경로도 아닙니다.
## 하위 경로 참조
가장 자주 사용되는 하위 경로를 목적별로 그룹화했습니다. 200개가 넘는
전체 하위 경로 목록은 생성된 `scripts/lib/plugin-sdk-entrypoints.json`에 있습니다.
가장 자주 사용하는 하위 경로를 용도별로 묶었습니다. 200개가 넘는 하위 경로의 전체 생성 목록은 `scripts/lib/plugin-sdk-entrypoints.json`에 있습니다.
예약된 번들 plugin helper 하위 경로도 이 생성 목록에 계속 표시됩니다.
문서 페이지에서 공개용으로 명시적으로 권장하지 않는 한, 이러한 경로는
구현 세부 사항/호환성 표면으로 취급하세요.
예약된 번들 plugin helper 하위 경로도 이 생성 목록에 계속 나타납니다. 문서 페이지에서 명시적으로 public으로 권장하지 않는 한, 이를 구현 세부 사항/호환성 표면으로 취급하세요.
### Plugin entry
| 하위 경로 | 주요 exports |
| -------------------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `plugin-sdk/plugin-entry` | `definePluginEntry` |
| `plugin-sdk/core` | `defineChannelPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase`, `defineSetupPluginEntry`, `buildChannelConfigSchema` |
| `plugin-sdk/config-schema` | `OpenClawSchema` |
| Subpath | 주요 exports |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
| `plugin-sdk/plugin-entry` | `definePluginEntry` |
| `plugin-sdk/core` | `defineChannelPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase`, `defineSetupPluginEntry`, `buildChannelConfigSchema` |
| `plugin-sdk/config-schema` | `OpenClawSchema` |
| `plugin-sdk/provider-entry` | `defineSingleProviderPluginEntry` |
<AccordionGroup>
<Accordion title="채널 하위 경로">
| 하위 경로 | 주요 exports |
<Accordion title="Channel 하위 경로">
| Subpath | 주요 exports |
| --- | --- |
| `plugin-sdk/channel-core` | `defineChannelPluginEntry`, `defineSetupPluginEntry`, `createChatChannelPlugin`, `createChannelPluginBase` |
| `plugin-sdk/config-schema` | 루트 `openclaw.json` Zod 스키마 export (`OpenClawSchema`) |
| `plugin-sdk/channel-setup` | `createOptionalChannelSetupSurface`, `createOptionalChannelSetupAdapter`, `createOptionalChannelSetupWizard`, 그리고 `DEFAULT_ACCOUNT_ID`, `createTopLevelChannelDmPolicy`, `setSetupChannelEnabled`, `splitSetupEntries` |
| `plugin-sdk/setup` | 공통 setup wizard helper, allowlist 프롬프트, setup 상태 builder |
| `plugin-sdk/setup` | 공용 setup wizard helper, 허용 목록 프롬프트, setup 상태 빌더 |
| `plugin-sdk/setup-runtime` | `createPatchedAccountSetupAdapter`, `createEnvPatchedAccountSetupAdapter`, `createSetupInputPresenceValidator`, `noteChannelLookupFailure`, `noteChannelLookupSummary`, `promptResolvedAllowFrom`, `splitSetupEntries`, `createAllowlistSetupWizardProxy`, `createDelegatedSetupWizardProxy` |
| `plugin-sdk/setup-adapter-runtime` | `createEnvPatchedAccountSetupAdapter` |
| `plugin-sdk/setup-tools` | `formatCliCommand`, `detectBinary`, `extractArchive`, `resolveBrewExecutable`, `formatDocsLink`, `CONFIG_DIR` |
| `plugin-sdk/account-core` | 다중 계정 config/action-gate helper, 기본 계정 fallback helper |
| `plugin-sdk/account-core` | 다중 계정 config/action-gate helper, 기본 계정 폴백 helper |
| `plugin-sdk/account-id` | `DEFAULT_ACCOUNT_ID`, account-id 정규화 helper |
| `plugin-sdk/account-resolution` | 계정 조회 + 기본 fallback helper |
| `plugin-sdk/account-resolution` | 계정 조회 + 기본 폴백 helper |
| `plugin-sdk/account-helpers` | 좁은 범위의 account-list/account-action helper |
| `plugin-sdk/channel-pairing` | `createChannelPairingController` |
| `plugin-sdk/channel-reply-pipeline` | `createChannelReplyPipeline` |
| `plugin-sdk/channel-config-helpers` | `createHybridChannelConfigAdapter` |
| `plugin-sdk/channel-config-schema` | 채널 config 스키마 타입 |
| `plugin-sdk/telegram-command-config` | 번들 계약 fallback이 포함된 Telegram custom-command 정규화/검증 helper |
| `plugin-sdk/channel-config-schema` | Channel config 스키마 타입 |
| `plugin-sdk/telegram-command-config` | 번들 계약 폴백이 포함된 Telegram 사용자 지정 command 정규화/검증 helper |
| `plugin-sdk/channel-policy` | `resolveChannelGroupRequireMention` |
| `plugin-sdk/channel-lifecycle` | `createAccountStatusSink` |
| `plugin-sdk/inbound-envelope` | 공통 인바운드 route + envelope builder helper |
| `plugin-sdk/inbound-reply-dispatch` | 공통 인바운드 record-and-dispatch helper |
| `plugin-sdk/inbound-envelope` | 공용 수신 라우트 + envelope 빌더 helper |
| `plugin-sdk/inbound-reply-dispatch` | 공용 수신 record-and-dispatch helper |
| `plugin-sdk/messaging-targets` | 대상 파싱/매칭 helper |
| `plugin-sdk/outbound-media` | 공통 아웃바운드 미디어 로딩 helper |
| `plugin-sdk/outbound-runtime` | 아웃바운드 identity/send delegate helper |
| `plugin-sdk/thread-bindings-runtime` | 스레드 바인딩 수명 주기 및 adapter helper |
| `plugin-sdk/agent-media-payload` | 레거시 agent media payload builder |
| `plugin-sdk/conversation-runtime` | 대화/스레드 바인딩, 페어링, 구성된 바인딩 helper |
| `plugin-sdk/runtime-config-snapshot` | 런타임 config snapshot helper |
| `plugin-sdk/runtime-group-policy` | 런타임 그룹 정책 해석 helper |
| `plugin-sdk/channel-status` | 공통 채널 상태 snapshot/summary helper |
| `plugin-sdk/channel-config-primitives` | 좁은 범위의 채널 config-schema primitive |
| `plugin-sdk/channel-config-writes` | 채널 config 쓰기 권한 부여 helper |
| `plugin-sdk/channel-plugin-common` | 공통 채널 plugin prelude exports |
| `plugin-sdk/allowlist-config-edit` | Allowlist config 편집/읽기 helper |
| `plugin-sdk/group-access` | 공통 그룹 접근 결정 helper |
| `plugin-sdk/direct-dm` | 공통 direct-DM 인증/guard helper |
| `plugin-sdk/interactive-runtime` | interactive reply payload 정규화/축소 helper |
| `plugin-sdk/channel-inbound` | 인바운드 debounce, 멘션 매칭, mention-policy helper, 그리고 envelope helper |
| `plugin-sdk/channel-send-result` | reply 결과 타입 |
| `plugin-sdk/outbound-media` | 공용 송신 미디어 로딩 helper |
| `plugin-sdk/outbound-runtime` | 송신 identity/send delegate helper |
| `plugin-sdk/thread-bindings-runtime` | 스레드 바인딩 lifecycle 및 adapter helper |
| `plugin-sdk/agent-media-payload` | 레거시 agent 미디어 payload 빌더 |
| `plugin-sdk/conversation-runtime` | 대화/스레드 바인딩, 페어링, configured-binding helper |
| `plugin-sdk/runtime-config-snapshot` | 런타임 config 스냅샷 helper |
| `plugin-sdk/runtime-group-policy` | 런타임 group-policy 해석 helper |
| `plugin-sdk/channel-status` | 공용 channel 상태 스냅샷/요약 helper |
| `plugin-sdk/channel-config-primitives` | 좁은 범위의 channel config-schema primitives |
| `plugin-sdk/channel-config-writes` | Channel config-write 권한 부여 helper |
| `plugin-sdk/channel-plugin-common` | 공용 channel plugin prelude exports |
| `plugin-sdk/allowlist-config-edit` | 허용 목록 config 편집/읽기 helper |
| `plugin-sdk/group-access` | 공용 group-access 결정 helper |
| `plugin-sdk/direct-dm` | 공용 direct-DM auth/guard helper |
| `plugin-sdk/interactive-runtime` | 대화형 reply payload 정규화/축소 helper |
| `plugin-sdk/channel-inbound` | 수신 debounce, mention 매칭, mention-policy helper 및 envelope helper |
| `plugin-sdk/channel-send-result` | Reply 결과 타입 |
| `plugin-sdk/channel-actions` | `createMessageToolButtonsSchema`, `createMessageToolCardSchema` |
| `plugin-sdk/channel-targets` | 대상 파싱/매칭 helper |
| `plugin-sdk/channel-contract` | 채널 계약 타입 |
| `plugin-sdk/channel-feedback` | 피드백/반응 연결 |
| `plugin-sdk/channel-secret-runtime` | `collectSimpleChannelFieldAssignments`, `getChannelSurface`, `pushAssignment`, secret 대상 타입 같은 좁은 secret 계약 helper |
| `plugin-sdk/channel-contract` | Channel 계약 타입 |
| `plugin-sdk/channel-feedback` | 피드백/reaction wiring |
| `plugin-sdk/channel-secret-runtime` | `collectSimpleChannelFieldAssignments`, `getChannelSurface`, `pushAssignment` 및 secret 대상 타입 같은 좁은 범위의 secret-contract helper |
</Accordion>
<Accordion title="Provider 하위 경로">
| 하위 경로 | 주요 exports |
| Subpath | 주요 exports |
| --- | --- |
| `plugin-sdk/provider-entry` | `defineSingleProviderPluginEntry` |
| `plugin-sdk/provider-setup` | 엄선된 로컬/자체 호스팅 provider setup helper |
| `plugin-sdk/self-hosted-provider-setup` | 집중된 OpenAI 호환 자체 호스팅 provider setup helper |
| `plugin-sdk/provider-setup` | 선별된 local/self-hosted provider setup helper |
| `plugin-sdk/self-hosted-provider-setup` | 집중된 OpenAI 호환 self-hosted provider setup helper |
| `plugin-sdk/cli-backend` | CLI backend 기본값 + watchdog 상수 |
| `plugin-sdk/provider-auth-runtime` | provider plugins용 런타임 API 키 해석 helper |
| `plugin-sdk/provider-auth-api-key` | `upsertApiKeyProfile` 같은 API 키 onboarding/profile-write helper |
| `plugin-sdk/provider-auth-result` | 표준 OAuth auth-result builder |
| `plugin-sdk/provider-auth-login` | provider plugins용 공통 interactive login helper |
| `plugin-sdk/provider-env-vars` | provider 인증 env-var 조회 helper |
| `plugin-sdk/provider-auth-result` | 표준 OAuth auth-result 빌더 |
| `plugin-sdk/provider-auth-login` | provider plugins용 공용 대화형 로그인 helper |
| `plugin-sdk/provider-env-vars` | Provider auth env-var 조회 helper |
| `plugin-sdk/provider-auth` | `createProviderApiKeyAuthMethod`, `ensureApiKeyFromOptionEnvOrPrompt`, `upsertAuthProfile`, `upsertApiKeyProfile`, `writeOAuthCredentials` |
| `plugin-sdk/provider-model-shared` | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`, 공통 replay-policy builder, provider-endpoint helper, 그리고 `normalizeNativeXaiModelId` 같은 model-id 정규화 helper |
| `plugin-sdk/provider-model-shared` | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`, 공용 replay-policy 빌더, provider-endpoint helper, `normalizeNativeXaiModelId` 같은 model-id 정규화 helper |
| `plugin-sdk/provider-catalog-shared` | `findCatalogTemplate`, `buildSingleProviderApiKeyCatalog`, `supportsNativeStreamingUsageCompat`, `applyProviderNativeStreamingUsageCompat` |
| `plugin-sdk/provider-http` | generic provider HTTP/endpoint capability helper |
| `plugin-sdk/provider-web-fetch-contract` | `enablePluginInConfig`, `WebFetchProviderPlugin` 같은 좁은 web-fetch config/selection 계약 helper |
| `plugin-sdk/provider-web-fetch` | web-fetch provider 등록/캐시 helper |
| `plugin-sdk/provider-web-search-contract` | `enablePluginInConfig`, `resolveProviderWebSearchPluginConfig`, 범위 지정된 자격 증명 setter/getter 같은 좁은 web-search config/credential 계약 helper |
| `plugin-sdk/provider-web-search` | web-search provider 등록/캐시/런타임 helper |
| `plugin-sdk/provider-tools` | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`, Gemini 스키마 정리 + 진단, 그리고 `resolveXaiModelCompatPatch` / `applyXaiModelCompat` 같은 xAI 호환 helper |
| `plugin-sdk/provider-http` | 일반적인 provider HTTP/endpoint capability helper |
| `plugin-sdk/provider-web-fetch-contract` | `enablePluginInConfig``WebFetchProviderPlugin` 같은 좁은 범위의 web-fetch config/selection 계약 helper |
| `plugin-sdk/provider-web-fetch` | Web-fetch provider 등록/cache helper |
| `plugin-sdk/provider-web-search-config-contract` | plugin-enable wiring이 필요 없는 provider를 위한 좁은 범위의 web-search config/credential helper |
| `plugin-sdk/provider-web-search-contract` | `createWebSearchProviderContractFields`, `enablePluginInConfig`, `resolveProviderWebSearchPluginConfig`, 범위가 지정된 credential setter/getter 같은 좁은 범위의 web-search config/credential 계약 helper |
| `plugin-sdk/provider-web-search` | Web-search provider 등록/cache/런타임 helper |
| `plugin-sdk/provider-tools` | `ProviderToolCompatFamily`, `buildProviderToolCompatFamilyHooks`, Gemini 스키마 정리 + 진단, `resolveXaiModelCompatPatch` / `applyXaiModelCompat` 같은 xAI 호환 helper |
| `plugin-sdk/provider-usage` | `fetchClaudeUsage` 등 |
| `plugin-sdk/provider-stream` | `ProviderStreamFamily`, `buildProviderStreamFamilyHooks`, `composeProviderStreamWrappers`, 스트림 wrapper 타입, 그리고 공통 Anthropic/Bedrock/Google/Kilocode/Moonshot/OpenAI/OpenRouter/Z.A.I/MiniMax/Copilot wrapper helper |
| `plugin-sdk/provider-onboard` | onboarding config patch helper |
| `plugin-sdk/provider-stream` | `ProviderStreamFamily`, `buildProviderStreamFamilyHooks`, `composeProviderStreamWrappers`, stream wrapper 타입, 공용 Anthropic/Bedrock/Google/Kilocode/Moonshot/OpenAI/OpenRouter/Z.A.I/MiniMax/Copilot wrapper helper |
| `plugin-sdk/provider-onboard` | Onboarding config patch helper |
| `plugin-sdk/global-singleton` | 프로세스 로컬 singleton/map/cache helper |
</Accordion>
<Accordion title="인증 및 보안 하위 경로">
| 하위 경로 | 주요 exports |
<Accordion title="Auth 및 보안 하위 경로">
| Subpath | 주요 exports |
| --- | --- |
| `plugin-sdk/command-auth` | `resolveControlCommandGate`, command registry helper, sender-authorization helper |
| `plugin-sdk/command-auth` | `resolveControlCommandGate`, command 레지스트리 helper, sender-authorization helper |
| `plugin-sdk/command-status` | `buildCommandsMessagePaginated`, `buildHelpMessage` 같은 command/help 메시지 빌더 |
| `plugin-sdk/approval-auth-runtime` | 승인자 해석 및 same-chat action-auth helper |
| `plugin-sdk/approval-client-runtime` | 네이티브 exec 승인 profile/filter helper |
| `plugin-sdk/approval-delivery-runtime` | 네이티브 승인 capability/delivery adapter |
| `plugin-sdk/approval-gateway-runtime` | 공 승인 gateway-resolution helper |
| `plugin-sdk/approval-handler-adapter-runtime` | hot 채널 entrypoint용 경량 네이티브 승인 adapter 로딩 helper |
| `plugin-sdk/approval-handler-runtime` | 더 넓은 승인 handler 런타임 helper; 좁은 adapter/gateway seam으로 충분하다면 그것들을 우선 사용하세요 |
| `plugin-sdk/approval-gateway-runtime` | 공 승인 gateway-resolution helper |
| `plugin-sdk/approval-handler-adapter-runtime` | 핫 channel entrypoint용 경량 네이티브 승인 adapter 로딩 helper |
| `plugin-sdk/approval-handler-runtime` | 더 넓은 범위의 승인 handler 런타임 helper. 좁은 adapter/gateway seam으로 충분하면 그것을 우선 사용하세요 |
| `plugin-sdk/approval-native-runtime` | 네이티브 승인 대상 + account-binding helper |
| `plugin-sdk/approval-reply-runtime` | exec/plugin 승인 reply payload helper |
| `plugin-sdk/approval-reply-runtime` | Exec/plugin 승인 reply payload helper |
| `plugin-sdk/command-auth-native` | 네이티브 command auth + 네이티브 session-target helper |
| `plugin-sdk/command-detection` | 공 command 감지 helper |
| `plugin-sdk/command-surface` | command-body 정규화 및 command-surface helper |
| `plugin-sdk/command-detection` | 공 command 감지 helper |
| `plugin-sdk/command-surface` | Command-body 정규화 및 command-surface helper |
| `plugin-sdk/allow-from` | `formatAllowFromLowercase` |
| `plugin-sdk/channel-secret-runtime` | 채널/plugin secret 표면용 좁은 secret 계약 수집 helper |
| `plugin-sdk/secret-ref-runtime` | secret-contract/config 파싱용 좁은 `coerceSecretRef` 및 SecretRef 타이핑 helper |
| `plugin-sdk/security-runtime` | 공통 신뢰, DM gating, external-content, secret-collection helper |
| `plugin-sdk/ssrf-policy` | 호스트 allowlist 및 private-network SSRF policy helper |
| `plugin-sdk/ssrf-runtime` | pinned-dispatcher, SSRF 보호 fetch, SSRF policy helper |
| `plugin-sdk/secret-input` | secret 입력 파싱 helper |
| `plugin-sdk/webhook-ingress` | webhook 요청/대상 helper |
| `plugin-sdk/webhook-request-guards` | 요청 본문 크기/timeout helper |
| `plugin-sdk/channel-secret-runtime` | channel/plugin secret 표면용 좁은 범위의 secret-contract 수집 helper |
| `plugin-sdk/secret-ref-runtime` | secret-contract/config 파싱용 좁은 범위의 `coerceSecretRef` 및 SecretRef 타입 helper |
| `plugin-sdk/security-runtime` | 공용 신뢰, DM 게이팅, 외부 콘텐츠, secret 수집 helper |
| `plugin-sdk/ssrf-policy` | 호스트 허용 목록 및 private-network SSRF 정책 helper |
| `plugin-sdk/ssrf-runtime` | pinned-dispatcher, SSRF 보호 fetch, SSRF 정책 helper |
| `plugin-sdk/secret-input` | Secret 입력 파싱 helper |
| `plugin-sdk/webhook-ingress` | Webhook 요청/대상 helper |
| `plugin-sdk/webhook-request-guards` | 요청 본문 크기/시간 초과 helper |
</Accordion>
<Accordion title="런타임 및 저장소 하위 경로">
| 하위 경로 | 주요 exports |
| Subpath | 주요 exports |
| --- | --- |
| `plugin-sdk/runtime` | 넓은 범위의 런타임/로깅/백업/plugin-install helper |
| `plugin-sdk/runtime` | 폭넓은 런타임/로깅/백업/plugin 설치 helper |
| `plugin-sdk/runtime-env` | 좁은 범위의 런타임 env, logger, timeout, retry, backoff helper |
| `plugin-sdk/channel-runtime-context` | generic 채널 runtime-context 등록 및 조회 helper |
| `plugin-sdk/channel-runtime-context` | 일반적인 channel runtime-context 등록 및 조회 helper |
| `plugin-sdk/runtime-store` | `createPluginRuntimeStore` |
| `plugin-sdk/plugin-runtime` | 공 plugin command/hook/http/interactive helper |
| `plugin-sdk/hook-runtime` | 공 webhook/internal hook 파이프라인 helper |
| `plugin-sdk/lazy-runtime` | `createLazyRuntimeModule`, `createLazyRuntimeMethod`, `createLazyRuntimeSurface` 같은 lazy 런타임 import/binding helper |
| `plugin-sdk/plugin-runtime` | 공 plugin command/hook/http/interactive helper |
| `plugin-sdk/hook-runtime` | 공 webhook/internal hook 파이프라인 helper |
| `plugin-sdk/lazy-runtime` | `createLazyRuntimeModule`, `createLazyRuntimeMethod`, `createLazyRuntimeSurface` 같은 지연 런타임 import/binding helper |
| `plugin-sdk/process-runtime` | 프로세스 exec helper |
| `plugin-sdk/cli-runtime` | CLI formatting, wait, version helper |
| `plugin-sdk/gateway-runtime` | Gateway 클라이언트 및 채널 상태 patch helper |
| `plugin-sdk/cli-runtime` | CLI 서식 지정, 대기, 버전 helper |
| `plugin-sdk/gateway-runtime` | Gateway client 및 channel-status patch helper |
| `plugin-sdk/config-runtime` | Config 로드/쓰기 helper |
| `plugin-sdk/telegram-command-config` | 번들 Telegram 계약 표면을 사용할 수 없더라도 Telegram command-name/description 정규화 및 중복/충돌 검사 |
| `plugin-sdk/approval-runtime` | exec/plugin 승인 helper, 승인 capability builder, auth/profile helper, 네이티브 라우팅/런타임 helper |
| `plugin-sdk/reply-runtime` | 공통 인바운드/reply 런타임 helper, 청킹, 디스패치, heartbeat, reply planner |
| `plugin-sdk/reply-dispatch-runtime` | 좁은 reply dispatch/finalize helper |
| `plugin-sdk/reply-history` | `buildHistoryContext`, `recordPendingHistoryEntry`, `clearHistoryEntriesIfEnabled` 같은 공통 짧은 창 reply-history helper |
| `plugin-sdk/telegram-command-config` | 번들 Telegram 계약 표면을 사용할 수 없을 때도 Telegram command-name/description 정규화 및 중복/충돌 검사 |
| `plugin-sdk/approval-runtime` | Exec/plugin 승인 helper, 승인-capability 빌더, auth/profile helper, 네이티브 라우팅/런타임 helper |
| `plugin-sdk/reply-runtime` | 공용 수신/reply 런타임 helper, chunking, dispatch, heartbeat, reply planner |
| `plugin-sdk/reply-dispatch-runtime` | 좁은 범위의 reply dispatch/finalize helper |
| `plugin-sdk/reply-history` | `buildHistoryContext`, `recordPendingHistoryEntry`, `clearHistoryEntriesIfEnabled` 같은 공용 짧은 기간 reply-history helper |
| `plugin-sdk/reply-reference` | `createReplyReferencePlanner` |
| `plugin-sdk/reply-chunking` | 좁은 텍스트/Markdown 청킹 helper |
| `plugin-sdk/reply-chunking` | 좁은 범위의 텍스트/markdown chunking helper |
| `plugin-sdk/session-store-runtime` | 세션 저장소 경로 + updated-at helper |
| `plugin-sdk/state-paths` | 상태/OAuth 디렉터리 경로 helper |
| `plugin-sdk/routing` | `resolveAgentRoute`, `buildAgentSessionKey`, `resolveDefaultAgentBoundAccountId` 같은 route/session-key/account binding helper |
| `plugin-sdk/status-helpers` | 공통 채널/계정 상태 summary helper, runtime-state 기본값, issue 메타데이터 helper |
| `plugin-sdk/target-resolver-runtime` | 공통 대상 resolver helper |
| `plugin-sdk/routing` | `resolveAgentRoute`, `buildAgentSessionKey`, `resolveDefaultAgentBoundAccountId` 같은 route/session-key/account 바인딩 helper |
| `plugin-sdk/status-helpers` | 공용 channel/account 상태 요약 helper, 런타임 상태 기본값, issue 메타데이터 helper |
| `plugin-sdk/target-resolver-runtime` | 공용 대상 해석 helper |
| `plugin-sdk/string-normalization-runtime` | slug/string 정규화 helper |
| `plugin-sdk/request-url` | fetch/request 유사 입력에서 문자열 URL 추출 |
| `plugin-sdk/run-command` | 정규화된 stdout/stderr 결과를 포함하는 timed command runner |
| `plugin-sdk/param-readers` | 공통 tool/CLI param reader |
| `plugin-sdk/tool-send` | tool 인수에서 canonical send target 필드 추출 |
| `plugin-sdk/temp-path` | 공통 임시 다운로드 경로 helper |
| `plugin-sdk/logging-core` | subsystem logger 및 redaction helper |
| `plugin-sdk/markdown-table-runtime` | Markdown 테이블 모드 helper |
| `plugin-sdk/json-store` | 소규모 JSON 상태 읽기/쓰기 helper |
| `plugin-sdk/file-lock` | 재진입 가능 파일 잠금 helper |
| `plugin-sdk/persistent-dedupe` | 디스크 기반 dedupe 캐시 helper |
| `plugin-sdk/run-command` | 정규화된 stdout/stderr 결과를 반환하는 시간 제한 command 실행기 |
| `plugin-sdk/param-readers` | 공용 tool/CLI 매개변수 리더 |
| `plugin-sdk/tool-payload` | tool 결과 객체에서 정규화된 payload 추출 |
| `plugin-sdk/tool-send` | tool args에서 정식 send 대상 필드 추출 |
| `plugin-sdk/temp-path` | 공용 임시 다운로드 경로 helper |
| `plugin-sdk/logging-core` | 서브시스템 logger 및 redaction helper |
| `plugin-sdk/markdown-table-runtime` | Markdown 표 모드 helper |
| `plugin-sdk/json-store` | 작은 JSON 상태 읽기/쓰기 helper |
| `plugin-sdk/file-lock` | 재진입 가능한 파일 잠금 helper |
| `plugin-sdk/persistent-dedupe` | 디스크 기반 dedupe cache helper |
| `plugin-sdk/acp-runtime` | ACP 런타임/세션 및 reply-dispatch helper |
| `plugin-sdk/agent-config-primitives` | 좁은 범위의 agent 런타임 config-schema primitive |
| `plugin-sdk/boolean-param` | 느슨한 boolean param reader |
| `plugin-sdk/agent-config-primitives` | 좁은 범위의 agent 런타임 config-schema primitives |
| `plugin-sdk/boolean-param` | 느슨한 boolean 매개변수 리더 |
| `plugin-sdk/dangerous-name-runtime` | 위험한 이름 매칭 해석 helper |
| `plugin-sdk/device-bootstrap` | 디바이스 bootstrap 및 페어링 토큰 helper |
| `plugin-sdk/extension-shared` | 공 passive-channel, 상태, ambient proxy helper primitive |
| `plugin-sdk/extension-shared` | 공 passive-channel, 상태, ambient proxy helper primitives |
| `plugin-sdk/models-provider-runtime` | `/models` command/provider reply helper |
| `plugin-sdk/skill-commands-runtime` | Skills command 목록 helper |
| `plugin-sdk/native-command-registry` | 네이티브 command registry/build/serialize helper |
| `plugin-sdk/native-command-registry` | 네이티브 command 레지스트리/build/serialize helper |
| `plugin-sdk/provider-zai-endpoint` | Z.AI endpoint 감지 helper |
| `plugin-sdk/infra-runtime` | 시스템 이벤트/heartbeat helper |
| `plugin-sdk/collection-runtime` | 소형 bounded cache helper |
| `plugin-sdk/collection-runtime` | 작은 bounded cache helper |
| `plugin-sdk/diagnostic-runtime` | 진단 플래그 및 이벤트 helper |
| `plugin-sdk/error-runtime` | 오류 그래프, formatting, 공통 오류 분류 helper, `isApprovalNotFoundError` |
| `plugin-sdk/error-runtime` | 오류 그래프, 서식 지정, 공용 오류 분류 helper, `isApprovalNotFoundError` |
| `plugin-sdk/fetch-runtime` | 래핑된 fetch, proxy, pinned lookup helper |
| `plugin-sdk/host-runtime` | 호스트명 및 SCP 호스트 정규화 helper |
| `plugin-sdk/retry-runtime` | retry config 및 retry runner helper |
| `plugin-sdk/agent-runtime` | agent 디렉터리/identity/workspace helper |
| `plugin-sdk/directory-runtime` | config 기반 디렉터리 query/dedup |
| `plugin-sdk/retry-runtime` | Retry config 및 retry 실행 helper |
| `plugin-sdk/agent-runtime` | agent 디렉터리/식별자/워크스페이스 helper |
| `plugin-sdk/directory-runtime` | config 기반 디렉터리 질의/dedup |
| `plugin-sdk/keyed-async-queue` | `KeyedAsyncQueue` |
</Accordion>
<Accordion title="Capability 및 테스트 하위 경로">
| 하위 경로 | 주요 exports |
| Subpath | 주요 exports |
| --- | --- |
| `plugin-sdk/media-runtime` | 공통 미디어 fetch/transform/store helper와 media payload builder |
| `plugin-sdk/media-generation-runtime` | 공 media-generation failover helper, 후보 선택, 누락된 모델 메시지 처리 |
| `plugin-sdk/media-understanding` | media understanding provider 타입과 provider 대상 이미지/오디오 helper export |
| `plugin-sdk/text-runtime` | assistant-visible-text 제거, Markdown render/chunking/table helper, redaction helper, directive-tag helper, safe-text utility 같은 공통 텍스트/Markdown/로깅 helper |
| `plugin-sdk/text-chunking` | 아웃바운드 텍스트 청킹 helper |
| `plugin-sdk/speech` | speech provider 타입과 provider 대상 directive, registry, validation helper |
| `plugin-sdk/speech-core` | 공통 speech provider 타입, registry, directive, 정규화 helper |
| `plugin-sdk/realtime-transcription` | realtime transcription provider 타입 및 registry helper |
| `plugin-sdk/realtime-voice` | realtime voice provider 타입 및 registry helper |
| `plugin-sdk/image-generation` | image generation provider 타입 |
| `plugin-sdk/image-generation-core` | 공통 image-generation 타입, failover, auth, registry helper |
| `plugin-sdk/music-generation` | music generation provider/request/result 타입 |
| `plugin-sdk/music-generation-core` | 공통 music-generation 타입, failover helper, provider lookup, model-ref 파싱 |
| `plugin-sdk/video-generation` | video generation provider/request/result 타입 |
| `plugin-sdk/video-generation-core` | 공통 video-generation 타입, failover helper, provider lookup, model-ref 파싱 |
| `plugin-sdk/webhook-targets` | webhook 대상 registry 및 route-install helper |
| `plugin-sdk/webhook-path` | webhook 경로 정규화 helper |
| `plugin-sdk/web-media` | 공 원격/로컬 미디어 로딩 helper |
| `plugin-sdk/zod` | plugin SDK 소비자를 위한 재export된 `zod` |
| `plugin-sdk/media-runtime` | 공용 미디어 fetch/transform/store helper 및 미디어 payload 빌더 |
| `plugin-sdk/media-generation-runtime` | 공 media-generation failover helper, 후보 선택, 모델 누락 메시지 처리 |
| `plugin-sdk/media-understanding` | Media understanding provider 타입 및 provider용 이미지/오디오 helper export |
| `plugin-sdk/text-runtime` | assistant-visible-text 제거, markdown render/chunking/table helper, redaction helper, directive-tag helper, safe-text 유틸리티 같은 공용 텍스트/markdown/로깅 helper |
| `plugin-sdk/text-chunking` | 송신 텍스트 chunking helper |
| `plugin-sdk/speech` | Speech provider 타입 및 provider용 directive, 레지스트리, 검증 helper |
| `plugin-sdk/speech-core` | 공용 speech provider 타입, 레지스트리, directive, 정규화 helper |
| `plugin-sdk/realtime-transcription` | Realtime transcription provider 타입 및 레지스트리 helper |
| `plugin-sdk/realtime-voice` | Realtime voice provider 타입 및 레지스트리 helper |
| `plugin-sdk/image-generation` | Image generation provider 타입 |
| `plugin-sdk/image-generation-core` | 공용 image-generation 타입, failover, auth, 레지스트리 helper |
| `plugin-sdk/music-generation` | Music generation provider/request/result 타입 |
| `plugin-sdk/music-generation-core` | 공용 music-generation 타입, failover helper, provider 조회, model-ref 파싱 |
| `plugin-sdk/video-generation` | Video generation provider/request/result 타입 |
| `plugin-sdk/video-generation-core` | 공용 video-generation 타입, failover helper, provider 조회, model-ref 파싱 |
| `plugin-sdk/webhook-targets` | Webhook 대상 레지스트리 및 route-install helper |
| `plugin-sdk/webhook-path` | Webhook 경로 정규화 helper |
| `plugin-sdk/web-media` | 공 원격/로컬 미디어 로딩 helper |
| `plugin-sdk/zod` | Plugin SDK 소비자를 위한 재export된 `zod` |
| `plugin-sdk/testing` | `installCommonResolveTargetErrorCases`, `shouldAckReaction` |
</Accordion>
<Accordion title="메모리 하위 경로">
| 하위 경로 | 주요 exports |
<Accordion title="Memory 하위 경로">
| Subpath | 주요 exports |
| --- | --- |
| `plugin-sdk/memory-core` | manager/config/file/CLI helper를 위한 번들 memory-core helper 표면 |
| `plugin-sdk/memory-core-engine-runtime` | 메모리 index/search 런타임 facade |
| `plugin-sdk/memory-core-host-engine-foundation` | 메모리 호스트 foundation engine exports |
| `plugin-sdk/memory-core-host-engine-embeddings` | 메모리 호스트 embedding engine exports |
| `plugin-sdk/memory-core-host-engine-qmd` | 메모리 호스트 QMD engine exports |
| `plugin-sdk/memory-core-host-engine-storage` | 메모리 호스트 storage engine exports |
| `plugin-sdk/memory-core-host-multimodal` | 메모리 호스트 multimodal helper |
| `plugin-sdk/memory-core-host-query` | 메모리 호스트 query helper |
| `plugin-sdk/memory-core-host-secret` | 메모리 호스트 secret helper |
| `plugin-sdk/memory-core-host-events` | 메모리 호스트 event journal helper |
| `plugin-sdk/memory-core-host-status` | 메모리 호스트 상태 helper |
| `plugin-sdk/memory-core-host-runtime-cli` | 메모리 호스트 CLI 런타임 helper |
| `plugin-sdk/memory-core-host-runtime-core` | 메모리 호스트 core 런타임 helper |
| `plugin-sdk/memory-core-host-runtime-files` | 메모리 호스트 파일/런타임 helper |
| `plugin-sdk/memory-host-core` | 메모리 호스트 core 런타임 helper를 위한 vendor-neutral 별칭 |
| `plugin-sdk/memory-host-events` | 메모리 호스트 event journal helper를 위한 vendor-neutral 별칭 |
| `plugin-sdk/memory-host-files` | 메모리 호스트 파일/런타임 helper를 위한 vendor-neutral 별칭 |
| `plugin-sdk/memory-host-markdown` | 메모리 인접 plugins용 공통 managed-markdown helper |
| `plugin-sdk/memory-host-search` | search-manager 접근용 활성 메모리 런타임 facade |
| `plugin-sdk/memory-host-status` | 메모리 호스트 상태 helper를 위한 vendor-neutral 별칭 |
| `plugin-sdk/memory-core-engine-runtime` | Memory index/search 런타임 파사드 |
| `plugin-sdk/memory-core-host-engine-foundation` | Memory host foundation engine exports |
| `plugin-sdk/memory-core-host-engine-embeddings` | Memory host embedding engine exports |
| `plugin-sdk/memory-core-host-engine-qmd` | Memory host QMD engine exports |
| `plugin-sdk/memory-core-host-engine-storage` | Memory host storage engine exports |
| `plugin-sdk/memory-core-host-multimodal` | Memory host multimodal helper |
| `plugin-sdk/memory-core-host-query` | Memory host query helper |
| `plugin-sdk/memory-core-host-secret` | Memory host secret helper |
| `plugin-sdk/memory-core-host-events` | Memory host 이벤트 저널 helper |
| `plugin-sdk/memory-core-host-status` | Memory host 상태 helper |
| `plugin-sdk/memory-core-host-runtime-cli` | Memory host CLI 런타임 helper |
| `plugin-sdk/memory-core-host-runtime-core` | Memory host core 런타임 helper |
| `plugin-sdk/memory-core-host-runtime-files` | Memory host 파일/런타임 helper |
| `plugin-sdk/memory-host-core` | 메모리 host core 런타임 helper를 위한 vendor-neutral 별칭 |
| `plugin-sdk/memory-host-events` | 메모리 host 이벤트 저널 helper를 위한 vendor-neutral 별칭 |
| `plugin-sdk/memory-host-files` | 메모리 host 파일/런타임 helper를 위한 vendor-neutral 별칭 |
| `plugin-sdk/memory-host-markdown` | 메모리 인접 plugins를 위한 공용 managed-markdown helper |
| `plugin-sdk/memory-host-search` | search-manager 접근을 위한 활성 메모리 런타임 파사드 |
| `plugin-sdk/memory-host-status` | 메모리 host 상태 helper를 위한 vendor-neutral 별칭 |
| `plugin-sdk/memory-lancedb` | 번들 memory-lancedb helper 표면 |
</Accordion>
<Accordion title="예약된 번들 helper 하위 경로">
| 계열 | 현재 하위 경로 | 의도된 용도 |
<Accordion title="예약된 bundled-helper 하위 경로">
| Family | 현재 하위 경로 | 의도된 용도 |
| --- | --- | --- |
| Browser | `plugin-sdk/browser-cdp`, `plugin-sdk/browser-config-runtime`, `plugin-sdk/browser-config-support`, `plugin-sdk/browser-control-auth`, `plugin-sdk/browser-node-runtime`, `plugin-sdk/browser-profiles`, `plugin-sdk/browser-security-runtime`, `plugin-sdk/browser-setup-tools`, `plugin-sdk/browser-support` | 번들 browser plugin 지원 helper (`browser-support`는 호환성 barrel로 유지됨) |
| Browser | `plugin-sdk/browser-cdp`, `plugin-sdk/browser-config-runtime`, `plugin-sdk/browser-config-support`, `plugin-sdk/browser-control-auth`, `plugin-sdk/browser-node-runtime`, `plugin-sdk/browser-profiles`, `plugin-sdk/browser-security-runtime`, `plugin-sdk/browser-setup-tools`, `plugin-sdk/browser-support` | 번들 browser plugin 지원 helper(`browser-support`는 호환성 barrel로 유지됨) |
| Matrix | `plugin-sdk/matrix`, `plugin-sdk/matrix-helper`, `plugin-sdk/matrix-runtime-heavy`, `plugin-sdk/matrix-runtime-shared`, `plugin-sdk/matrix-runtime-surface`, `plugin-sdk/matrix-surface`, `plugin-sdk/matrix-thread-bindings` | 번들 Matrix helper/런타임 표면 |
| Line | `plugin-sdk/line`, `plugin-sdk/line-core`, `plugin-sdk/line-runtime`, `plugin-sdk/line-surface` | 번들 LINE helper/런타임 표면 |
| IRC | `plugin-sdk/irc`, `plugin-sdk/irc-surface` | 번들 IRC helper 표면 |
| 채널별 helper | `plugin-sdk/googlechat`, `plugin-sdk/zalouser`, `plugin-sdk/bluebubbles`, `plugin-sdk/bluebubbles-policy`, `plugin-sdk/mattermost`, `plugin-sdk/mattermost-policy`, `plugin-sdk/feishu-conversation`, `plugin-sdk/msteams`, `plugin-sdk/nextcloud-talk`, `plugin-sdk/nostr`, `plugin-sdk/tlon`, `plugin-sdk/twitch` | 번들 채널 호환성/helper seam |
| 인증/plugin별 helper | `plugin-sdk/github-copilot-login`, `plugin-sdk/github-copilot-token`, `plugin-sdk/diagnostics-otel`, `plugin-sdk/diffs`, `plugin-sdk/llm-task`, `plugin-sdk/thread-ownership`, `plugin-sdk/voice-call` | 번들 기능/plugin helper seam; `plugin-sdk/github-copilot-token`은 현재 `DEFAULT_COPILOT_API_BASE_URL`, `deriveCopilotApiBaseUrlFromToken`, `resolveCopilotApiToken`을 export |
| Channel 전용 helper | `plugin-sdk/googlechat`, `plugin-sdk/zalouser`, `plugin-sdk/bluebubbles`, `plugin-sdk/bluebubbles-policy`, `plugin-sdk/mattermost`, `plugin-sdk/mattermost-policy`, `plugin-sdk/feishu-conversation`, `plugin-sdk/msteams`, `plugin-sdk/nextcloud-talk`, `plugin-sdk/nostr`, `plugin-sdk/tlon`, `plugin-sdk/twitch` | 번들 channel 호환성/helper seam |
| Auth/plugin 전용 helper | `plugin-sdk/github-copilot-login`, `plugin-sdk/github-copilot-token`, `plugin-sdk/diagnostics-otel`, `plugin-sdk/diffs`, `plugin-sdk/llm-task`, `plugin-sdk/thread-ownership`, `plugin-sdk/voice-call` | 번들 기능/plugin helper seam; `plugin-sdk/github-copilot-token`은 현재 `DEFAULT_COPILOT_API_BASE_URL`, `deriveCopilotApiBaseUrlFromToken`, `resolveCopilotApiToken`을 export합니다 |
</Accordion>
</AccordionGroup>
## Registration API
## 등록 API
`register(api)` 콜백은 다음 메서드를 가진 `OpenClawPluginApi` 객체를 받습니다:
`register(api)` 콜백은 다음 메서드를 가진 `OpenClawPluginApi` 객체를 받습니다.
### Capability 등록
| 메서드 | 등록되는 항목 |
| ------------------------------------------------ | ---------------------------- |
| `api.registerProvider(...)` | 텍스트 추론 (LLM) |
| `api.registerCliBackend(...)` | 로컬 CLI 추론 backend |
| `api.registerChannel(...)` | 메시징 채널 |
| `api.registerSpeechProvider(...)` | 텍스트 음성 변환 / STT 합성 |
| `api.registerRealtimeTranscriptionProvider(...)` | 스트리밍 realtime transcription |
| `api.registerRealtimeVoiceProvider(...)` | 양방향 realtime voice 세션 |
| `api.registerMediaUnderstandingProvider(...)` | 이미지/오디오/비디오 분석 |
| `api.registerImageGenerationProvider(...)` | 이미지 생성 |
| `api.registerMusicGenerationProvider(...)` | 음악 생성 |
| `api.registerVideoGenerationProvider(...)` | 비디오 생성 |
| `api.registerWebFetchProvider(...)` | 웹 fetch / scrape provider |
| `api.registerWebSearchProvider(...)` | 웹 검색 |
| Method | 등록되는 항목 |
| ------------------------------------------------ | -------------------------------- |
| `api.registerProvider(...)` | 텍스트 추론(LLM) |
| `api.registerCliBackend(...)` | 로컬 CLI 추론 backend |
| `api.registerChannel(...)` | 메시징 channel |
| `api.registerSpeechProvider(...)` | 텍스트 음성 변환 / STT 합성 |
| `api.registerRealtimeTranscriptionProvider(...)` | 스트리밍 realtime transcription |
| `api.registerRealtimeVoiceProvider(...)` | 양방향 realtime 음성 세션 |
| `api.registerMediaUnderstandingProvider(...)` | 이미지/오디오/비디오 분석 |
| `api.registerImageGenerationProvider(...)` | 이미지 생성 |
| `api.registerMusicGenerationProvider(...)` | 음악 생성 |
| `api.registerVideoGenerationProvider(...)` | 비디오 생성 |
| `api.registerWebFetchProvider(...)` | 웹 fetch / scrape provider |
| `api.registerWebSearchProvider(...)` | 웹 검색 |
### Tools 및 commands
### 도구 및 commands
| 메서드 | 등록되는 항목 |
| ------------------------------- | -------------------------------------------- |
| `api.registerTool(tool, opts?)` | agent tool (필수 또는 `{ optional: true }`) |
| `api.registerCommand(def)` | custom command (LLM 우회) |
| Method | 등록되는 항목 |
| ------------------------------- | ---------------------------------------------- |
| `api.registerTool(tool, opts?)` | agent 도구(필수 또는 `{ optional: true }`) |
| `api.registerCommand(def)` | 사용자 지정 command(LLM 우회) |
### 인프라
| 메서드 | 등록되는 항목 |
| ---------------------------------------------- | --------------------------------------- |
| `api.registerHook(events, handler, opts?)` | 이벤트 hook |
| `api.registerHttpRoute(params)` | Gateway HTTP endpoint |
| `api.registerGatewayMethod(name, handler)` | Gateway RPC method |
| `api.registerCli(registrar, opts?)` | CLI 하위 명령 |
| `api.registerService(service)` | 백그라운드 서비스 |
| `api.registerInteractiveHandler(registration)` | interactive handler |
| `api.registerMemoryPromptSupplement(builder)` | 추가형 메모리 인접 prompt 섹션 |
| `api.registerMemoryCorpusSupplement(adapter)` | 추가형 메모리 검색/읽기 corpus |
| Method | 등록되는 항목 |
| ---------------------------------------------- | ---------------------------------------- |
| `api.registerHook(events, handler, opts?)` | 이벤트 hook |
| `api.registerHttpRoute(params)` | Gateway HTTP endpoint |
| `api.registerGatewayMethod(name, handler)` | Gateway RPC 메서드 |
| `api.registerCli(registrar, opts?)` | CLI 하위 명령 |
| `api.registerService(service)` | 백그라운드 서비스 |
| `api.registerInteractiveHandler(registration)` | 대화형 handler |
| `api.registerMemoryPromptSupplement(builder)` | 추가형 memory 인접 프롬프트 섹션 |
| `api.registerMemoryCorpusSupplement(adapter)` | 추가형 memory 검색/읽기 corpus |
예약된 core admin namespace(`config.*`, `exec.approvals.*`, `wizard.*`,
`update.*`)는 plugin이 더 좁은 gateway method 범위를
할당하려고 해도 항상 `operator.admin`으로 유지됩니다. plugin 소유 method에는
plugin별 접두사를 사용하는 것이 좋습니다.
예약된 core 관리자 네임스페이스(`config.*`, `exec.approvals.*`, `wizard.*`, `update.*`)는 plugin이 더 좁은 gateway 메서드 범위를 할당하려고 해도 항상 `operator.admin`으로 유지됩니다. plugin 소유 메서드에는 plugin 전용 접두사를 사용하는 것이 좋습니다.
### CLI 등록 메타데이터
`api.registerCli(registrar, opts?)`는 두 종류의 최상위 메타데이터를 받습니다:
`api.registerCli(registrar, opts?)`는 두 가지 종류의 최상위 메타데이터를 받습니다.
- `commands`: registrar가 소유하는 명시적인 command 루트
- `descriptors`: 루트 CLI 도움말,
라우팅, lazy plugin CLI 등록에 사용되는 parse 시점 command descriptor
- `commands`: registrar가 소유한 명시적 command 루트
- `descriptors`: 루트 CLI help, 라우팅, 지연 plugin CLI 등록에 사용되는 파싱 시점 command descriptor
plugin command가 일반 루트 CLI 경로에서 lazy-loaded 상태로 유지되게 하려면,
해당 registrar가 노출하는 모든 최상위 command 루트를 포괄하는 `descriptors`를 제공하세요.
plugin command를 일반 루트 CLI 경로에서 지연 로드 상태로 유지하려면, 해당 registrar가 노출하는 모든 최상위 command 루트를 포괄하는 `descriptors`를 제공하세요.
```typescript
api.registerCli(
@ -366,7 +345,7 @@ api.registerCli(
descriptors: [
{
name: "matrix",
description: "Matrix 계정, 검증, 디바이스, 프로필 상태 관리",
description: "Matrix 계정, 검증, 디바이스 프로필 상태 관리",
hasSubcommands: true,
},
],
@ -374,135 +353,107 @@ api.registerCli(
);
```
일반 루트 CLI 등록에 lazy 로딩이 필요하지 않은 경우에만 `commands`를 단독으로 사용하세요.
이 eager 호환성 경로는 계속 지원되지만, parse 시점 lazy 로딩을 위한
descriptor 기반 placeholder는 설치하지 않습니다.
지연 루트 CLI 등록이 필요하지 않을 때만 `commands`를 단독으로 사용하세요. 이 eager 호환성 경로는 여전히 지원되지만, 파싱 시점 지연 로드를 위한 descriptor 기반 placeholder는 설치하지 않습니다.
### CLI backend 등록
`api.registerCliBackend(...)`를 사용하면 plugin이 `codex-cli` 같은 로컬
AI CLI backend의 기본 config를 소유할 수 있습니다.
`api.registerCliBackend(...)`를 사용하면 plugin이 `codex-cli` 같은 로컬 AI CLI backend의 기본 config를 소유할 수 있습니다.
- backend `id``codex-cli/gpt-5` 같은 model ref의 provider 접두사가 됩니다.
- backend `config``agents.defaults.cliBackends.<id>`와 같은 형태를 사용합니다.
- 사용자 config가 여전히 우선합니다. OpenClaw는 CLI를 실행하기 전에
`agents.defaults.cliBackends.<id>`를 plugin 기본값 위에 병합합니다.
- backend가 병합 후 호환성 재작성 작업을 필요로 하는 경우
(예: 오래된 플래그 형태 정규화) `normalizeConfig`를 사용하세요.
- backend `config``agents.defaults.cliBackends.<id>`와 동일한 형태를 사용합니다.
- 사용자 config가 여전히 우선합니다. OpenClaw는 CLI를 실행하기 전에 plugin 기본값 위에 `agents.defaults.cliBackends.<id>`를 병합합니다.
- 병합 후 backend에 호환성 재작성(예: 이전 플래그 형태 정규화)이 필요하다면 `normalizeConfig`를 사용하세요.
### 독점 슬롯
### 배타적 슬롯
| 메서드 | 등록되는 항목 |
| ------------------------------------------ | ------------------------------------- |
| `api.registerContextEngine(id, factory)` | 컨텍스트 엔진 (한 번에 하나만 활성) |
| `api.registerMemoryCapability(capability)` | 통합 메모리 capability |
| `api.registerMemoryPromptSection(builder)` | 메모리 prompt 섹션 builder |
| `api.registerMemoryFlushPlan(resolver)` | 메모리 flush plan resolver |
| `api.registerMemoryRuntime(runtime)` | 메모리 런타임 adapter |
| Method | 등록되는 항목 |
| ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `api.registerContextEngine(id, factory)` | 컨텍스트 엔진(한 번에 하나만 활성). `assemble()` 콜백은 `availableTools``citationsMode`를 받아 엔진이 프롬프트 추가 내용을 맞춤 조정할 수 있게 합니다. |
| `api.registerMemoryCapability(capability)` | 통합 memory capability |
| `api.registerMemoryPromptSection(builder)` | Memory 프롬프트 섹션 빌더 |
| `api.registerMemoryFlushPlan(resolver)` | Memory flush plan resolver |
| `api.registerMemoryRuntime(runtime)` | Memory 런타임 adapter |
### 메모리 임베딩 adapter
### Memory embedding adapters
| 메서드 | 등록되는 항목 |
| Method | 등록되는 항목 |
| ---------------------------------------------- | -------------------------------------------------- |
| `api.registerMemoryEmbeddingProvider(adapter)` | 활성 plugin용 메모리 임베딩 adapter |
| `api.registerMemoryEmbeddingProvider(adapter)` | 활성 plugin용 memory embedding adapter |
- `registerMemoryCapability`가 권장되는 독점 메모리 plugin API입니다.
- `registerMemoryCapability`는 companion plugins가 특정
메모리 plugin의 비공개 레이아웃에 접근하지 않고
`openclaw/plugin-sdk/memory-host-core`를 통해 export된 메모리 artifact를 소비할 수 있도록
`publicArtifacts.listArtifacts(...)`도 노출할 수 있습니다.
- `registerMemoryPromptSection`, `registerMemoryFlushPlan`,
`registerMemoryRuntime`는 레거시 호환용 독점 메모리 plugin API입니다.
- `registerMemoryEmbeddingProvider`를 사용하면 활성 메모리 plugin이
하나 이상의 임베딩 adapter id(예: `openai`, `gemini`, 또는 사용자 정의
plugin 정의 id)를 등록할 수 있습니다.
- `agents.defaults.memorySearch.provider`,
`agents.defaults.memorySearch.fallback` 같은 사용자 config는
등록된 adapter id를 기준으로 해석됩니다.
- `registerMemoryCapability`가 권장되는 배타적 memory-plugin API입니다.
- `registerMemoryCapability`는 companion plugins가 특정 memory plugin의 private 레이아웃에 직접 접근하지 않고 `openclaw/plugin-sdk/memory-host-core`를 통해 export된 memory artifact를 사용할 수 있도록 `publicArtifacts.listArtifacts(...)`도 노출할 수 있습니다.
- `registerMemoryPromptSection`, `registerMemoryFlushPlan`, `registerMemoryRuntime`는 레거시 호환용 배타적 memory-plugin API입니다.
- `registerMemoryEmbeddingProvider`를 사용하면 활성 memory plugin이 하나 이상의 embedding adapter id(예: `openai`, `gemini`, 또는 plugin이 정의한 사용자 지정 id)를 등록할 수 있습니다.
- `agents.defaults.memorySearch.provider``agents.defaults.memorySearch.fallback` 같은 사용자 config는 이러한 등록된 adapter id를 기준으로 해석됩니다.
### 이벤트 및 수명 주기
### 이벤트 및 lifecycle
| 메서드 | 수행하는 작업 |
| -------------------------------------------- | -------------------------- |
| `api.on(hookName, handler, opts?)` | 타입 지정 lifecycle hook |
| `api.onConversationBindingResolved(handler)` | 대화 바인딩 콜백 |
| Method | 동작 |
| -------------------------------------------- | ---------------------------- |
| `api.on(hookName, handler, opts?)` | 타입 지정된 lifecycle hook |
| `api.onConversationBindingResolved(handler)` | 대화 바인딩 콜백 |
### Hook 결정 의미
- `before_tool_call`: `{ block: true }`를 반환하면 최종 결정입니다. 어떤 handler든 이를 설정하면 더 낮은 우선순위 handler는 건너뜁니다.
- `before_tool_call`: `{ block: false }`를 반환하면 결정 없음으로 처리됩니다(`block`을 생략한 것과 동일). override로 처리되지 않습니다.
- `before_install`: `{ block: true }`를 반환하면 최종 결정입니다. 어떤 handler든 이를 설정하면 더 낮은 우선순위 handler는 건너뜁니다.
- `before_install`: `{ block: false }`를 반환하면 결정 없음으로 처리됩니다(`block`을 생략한 것과 동일). override로 처리되지 않습니다.
- `reply_dispatch`: `{ handled: true, ... }`를 반환하면 최종 결정입니다. 어떤 handler든 디스패치를 가져가면 더 낮은 우선순위 handler와 기본 모델 디스패치 경로는 건너뜁니다.
- `message_sending`: `{ cancel: true }`를 반환하면 최종 결정입니다. 어떤 handler든 이를 설정하면 더 낮은 우선순위 handler는 건너뜁니다.
- `message_sending`: `{ cancel: false }`를 반환하면 결정 없음으로 처리됩니다(`cancel`을 생략한 것과 동일). override로 처리되지 않습니다.
- `before_tool_call`: `{ block: true }`를 반환하면 종료됩니다. 어떤 handler든 이를 설정하면 더 낮은 우선순위 handler는 건너뜁니다.
- `before_tool_call`: `{ block: false }`를 반환하면 결정 없음(`block` 생략과 동일)으로 처리되며, override가 아닙니다.
- `before_install`: `{ block: true }`를 반환하면 종료됩니다. 어떤 handler든 이를 설정하면 더 낮은 우선순위 handler는 건너뜁니다.
- `before_install`: `{ block: false }`를 반환하면 결정 없음(`block` 생략과 동일)으로 처리되며, override가 아닙니다.
- `reply_dispatch`: `{ handled: true, ... }`를 반환하면 종료됩니다. 어떤 handler든 dispatch를 처리했다고 선언하면 더 낮은 우선순위 handler와 기본 모델 dispatch 경로를 건너뜁니다.
- `message_sending`: `{ cancel: true }`를 반환하면 종료됩니다. 어떤 handler든 이를 설정하면 더 낮은 우선순위 handler는 건너뜁니다.
- `message_sending`: `{ cancel: false }`를 반환하면 결정 없음(`cancel` 생략과 동일)으로 처리되며, override가 아닙니다.
### API 객체 필드
| 필드 | 타입 | 설명 |
| ------------------------ | ------------------------- | ------------------------------------------------------------------------------------ |
| `api.id` | `string` | Plugin id |
| `api.name` | `string` | 표시 이름 |
| `api.version` | `string?` | Plugin 버전 (선택 사항) |
| `api.description` | `string?` | Plugin 설명 (선택 사항) |
| `api.source` | `string` | Plugin 소스 경로 |
| `api.rootDir` | `string?` | Plugin 루트 디렉터리 (선택 사항) |
| `api.config` | `OpenClawConfig` | 현재 config snapshot (가능한 경우 활성 메모리 내 런타임 snapshot) |
| `api.pluginConfig` | `Record<string, unknown>` | `plugins.entries.<id>.config`의 plugin별 config |
| `api.runtime` | `PluginRuntime` | [Runtime helpers](/ko/plugins/sdk-runtime) |
| `api.logger` | `PluginLogger` | 범위 지정 logger (`debug`, `info`, `warn`, `error`) |
| `api.registrationMode` | `PluginRegistrationMode` | 현재 로드 모드; `"setup-runtime"`은 전체 entry 이전의 경량 시작/setup 구간입니다 |
| `api.resolvePath(input)` | `(string) => string` | plugin 루트를 기준으로 경로 해석 |
| Field | Type | 설명 |
| ------------------------ | ------------------------- | -------------------------------------------------------------------------------------------- |
| `api.id` | `string` | Plugin id |
| `api.name` | `string` | 표시 이름 |
| `api.version` | `string?` | Plugin 버전(선택 사항) |
| `api.description` | `string?` | Plugin 설명(선택 사항) |
| `api.source` | `string` | Plugin 소스 경로 |
| `api.rootDir` | `string?` | Plugin 루트 디렉터리(선택 사항) |
| `api.config` | `OpenClawConfig` | 현재 config 스냅샷(사용 가능할 경우 활성 in-memory 런타임 스냅샷) |
| `api.pluginConfig` | `Record<string, unknown>` | `plugins.entries.<id>.config`의 plugin 전용 config |
| `api.runtime` | `PluginRuntime` | [Runtime helpers](/ko/plugins/sdk-runtime) |
| `api.logger` | `PluginLogger` | 범위 지정 logger(`debug`, `info`, `warn`, `error`) |
| `api.registrationMode` | `PluginRegistrationMode` | 현재 로드 모드. `"setup-runtime"`은 가벼운 전체 entry 이전 시작/setup 구간입니다 |
| `api.resolvePath(input)` | `(string) => string` | plugin 루트를 기준으로 경로 해석 |
## 내부 모듈 규칙
plugin 내부에서는 내부 import에 로컬 barrel 파일을 사용하세요:
plugin 내부에서는 내부 import에 로컬 barrel 파일을 사용하세요.
```
my-plugin/
api.ts # 외부 소비자를 위한 공개 exports
api.ts # 외부 소비자를 위한 public exports
runtime-api.ts # 내부 전용 런타임 exports
index.ts # Plugin entry point
setup-entry.ts # 경량 setup 전용 entry (선택 사항)
setup-entry.ts # 가벼운 setup 전용 entry(선택 사항)
```
<Warning>
프로덕션 코드에서 자신의 plugin을 `openclaw/plugin-sdk/<your-plugin>`을 통해
import하지 마세요. 내부 import는 `./api.ts` 또는
`./runtime-api.ts`를 통해 처리하세요. SDK 경로는 외부 계약 전용입니다.
프로덕션 코드에서 `openclaw/plugin-sdk/<your-plugin>`을 통해 자신의 plugin을 절대 import하지 마세요. 내부 import는 `./api.ts` 또는 `./runtime-api.ts`를 통해 처리하세요. SDK 경로는 외부 계약 전용입니다.
</Warning>
Facade로 로드되는 번들 plugin 공개 표면(`api.ts`, `runtime-api.ts`,
`index.ts`, `setup-entry.ts`, 및 유사한 공개 entry 파일)은 이제
OpenClaw가 이미 실행 중인 경우 활성 런타임 config snapshot을 우선 사용합니다. 아직 런타임
snapshot이 없으면, 디스크에서 해석된 config 파일로 대체합니다.
파사드로 로드되는 번들 plugin public 표면(`api.ts`, `runtime-api.ts`, `index.ts`, `setup-entry.ts` 및 유사한 public entry 파일)은 이제 OpenClaw가 이미 실행 중일 때 활성 런타임 config 스냅샷을 우선 사용합니다. 아직 런타임 스냅샷이 없으면 디스크의 해석된 config 파일로 폴백합니다.
Provider plugins는 helper가 의도적으로 provider 전용이며 아직 generic SDK
하위 경로에 속하지 않을 때, 좁은 범위의 plugin 로컬 계약 barrel을 노출할 수도 있습니다. 현재 번들 예시:
Anthropic provider는 Anthropic beta-header와 `service_tier` 로직을 generic
`plugin-sdk/*` 계약으로 승격하는 대신 자체 공개 `api.ts` / `contract-api.ts` seam에
Claude stream helper를 유지합니다.
Provider plugins는 helper가 의도적으로 provider 전용이고 아직 일반적인 SDK 하위 경로에 속하지 않을 경우 좁은 범위의 plugin 로컬 계약 barrel도 노출할 수 있습니다. 현재 번들 예시: Anthropic provider는 Anthropic 베타 헤더와 `service_tier` 로직을 일반적인 `plugin-sdk/*` 계약으로 올리는 대신 Claude stream helper를 자체 public `api.ts` / `contract-api.ts` seam에 유지합니다.
기타 현재 번들 예시:
그 밖의 현재 번들 예시:
- `@openclaw/openai-provider`: `api.ts`는 provider builder,
default-model helper, realtime provider builder를 export합니다
- `@openclaw/openrouter-provider`: `api.ts`는 provider builder와
onboarding/config helper를 export합니다
- `@openclaw/openai-provider`: `api.ts`는 provider 빌더, 기본 model helper, realtime provider 빌더를 export합니다
- `@openclaw/openrouter-provider`: `api.ts`는 provider 빌더와 onboarding/config helper를 export합니다
<Warning>
extension 프로덕션 코드도 `openclaw/plugin-sdk/<other-plugin>`
import를 피해야 합니다. helper가 진정으로 공유되어야 한다면,
두 plugins를 결합시키는 대신
`openclaw/plugin-sdk/speech`, `.../provider-model-shared`, 또는 다른
capability 지향 표면 같은 중립적인 SDK 하위 경로로 승격하세요.
확장 프로덕션 코드도 `openclaw/plugin-sdk/<other-plugin>` import를 피해야 합니다. helper가 정말 공용이어야 한다면 두 plugins를 결합하는 대신 `openclaw/plugin-sdk/speech`, `.../provider-model-shared` 또는 다른 capability 지향 표면 같은 중립적인 SDK 하위 경로로 승격하세요.
</Warning>
## 관련 항목
## 관련 문서
- [Entry Points](/ko/plugins/sdk-entrypoints) — `definePluginEntry``defineChannelPluginEntry` 옵션
- [Runtime Helpers](/ko/plugins/sdk-runtime) — 전체 `api.runtime` namespace 참조
- [Setup and Config](/ko/plugins/sdk-setup) — 패키징, manifest, config 스키마
- [Runtime Helpers](/ko/plugins/sdk-runtime) — 전체 `api.runtime` 네임스페이스 참조
- [Setup and Config](/ko/plugins/sdk-setup) — 패키징, 매니페스트, config 스키마
- [Testing](/ko/plugins/sdk-testing) — 테스트 유틸리티 및 lint 규칙
- [SDK Migration](/ko/plugins/sdk-migration) — deprecated 표면에서 마이그레이션
- [Plugin Internals](/ko/plugins/architecture) — 심 아키텍처 및 capability 모델
- [SDK Migration](/ko/plugins/sdk-migration) — 더 이상 권장되지 않는 표면에서 마이그레이션
- [Plugin Internals](/ko/plugins/architecture) — 심 아키텍처 및 capability 모델

View File

@ -1,33 +1,33 @@
---
read_when:
- 새 모델 제공자 플러그인을 구축하고 있습니다
- OpenAI 호환 프록시 또는 사용자 지정 LLM을 OpenClaw에 추가하려고 합니다
- 제공자 인증, 카탈로그, 런타임 을 이해해야 합니다
- OpenAI 호환 프록시나 커스텀 LLM을 OpenClaw에 추가하려고 합니다
- 제공자 인증, 카탈로그, 런타임 hook을 이해해야 합니다
sidebarTitle: Provider Plugins
summary: OpenClaw용 모델 제공자 플러그인을 구축하는 단계별 가이드
title: 제공자 플러그인 구축하기
x-i18n:
generated_at: "2026-04-07T06:02:12Z"
generated_at: "2026-04-09T01:31:20Z"
model: gpt-5.4
provider: openai
source_hash: 4da82a353e1bf4fe6dc09e14b8614133ac96565679627de51415926014bd3990
source_hash: 38d9af522dc19e49c81203a83a4096f01c2398b1df771c848a30ad98f251e9e1
source_path: plugins/sdk-provider-plugins.md
workflow: 15
---
# 제공자 플러그인 구축하기
이 가이드는 OpenClaw에 모델 제공자(LLM)를 추가하는 제공자 플러그인을
구축하는 과정을 안내합니다. 이 과정을 마치면 모델 카탈로그,
이 가이드는 OpenClaw에 모델 제공자
(LLM)를 추가하는 제공자 플러그인을 구축하는 과정을 설명합니다. 끝까지 따라가면 모델 카탈로그,
API 키 인증, 동적 모델 해석을 갖춘 제공자를 만들 수 있습니다.
<Info>
아직 OpenClaw 플러그인을 한 번도 만들어본 적이 없다면,
먼저 [시작하기](/ko/plugins/building-plugins)를 읽고 기본 패키지 구조와
매니페스트 설정을 확인하세요.
아직 OpenClaw 플러그인을 한 번도 만들어 본 적이 없다면,
먼저 [시작하기](/ko/plugins/building-plugins)를 읽고 기본 패키지
구조와 매니페스트 설정을 확인하세요.
</Info>
## 단계별 안내
## 따라 하기
<Steps>
<a id="step-1-package-and-manifest"></a>
@ -65,6 +65,9 @@ API 키 인증, 동적 모델 해석을 갖춘 제공자를 만들 수 있습니
"providerAuthEnvVars": {
"acme-ai": ["ACME_AI_API_KEY"]
},
"providerAuthAliases": {
"acme-ai-coding": "acme-ai"
},
"providerAuthChoices": [
{
"provider": "acme-ai",
@ -86,13 +89,12 @@ API 키 인증, 동적 모델 해석을 갖춘 제공자를 만들 수 있습니
```
</CodeGroup>
매니페스트는 `providerAuthEnvVars`를 선언하여 OpenClaw가
플러그인 런타임을 로드하지 않고도 자격 증명을 감지할 수 있게 합니다.
`modelSupport`는 선택 사항이며, 런타임 훅이 존재하기 전에도
`acme-large` 같은 축약형 모델 id로부터 OpenClaw가 제공자 플러그인을
자동 로드할 수 있게 합니다. 제공자를 ClawHub에 게시하는 경우,
`package.json``openclaw.compat``openclaw.build` 필드는
필수입니다.
매니페스트는 `providerAuthEnvVars`를 선언하므로 OpenClaw가
플러그인 런타임을 로드하지 않고도 자격 증명을 감지할 수 있습니다. 제공자 변형이 다른 제공자 id의 인증을 재사용해야 하는 경우
`providerAuthAliases`를 추가하세요. `modelSupport`는 선택 사항이며, 런타임 hook이 생기기 전에
`acme-large` 같은 축약형 모델 id에서 OpenClaw가 제공자 플러그인을 자동 로드하도록 해줍니다.
제공자를 ClawHub에 게시하는 경우 `package.json`
`openclaw.compat``openclaw.build` 필드는 필수입니다.
</Step>
@ -168,12 +170,12 @@ API 키 인증, 동적 모델 해석을 갖춘 제공자를 만들 수 있습니
});
```
이것으로 동작하는 제공자가 됩니다. 이제 사용자는
이것으로 동작하는 제공자가 완성됩니다. 이제 사용자는
`openclaw onboard --acme-ai-api-key <key>`를 실행하고
`acme-ai/acme-large` 모델로 선택할 수 있습니다.
모델로 `acme-ai/acme-large`를 선택할 수 있습니다.
API 키 인증과 단일 카탈로그 기반 런타임만 등록하는 텍스트 제공자 하나로
구성된 번들 제공자의 경우, 더 좁은 범위의
API 키 인증이 있는 텍스트 제공자 하나와 카탈로그 기반 런타임 하나만 등록하는 번들 제공자의 경우,
더 좁은 범위의
`defineSingleProviderPluginEntry(...)` 헬퍼를 사용하는 것이 좋습니다:
```typescript
@ -209,26 +211,24 @@ API 키 인증, 동적 모델 해석을 갖춘 제공자를 만들 수 있습니
});
```
인증 흐름이 온보딩 중에 `models.providers.*`, 별칭, 에이전트 기본 모델까지
함께 패치해야 한다면
`openclaw/plugin-sdk/provider-onboard`의 프리셋 헬퍼를 사용하세요.
가장 좁은 범위의 헬퍼는
인증 흐름이 온보딩 중 `models.providers.*`, 별칭, 에이전트 기본 모델도 함께 수정해야 한다면
`openclaw/plugin-sdk/provider-onboard`의 프리셋 헬퍼를 사용하세요. 가장 범위가 좁은 헬퍼는
`createDefaultModelPresetAppliers(...)`,
`createDefaultModelsPresetAppliers(...)`,
`createDefaultModelsPresetAppliers(...)`, 그리고
`createModelCatalogPresetAppliers(...)`입니다.
제공자의 네이티브 엔드포인트가 일반 `openai-completions` 전송에서
스트리밍 사용량 블록을 지원하는 경우, 제공자 id 검사 코드를 하드코딩하는 대신
`openclaw/plugin-sdk/provider-catalog-shared`의 공용 카탈로그 헬퍼를
사용하는 것이 좋습니다. `supportsNativeStreamingUsageCompat(...)`
`applyProviderNativeStreamingUsageCompat(...)`는 엔드포인트 기능 맵에서
지원 여부를 감지하므로, 사용자 지정 제공자 id를 사용하는 플러그인이라도
네이티브 Moonshot/DashScope 스타일 엔드포인트는 여전히 옵트인할 수 있습니다.
제공자의 네이티브 엔드포인트가 일반 `openai-completions` 전송에서 스트리밍된 사용량 블록을 지원한다면,
제공자 id 검사를 하드코딩하는 대신
`openclaw/plugin-sdk/provider-catalog-shared`의 공유 카탈로그 헬퍼를 사용하는 것이 좋습니다.
`supportsNativeStreamingUsageCompat(...)`
`applyProviderNativeStreamingUsageCompat(...)`는 엔드포인트 capability 맵에서 지원 여부를 감지하므로,
플러그인이 커스텀 제공자 id를 사용하더라도 네이티브 Moonshot/DashScope 스타일 엔드포인트를 계속
opt in할 수 있습니다.
</Step>
<Step title="동적 모델 해석 추가">
제공자가 임의의 모델 ID(프록시나 라우터처럼)를 허용하는 경우,
제공자가 프록시나 라우터처럼 임의의 모델 ID를 허용한다면
`resolveDynamicModel`을 추가하세요:
```typescript
@ -251,17 +251,16 @@ API 키 인증, 동적 모델 해석을 갖춘 제공자를 만들 수 있습니
```
해석에 네트워크 호출이 필요하다면 비동기 워밍업을 위해
`prepareDynamicModel`을 사용하세요. 완료 후 `resolveDynamicModel`
다시 실행됩니다.
`prepareDynamicModel`을 사용하세요. 완료되면 `resolveDynamicModel`이 다시 실행됩니다.
</Step>
<Step title="런타임 추가(필요한 경우)">
대부분의 제공자는 `catalog``resolveDynamicModel`만 필요합니다.
제공자에 필요한 만큼 훅을 점진적으로 추가하세요.
<Step title="런타임 hook 추가(필요한 경우)">
대부분의 제공자는 `catalog` + `resolveDynamicModel`만 있으면 됩니다. 제공자에 필요해질 때만
점진적으로 hook을 추가하세요.
이제 공용 헬퍼 빌더가 가장 흔한 replay/tool-compat 계열을 다루므로,
플러그인은 보통 각 훅을 하나씩 직접 연결할 필요가 없습니다:
이제 공유 헬퍼 빌더가 가장 일반적인 replay/tool-compat
계열을 다루므로, 보통 플러그인에서 각 hook을 하나씩 직접 연결할 필요가 없습니다:
```typescript
import { buildProviderReplayFamilyHooks } from "openclaw/plugin-sdk/provider-model-shared";
@ -283,113 +282,115 @@ API 키 인증, 동적 모델 해석을 갖춘 제공자를 만들 수 있습니
현재 사용 가능한 replay 계열:
| 계열 | 연결되는 항목 |
| Family | 연결되는 항목 |
| --- | --- |
| `openai-compatible` | OpenAI 호환 전송을 위한 공용 OpenAI 스타일 replay 정책. tool-call-id 정리, assistant-first 순서 수정, 그리고 전송 계층에서 필요할 때의 일반적인 Gemini 턴 검증을 포함합니다 |
| `anthropic-by-model` | `modelId`로 선택되는 Claude 인지 replay 정책. Anthropic 메시지 전송은 해석된 모델이 실제 Claude id일 때만 Claude 전용 thinking 블록 정리를 적용합니다 |
| `google-gemini` | 네이티브 Gemini replay 정책과 bootstrap replay 정리, 태그된 reasoning-output 모드 |
| `passthrough-gemini` | OpenAI 호환 프록시 전송을 통해 실행되는 Gemini 모델용 Gemini thought-signature 정리. 네이티브 Gemini replay 검증이나 bootstrap 재작성은 활성화하지 않습니다 |
| `hybrid-anthropic-openai` | 하나의 플러그인에서 Anthropic 메시지와 OpenAI 호환 모델 표면을 함께 제공하는 제공자를 위한 하이브리드 정책. 선택적인 Claude 전용 thinking 블록 제거는 Anthropic 쪽에만 한정됩니다 |
| `openai-compatible` | 도구 호출 ID 정리, assistant-first 순서 수정, 전송에 필요할 때의 일반 Gemini 턴 검증을 포함한 공유 OpenAI 스타일 replay 정책 |
| `anthropic-by-model` | `modelId`로 선택되는 Claude 인식 replay 정책으로, Anthropic-message 전송이 실제 해석된 모델이 Claude id일 때만 Claude 전용 thinking 블록 정리를 받도록 함 |
| `google-gemini` | 네이티브 Gemini replay 정책, bootstrap replay 정리, 태그형 추론 출력 모드 |
| `passthrough-gemini` | OpenAI 호환 프록시 전송을 통해 실행되는 Gemini 모델의 Gemini thought-signature 정리; 네이티브 Gemini replay 검증이나 bootstrap 재작성을 활성화하지 않음 |
| `hybrid-anthropic-openai` | 하나의 플러그인 안에서 Anthropic-message와 OpenAI 호환 모델 표면을 혼합하는 제공자를 위한 하이브리드 정책; 선택적인 Claude 전용 thinking 블록 제거는 Anthropic 쪽에만 한정됨 |
실제 번들 예시:
- `google`, `google-gemini-cli`: `google-gemini`
- `google` `google-gemini-cli`: `google-gemini`
- `openrouter`, `kilocode`, `opencode`, `opencode-go`: `passthrough-gemini`
- `amazon-bedrock`, `anthropic-vertex`: `anthropic-by-model`
- `amazon-bedrock` `anthropic-vertex`: `anthropic-by-model`
- `minimax`: `hybrid-anthropic-openai`
- `moonshot`, `ollama`, `xai`, `zai`: `openai-compatible`
현재 사용 가능한 스트림 계열:
현재 사용 가능한 stream 계열:
| 계열 | 연결되는 항목 |
| Family | 연결되는 항목 |
| --- | --- |
| `google-thinking` | 공용 스트림 경로에서의 Gemini thinking 페이로드 정규화 |
| `kilocode-thinking` | 공용 프록시 스트림 경로에서의 Kilo reasoning 래퍼. `kilo/auto`와 지원되지 않는 프록시 reasoning id는 주입된 thinking을 건너뜁니다 |
| `moonshot-thinking` | 설정 + `/think` 수준에서의 Moonshot 바이너리 native-thinking 페이로드 매핑 |
| `minimax-fast-mode` | 공용 스트림 경로에서의 MiniMax fast-mode 모델 재작성 |
| `openai-responses-defaults` | 공 네이티브 OpenAI/Codex Responses 래퍼: attribution 헤더, `/fast`/`serviceTier`, 텍스트 verbosity, 네이티브 Codex 웹 검색, reasoning-compat 페이로드 형성, Responses 컨텍스트 관리 |
| `openrouter-thinking` | 프록시 라우트용 OpenRouter reasoning 래퍼. 지원되지 않는 모델과 `auto` 건너뛰기를 중앙에서 처리합니다 |
| `tool-stream-default-on` | Z.AI 같은 제공자를 위한 기본 활성화 `tool_stream` 래퍼. 명시적으로 비활성화하지 않는 한 tool streaming을 사용합니다 |
| `google-thinking` | 공유 stream 경로에서 Gemini thinking 페이로드 정규화 |
| `kilocode-thinking` | 공유 프록시 stream 경로에서 Kilo 추론 래퍼를 적용하며, `kilo/auto`와 지원되지 않는 프록시 추론 id는 주입된 thinking을 건너뜀 |
| `moonshot-thinking` | config + `/think` 수준에서 Moonshot 이진 네이티브 thinking 페이로드 매핑 |
| `minimax-fast-mode` | 공유 stream 경로에서 MiniMax fast-mode 모델 재작성 |
| `openai-responses-defaults` | 공 네이티브 OpenAI/Codex Responses 래퍼: attribution 헤더, `/fast`/`serviceTier`, 텍스트 verbosity, 네이티브 Codex 웹 검색, 추론 호환 페이로드 형성, Responses 컨텍스트 관리 |
| `openrouter-thinking` | 프록시 경로를 위한 OpenRouter 추론 래퍼로, 지원되지 않는 모델/`auto` 건너뛰기를 중앙에서 처리 |
| `tool-stream-default-on` | Z.AI 같은 제공자를 위한 기본 활성화 `tool_stream` 래퍼로, 명시적으로 비활성화되지 않는 한 도구 스트리밍을 사용함 |
실제 번들 예시:
- `google`, `google-gemini-cli`: `google-thinking`
- `google` `google-gemini-cli`: `google-thinking`
- `kilocode`: `kilocode-thinking`
- `moonshot`: `moonshot-thinking`
- `minimax`, `minimax-portal`: `minimax-fast-mode`
- `openai`, `openai-codex`: `openai-responses-defaults`
- `minimax` `minimax-portal`: `minimax-fast-mode`
- `openai` `openai-codex`: `openai-responses-defaults`
- `openrouter`: `openrouter-thinking`
- `zai`: `tool-stream-default-on`
`openclaw/plugin-sdk/provider-model-shared`는 replay 계열 enum과
해당 계열이 기반으로 하는 공용 헬퍼도 내보냅니다. 일반적인 공개 export는
다음과 같습니다:
`openclaw/plugin-sdk/provider-model-shared`는 replay-family
enum과 해당 계열이 기반으로 하는 공유 헬퍼도 내보냅니다. 일반적인 공개 export에는 다음이 포함됩니다:
- `ProviderReplayFamily`
- `buildProviderReplayFamilyHooks(...)`
- `buildOpenAICompatibleReplayPolicy(...)`,
`buildAnthropicReplayPolicyForModel(...)`,
`buildGoogleGeminiReplayPolicy(...)`,
`buildHybridAnthropicOrOpenAIReplayPolicy(...)` 같은 공 replay 빌더
- `sanitizeGoogleGeminiReplayHistory(...)`,
`resolveTaggedReasoningOutputMode()` 같은 Gemini replay 헬퍼
`buildGoogleGeminiReplayPolicy(...)`, 그리고
`buildHybridAnthropicOrOpenAIReplayPolicy(...)` 같은 공 replay 빌더
- `sanitizeGoogleGeminiReplayHistory(...)`
`resolveTaggedReasoningOutputMode()` 같은 Gemini replay 헬퍼
- `resolveProviderEndpoint(...)`,
`normalizeProviderId(...)`, `normalizeGooglePreviewModelId(...)`,
`normalizeProviderId(...)`, `normalizeGooglePreviewModelId(...)`, 그리고
`normalizeNativeXaiModelId(...)` 같은 엔드포인트/모델 헬퍼
`openclaw/plugin-sdk/provider-stream`는 계열 빌더와 해당 계열이 재사용하는
공개 래퍼 헬퍼를 모두 노출합니다. 일반적인 공개 export는
다음과 같습니다:
`openclaw/plugin-sdk/provider-stream`은 family 빌더와
해당 family가 재사용하는 공개 래퍼 헬퍼를 모두 제공합니다. 일반적인 공개 export에는 다음이 포함됩니다:
- `ProviderStreamFamily`
- `buildProviderStreamFamilyHooks(...)`
- `composeProviderStreamWrappers(...)`
- `createOpenAIAttributionHeadersWrapper(...)`,
- 다음과 같은 공유 OpenAI/Codex 래퍼:
`createOpenAIAttributionHeadersWrapper(...)`,
`createOpenAIFastModeWrapper(...)`,
`createOpenAIServiceTierWrapper(...)`,
`createOpenAIResponsesContextManagementWrapper(...)`,
`createCodexNativeWebSearchWrapper(...)` 같은 공용 OpenAI/Codex 래퍼
`createOpenAIResponsesContextManagementWrapper(...)`, 그리고
`createCodexNativeWebSearchWrapper(...)`
- `createOpenRouterWrapper(...)`,
`createToolStreamWrapper(...)`, `createMinimaxFastModeWrapper(...)` 같은
프록시/제공자 래퍼
프록시/제공자 래퍼
일부 스트림 헬퍼는 의도적으로 제공자 로컬에 유지됩니다. 현재 번들 예시로
`@openclaw/anthropic-provider`는 공개 `api.ts` /
`contract-api.ts` 경계에서 `wrapAnthropicProviderStream`,
`resolveAnthropicBetas`, `resolveAnthropicFastMode`,
`resolveAnthropicServiceTier`, 그리고 더 낮은 수준의 Anthropic 래퍼 빌더를
export합니다. 이 헬퍼들은 Claude OAuth 베타 처리와 `context1m` 게이팅도
인코딩하기 때문에 Anthropic 전용으로 남아 있습니다.
일부 stream 헬퍼는 의도적으로 provider-local로 유지됩니다. 현재 번들
예시: `@openclaw/anthropic-provider`
공개 `api.ts` /
`contract-api.ts` 경계에서 `wrapAnthropicProviderStream`, `resolveAnthropicBetas`,
`resolveAnthropicFastMode`, `resolveAnthropicServiceTier`, 그리고
더 낮은 수준의 Anthropic 래퍼 빌더를 export합니다. 이 헬퍼들은
Claude OAuth 베타 처리와 `context1m` 게이팅도 함께 인코딩하므로
Anthropic 전용으로 유지됩니다.
다른 번들 제공자들도 동작을 계열 전반에 깔끔하게 공유하기 어려운 경우
전송 계층별 래퍼를 로컬에 유지합니다. 현재 예시로 번들 xAI 플러그인은
네이티브 xAI Responses 형성을 자체 `wrapStreamFn` 안에 유지하며,
여기에는 `/fast` 별칭 재작성, 기본 `tool_stream`,
지원되지 않는 strict-tool 정리, xAI 전용 reasoning 페이로드 제거가
포함됩니다.
다른 번들 제공자들도 동작이 계열 전체에 깔끔하게 공유되지 않는 경우
전송 전용 래퍼를 로컬에 유지합니다. 현재 예시: 번들 xAI 플러그인은
네이티브 xAI Responses 형성을 자체
`wrapStreamFn` 안에 유지하며, 여기에는 `/fast` 별칭 재작성, 기본 `tool_stream`,
지원되지 않는 strict-tool 정리, xAI 전용 추론 페이로드
제거가 포함됩니다.
`openclaw/plugin-sdk/provider-tools`는 현재 하나의 공용 도구 스키마 계열과
공용 스키마/호환성 헬퍼를 노출합니다:
`openclaw/plugin-sdk/provider-tools`는 현재 하나의 공
tool-schema 계열과 공유 스키마/호환성 헬퍼를 노출합니다:
- `ProviderToolCompatFamily`는 현재 공용 계열 목록을 문서화합니다.
- `buildProviderToolCompatFamilyHooks("gemini")`는 Gemini에 안전한 도구 스키마가 필요한 제공자를 위해 Gemini 스키마 정리와 진단을 연결합니다.
- `normalizeGeminiToolSchemas(...)``inspectGeminiToolSchemas(...)`는 기반이 되는 공개 Gemini 스키마 헬퍼입니다.
- `ProviderToolCompatFamily`는 현재의 공유 계열 목록을 문서화합니다.
- `buildProviderToolCompatFamilyHooks("gemini")`는 Gemini 안전 도구 스키마가 필요한 제공자를 위해
Gemini 스키마 정리 + 진단을 연결합니다.
- `normalizeGeminiToolSchemas(...)``inspectGeminiToolSchemas(...)`
그 기반이 되는 공개 Gemini 스키마 헬퍼입니다.
- `resolveXaiModelCompatPatch()`는 번들 xAI 호환성 패치를 반환합니다:
`toolSchemaProfile: "xai"`, 지원되지 않는 스키마 키워드, 네이티브
`web_search` 지원, HTML 엔티티 도구 호출 인수 디코딩.
- `applyXaiModelCompat(model)`은 실행기에 도달하기 전에 해석된 모델에
동일한 xAI 호환성 패치를 적용합니다.
`web_search` 지원, HTML 엔터티 도구 호출 인자 디코딩.
- `applyXaiModelCompat(model)`은 실행기에 도달하기 전에
동일한 xAI 호환성 패치를 해석된 모델에 적용합니다.
실제 번들 예시: xAI 플러그인은 `normalizeResolvedModel`
`contributeResolvedModelCompat`를 사용해 이 호환성 메타데이터를
코어에 xAI 규칙을 하드코딩하는 대신 제공자 소유로 유지합니다.
실제 번들 예시: xAI 플러그인은
코어에 xAI 규칙을 하드코딩하는 대신
`normalizeResolvedModel``contributeResolvedModelCompat`를 사용해 해당 호환성 메타데이터의 소유권을 제공자에 둡니다.
동일한 패키지 루트 패턴은 다른 번들 제공자에도 적용됩니다:
- `@openclaw/openai-provider`: `api.ts` 제공자 빌더,
기본 모델 헬퍼, 실시간 제공자 빌더를 export합니다
- `@openclaw/openrouter-provider`: `api.ts` 제공자 빌더와
온보딩/설정 헬퍼를 export합니다
- `@openclaw/openai-provider`: `api.ts` 제공자 빌더,
기본 모델 헬퍼, realtime 제공자 빌더를 export
- `@openclaw/openrouter-provider`: `api.ts` 제공자 빌더와
온보딩/config 헬퍼를 export
<Tabs>
<Tab title="토큰 교환">
@ -406,8 +407,8 @@ API 키 인증, 동적 모델 해석을 갖춘 제공자를 만들 수 있습니
},
```
</Tab>
<Tab title="사용자 지정 헤더">
사용자 지정 요청 헤더 또는 본문 수정이 필요한 제공자의 경우:
<Tab title="커스텀 헤더">
커스텀 요청 헤더나 본문 수정이 필요한 제공자의 경우:
```typescript
// wrapStreamFn은 ctx.streamFn에서 파생된 StreamFn을 반환합니다
@ -424,9 +425,8 @@ API 키 인증, 동적 모델 해석을 갖춘 제공자를 만들 수 있습니
},
```
</Tab>
<Tab title="네이티브 전송 식별자">
일반 HTTP 또는 WebSocket 전송에서 네이티브 요청/세션 헤더나
메타데이터가 필요한 제공자의 경우:
<Tab title="네이티브 전송 ID">
일반 HTTP 또는 WebSocket 전송에서 네이티브 요청/세션 헤더나 메타데이터가 필요한 제공자의 경우:
```typescript
resolveTransportTurnState: (ctx) => ({
@ -447,7 +447,7 @@ API 키 인증, 동적 모델 해석을 갖춘 제공자를 만들 수 있습니
```
</Tab>
<Tab title="사용량 및 과금">
사용량/과금 데이터를 제공하는 제공자의 경우:
사용량/과금 데이터를 노출하는 제공자의 경우:
```typescript
resolveUsageAuth: async (ctx) => {
@ -461,84 +461,83 @@ API 키 인증, 동적 모델 해석을 갖춘 제공자를 만들 수 있습니
</Tab>
</Tabs>
<Accordion title="사용 가능한 모든 제공자 ">
OpenClaw는 다음 순서로 을 호출합니다. 대부분의 제공자는 2~3개만 사용합니다:
<Accordion title="사용 가능한 모든 제공자 hook">
OpenClaw는 다음 순서로 hook을 호출합니다. 대부분의 제공자는 2~3개만 사용합니다:
| # | | 사용 시점 |
| # | Hook | 사용 시점 |
| --- | --- | --- |
| 1 | `catalog` | 모델 카탈로그 또는 기본 `baseUrl` |
| 2 | `applyConfigDefaults` | 설정 구체화 중 제공자 소유 전역 기본값 |
| 1 | `catalog` | 모델 카탈로그 또는 base URL 기본값 |
| 2 | `applyConfigDefaults` | config materialization 중 제공자 소유 전역 기본값 |
| 3 | `normalizeModelId` | 조회 전 레거시/프리뷰 모델 id 별칭 정리 |
| 4 | `normalizeTransport` | 일반 모델 조립 전 제공자 계열 `api` / `baseUrl` 정리 |
| 5 | `normalizeConfig` | `models.providers.<id>` 설정 정규화 |
| 6 | `applyNativeStreamingUsageCompat` | 설정 제공자를 위한 네이티브 streaming-usage 호환성 재작성 |
| 5 | `normalizeConfig` | `models.providers.<id>` config 정규화 |
| 6 | `applyNativeStreamingUsageCompat` | config 제공자용 네이티브 스트리밍 사용량 호환성 재작성 |
| 7 | `resolveConfigApiKey` | 제공자 소유 env-marker 인증 해석 |
| 8 | `resolveSyntheticAuth` | 로컬/자체 호스팅 또는 설정 기반 synthetic auth |
| 9 | `shouldDeferSyntheticProfileAuth` | synthetic 저장 프로필 플레이스홀더를 env/config 인증보다 뒤로 미루기 |
| 8 | `resolveSyntheticAuth` | 로컬/셀프호스트형 또는 config 기반 synthetic 인증 |
| 9 | `shouldDeferSyntheticProfileAuth` | synthetic 저장 프로필 플레이스홀더를 env/config 인증보다 뒤로 낮춤 |
| 10 | `resolveDynamicModel` | 임의의 업스트림 모델 ID 허용 |
| 11 | `prepareDynamicModel` | 해석 전 비동기 메타데이터 가져오기 |
| 12 | `normalizeResolvedModel` | 실행기 전 transport 재작성 |
| 11 | `prepareDynamicModel` | 해석 전 비동기 메타데이터 조회 |
| 12 | `normalizeResolvedModel` | 실행기 이전의 전송 재작성 |
런타임 폴백 참고 사항:
런타임 폴백 참고:
- `normalizeConfig`는 먼저 일치하는 제공자를 확인하고, 실제로 설정을 변경하는
훅 지원 제공자 플러그인이 나올 때까지 다른 훅 지원 제공자 플러그인을
확인합니다. 어떤 제공자 훅도 지원되는 Google 계열 설정 항목을
재작성하지 않으면 번들 Google 설정 정규화가 여전히 적용됩니다.
- `resolveConfigApiKey`는 제공자 훅이 노출된 경우 해당 훅을 사용합니다.
번들 `amazon-bedrock` 경로도 여기서 AWS env-marker 해석기를
내장하고 있지만, Bedrock 런타임 인증 자체는 여전히 AWS SDK 기본 체인을
사용합니다.
| 13 | `contributeResolvedModelCompat` | 다른 호환 전송 뒤에 있는 벤더 모델용 호환성 플래그 |
| 14 | `capabilities` | 레거시 정적 기능 가방; 호환성 전용 |
- `normalizeConfig`는 먼저 일치한 제공자를 확인한 다음,
실제로 config를 변경할 때까지 다른 hook 지원 제공자 플러그인을 확인합니다.
지원되는 Google 계열 config 항목을 어떤 제공자 hook도 재작성하지 않으면
번들된 Google config 정규화기가 계속 적용됩니다.
- `resolveConfigApiKey`는 노출된 경우 제공자 hook을 사용합니다. 번들된
`amazon-bedrock` 경로도 여기에서 내장 AWS env-marker 해석기를 가지지만,
Bedrock 런타임 인증 자체는 여전히 AWS SDK 기본 체인을 사용합니다.
| 13 | `contributeResolvedModelCompat` | 다른 호환 전송 뒤에 있는 공급업체 모델용 호환성 플래그 |
| 14 | `capabilities` | 레거시 정적 capability bag; 호환성 전용 |
| 15 | `normalizeToolSchemas` | 등록 전 제공자 소유 도구 스키마 정리 |
| 16 | `inspectToolSchemas` | 제공자 소유 도구 스키마 진단 |
| 17 | `resolveReasoningOutputMode` | 태그형 vs 네이티브 reasoning-output 계약 |
| 17 | `resolveReasoningOutputMode` | 태그형 대 네이티브 추론 출력 계약 |
| 18 | `prepareExtraParams` | 기본 요청 파라미터 |
| 19 | `createStreamFn` | 완전한 사용자 지정 StreamFn 전송 |
| 20 | `wrapStreamFn` | 일반 스트림 경로의 사용자 지정 헤더/본문 래퍼 |
| 19 | `createStreamFn` | 완전히 커스텀 StreamFn 전송 |
| 20 | `wrapStreamFn` | 일반 stream 경로의 커스텀 헤더/본문 래퍼 |
| 21 | `resolveTransportTurnState` | 네이티브 턴별 헤더/메타데이터 |
| 22 | `resolveWebSocketSessionPolicy` | 네이티브 WS 세션 헤더/쿨다운 |
| 23 | `formatApiKey` | 사용자 지정 런타임 토큰 형식 |
| 24 | `refreshOAuth` | 사용자 지정 OAuth 갱신 |
| 23 | `formatApiKey` | 커스텀 런타임 토큰 형태 |
| 24 | `refreshOAuth` | 커스텀 OAuth 갱신 |
| 25 | `buildAuthDoctorHint` | 인증 복구 안내 |
| 26 | `matchesContextOverflowError` | 제공자 소유 overflow 감지 |
| 26 | `matchesContextOverflowError` | 제공자 소유 오버플로 감지 |
| 27 | `classifyFailoverReason` | 제공자 소유 rate-limit/overload 분류 |
| 28 | `isCacheTtlEligible` | 프롬프트 캐시 TTL 게이팅 |
| 29 | `buildMissingAuthMessage` | 사용자 지정 누락 인증 힌트 |
| 29 | `buildMissingAuthMessage` | 커스텀 누락 인증 힌트 |
| 30 | `suppressBuiltInModel` | 오래된 업스트림 행 숨기기 |
| 31 | `augmentModelCatalog` | synthetic forward-compat 행 |
| 32 | `isBinaryThinking` | 바이너리 thinking 켜기/끄기 |
| 33 | `supportsXHighThinking` | `xhigh` reasoning 지원 |
| 31 | `augmentModelCatalog` | synthetic 순방향 호환 행 |
| 32 | `isBinaryThinking` | 이진 thinking on/off |
| 33 | `supportsXHighThinking` | `xhigh` 추론 지원 |
| 34 | `resolveDefaultThinkingLevel` | 기본 `/think` 정책 |
| 35 | `isModernModelRef` | 라이브/스모크 모델 매칭 |
| 35 | `isModernModelRef` | live/smoke 모델 매칭 |
| 36 | `prepareRuntimeAuth` | 추론 전 토큰 교환 |
| 37 | `resolveUsageAuth` | 사용자 지정 사용량 자격 증명 파싱 |
| 38 | `fetchUsageSnapshot` | 사용자 지정 사용량 엔드포인트 |
| 37 | `resolveUsageAuth` | 커스텀 사용량 자격 증명 파싱 |
| 38 | `fetchUsageSnapshot` | 커스텀 사용량 엔드포인트 |
| 39 | `createEmbeddingProvider` | 메모리/검색용 제공자 소유 임베딩 어댑터 |
| 40 | `buildReplayPolicy` | 사용자 지정 대화 기록 replay/압축 정책 |
| 40 | `buildReplayPolicy` | 커스텀 전사 기록 replay/압축 정책 |
| 41 | `sanitizeReplayHistory` | 일반 정리 후 제공자 전용 replay 재작성 |
| 42 | `validateReplayTurns` | 임베디드 실행기 전 엄격한 replay 턴 검증 |
| 42 | `validateReplayTurns` | 내장 실행기 전 엄격한 replay-turn 검증 |
| 43 | `onModelSelected` | 선택 후 콜백(예: 텔레메트리) |
프롬프트 튜닝 참고:
- `resolveSystemPromptContribution`은 제공자가 모델 계열용 캐시 인식
시스템 프롬프트 안내를 주입할 수 있게 합니다. 동작이 특정
제공자/모델 계열에 속하고 안정적/동적 캐시 분할을 유지해야 한다면
- `resolveSystemPromptContribution`을 사용하면 제공자가 모델 계열에 대한 캐시 인식
시스템 프롬프트 지침을 주입할 수 있습니다. 동작이 특정 제공자/모델
계열에 속하고 안정/동적 캐시 분리를 유지해야 한다면
`before_prompt_build`보다 이것을 사용하는 것이 좋습니다.
자세한 설명과 실제 예시는
[내부 구조: 제공자 런타임 훅](/ko/plugins/architecture#provider-runtime-hooks)을
참고하세요.
[내부 구조: 제공자 런타임 Hooks](/ko/plugins/architecture#provider-runtime-hooks)를 참조하세요.
</Accordion>
</Step>
<Step title="추가 기능 추가(선택 사항)">
<Step title="추가 capability 추가(선택 사항)">
<a id="step-5-add-extra-capabilities"></a>
제공자 플러그인은 텍스트 추론과 함께 음성, 실시간 전사, 실시간 음성,
미디어 이해, 이미지 생성, 비디오 생성, 웹 가져오기, 웹 검색도 등록할 수 있습니다:
제공자 플러그인은 텍스트 추론과 함께 음성, realtime 전사, realtime
음성, 미디어 이해, 이미지 생성, 비디오 생성, 웹 가져오기,
웹 검색을 등록할 수 있습니다:
```typescript
register(api) {
@ -646,21 +645,21 @@ API 키 인증, 동적 모델 해석을 갖춘 제공자를 만들 수 있습니
}
```
OpenClaw는 이를 **hybrid-capability** 플러그인으로 분류합니다.
이것은 회사용 플러그인(벤더당 하나의 플러그인)에 권장되는 패턴입니다.
[내부 구조: 기능 소유권](/ko/plugins/architecture#capability-ownership-model)을
참고하세요.
OpenClaw는 이를 **하이브리드 capability** 플러그인으로 분류합니다. 이것이
회사 플러그인(공급업체당 플러그인 하나)에 권장되는 패턴입니다.
[내부 구조: Capability 소유권](/ko/plugins/architecture#capability-ownership-model)을 참조하세요.
비디오 생성의 경우 위에 나온 모드 인식 기능 형태를 사용하는 것이 좋습니다:
`generate`, `imageToVideo`, `videoToVideo`. `maxInputImages`,
`maxInputVideos`, `maxDurationSeconds` 같은 평면 집계 필드만으로는
변환 모드 지원이나 비활성화된 모드를 명확하게 알리기에 충분하지 않습니다.
비디오 생성의 경우 위에 나온 모드 인식 capability 형태를 사용하는 것이 좋습니다:
`generate`, `imageToVideo`, `videoToVideo`. `maxInputImages`, `maxInputVideos`, `maxDurationSeconds` 같은
평평한 집계 필드만으로는
변환 모드 지원이나 비활성화된 모드를 깔끔하게 알리기에 충분하지 않습니다.
음악 생성 제공자도 동일한 패턴을 따라야 합니다:
프롬프트만 사용하는 생성에는 `generate`, 참조 이미지 기반 생성에는
`edit`를 사용합니다. `maxInputImages`, `supportsLyrics`,
`supportsFormat` 같은 평면 집계 필드만으로는 edit 지원을 알리기에
충분하지 않으며, 명시적인 `generate` / `edit` 블록이 기대되는 계약입니다.
음악 생성 제공자도 같은 패턴을 따라야 합니다:
프롬프트 전용 생성에는 `generate`, 참조 이미지 기반
생성에는 `edit`를 사용합니다. `maxInputImages`,
`supportsLyrics`, `supportsFormat` 같은 평평한 집계 필드만으로는 편집
지원을 알리기에 충분하지 않으며, 명시적인 `generate` / `edit` 블록이
기대되는 계약입니다.
</Step>
@ -668,11 +667,11 @@ API 키 인증, 동적 모델 해석을 갖춘 제공자를 만들 수 있습니
<a id="step-6-test"></a>
```typescript src/provider.test.ts
import { describe, it, expect } from "vitest";
// index.ts 또는 전용 파일에서 제공자 설정 객체를 export하세요
// index.ts 또는 전용 파일에서 제공자 config 객체를 export하세요
import { acmeProvider } from "./provider.js";
describe("acme-ai provider", () => {
it("동적 모델을 해석한다", () => {
it("resolves dynamic models", () => {
const model = acmeProvider.resolveDynamicModel!({
modelId: "acme-beta-v3",
} as any);
@ -680,14 +679,14 @@ API 키 인증, 동적 모델 해석을 갖춘 제공자를 만들 수 있습니
expect(model.provider).toBe("acme-ai");
});
it("키가 있으면 카탈로그를 반환한다", async () => {
it("returns catalog when key is available", async () => {
const result = await acmeProvider.catalog!.run({
resolveProviderApiKey: () => ({ apiKey: "test-key" }),
} as any);
expect(result?.provider?.models).toHaveLength(2);
});
it("키가 없으면 null 카탈로그를 반환한다", async () => {
it("returns null catalog when no key", async () => {
const result = await acmeProvider.catalog!.run({
resolveProviderApiKey: () => ({ apiKey: undefined }),
} as any);
@ -699,16 +698,16 @@ API 키 인증, 동적 모델 해석을 갖춘 제공자를 만들 수 있습니
</Step>
</Steps>
## ClawHub에 게시하기
## ClawHub에 게시
제공자 플러그인은 다른 외부 코드 플러그인과 동일한 방식으로 게시합니다:
제공자 플러그인은 다른 외부 코드 플러그인과 같은 방식으로 게시합니다:
```bash
clawhub package publish your-org/your-plugin --dry-run
clawhub package publish your-org/your-plugin
```
여기서는 레거시 skill 전용 게시 별칭을 사용하지 마세요. 플러그인 패키지는
여기서는 레거시 skill-only 게시 별칭을 사용하지 마세요. 플러그인 패키지는
`clawhub package publish`를 사용해야 합니다.
## 파일 구조
@ -716,7 +715,7 @@ clawhub package publish your-org/your-plugin
```
<bundled-plugin-root>/acme-ai/
├── package.json # openclaw.providers 메타데이터
├── openclaw.plugin.json # providerAuthEnvVars가 포함된 매니페스트
├── openclaw.plugin.json # 제공자 인증 메타데이터가 있는 매니페스트
├── index.ts # definePluginEntry + registerProvider
└── src/
├── provider.test.ts # 테스트
@ -725,18 +724,19 @@ clawhub package publish your-org/your-plugin
## 카탈로그 순서 참고
`catalog.order`는 내장 제공자에 비해 카탈로그가 언제 병합되는지 제어합니다:
`catalog.order`는 기본 제공
제공자에 비해 카탈로그가 언제 병합되는지를 제어합니다:
| 순서 | 시점 | 사용 사례 |
| Order | 시점 | 사용 사례 |
| --------- | ------------- | ----------------------------------------------- |
| `simple` | 첫 번째 패스 | 일반 API 키 제공자 |
| `profile` | simple 이후 | 인증 프로필에 따라 결정되는 제공자 |
| `paired` | profile 이후 | 여러 관련 항목 합성 |
| `late` | 마지막 패스 | 기존 제공자를 덮어씀(충돌 시 우선) |
| `simple` | 첫 번째 패스 | 일반 API 키 제공자 |
| `profile` | simple 이후 | 인증 프로필에 의해 제한되는 제공자 |
| `paired` | profile 이후 | 여러 관련 항목 합성 |
| `late` | 마지막 패스 | 기존 제공자 재정의(충돌 시 우선 적용) |
## 다음 단계
- [채널 플러그인](/ko/plugins/sdk-channel-plugins) — 플러그인이 채널도 제공하는 경우
- [SDK 런타임](/ko/plugins/sdk-runtime) — `api.runtime` 헬퍼(TTS, 검색, 서브에이전트)
- [SDK 개요](/ko/plugins/sdk-overview) — 전체 하위 경로 import 참
- [플러그인 내부 구조](/ko/plugins/architecture#provider-runtime-hooks) — 훅 세부 정보와 번들 예시
- [SDK Runtime](/ko/plugins/sdk-runtime) — `api.runtime` 헬퍼(TTS, 검색, 하위 에이전트)
- [SDK 개요](/ko/plugins/sdk-overview) — 전체 하위 경로 import 참
- [플러그인 내부 구조](/ko/plugins/architecture#provider-runtime-hooks) — hook 세부 사항 및 번들 예시

View File

@ -1,14 +1,14 @@
---
read_when:
- OpenClaw와 함께 Google Gemini 모델을 사용하려는 경우
- OpenClaw에서 Google Gemini 모델을 사용하려는 경우
- API 키 또는 OAuth 인증 흐름이 필요한 경우
summary: Google Gemini 설정(API 키 + OAuth, 이미지 생성, 미디어 이해, 웹 검색)
title: Google (Gemini)
x-i18n:
generated_at: "2026-04-08T02:17:36Z"
generated_at: "2026-04-09T01:30:29Z"
model: gpt-5.4
provider: openai
source_hash: e9e558f5ce35c853e0240350be9a1890460c5f7f7fd30b05813a656497dee516
source_hash: fad2ff68987301bd86145fa6e10de8c7b38d5bd5dbcd13db9c883f7f5b9a4e01
source_path: providers/google.md
workflow: 15
---
@ -19,19 +19,19 @@ Google plugin은 Google AI Studio를 통해 Gemini 모델에 대한 액세스를
Gemini Grounding을 통한 이미지 생성, 미디어 이해(이미지/오디오/비디오), 웹 검색도 지원합니다.
- Provider: `google`
- Auth: `GEMINI_API_KEY` 또는 `GOOGLE_API_KEY`
- 인증: `GEMINI_API_KEY` 또는 `GOOGLE_API_KEY`
- API: Google Gemini API
- 대체 provider: `google-gemini-cli` (OAuth)
## 빠른 시작
1. API 키를 설정합니다:
1. API 키를 설정합니다.
```bash
openclaw onboard --auth-choice gemini-api-key
```
2. 기본 모델을 설정합니다:
2. 기본 모델을 설정합니다.
```json5
{
@ -54,13 +54,13 @@ openclaw onboard --non-interactive \
## OAuth (Gemini CLI)
대체 provider인 `google-gemini-cli`는 API
키 대신 PKCE OAuth를 사용합니다. 이것은 비공식 통합이며, 일부 사용자는 계정
제한을 보고했습니다. 사용에 따른 책임은 본인에게 있습니다.
대체 provider인 `google-gemini-cli`는 API 키 대신 PKCE OAuth를 사용합니다.
이 통합은 비공식이며, 일부 사용자는 계정 제한을
보고했습니다. 사용에 따른 책임은 사용자에게 있습니다.
- 기본 모델: `google-gemini-cli/gemini-3-flash-preview`
- 별칭: `gemini-cli`
- 설치 선행 조건: 로컬 Gemini CLI를 `gemini`로 사용할 수 있어야 함
- 설치 전제 조건: 로컬 Gemini CLI를 `gemini`로 사용할 수 있어야 함
- Homebrew: `brew install gemini-cli`
- npm: `npm install -g @google/gemini-cli`
- 로그인:
@ -74,44 +74,47 @@ openclaw models auth login --provider google-gemini-cli --set-default
- `OPENCLAW_GEMINI_OAUTH_CLIENT_ID`
- `OPENCLAW_GEMINI_OAUTH_CLIENT_SECRET`
(`GEMINI_CLI_*` 변형도 가능)
(`GEMINI_CLI_*` 변형도 사용 가능)
로그인 후 Gemini CLI OAuth 요청이 실패하면
gateway 호스트에 `GOOGLE_CLOUD_PROJECT` 또는 `GOOGLE_CLOUD_PROJECT_ID`를 설정하고
게이트웨이 호스트에 `GOOGLE_CLOUD_PROJECT` 또는 `GOOGLE_CLOUD_PROJECT_ID`를 설정한 다음
다시 시도하세요.
브라우저 흐름이 시작되기 전에 로그인이 실패하면 로컬 `gemini`
명령이 설치되어 있고 `PATH`에 있는지 확인하세요. OpenClaw는 Homebrew 설치와
브라우저 흐름이 시작되기 전에 로그인이 실패하면, 로컬 `gemini`
명령이 설치되어 있고 `PATH`포함되어 있는지 확인하세요. OpenClaw는 Homebrew 설치와
전역 npm 설치를 모두 지원하며, 일반적인 Windows/npm 레이아웃도 포함합니다.
Gemini CLI JSON 사용 참고 사항:
- 응답 텍스트는 CLI JSON `response` 필드에서 가져옵니다.
- CLI가 `usage`를 비워 두면 사용량은 `stats`로 대체됩니다.
- `stats.cached`업스트림 `cacheRead`로 정규화됩니다.
- `stats.cached`OpenClaw `cacheRead`로 정규화됩니다.
- `stats.input`이 없으면 OpenClaw는
`stats.input_tokens - stats.cached`로부터 입력 토큰을 계산합니다.
`stats.input_tokens - stats.cached`에서 입력 토큰 수를 계산합니다.
## 기능
| Capability | Supported |
| ---------------------- | ---------------- |
| Chat completions | 예 |
| Image generation | 예 |
| Music generation | 예 |
| Image understanding | 예 |
| Audio transcription | 예 |
| Video understanding | 예 |
| Web search (Grounding) | 예 |
| 기능 | 지원 여부 |
| ---------------------- | ----------------- |
| 채팅 completions | 예 |
| 이미지 생성 | 예 |
| 음악 생성 | 예 |
| 이미지 이해 | 예 |
| 오디오 전사 | 예 |
| 비디오 이해 | 예 |
| 웹 검색 (Grounding) | 예 |
| Thinking/reasoning | 예 (Gemini 3.1+) |
| Gemma 4 모델 | 예 |
Gemma 4 모델(예: `gemma-4-26b-a4b-it`)은 thinking 모드를 지원합니다. OpenClaw는 Gemma 4에 대해 `thinkingBudget`을 지원되는 Google `thinkingLevel`로 재작성합니다. thinking을 `off`로 설정하면 `MINIMAL`로 매핑되지 않고 thinking 비활성화가 유지됩니다.
## 직접 Gemini 캐시 재사용
직접 Gemini API 실행(`api: "google-generative-ai"`)의 경우, OpenClaw는 이제
구성된 `cachedContent` 핸들을 Gemini 요청에 그대로 전달합니다.
- 모델별 또는 전역 `params`
`cachedContent` 또는 레거시 `cached_content` 중 하나 구성할 수 있습니다
- 모델별 또는 전역 params에
`cachedContent` 또는 레거시 `cached_content` 중 하나 구성할 수 있습니다
- 둘 다 존재하면 `cachedContent`가 우선합니다
- 예시 값: `cachedContents/prebuilt-context`
- Gemini 캐시 적중 사용량은 업스트림 `cachedContentTokenCount`에서
@ -137,19 +140,19 @@ Gemini CLI JSON 사용 참고 사항:
## 이미지 생성
번들 `google` 이미지 생성 provider의 기본값은
번들 `google` 이미지 생성 provider의 기본값은
`google/gemini-3.1-flash-image-preview`입니다.
- `google/gemini-3-pro-image-preview`도 지원
- `google/gemini-3-pro-image-preview`도 지원합니다
- 생성: 요청당 최대 4개 이미지
- 편집 모드: 활성화됨, 입력 이미지 최대 5개
- 기하 제어: `size`, `aspectRatio`, `resolution`
- 편집 모드: 활성화됨, 입력 이미지 최대 5개
- Geometry 제어: `size`, `aspectRatio`, `resolution`
OAuth 전용 `google-gemini-cli` provider는 별도의 텍스트 추론
표면입니다. 이미지 생성, 미디어 이해, Gemini Grounding은 계속
`google` provider id에 유지됩니다.
Google을 기본 이미지 provider로 사용하려면:
Google을 기본 이미지 provider로 사용하려면 다음과 같이 설정합니다.
```json5
{
@ -163,20 +166,20 @@ Google을 기본 이미지 provider로 사용하려면:
}
```
통 도구 매개변수, provider 선택, 장애 조치 동작은
[Image Generation](/ko/tools/image-generation)을 참하세요.
용 도구 매개변수,
provider 선택, 장애 조치 동작은 [Image Generation](/ko/tools/image-generation)을 참하세요.
## 비디오 생성
번들 `google` plugin은 공통
번들`google` plugin은 공용
`video_generate` 도구를 통해 비디오 생성도 등록합니다.
- 기본 비디오 모델: `google/veo-3.1-fast-generate-preview`
- 모드: 텍스트-비디오, 이미지-비디오, 단일 비디오 참조 흐름
- 모드: text-to-video, image-to-video, 단일 비디오 참조 흐름
- `aspectRatio`, `resolution`, `audio` 지원
- 현재 길이 제한: **4~8초**
- 현재 duration 제한: **4~8초**
Google을 기본 비디오 provider로 사용하려면:
Google을 기본 비디오 provider로 사용하려면 다음과 같이 설정합니다.
```json5
{
@ -190,22 +193,22 @@ Google을 기본 비디오 provider로 사용하려면:
}
```
통 도구 매개변수, provider 선택, 장애 조치 동작은
[Video Generation](/ko/tools/video-generation)을 참하세요.
용 도구 매개변수,
provider 선택, 장애 조치 동작은 [Video Generation](/ko/tools/video-generation)을 참하세요.
## 음악 생성
번들 `google` plugin은 공통
번들`google` plugin은 공용
`music_generate` 도구를 통해 음악 생성도 등록합니다.
- 기본 음악 모델: `google/lyria-3-clip-preview`
- `google/lyria-3-pro-preview`도 지원
- 프롬프트 제어: `lyrics``instrumental`
- 출력 형식: 기본적으로 `mp3`, `google/lyria-3-pro-preview`에서는 `wav`도 지원
- 참조 입력: 최대 10개 이미지
- 세션 기반 실행은 공통 작업/상태 흐름을 통해 분리되며, `action: "status"`도 포함합니다
- 출력 형식: 기본 `mp3`, `google/lyria-3-pro-preview`에서는 `wav`도 지원
- 참조 입력: 이미지 최대 10개
- 세션 기반 실행은 `action: "status"`를 포함한 공용 task/status 흐름을 통해 분리 실행됩니다
Google을 기본 음악 provider로 사용하려면:
Google을 기본 음악 provider로 사용하려면 다음과 같이 설정합니다.
```json5
{
@ -219,11 +222,11 @@ Google을 기본 음악 provider로 사용하려면:
}
```
통 도구 매개변수, provider 선택, 장애 조치 동작은
[Music Generation](/ko/tools/music-generation)을 참하세요.
용 도구 매개변수,
provider 선택, 장애 조치 동작은 [Music Generation](/ko/tools/music-generation)을 참하세요.
## 환경 참고
Gateway가 데몬(launchd/systemd)으로 실행되는 경우 `GEMINI_API_KEY`
Gateway가 데몬(launchd/systemd)으로 실행되는 경우, `GEMINI_API_KEY`
해당 프로세스에서 사용 가능해야 합니다(예: `~/.openclaw/.env` 또는
`env.shellEnv`를 통해).

View File

@ -1,43 +1,39 @@
---
read_when:
- 로컬 inferrs 서버에 대해 OpenClaw를 실행하려는 경우
- inferrs를 통해 Gemma 또는 다른 모델을 서빙하는 경우
- inferrs에 필요한 정확한 OpenClaw compat 플래그가 필요한 경우
summary: inferrs(OpenAI 호환 로컬 서버)를 통해 OpenClaw 실행
- inferrs를 통해 Gemma 또는 다른 모델을 제공하는 경우
- inferrs용 정확한 OpenClaw 호환 플래그가 필요한 경우
summary: inferrs(OpenAI 호환 로컬 서버)를 통해 OpenClaw 실행하기
title: inferrs
x-i18n:
generated_at: "2026-04-08T02:17:50Z"
generated_at: "2026-04-09T01:30:27Z"
model: gpt-5.4
provider: openai
source_hash: d84f660d49a682d0c0878707eebe1bc1e83dd115850687076ea3938b9f9c86c6
source_hash: 03b9d5a9935c75fd369068bacb7807a5308cd0bd74303b664227fb664c3a2098
source_path: providers/inferrs.md
workflow: 15
---
# inferrs
[inferrs](https://github.com/ericcurtin/inferrs)는
OpenAI 호환 `/v1` API 뒤에서 로컬 모델을 서빙할 수 있습니다. OpenClaw는 일반적인
`openai-completions` 경로를 통해 `inferrs`와 함께 동작합니다.
[inferrs](https://github.com/ericcurtin/inferrs)는 OpenAI 호환 `/v1` API 뒤에서 로컬 모델을 제공할 수 있습니다. OpenClaw는 일반 `openai-completions` 경로를 통해 `inferrs`와 함께 동작합니다.
현재 `inferrs`는 전용 OpenClaw provider plugin이라기보다
사용자 지정 self-hosted OpenAI 호환
백엔드로 취급하는 것이 가장 적절합니다.
현재 `inferrs`는 전용 OpenClaw provider plugin이 아니라 사용자 지정 자체 호스팅 OpenAI 호환 백엔드로 취급하는 것이 가장 적절합니다.
## 빠른 시작
1. 모델과 함께 `inferrs`를 시작합니다.
1. 모델 `inferrs`를 시작합니다.
:
예:
```bash
inferrs serve gg-hf-gg/gemma-4-E2B-it \
inferrs serve google/gemma-4-E2B-it \
--host 127.0.0.1 \
--port 8080 \
--device metal
```
2. 서버에 연결 가능한지 확인합니다.
2. 서버에 연결할 수 있는지 확인합니다.
```bash
curl http://127.0.0.1:8080/health
@ -46,17 +42,17 @@ curl http://127.0.0.1:8080/v1/models
3. 명시적인 OpenClaw provider 항목을 추가하고 기본 모델이 이를 가리키도록 설정합니다.
## 전체 구성 예
## 전체 구성 예
이 예는 로컬 `inferrs` 서버에서 Gemma 4를 사용합니다.
이 예는 로컬 `inferrs` 서버에서 Gemma 4를 사용합니다.
```json5
{
agents: {
defaults: {
model: { primary: "inferrs/gg-hf-gg/gemma-4-E2B-it" },
model: { primary: "inferrs/google/gemma-4-E2B-it" },
models: {
"inferrs/gg-hf-gg/gemma-4-E2B-it": {
"inferrs/google/gemma-4-E2B-it": {
alias: "Gemma 4 (inferrs)",
},
},
@ -71,7 +67,7 @@ curl http://127.0.0.1:8080/v1/models
api: "openai-completions",
models: [
{
id: "gg-hf-gg/gemma-4-E2B-it",
id: "google/gemma-4-E2B-it",
name: "Gemma 4 E2B (inferrs)",
reasoning: false,
input: ["text"],
@ -91,10 +87,9 @@ curl http://127.0.0.1:8080/v1/models
## `requiresStringContent`가 중요한 이유
일부 `inferrs` Chat Completions 경로는 구조화된 content-part 배열이 아니라
문자열 형태의 `messages[].content`만 허용합니다.
일부 `inferrs` Chat Completions 경로는 구조화된 content-part 배열이 아니라 문자열 `messages[].content`만 허용합니다.
OpenClaw 실행이 다음과 같은 오류로 실패한다면:
OpenClaw 실행 시 다음과 같은 오류가 발생하면:
```text
messages[1].content: invalid type: sequence, expected a string
@ -108,14 +103,11 @@ compat: {
}
```
OpenClaw는 요청을 보내기 전에 순수 텍스트 content part를
일반 문자열로 평탄화합니다.
OpenClaw는 요청을 보내기 전에 순수 텍스트 content part를 일반 문자열로 평탄화합니다.
## Gemma 및 도구 스키마 주의 사항
## Gemma 및 tool-schema 주의 사항
현재의 일부 `inferrs` + Gemma 조합은 작은 직접
`/v1/chat/completions` 요청은 허용하지만 전체 OpenClaw 에이전트 런타임
턴에서는 여전히 실패합니다.
현재 일부 `inferrs` + Gemma 조합은 작은 직접 `/v1/chat/completions` 요청은 수락하지만 전체 OpenClaw agent-runtime 턴에서는 여전히 실패합니다.
이 경우 먼저 다음을 시도하세요:
@ -126,53 +118,44 @@ compat: {
}
```
이렇게 하면 해당 모델에 대해 OpenClaw의 도구 스키마 표면이 비활성화되며,
더 엄격한 로컬 백엔드에서 프롬프트 부담을 줄일 수 있습니다.
이 설정은 해당 모델에 대한 OpenClaw의 tool schema 표면을 비활성화하며, 더 엄격한 로컬 백엔드에서 prompt 부담을 줄일 수 있습니다.
작은 직접 요청은 계속 동작하지만 일반적인 OpenClaw 에이전트 턴이 계속
`inferrs` 내부에서 크래시한다면, 남은 문제는 보통 OpenClaw의 전송 계층보다는
업스트림 모델/서버 동작입니다.
작은 직접 요청은 여전히 동작하지만 일반 OpenClaw agent 턴이 `inferrs` 내부에서 계속 충돌한다면, 남아 있는 문제는 보통 OpenClaw의 전송 계층보다는 업스트림 모델/서버 동작에 있습니다.
## 수동 스모크 테스트
구성한 뒤에는 두 계층을 모두 테스트하세요.
구성한 후에는 두 계층을 모두 테스트하세요:
```bash
curl http://127.0.0.1:8080/v1/chat/completions \
-H 'content-type: application/json' \
-d '{"model":"gg-hf-gg/gemma-4-E2B-it","messages":[{"role":"user","content":"What is 2 + 2?"}],"stream":false}'
-d '{"model":"google/gemma-4-E2B-it","messages":[{"role":"user","content":"What is 2 + 2?"}],"stream":false}'
openclaw infer model run \
--model inferrs/gg-hf-gg/gemma-4-E2B-it \
--model inferrs/google/gemma-4-E2B-it \
--prompt "What is 2 + 2? Reply with one short sentence." \
--json
```
첫 번째 명령은 동작하지만 두 번째가 실패한다면, 아래의 문제 해결 참고 사항을 사용하세요.
첫 번째 명령은 동작하지만 두 번째가 실패하면 아래 문제 해결 참고 사항을 사용하세요.
## 문제 해결
- `curl /v1/models`가 실패함: `inferrs`가 실행 중이 아니거나, 연결할 수 없거나,
예상한 호스트/포트에 바인딩되지 않았습니다.
- `curl /v1/models` 실패: `inferrs`가 실행 중이 아니거나, 연결할 수 없거나, 예상한 host/port에 바인딩되지 않았습니다.
- `messages[].content ... expected a string`: `compat.requiresStringContent: true`를 설정하세요.
- 작은 직접 `/v1/chat/completions` 호출은 통과하지만 `openclaw infer model run`
실패함: `compat.supportsTools: false`를 시도하세요.
- OpenClaw에서 더 이상 스키마 오류는 나지 않지만 `inferrs`가 더 큰
에이전트 턴에서 여전히 크래시함: 이를 업스트림 `inferrs` 또는 모델 한계로 보고
프롬프트 부담을 줄이거나 로컬 백엔드/모델을 바꾸세요.
- 직접적인 작은 `/v1/chat/completions` 호출은 통과하지만 `openclaw infer model run`은 실패: `compat.supportsTools: false`를 시도하세요.
- OpenClaw에서 더 이상 스키마 오류는 발생하지 않지만 `inferrs`가 더 큰 agent 턴에서 여전히 충돌: 이를 업스트림 `inferrs` 또는 모델의 제한으로 보고 prompt 부담을 줄이거나 로컬 백엔드/모델을 전환하세요.
## 프록시 스타일 동작
`inferrs`는 네이티브
OpenAI 엔드포인트가 아니라 프록시 스타일 OpenAI 호환 `/v1` 백엔드로 취급됩니다.
`inferrs`는 네이티브 OpenAI 엔드포인트가 아니라 프록시 스타일 OpenAI 호환 `/v1` 백엔드로 취급됩니다.
- 네이티브 OpenAI 전용 요청 셰이핑은 여기에 적용되지 않습니다
- `service_tier`, Responses `store`, 프롬프트 캐시 힌트, OpenAI 추론 호환 페이로드 셰이핑이 없습니다
- 숨겨진 OpenClaw attribution 헤더(`originator`, `version`, `User-Agent`)는
사용자 지정 `inferrs` base URL에 주입되지 않습니다
- 네이티브 OpenAI 전용 요청 형태 조정은 여기에는 적용되지 않음
- `service_tier`, Responses `store`, prompt-cache 힌트, OpenAI reasoning-compat 페이로드 형태 조정이 없음
- 숨겨진 OpenClaw attribution 헤더(`originator`, `version`, `User-Agent`)는 사용자 지정 `inferrs` base URL에 주입되지 않음
## 함께 보기
- [로컬 모델](/ko/gateway/local-models)
- [게이트웨이 문제 해결](/ko/gateway/troubleshooting#local-openai-compatible-backend-passes-direct-probes-but-agent-runs-fail)
- [모델 프로바이더](/ko/concepts/model-providers)
- [Local models](/ko/gateway/local-models)
- [Gateway troubleshooting](/ko/gateway/troubleshooting#local-openai-compatible-backend-passes-direct-probes-but-agent-runs-fail)
- [Model providers](/ko/concepts/model-providers)

View File

@ -1,24 +1,24 @@
---
read_when:
- Ollama를 통해 클라우드 또는 로컬 모델로 OpenClaw를 실행하고 싶을 때
- Ollama 설정 및 구성 가이드가 필요할 때
summary: Ollama를 통해 OpenClaw를 실행합니다(클라우드 및 로컬 모델)
- Ollama를 통해 클라우드 또는 로컬 모델로 OpenClaw를 실행하려는 경우
- Ollama 설정 및 구성 가이드가 필요한 경우
summary: Ollama로 OpenClaw 실행하기(클라우드 및 로컬 모델)
title: Ollama
x-i18n:
generated_at: "2026-04-08T02:18:23Z"
generated_at: "2026-04-09T01:31:04Z"
model: gpt-5.4
provider: openai
source_hash: 222ec68f7d4bb29cc7796559ddef1d5059f5159e7a51e2baa3a271ddb3abb716
source_hash: d3295a7c879d3636a2ffdec05aea6e670e54a990ef52bd9b0cae253bc24aa3f7
source_path: providers/ollama.md
workflow: 15
---
# Ollama
Ollama는 머신에서 오픈 소스 모델을 쉽게 실행할 수 있게 해주는 로컬 LLM 런타임입니다. OpenClaw는 Ollama의 네이티브 API(`/api/chat`)와 통합되며, 스트리밍과 도구 호출을 지원하고, `OLLAMA_API_KEY`(또는 인증 프로필)로 opt in하고 명시적인 `models.providers.ollama` 항목을 정의하지 않으면 로컬 Ollama 모델을 자동으로 검색할 수 있습니다.
Ollama는 머신에서 오픈 소스 모델을 쉽게 실행할 수 있게 해 주는 로컬 LLM 런타임입니다. OpenClaw는 Ollama의 네이티브 API(`/api/chat`)와 통합되며, 스트리밍과 tool calling을 지원하고, `OLLAMA_API_KEY`(또는 auth profile)로 옵트인하고 명시적인 `models.providers.ollama` 항목을 정의하지 않으면 로컬 Ollama 모델을 자동으로 검색할 수 있습니다.
<Warning>
**원격 Ollama 사용자**: OpenClaw에서 `/v1` OpenAI 호환 URL(`http://host:11434/v1`)을 사용하지 마세요. 이렇게 하면 도구 호출이 깨지고 모델이 원시 도구 JSON을 일반 텍스트로 출력할 수 있습니다. 대신 네이티브 Ollama API URL을 사용하세요: `baseUrl: "http://host:11434"` (`/v1` 없음).
**원격 Ollama 사용자**: OpenClaw와 함께 `/v1` OpenAI 호환 URL(`http://host:11434/v1`)을 사용하지 마세요. 이렇게 하면 tool calling이 깨지고 모델이 원시 tool JSON을 일반 텍스트로 출력할 수 있습니다. 대신 네이티브 Ollama API URL을 사용하세요: `baseUrl: "http://host:11434"` (`/v1` 없음).
</Warning>
## 빠른 시작
@ -31,13 +31,13 @@ Ollama를 설정하는 가장 빠른 방법은 온보딩을 사용하는 것입
openclaw onboard
```
제공자 목록에서 **Ollama**를 선택하세요. 온보딩은 다음을 수행합니다:
provider 목록에서 **Ollama**를 선택하세요. 온보딩은 다음을 수행합니다:
1. 인스턴스에 접근할 수 있는 Ollama base URL을 묻습니다(기본값 `http://127.0.0.1:11434`).
2. **Cloud + Local**(클라우드 모델 로컬 모델) 또는 **Local**(로컬 모델만)을 선택하게 합니다.
3. **Cloud + Local**을 선택했고 ollama.com에 로그인되어 있지 않다면 브라우저 로그인 흐름을 엽니다.
1. 인스턴스에 접근할 수 있는 Ollama 기본 URL을 묻습니다(기본값 `http://127.0.0.1:11434`).
2. **Cloud + Local**(클라우드 모델 로컬 모델) 또는 **Local**(로컬 모델만)을 선택하게 합니다.
3. **Cloud + Local**을 선택했고 `ollama.com`에 로그인되어 있지 않으면 브라우저 로그인 흐름을 엽니다.
4. 사용 가능한 모델을 검색하고 기본값을 제안합니다.
5. 선택한 모델이 로컬에 없면 자동으로 pull합니다.
5. 선택한 모델이 로컬에 없면 자동으로 pull합니다.
비대화형 모드도 지원됩니다:
@ -47,7 +47,7 @@ openclaw onboard --non-interactive \
--accept-risk
```
선택적으로 커스텀 base URL 또는 모델을 지정할 수 있습니다:
선택적으로 사용자 지정 base URL 또는 모델을 지정할 수 있습니다:
```bash
openclaw onboard --non-interactive \
@ -59,15 +59,15 @@ openclaw onboard --non-interactive \
### 수동 설정
1. Ollama 설치합니다: [https://ollama.com/download](https://ollama.com/download)
1. Ollama 설치: [https://ollama.com/download](https://ollama.com/download)
2. 로컬 추론을 원한다면 로컬 모델을 pull합니다:
2. 로컬 추론을 원면 로컬 모델을 pull합니다:
```bash
ollama pull gemma4
# or
# 또는
ollama pull gpt-oss:20b
# or
# 또는
ollama pull llama3.3
```
@ -84,21 +84,21 @@ openclaw onboard
```
- `Local`: 로컬 모델만
- `Cloud + Local`: 로컬 모델 + 클라우드 모델
- `Cloud + Local`: 로컬 모델 클라우드 모델
- `kimi-k2.5:cloud`, `minimax-m2.7:cloud`, `glm-5.1:cloud` 같은 클라우드 모델은 로컬 `ollama pull`이 **필요하지 않습니다**
현재 OpenClaw는 다음을 제안합니다:
OpenClaw는 현재 다음을 제안합니다:
- 로컬 기본값: `gemma4`
- 클라우드 기본값: `kimi-k2.5:cloud`, `minimax-m2.7:cloud`, `glm-5.1:cloud`
5. 수동 설정을 선호한다면 OpenClaw용 Ollama를 직접 활성화하세요(아무 값이나 동작합니다. Ollama는 실제 키를 요구하지 않습니다):
5. 수동 설정을 선호한다면 OpenClaw에서 Ollama를 직접 활성화하세요(아무 값이나 동작하며, Ollama는 실제 키가 필요하지 않습니다):
```bash
# Set environment variable
# 환경 변수 설정
export OLLAMA_API_KEY="ollama-local"
# Or configure in your config file
# 또는 config 파일에 설정
openclaw config set models.providers.ollama.apiKey "ollama-local"
```
@ -121,26 +121,27 @@ openclaw models set ollama/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`를 조회
- 가능할 때 `contextWindow`를 읽기 위해 최선의 노력으로 `/api/show` 조회 사용
- `/api/tags` 조회
- 가능할 때 `contextWindow`를 읽고 기능(비전 포함)을 감지하기 위해 최선의 노력 방식으로 `/api/show` 조회 사용
- `/api/show`가 보고한 `vision` 기능이 있는 모델은 이미지 입력 가능 모델(`input: ["text", "image"]`)로 표시되므로 OpenClaw가 해당 모델의 프롬프트에 이미지를 자동 주입함
- 모델 이름 휴리스틱(`r1`, `reasoning`, `think`)으로 `reasoning` 표시
- `maxTokens`를 OpenClaw가 사용하는 기본 Ollama 최대 토큰 상한으로 설정
- OpenClaw가 사용하는 기본 Ollama max-token 제한으로 `maxTokens` 설정
- 모든 비용을 `0`으로 설정
이렇게 하면 수동 모델 항목 없이도 카탈로그를 로컬 Ollama 인스턴스와 맞춘 상태로 유지할 수 있습니다.
사용 가능한 모델을 려면:
사용 가능한 모델을 확인하려면:
```bash
ollama list
openclaw models list
```
새 모델을 추가하려면 Ollama로 pull하면 됩니다:
새 모델을 추가하려면 Ollama로 pull하기만 하면 됩니다:
```bash
ollama pull mistral
@ -148,7 +149,7 @@ ollama pull mistral
새 모델은 자동으로 검색되어 사용할 수 있게 됩니다.
`models.providers.ollama`를 명시적으로 설정하면 자동 검색은 건너뛰며 모델을 수동으로 정의해야 합니다(아래 참).
`models.providers.ollama`를 명시적으로 설정하면 자동 검색은 건너뛰며 모델을 수동으로 정의해야 합니다(아래 참).
## 구성
@ -164,9 +165,9 @@ export OLLAMA_API_KEY="ollama-local"
다음 경우에는 명시적 config를 사용하세요:
- Ollama가 다른 호스트/포트에서 실행될 때
- 특정 컨텍스트 윈도우나 모델 목록을 강제로 지정하고 싶을 때
- 모델 정의를 완전히 수동으로 관리하고 싶을 때
- Ollama가 다른 host/port에서 실행되는 경우
- 특정 컨텍스트 윈도우나 모델 목록을 강제하고 싶은 경우
- 완전히 수동으로 모델을 정의하고 싶은 경우
```json5
{
@ -193,11 +194,11 @@ export OLLAMA_API_KEY="ollama-local"
}
```
`OLLAMA_API_KEY`가 설정되어 있다면 provider 항목의 `apiKey`는 생략할 수 있으며, OpenClaw가 가용성 확인을 위해 이를 채워 넣습니다.
`OLLAMA_API_KEY`가 설정되어 있으면 provider 항목에서 `apiKey`를 생략해도 되며 OpenClaw가 가용성 확인을 위해 이를 채웁니다.
### 커스텀 base URL(명시적 config)
### 사용자 지정 base URL(명시적 config)
Ollama가 다른 호스트나 포트에서 실행 중이라면(명시적 config는 자동 검색을 비활성화하므로 모델을 수동으로 정의해야 함):
Ollama가 다른 host 또는 port에서 실행 중인 경우(명시적 config는 자동 검색을 비활성화하므로 모델을 수동 정의해야 함):
```json5
{
@ -205,8 +206,8 @@ Ollama가 다른 호스트나 포트에서 실행 중이라면(명시적 config
providers: {
ollama: {
apiKey: "ollama-local",
baseUrl: "http://ollama-host:11434", // No /v1 - use native Ollama API URL
api: "ollama", // Set explicitly to guarantee native tool-calling behavior
baseUrl: "http://ollama-host:11434", // /v1 없음 - 네이티브 Ollama API URL 사용
api: "ollama", // 네이티브 tool-calling 동작을 보장하려면 명시적으로 설정
},
},
},
@ -214,12 +215,12 @@ Ollama가 다른 호스트나 포트에서 실행 중이라면(명시적 config
```
<Warning>
URL에 `/v1`을 추가하지 마세요. `/v1` 경로는 OpenAI 호환 모드를 사용하며, 여기서는 도구 호출이 신뢰할 수 없습니다. 경로 접미사 없이 기본 Ollama URL을 사용하세요.
URL에 `/v1`을 추가하지 마세요. `/v1` 경로는 OpenAI 호환 모드를 사용하며 tool calling이 신뢰할 수 없습니다. 경로 접미사가 없는 기본 Ollama URL을 사용하세요.
</Warning>
### 모델 선택
구성이 끝나면 모든 Ollama 모델을 사용할 수 있습니다:
구성면 모든 Ollama 모델을 사용할 수 있습니다:
```json5
{
@ -236,24 +237,21 @@ URL에 `/v1`을 추가하지 마세요. `/v1` 경로는 OpenAI 호환 모드를
## 클라우드 모델
클라우드 모델을 사용하면 로컬 모델과 함께 클라우드 호스팅 모델(예: `kimi-k2.5:cloud`, `minimax-m2.7:cloud`, `glm-5.1:cloud`) 실행할 수 있습니다.
클라우드 모델을 사용하면 로컬 모델과 함께 클라우드 호스팅 모델(예: `kimi-k2.5:cloud`, `minimax-m2.7:cloud`, `glm-5.1:cloud`) 실행할 수 있습니다.
클라우드 모델을 사용하려면 설정 중에 **Cloud + Local** 모드를 선택하세요. wizard는 로그인 상태를 확인하고 필요할 때 브라우저 로그인 흐름을 엽니다. 인증을 확인할 수 없으면 wizard는 로컬 모델 기본값으로 대체합니다.
클라우드 모델을 사용하려면 설정 중에 **Cloud + Local** 모드를 선택하세요. 마법사는 로그인 상태를 확인하고 필요하면 브라우저 로그인 흐름을 엽니다. 인증을 확인할 수 없으면 마법사는 로컬 모델 기본값으로 대체합니다.
직접 [ollama.com/signin](https://ollama.com/signin)에서 로그인할 수도 있습니다.
[ollama.com/signin](https://ollama.com/signin)에서 직접 로그인할 수도 있습니다.
## Ollama 웹 검색
## Ollama Web Search
OpenClaw는 번들된 `web_search`
제공자로 **Ollama 웹 검색**도 지원합니다.
OpenClaw는 번들된 `web_search` provider로 **Ollama Web Search**도 지원합니다.
- 설정된 Ollama 호스트를 사용합니다(`models.providers.ollama.baseUrl`이
설정되어 있으면 그 값을 사용하고, 아니면 `http://127.0.0.1:11434` 사용).
- 구성된 Ollama host를 사용합니다(`models.providers.ollama.baseUrl`가 설정된 경우 그 값, 아니면 `http://127.0.0.1:11434`).
- 키가 필요 없습니다.
- Ollama가 실행 중이어야 하고 `ollama signin`으로 로그인되어 있어야 합니다.
`openclaw onboard` 또는
`openclaw configure --section web` 중에 **Ollama 웹 검색**을 선택하거나, 다음과 같이 설정하세요:
`openclaw onboard` 또는 `openclaw configure --section web` 중에 **Ollama Web Search**를 선택하거나 다음을 설정하세요:
```json5
{
@ -267,13 +265,13 @@ OpenClaw는 번들된 `web_search`
}
```
전체 설정 및 동작 상세 정보는 [Ollama 웹 검색](/ko/tools/ollama-search)을 참고하세요.
전체 설정 및 동작 세부 정보는 [Ollama Web Search](/ko/tools/ollama-search)를 참조하세요.
## 고급
### 추론 모델
### reasoning 모델
OpenClaw는 기본적으로 `deepseek-r1`, `reasoning`, `think` 같은 이름이 포함된 모델을 추론 가능 모델로 취급합니다:
OpenClaw는 기본적으로 `deepseek-r1`, `reasoning`, `think` 같은 이름의 모델을 reasoning 가능 모델로 취급합니다:
```bash
ollama pull deepseek-r1:32b
@ -281,19 +279,19 @@ ollama pull deepseek-r1:32b
### 모델 비용
Ollama는 무료이며 로컬에서 실행되므로, 모든 모델 비용은 $0으로 설정됩니다.
Ollama는 무료이며 로컬에서 실행되므로 모든 모델 비용은 $0으로 설정됩니다.
### 스트리밍 구성
OpenClaw의 Ollama 통합은 기본적으로 **네이티브 Ollama API**(`/api/chat`)를 사용하며, 스트리밍과 도구 호출을 동시에 완전히 지원합니다. 별도의 특별한 설정은 필요하지 않습니다.
OpenClaw의 Ollama 통합은 기본적으로 **네이티브 Ollama API**(`/api/chat`)를 사용하며, 스트리밍과 tool calling을 동시에 완전히 지원합니다. 별도의 특별한 설정은 필요하지 않습니다.
#### 레거시 OpenAI 호환 모드
<Warning>
**OpenAI 호환 모드에서는 도구 호출이 신뢰할 수 없습니다.** 프록시에 OpenAI 형식이 필요하고 네이티브 도구 호출 동작에 의존하지 않을 때만 이 모드를 사용하세요.
**OpenAI 호환 모드에서는 tool calling이 신뢰할 수 없습니다.** 프록시 때문에 OpenAI 형식이 필요하고 네이티브 tool calling 동작에 의존하지 않는 경우에만 이 모드를 사용하세요.
</Warning>
대신 OpenAI 호환 엔드포인트를 사용해야 한다면(예: OpenAI 형식만 지원하는 프록시 뒤에 있는 경우), `api: "openai-completions"`를 명시적으로 설정하세요:
대신 OpenAI 호환 엔드포인트를 사용해야 하는 경우(예: OpenAI 형식만 지원하는 프록시 뒤에 있는 경우) `api: "openai-completions"`를 명시적으로 설정하세요:
```json5
{
@ -302,7 +300,7 @@ OpenClaw의 Ollama 통합은 기본적으로 **네이티브 Ollama API**(`/api/c
ollama: {
baseUrl: "http://ollama-host:11434/v1",
api: "openai-completions",
injectNumCtxForOpenAICompat: true, // default: true
injectNumCtxForOpenAICompat: true, // 기본값: true
apiKey: "ollama-local",
models: [...]
}
@ -311,9 +309,9 @@ OpenClaw의 Ollama 통합은 기본적으로 **네이티브 Ollama API**(`/api/c
}
```
이 모드는 스트리밍 + 도구 호출을 동시에 지원하지 않을 수 있습니다. 모델 config의 `params: { streaming: false }`로 스트리밍을 비활성화해야 할 수 있습니다.
이 모드는 스트리밍과 tool calling을 동시에 지원하지 않을 수 있습니다. 모델 config에서 `params: { streaming: false }`로 스트리밍을 비활성화해야 할 수 있습니다.
Ollama에서 `api: "openai-completions"`를 사용할 때 OpenClaw는 기본적으로 `options.num_ctx`를 주입하므로 Ollama가 조용히 4096 컨텍스트 윈도우로 대체되지 않습니다. 프록시/업스트림이 알 수 없는 `options` 필드를 거부한다면 이 동작을 비활성화하세요:
Ollama와 함께 `api: "openai-completions"`를 사용하면 OpenClaw는 Ollama가 조용히 4096 컨텍스트 윈도우로 되돌아가지 않도록 기본적으로 `options.num_ctx`를 주입합니다. 프록시/업스트림이 알 수 없는 `options` 필드를 거부하면 이 동작을 비활성화하세요:
```json5
{
@ -333,19 +331,19 @@ Ollama에서 `api: "openai-completions"`를 사용할 때 OpenClaw는 기본적
### 컨텍스트 윈도우
자동 검색된 모델의 경우 OpenClaw는 가능하면 Ollama가 보고한 컨텍스트 윈도우를 사용하고, 그렇지 않으면 OpenClaw가 사용하는 기본 Ollama 컨텍스트 윈도우로 대체합니다. 명시적 provider config에서 `contextWindow``maxTokens`를 재정의할 수 있습니다.
자동 검색된 모델의 경우 OpenClaw는 가능한 경우 Ollama가 보고한 컨텍스트 윈도우를 사용하고, 그렇지 않으면 OpenClaw가 사용하는 기본 Ollama 컨텍스트 윈도우로 대체합니다. 명시적 provider config에서 `contextWindow``maxTokens`를 재정의할 수 있습니다.
## 문제 해결
### Ollama가 감지되지 않음
Ollama가 실행 중인지, `OLLAMA_API_KEY`(또는 인증 프로필)를 설정했는지, 그리고 **명시적인** `models.providers.ollama` 항목을 정의하지 않았는지 확인하세요:
Ollama가 실행 중인지, `OLLAMA_API_KEY`(또는 auth profile)를 설정했는지, 그리고 명시적인 `models.providers.ollama` 항목을 **정의하지 않았는지** 확인하세요:
```bash
ollama serve
```
또한 API에 접근 가능한지 확인하세요:
또한 API에 접근 가능한지 확인하세요:
```bash
curl http://localhost:11434/api/tags
@ -353,34 +351,34 @@ curl http://localhost:11434/api/tags
### 사용 가능한 모델이 없음
모델이 목록에 없면 다음 중 하나입니다:
모델이 목록에 없면 다음 중 하나입니다:
- 로컬에서 모델을 pull하거나
- `models.providers.ollama`에 모델을 명시적으로 정의해야 합니다
- 모델을 로컬에 pull하거나
- `models.providers.ollama`에 모델을 명시적으로 정의하세요.
모델을 추가하려면:
모델 추가 방법:
```bash
ollama list # See what's installed
ollama list # 설치된 항목 확인
ollama pull gemma4
ollama pull gpt-oss:20b
ollama pull llama3.3 # Or another model
ollama pull llama3.3 # 또는 다른 모델
```
### 연결 거부됨
Ollama가 올바른 포트에서 실행 중인지 확인하세요:
Ollama가 올바른 port에서 실행 중인지 확인하세요:
```bash
# Check if Ollama is running
# Ollama 실행 여부 확인
ps aux | grep ollama
# Or restart Ollama
# 또는 Ollama 재시작
ollama serve
```
## 참고 항목
## 함께 보기
- [모델 제공자](/ko/concepts/model-providers) - 모든 제공자 개요
- [모델 선택](/ko/concepts/models) - 모델 선택 방법
- [구성](/ko/gateway/configuration) - 전체 config 참조
- [Model Providers](/ko/concepts/model-providers) - 모든 provider 개요
- [Model Selection](/ko/concepts/models) - 모델 선택 방법
- [Configuration](/ko/gateway/configuration) - 전체 config 참조

View File

@ -1,14 +1,14 @@
---
read_when:
- OpenClaw에서 Qwen을 사용하려고 합니다
- 이전에 Qwen OAuth를 사용했습니다
summary: OpenClaw의 번들 qwen provider를 통해 Qwen Cloud 사용하기
- OpenClaw에서 Qwen을 사용하려는 경우
- 이전에 Qwen OAuth를 사용한 적이 있는 경우
summary: OpenClaw의 번들 qwen provider를 통해 Qwen Cloud 사용
title: Qwen
x-i18n:
generated_at: "2026-04-06T03:11:41Z"
generated_at: "2026-04-09T01:30:59Z"
model: gpt-5.4
provider: openai
source_hash: f175793693ab6a4c3f1f4d42040e673c15faf7603a500757423e9e06977c989d
source_hash: 4786df2cb6ec1ab29d191d012c61dcb0e5468bf0f8561fbbb50eed741efad325
source_path: providers/qwen.md
workflow: 15
---
@ -20,44 +20,44 @@ x-i18n:
**Qwen OAuth는 제거되었습니다.** `portal.qwen.ai` 엔드포인트를 사용하던
무료 등급 OAuth 통합(`qwen-portal`)은 더 이상 사용할 수 없습니다.
배경은 [Issue #49557](https://github.com/openclaw/openclaw/issues/49557)를
하세요.
하세요.
</Warning>
## 권장: Qwen Cloud
이제 OpenClaw는 Qwen을 정식 번들 provider로 취급하며 정식 ID는
`qwen`니다. 번들 provider는 Qwen Cloud / Alibaba DashScope 및
Coding Plan 엔드포인트를 대상으로 하며, 레거시 `modelstudio` ID
OpenClaw는 이제 Qwen을 정식 canonical id
`qwen`을 가진 1급 번들 provider로 취급합니다. 번들 provider는 Qwen Cloud / Alibaba DashScope 및
Coding Plan 엔드포인트를 대상으로 하며, 레거시 `modelstudio` id
호환성 별칭으로 계속 작동합니다.
- Provider: `qwen`
- 권장 env var: `QWEN_API_KEY`
- 호환성을 위해 다음도 허용: `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY`
- 호환성을 위해 추가 지원: `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY`
- API 스타일: OpenAI 호환
`qwen3.6-plus`를 사용하려면 **Standard (pay-as-you-go)** 엔드포인트를
권장합니다. Coding Plan 지원은 공개 카탈로그보다 늦을 수 있습니다.
```bash
# 전역 Coding Plan 엔드포인트
# Global Coding Plan endpoint
openclaw onboard --auth-choice qwen-api-key
# 중국 Coding Plan 엔드포인트
# China Coding Plan endpoint
openclaw onboard --auth-choice qwen-api-key-cn
# 전역 Standard (pay-as-you-go) 엔드포인트
# Global Standard (pay-as-you-go) endpoint
openclaw onboard --auth-choice qwen-standard-api-key
# 중국 Standard (pay-as-you-go) 엔드포인트
# China Standard (pay-as-you-go) endpoint
openclaw onboard --auth-choice qwen-standard-api-key-cn
```
레거시 `modelstudio-*` auth-choice ID와 `modelstudio/...` 모델 ref
호환성 별칭으로 계속 작동하지만, 새로운 setup 흐름에서는 정식
`qwen-*` auth-choice ID와 `qwen/...` 모델 ref를 사용하는 것이 좋습니다.
레거시 `modelstudio-*` auth-choice id와 `modelstudio/...` 모델 참조
호환성 별칭으로 계속 작동하지만, 새 설정 흐름에서는 canonical
`qwen-*` auth-choice id와 `qwen/...` 모델 참조를 사용하는 것이 좋습니다.
온보딩 후 기본 모델을 설정하세요:
온보딩 후 기본 모델을 설정하세요.
```json5
{
@ -69,83 +69,84 @@ openclaw onboard --auth-choice qwen-standard-api-key-cn
}
```
## 플랜 유형 엔드포인트
## 플랜 유형 엔드포인트
| 플랜 | 리전 | Auth choice | 엔드포인트 |
| --------------------------- | ---- | -------------------------- | ---------------------------------------------- |
| Standard (pay-as-you-go) | 중국 | `qwen-standard-api-key-cn` | `dashscope.aliyuncs.com/compatible-mode/v1` |
| Standard (pay-as-you-go) | 전역 | `qwen-standard-api-key` | `dashscope-intl.aliyuncs.com/compatible-mode/v1` |
| Coding Plan (구독) | 중국 | `qwen-api-key-cn` | `coding.dashscope.aliyuncs.com/v1` |
| Coding Plan (구독) | 전역 | `qwen-api-key` | `coding-intl.dashscope.aliyuncs.com/v1` |
| 플랜 | 지역 | Auth choice | 엔드포인트 |
| -------------------------- | ------ | -------------------------- | ----------------------------------------------- |
| Standard (pay-as-you-go) | China | `qwen-standard-api-key-cn` | `dashscope.aliyuncs.com/compatible-mode/v1` |
| Standard (pay-as-you-go) | Global | `qwen-standard-api-key` | `dashscope-intl.aliyuncs.com/compatible-mode/v1` |
| Coding Plan (subscription) | China | `qwen-api-key-cn` | `coding.dashscope.aliyuncs.com/v1` |
| Coding Plan (subscription) | Global | `qwen-api-key` | `coding-intl.dashscope.aliyuncs.com/v1` |
provider는 auth choice를 기반으로 엔드포인트를 자동 선택합니다. 정식
choice는 `qwen-*` 계열을 사용하며, `modelstudio-*`는 호환성 전용으로 유지됩니다.
config에서 사용자 지정 `baseUrl`로 재정의할 수 있습니다.
provider는 auth choice에 따라 엔드포인트를 자동 선택합니다. canonical
선택지는 `qwen-*` 계열을 사용하며, `modelstudio-*`는 호환성 전용입니다.
config에서 커스텀 `baseUrl`로 재정의할 수 있습니다.
기본 Model Studio 엔드포인트는 공유
`openai-completions` 전송에서 스트리밍 사용량 호환성을 알립니다. OpenClaw는 이제 이를 엔드포인트
capability를 기준으로 처리하므로, 동일한 기본 호스트를 대상으로 하는 DashScope 호환
사용자 지정 provider ID도 내장 `qwen` provider ID를 특별히 요구하지 않고
동일한 스트리밍 사용량 동작을 상속합니다.
기본 Model Studio 엔드포인트는 공용
`openai-completions` 전송에서 스트리밍 사용량 호환성을 알립니다. OpenClaw는 이제 이를 엔드포인트 기능 기준으로 처리하므로, 동일한 기본 호스트를 대상으로 하는 DashScope 호환 커스텀 provider id도
내장 `qwen` provider id를 특별히 요구하지 않고 동일한 스트리밍 사용량 동작을 상속합니다.
## API key 받기
## API 키 받기
- **키 관리**: [home.qwencloud.com/api-keys](https://home.qwencloud.com/api-keys)
- **문서**: [docs.qwencloud.com](https://docs.qwencloud.com/developer-guides/getting-started/introduction)
## 내장 카탈로그
OpenClaw는 현재 다음 번들 Qwen 카탈로그를 제공합니다:
OpenClaw는 현재 다음 번들 Qwen 카탈로그를 제공합니다. 구성된 카탈로그는
엔드포인트 인식형입니다. Coding Plan config에서는 Standard 엔드포인트에서만
작동하는 것으로 알려진 모델이 제외됩니다.
| Model ref | 입력 | 컨텍스트 | 참고사항 |
| --------------------------- | ----------- | --------- | -------------------------------------------------- |
| 모델 참조 | 입력 | 컨텍스트 | 참고 |
| -------------------------- | ----------- | --------- | -------------------------------------------------- |
| `qwen/qwen3.5-plus` | text, image | 1,000,000 | 기본 모델 |
| `qwen/qwen3.6-plus` | text, image | 1,000,000 | 이 모델이 필요하면 Standard 엔드포인트 권장 |
| `qwen/qwen3-max-2026-01-23` | text | 262,144 | Qwen Max 라인 |
| `qwen/qwen3-max-2026-01-23` | text | 262,144 | Qwen Max 계열 |
| `qwen/qwen3-coder-next` | text | 262,144 | 코딩 |
| `qwen/qwen3-coder-plus` | text | 1,000,000 | 코딩 |
| `qwen/MiniMax-M2.5` | text | 1,000,000 | 추론 활성화 |
| `qwen/MiniMax-M2.5` | text | 1,000,000 | reasoning 활성화됨 |
| `qwen/glm-5` | text | 202,752 | GLM |
| `qwen/glm-4.7` | text | 202,752 | GLM |
| `qwen/kimi-k2.5` | text, image | 262,144 | Alibaba를 통한 Moonshot AI |
모델이 번들 카탈로그에 있더라도 엔드포인트와 과금 플랜에 따라 사용 가능 여부는 달라질 수 있습니다.
모델이 번들 카탈로그에 있더라도, 실제 사용 가능 여부는 엔드포인트와 결제 플랜에 따라 달라질 수 있습니다.
기본 스트리밍 사용량 호환성은 Coding Plan 호스트와
Standard DashScope 호환 호스트 모두에 적용됩니다:
Standard DashScope 호환 호스트 모두에 적용됩니다.
- `https://coding.dashscope.aliyuncs.com/v1`
- `https://coding-intl.dashscope.aliyuncs.com/v1`
- `https://dashscope.aliyuncs.com/compatible-mode/v1`
- `https://dashscope-intl.aliyuncs.com/compatible-mode/v1`
## Qwen 3.6 Plus 가용성
## Qwen 3.6 Plus 사용 가능 여부
`qwen3.6-plus`는 Standard (pay-as-you-go) Model Studio
엔드포인트에서 사용할 수 있습니다:
엔드포인트에서 사용할 수 있습니다.
- 중국: `dashscope.aliyuncs.com/compatible-mode/v1`
- 전역: `dashscope-intl.aliyuncs.com/compatible-mode/v1`
- China: `dashscope.aliyuncs.com/compatible-mode/v1`
- Global: `dashscope-intl.aliyuncs.com/compatible-mode/v1`
Coding Plan 엔드포인트가 `qwen3.6-plus`에 대해 "unsupported model" 오류를 반환하면,
Coding Plan 엔드포인트/key 조합 대신 Standard (pay-as-you-go)로 전환하세요.
Coding Plan 엔드포인트에서 `qwen3.6-plus`에 대해
"unsupported model" 오류가 반환되면, Coding Plan
엔드포인트/키 조합 대신 Standard (pay-as-you-go)로 전환하세요.
## capability 계획
## 기능 계획
`qwen` extension은 단지 coding/text 모델만이 아니라
전체 Qwen Cloud 표면을 위한 벤더 홈으로 자리 잡고 있습니다.
`qwen` 확장은 단순한 코딩/텍스트 모델뿐 아니라 전체 Qwen
Cloud 표면의 벤더 홈으로 자리 잡고 있습니다.
- 텍스트/채팅 모델: 현재 번들 제공
- tool calling, 구조화 출력, thinking: OpenAI 호환 전송에서 상속
- 이미지 생성: provider-plugin 계층에서 계획 중
- Tool calling, structured output, thinking: OpenAI 호환 전송에서 상속
- 이미지 생성: provider-plugin 계층에서 예정
- 이미지/비디오 이해: 현재 Standard 엔드포인트에서 번들 제공
- speech/오디오: provider-plugin 계층에서 계획 중
- 메모리 임베딩/리랭킹: 임베딩 adapter 표면을 통해 계획 중
- 비디오 생성: 공유 video-generation capability를 통해 현재 번들 제공
- 음성/오디오: provider-plugin 계층에서 예정
- 메모리 임베딩/reranking: 임베딩 어댑터 표면을 통해 예정
- 비디오 생성: 공용 비디오 생성 기능을 통해 현재 번들 제공
## 멀티모달 추가 기능
이제 `qwen` extension은 다음도 제공합니다:
`qwen` 확장은 이제 다음도 제공합니다.
- `qwen-vl-max-latest`를 통한 비디오 이해
- 다음을 통한 Wan 비디오 생성:
@ -158,20 +159,20 @@ Coding Plan 엔드포인트/key 조합 대신 Standard (pay-as-you-go)로 전환
이 멀티모달 표면은 Coding Plan 엔드포인트가 아니라
**Standard** DashScope 엔드포인트를 사용합니다.
- 전역/국제 Standard base URL: `https://dashscope-intl.aliyuncs.com/compatible-mode/v1`
- 중국 Standard base URL: `https://dashscope.aliyuncs.com/compatible-mode/v1`
- Global/Intl Standard base URL: `https://dashscope-intl.aliyuncs.com/compatible-mode/v1`
- China Standard base URL: `https://dashscope.aliyuncs.com/compatible-mode/v1`
비디오 생성의 경우 OpenClaw는 작업 제출 전에 구성된 Qwen 리전을
일치하는 DashScope AIGC 호스트로 매핑합니다:
비디오 생성의 경우, OpenClaw는 작업 제출 전에 구성된 Qwen 지역을 일치하는
DashScope AIGC 호스트에 매핑합니다.
- 전역/국제: `https://dashscope-intl.aliyuncs.com`
- 중국: `https://dashscope.aliyuncs.com`
- Global/Intl: `https://dashscope-intl.aliyuncs.com`
- China: `https://dashscope.aliyuncs.com`
즉, Coding Plan 또는 Standard Qwen 호스트 중 하나를 가리키는 일반적인
`models.providers.qwen.baseUrl`을 사용해도 비디오 생성은 계속 올바른
리전 DashScope 비디오 엔드포인트를 사용하게 됩니다.
즉, Coding Plan 또는 Standard Qwen 호스트를 가리키는 일반적인
`models.providers.qwen.baseUrl`을 사용하더라도 비디오 생성은 올바른
지역 DashScope 비디오 엔드포인트를 계속 사용합니다.
비디오 생성의 경우 기본 모델을 명시적으로 설정하세요:
비디오 생성의 경우 기본 모델을 명시적으로 설정하세요.
```json5
{
@ -185,20 +186,20 @@ Coding Plan 엔드포인트/key 조합 대신 Standard (pay-as-you-go)로 전환
현재 번들 Qwen 비디오 생성 제한:
- 요청당 출력 비디오는 최대 **1**
- 입력 이미지는 최대 **1**
- 입력 비디오는 최대 **4**
- 길이는 최대 **10초**
- 요청당 최대 **1**개 출력 비디오
- 최대 **1**개 입력 이미지
- 최대 **4**개 입력 비디오
- 최대 **10초** duration
- `size`, `aspectRatio`, `resolution`, `audio`, `watermark` 지원
- 참조 이미지/비디오 모드는 현재 **원격 http(s) URL**이 필요합니다. DashScope 비디오 엔드포인트가
해당 참조에 대해 업로드된 로컬 버퍼를 허용하지 않기 때문에 로컬
파일 경로는 초기에 거부됩니다.
- 참조 이미지/비디오 모드는 현재 **원격 http(s) URL**이 필요합니다. 로컬
파일 경로는 DashScope 비디오 엔드포인트가 해당 참조에 대해 업로드된 로컬 버퍼를
허용하지 않기 때문에 사전에 거부됩니다.
유 도구 파라미터, provider 선택, failover 동작은
[Video Generation](/tools/video-generation)을 참조하세요.
용 도구 매개변수,
provider 선택, 장애 조치 동작은 [Video Generation](/ko/tools/video-generation)을 참고하세요.
## 환경 참고
Gateway가 데몬(launchd/systemd)으로 실행되는 경우 `QWEN_API_KEY`
Gateway가 데몬(launchd/systemd)으로 실행되는 경우, `QWEN_API_KEY`
해당 프로세스에서 사용 가능해야 합니다(예: `~/.openclaw/.env` 또는
`env.shellEnv`를 통해).