Gateway
بکاندهای CLI
OpenClaw میتواند CLIهای هوش مصنوعی محلی را بهعنوان یک مسیر جایگزین فقط متنی اجرا کند، وقتی ارائهدهندگان API از دسترس خارجاند، محدودیت نرخ دارند، یا موقتاً بدرفتار میکنند. این طراحی عمداً محافظهکارانه است:
- ابزارهای OpenClaw مستقیماً تزریق نمیشوند، اما backendهایی با
bundleMcp: trueمیتوانند ابزارهای gateway را از طریق یک پل MCP مبتنی بر local loopback دریافت کنند. - استریم JSONL برای CLIهایی که از آن پشتیبانی میکنند.
- نشستها پشتیبانی میشوند (تا نوبتهای پیگیری منسجم بمانند).
- تصاویر میتوانند عبور داده شوند اگر CLI مسیرهای تصویر را بپذیرد.
این بیشتر بهعنوان یک شبکه ایمنی طراحی شده است تا مسیر اصلی. وقتی پاسخهای متنی «همیشه کار میکند» میخواهید بدون اتکا به APIهای خارجی، از آن استفاده کنید.
اگر runtime کامل harness با کنترلهای نشست ACP، وظایف پسزمینه، اتصال thread/conversation، و نشستهای کدنویسی خارجی پایدار میخواهید، بهجای آن از عاملهای ACP استفاده کنید. backendهای CLI، ACP نیستند.
شروع سریع مناسب مبتدیان
میتوانید از Codex CLI بدون هیچ پیکربندیای استفاده کنید (Plugin بستهبندیشده OpenAI یک backend پیشفرض ثبت میکند):
openclaw agent --message "hi" --model codex-cli/gpt-5.5اگر gateway شما زیر launchd/systemd اجرا میشود و PATH حداقلی است، فقط مسیر command را اضافه کنید:
{ agents: { defaults: { cliBackends: { "codex-cli": { command: "/opt/homebrew/bin/codex", }, }, }, },}تمام است. هیچ کلید یا پیکربندی auth اضافهای فراتر از خود CLI لازم نیست.
اگر از یک backend CLI بستهبندیشده بهعنوان ارائهدهنده اصلی پیام روی یک
میزبان gateway استفاده میکنید، OpenClaw اکنون وقتی پیکربندی شما صراحتاً به آن backend در یک model ref یا زیر
agents.defaults.cliBackends اشاره کند، Plugin بستهبندیشده مالک را بهصورت خودکار بارگذاری میکند.
استفاده از آن بهعنوان fallback
یک backend CLI را به فهرست fallback خود اضافه کنید تا فقط وقتی مدلهای اصلی شکست میخورند اجرا شود:
{ agents: { defaults: { model: { primary: "anthropic/claude-opus-4-6", fallbacks: ["codex-cli/gpt-5.5"], }, models: { "anthropic/claude-opus-4-6": { alias: "Opus" }, "codex-cli/gpt-5.5": {}, }, }, },}نکتهها:
- اگر از
agents.defaults.models(allowlist) استفاده میکنید، باید مدلهای backend CLI خود را هم آنجا وارد کنید. - اگر ارائهدهنده اصلی شکست بخورد (auth، محدودیت نرخ، timeout)، OpenClaw بعداً backend CLI را امتحان میکند.
نمای کلی پیکربندی
همه backendهای CLI زیر این مسیر قرار دارند:
agents.defaults.cliBackendsهر ورودی با یک provider id کلیدگذاری میشود (مثلاً codex-cli، my-cli).
provider id به سمت چپ model ref شما تبدیل میشود:
<provider>/<model>نمونه پیکربندی
{ agents: { defaults: { cliBackends: { "codex-cli": { command: "/opt/homebrew/bin/codex", }, "my-cli": { command: "my-cli", args: ["--json"], output: "json", input: "arg", modelArg: "--model", modelAliases: { "claude-opus-4-6": "opus", "claude-sonnet-4-6": "sonnet", }, sessionArg: "--session", sessionMode: "existing", sessionIdFields: ["session_id", "conversation_id"], systemPromptArg: "--system", // For CLIs with a dedicated prompt-file flag: // systemPromptFileArg: "--system-file", // Codex-style CLIs can point at a prompt file instead: // systemPromptFileConfigArg: "-c", // systemPromptFileConfigKey: "model_instructions_file", systemPromptWhen: "first", imageArg: "--image", imageMode: "repeat", // Opt in only if this backend may reseed safe invalidated sessions // from bounded raw OpenClaw transcript history before compaction. reseedFromRawTranscriptWhenUncompacted: true, serialize: true, }, }, }, },}شیوه کار
- یک backend انتخاب میکند بر اساس پیشوند provider (
codex-cli/...). - یک system prompt میسازد با همان prompt و بافت workspace در OpenClaw.
- CLI را اجرا میکند با یک شناسه نشست (اگر پشتیبانی شود) تا تاریخچه سازگار بماند.
backend بستهبندیشده
claude-cliبرای هر نشست OpenClaw یک فرایند Claude stdio را زنده نگه میدارد و نوبتهای پیگیری را از طریق stream-json stdin میفرستد. - خروجی را parse میکند (JSON یا متن ساده) و متن نهایی را برمیگرداند.
- شناسههای نشست را پایدار نگه میدارد برای هر backend، تا پیگیریها همان نشست CLI را دوباره استفاده کنند.
backend بستهبندیشده OpenAI یعنی codex-cli، system prompt در OpenClaw را از طریق override پیکربندی
model_instructions_file در Codex عبور میدهد (-c model_instructions_file="..."). Codex یک flag به سبک Claude با نام
--append-system-prompt ارائه نمیکند، بنابراین OpenClaw prompt مونتاژشده را برای هر نشست تازه Codex CLI در یک
فایل موقت مینویسد.
backend بستهبندیشده Anthropic یعنی claude-cli، snapshot مربوط به Skills در OpenClaw را
به دو روش دریافت میکند: کاتالوگ فشرده Skills در OpenClaw داخل system prompt افزودهشده، و
یک Claude Code Plugin موقت که با --plugin-dir فرستاده میشود. Plugin فقط
Skills واجد شرایط همان agent/session را دارد، بنابراین resolver بومی skill در Claude Code
همان مجموعه فیلترشدهای را میبیند که OpenClaw در غیر این صورت در
prompt تبلیغ میکرد. overrideهای env/API key مربوط به Skill همچنان توسط OpenClaw روی
محیط child process برای اجرا اعمال میشوند.
Claude CLI همچنین حالت مجوز noninteractive خودش را دارد. OpenClaw آن را
بهجای افزودن پیکربندی مخصوص Claude، به سیاست exec موجود نگاشت میکند: وقتی
سیاست exec مؤثر درخواستشده YOLO باشد (tools.exec.security: "full" و
tools.exec.ask: "off")، OpenClaw گزینه --permission-mode bypassPermissions را اضافه میکند.
تنظیمات per-agent در agents.list[].tools.exec تنظیمات سراسری tools.exec را برای
آن agent override میکند. برای اجبار یک حالت Claude متفاوت، raw backend args صریح
مانند --permission-mode default یا --permission-mode acceptEdits را زیر
agents.defaults.cliBackends.claude-cli.args و resumeArgs متناظر تنظیم کنید.
backend بستهبندیشده Anthropic یعنی claude-cli همچنین سطوح /think در OpenClaw را
برای سطوحی غیر از off به flag بومی --effort در Claude Code نگاشت میکند. minimal و
low به low نگاشت میشوند، adaptive و medium به medium نگاشت میشوند، و high،
xhigh، و max مستقیماً نگاشت میشوند. سایر backendهای CLI به Plugin مالک خود نیاز دارند تا
پیش از آنکه /think بتواند روی CLI اجراشده اثر بگذارد، یک mapper معادل argv
اعلام کند.
پیش از آنکه OpenClaw بتواند از backend بستهبندیشده claude-cli استفاده کند، خود Claude Code
باید از قبل روی همان میزبان login شده باشد:
claude auth loginclaude auth status --textopenclaw models auth login --provider anthropic --method cli --set-defaultفقط زمانی از agents.defaults.cliBackends.claude-cli.command استفاده کنید که باینری claude
از قبل روی PATH نباشد.
نشستها
- اگر CLI از نشستها پشتیبانی میکند،
sessionArg(مثلاً--session-id) یاsessionArgs(placeholder{sessionId}) را تنظیم کنید وقتی ID باید در چند flag درج شود. - اگر CLI از یک زیرفرمان resume با flagهای متفاوت استفاده میکند،
resumeArgs(جایگزینargsهنگام resume) و بهصورت اختیاریresumeOutput(برای resumeهای غیر JSON) را تنظیم کنید. sessionMode:always: همیشه یک شناسه نشست بفرستید (اگر هیچکدام ذخیره نشده باشد UUID جدید).existing: فقط اگر قبلاً یک شناسه نشست ذخیره شده باشد، آن را بفرستید.none: هرگز شناسه نشست نفرستید.
claude-cliبهصورت پیشفرض رویliveSession: "claude-stdio"،output: "jsonl"، وinput: "stdin"قرار دارد تا نوبتهای پیگیری، وقتی فرایند Claude فعال است، همان فرایند زنده را دوباره استفاده کنند. stdio گرم اکنون پیشفرض است، از جمله برای پیکربندیهای سفارشی که فیلدهای transport را حذف میکنند. اگر Gateway restart شود یا فرایند idle خارج شود، OpenClaw از شناسه نشست ذخیرهشده Claude resume میکند. شناسههای نشست ذخیرهشده پیش از resume در برابر transcript پروژه خوانای موجود اعتبارسنجی میشوند، بنابراین bindingهای خیالی باreason=transcript-missingپاک میشوند بهجای اینکه بیصدا یک نشست تازه Claude CLI را زیر--resumeشروع کنند.- نشستهای زنده Claude نگهبانهای محدودشده خروجی JSONL را نگه میدارند. پیشفرضها تا
8 MiB و 20,000 خط خام JSONL را در هر نوبت مجاز میکنند. نوبتهای Claude با ابزارهای زیاد میتوانند
آنها را برای هر backend با
agents.defaults.cliBackends.claude-cli.reliability.outputLimits.maxTurnRawCharsوmaxTurnLinesافزایش دهند؛ OpenClaw این تنظیمات را به 64 MiB و 100,000 خط clamp میکند. - نشستهای ذخیرهشده CLI تداوم تحت مالکیت provider هستند. reset ضمنی روزانه نشست
آنها را قطع نمیکند؛
/resetو سیاستهای صریحsession.resetهمچنان این کار را میکنند. - نشستهای تازه CLI معمولاً فقط از خلاصه Compaction در OpenClaw
بهعلاوه دنباله پس از compaction دوباره seed میشوند. برای بازیابی نشستهای کوتاهی که
پیش از compaction نامعتبر میشوند، یک backend میتواند با
reseedFromRawTranscriptWhenUncompacted: trueopt in کند. OpenClaw همچنان reseed از transcript خام را محدود نگه میدارد و آن را به invalidationهای ایمن مانند نبودن transcriptهای CLI، تغییرات system-prompt/MCP، یا retry پس از session-expired محدود میکند؛ تغییرات auth profile یا credential-epoch هرگز تاریخچه transcript خام را دوباره seed نمیکنند.
نکتههای serialization:
serialize: trueاجراهای همان lane را مرتب نگه میدارد.- بیشتر CLIها روی یک lane provider serialize میشوند.
- وقتی هویت auth انتخابشده تغییر کند، OpenClaw استفاده مجدد از نشست CLI ذخیرهشده را کنار میگذارد، از جمله تغییر auth profile id، API key ایستا، token ایستا، یا هویت account در OAuth وقتی CLI آن را expose کند. چرخش access token و refresh token در OAuth نشست CLI ذخیرهشده را قطع نمیکند. اگر یک CLI شناسه account پایدار OAuth را expose نکند، OpenClaw اجازه میدهد همان CLI مجوزهای resume را enforce کند.
مقدمه fallback از نشستهای claude-cli
وقتی یک تلاش claude-cli به یک کاندید غیر CLI در
agents.defaults.model.fallbacks fail over میکند، OpenClaw
تلاش بعدی را با یک context prelude که از transcript محلی JSONL مربوط به Claude Code در
~/.claude/projects/ برداشت شده است seed میکند. بدون این seed، ارائهدهنده fallback
از صفر شروع میکرد چون transcript نشست خود OpenClaw برای اجراهای claude-cli خالی است.
- prelude جدیدترین خلاصه
/compactیا markercompact_boundaryرا ترجیح میدهد، سپس تازهترین نوبتهای پس از boundary را تا سقف بودجه char اضافه میکند. نوبتهای پیش از boundary حذف میشوند چون خلاصه از قبل نماینده آنهاست. - بلوکهای ابزار به hintهای فشرده
(tool call: name)و(tool result: …)ادغام میشوند تا بودجه prompt دقیق بماند. اگر خلاصه سرریز کند، با(truncated)برچسبگذاری میشود. - fallbackهای همان provider از
claude-cliبهclaude-cliبه--resumeخود Claude تکیه میکنند و prelude را رد میکنند. - این seed از اعتبارسنجی مسیر فایل نشست موجود Claude دوباره استفاده میکند، بنابراین مسیرهای دلخواه نمیتوانند خوانده شوند.
تصاویر (pass-through)
اگر CLI شما مسیرهای تصویر را میپذیرد، imageArg را تنظیم کنید:
imageArg: "--image",imageMode: "repeat"OpenClaw تصاویر base64 را در فایلهای موقت مینویسد. اگر imageArg تنظیم شده باشد، آن
مسیرها بهعنوان آرگومانهای CLI فرستاده میشوند. اگر imageArg وجود نداشته باشد، OpenClaw
مسیرهای فایل را به prompt اضافه میکند (path injection)، که برای CLIهایی که فایلهای محلی را از مسیرهای ساده
بهصورت خودکار بارگذاری میکنند کافی است.
ورودیها / خروجیها
output: "json"(پیشفرض) تلاش میکند JSON را parse کند و متن + شناسه نشست را استخراج کند.- برای خروجی JSON در Gemini CLI، OpenClaw متن پاسخ را از
responseو usage را ازstatsمیخواند وقتیusageوجود ندارد یا خالی است. output: "jsonl"streamهای JSONL را parse میکند (برای مثال Codex CLI--json) و پیام نهایی agent بهعلاوه شناسههای نشست را در صورت وجود استخراج میکند.output: "text"با stdout بهعنوان پاسخ نهایی رفتار میکند.
حالتهای ورودی:
input: "arg"(پیشفرض) prompt را بهعنوان آخرین آرگومان CLI میفرستد.input: "stdin"prompt را از طریق stdin میفرستد.- اگر prompt بسیار طولانی باشد و
maxPromptArgCharsتنظیم شده باشد، از stdin استفاده میشود.
پیشفرضها (تحت مالکیت Plugin)
Plugin بستهبندیشده OpenAI همچنین یک پیشفرض برای codex-cli ثبت میکند:
command: "codex"args: ["exec","--json","--color","never","--sandbox","workspace-write","--skip-git-repo-check"]resumeArgs: ["exec","resume","{sessionId}","-c","sandbox_mode=\"workspace-write\"","--skip-git-repo-check"]output: "jsonl"resumeOutput: "text"modelArg: "--model"imageArg: "--image"sessionMode: "existing"
Plugin همراه Google همچنین یک پیشفرض برای google-gemini-cli ثبت میکند:
command: "gemini"args: ["--output-format", "json", "--prompt", "{prompt}"]resumeArgs: ["--resume", "{sessionId}", "--output-format", "json", "--prompt", "{prompt}"]imageArg: "@"imagePathScope: "workspace"modelArg: "--model"sessionMode: "existing"sessionIdFields: ["session_id", "sessionId"]
پیشنیاز: CLI محلی Gemini باید نصب شده باشد و بهصورت
gemini در PATH در دسترس باشد (brew install gemini-cli یا
npm install -g @google/gemini-cli).
نکتههای JSON در Gemini CLI:
- متن پاسخ از فیلد JSON با نام
responseخوانده میشود. - وقتی
usageوجود ندارد یا خالی است، مصرف بهstatsبازمیگردد. - مقدار
stats.cachedبهcacheReadدر OpenClaw نرمالسازی میشود. - اگر
stats.inputموجود نباشد، OpenClaw توکنهای ورودی را ازstats.input_tokens - stats.cachedاستخراج میکند.
فقط در صورت نیاز بازنویسی کنید (مورد رایج: مسیر مطلق command).
پیشفرضهای متعلق به Plugin
پیشفرضهای بکاند CLI اکنون بخشی از سطح Plugin هستند:
- Pluginها آنها را با
api.registerCliBackend(...)ثبت میکنند. - مقدار
idبکاند به پیشوند provider در model refها تبدیل میشود. - پیکربندی کاربر در
agents.defaults.cliBackends.<id>همچنان پیشفرض Plugin را بازنویسی میکند. - پاکسازی پیکربندی ویژه هر بکاند از طریق hook اختیاری
normalizeConfigهمچنان متعلق به Plugin باقی میماند.
Pluginهایی که به shimهای کوچک سازگاری prompt/message نیاز دارند، میتوانند تبدیلهای متنی دوطرفه را بدون جایگزینکردن یک provider یا بکاند CLI اعلام کنند:
api.registerTextTransforms({ input: [ { from: /red basket/g, to: "blue basket" }, { from: /paper ticket/g, to: "digital ticket" }, { from: /left shelf/g, to: "right shelf" }, ], output: [ { from: /blue basket/g, to: "red basket" }, { from: /digital ticket/g, to: "paper ticket" }, { from: /right shelf/g, to: "left shelf" }, ],});input، system prompt و user prompt ارسالشده به CLI را بازنویسی میکند. output
دلتاهای assistant در حال stream و متن نهایی parseشده را پیش از آنکه OpenClaw
نشانگرهای کنترلی خودش و تحویل به channel را مدیریت کند، بازنویسی میکند.
برای CLIهایی که JSONL سازگار با Claude Code stream-json منتشر میکنند،
jsonlDialect: "claude-stream-json" را در پیکربندی آن بکاند تنظیم کنید.
همپوشانهای MCP بسته
بکاندهای CLI فراخوانیهای ابزار OpenClaw را بهطور مستقیم دریافت نمیکنند، اما یک بکاند میتواند
با bundleMcp: true از همپوشان پیکربندی MCP تولیدشده استفاده کند.
رفتار همراه فعلی:
claude-cli: فایل پیکربندی MCP سختگیرانه تولیدشدهcodex-cli: بازنویسیهای درونخطی پیکربندی برایmcp_servers؛ سرور loopback تولیدشده OpenClaw با حالت تأیید ابزار بهازای هر سرور در Codex علامتگذاری میشود تا فراخوانیهای MCP روی promptهای تأیید محلی متوقف نشوندgoogle-gemini-cli: فایل تنظیمات سیستم Gemini تولیدشده
وقتی MCP بسته فعال باشد، OpenClaw:
- یک سرور HTTP MCP loopback اجرا میکند که ابزارهای gateway را در اختیار فرایند CLI میگذارد
- bridge را با یک token بهازای هر session احراز هویت میکند (
OPENCLAW_MCP_TOKEN) - دسترسی ابزار را به session، account و context فعلی channel محدود میکند
- سرورهای bundle-MCP فعالشده برای workspace فعلی را بارگذاری میکند
- آنها را با هر شکل موجود از پیکربندی/تنظیمات MCP بکاند ادغام میکند
- پیکربندی اجرا را با استفاده از حالت integration متعلق به بکاند از extension مالک بازنویسی میکند
اگر هیچ سرور MCP فعالی وجود نداشته باشد، وقتی یک بکاند MCP بسته را فعال میکند، OpenClaw همچنان یک پیکربندی سختگیرانه تزریق میکند تا اجراهای پسزمینه ایزوله بمانند.
runtimeهای MCP همراه با محدوده session برای استفاده مجدد درون یک session cache میشوند، سپس
پس از mcp.sessionIdleTtlMs میلیثانیه زمان بیکاری پاک میشوند (پیشفرض ۱۰
دقیقه؛ برای غیرفعالسازی 0 را تنظیم کنید). اجراهای embedded یکباره مانند بررسیهای auth،
تولید slug، و active-memory recall در پایان اجرا cleanup درخواست میکنند تا فرزندان stdio
و streamهای Streamable HTTP/SSE پس از اجرا باقی نمانند.
محدودیتها
- بدون فراخوانی مستقیم ابزار OpenClaw. OpenClaw فراخوانی ابزار را به
پروتکل بکاند CLI تزریق نمیکند. بکاندها فقط وقتی ابزارهای gateway را میبینند که
bundleMcp: trueرا فعال کنند. - Streaming ویژه بکاند است. بعضی بکاندها JSONL را stream میکنند؛ برخی دیگر تا زمان خروج buffer میکنند.
- خروجیهای ساختیافته به قالب JSON خود CLI وابستهاند.
- sessionهای Codex CLI از طریق خروجی متنی resume میشوند (بدون JSONL)، که نسبت به
اجرای اولیه
--jsonساختیافتگی کمتری دارد. sessionهای OpenClaw همچنان بهصورت عادی کار میکنند.
عیبیابی
- CLI پیدا نشد: مقدار
commandرا روی یک مسیر کامل تنظیم کنید. - نام مدل نادرست: از
modelAliasesبرای نگاشتprovider/model→ مدل CLI استفاده کنید. - نبود تداوم session: مطمئن شوید
sessionArgتنظیم شده وsessionModeبرابرnoneنیست (Codex CLI در حال حاضر نمیتواند با خروجی JSON resume شود). - نادیده گرفتهشدن تصاویر: مقدار
imageArgرا تنظیم کنید (و مطمئن شوید CLI از مسیرهای فایل پشتیبانی میکند).