Tools

حالت کد

حالت کد یک قابلیت آزمایشی و اختیاری در زمان اجرای عامل OpenClaw است. وقتی فعال باشد، مدل دیگر طرح‌وارهٔ همهٔ ابزارهای فعال را نمی‌بیند؛ در عوض، exec، wait و هر ابزار فقط‌مستقیمی را می‌بیند که نتیجهٔ ساخت‌یافتهٔ آن نمی‌تواند از پل مهمانِ صرفاً JSON عبور کند. مدل یک برنامهٔ کوچک JavaScript یا TypeScript می‌نویسد که کاتالوگ پنهان ابزارها را جست‌وجو و توصیف می‌کند و ابزارهای آن را فرامی‌خواند.

این صفحه حالت کد OpenClaw را مستند می‌کند، نه Codex Code Mode را. این دو قابلیت نام و نام‌های ابزار کنترلی یکسانی (exec، wait) دارند، اما پیاده‌سازی‌های جداگانه‌ای هستند:

  • Codex Code Mode درون محیط کدنویسی Codex اجرا می‌شود. ابزار exec آن یک ابزار با دستور زبان آزاد است: مدل کد منبع خام JavaScript می‌نویسد (که می‌تواند با یک خط pragma به‌شکل // @exec: {...} برای گزینه‌های اجرا آغاز شود) و این کد در محیط اجرای درون‌پردازه‌ای V8 Code Mode متعلق به Codex اجرا می‌شود.
  • حالت کد OpenClaw در محیط اجرای عمومی عامل OpenClaw اجرا می‌شود و تا زمانی که tools.codeMode.enabled: true پیکربندی نشده باشد غیرفعال است. ابزار exec آن یک بارِ دادهٔ JSON به‌شکل { code, language } می‌پذیرد که در یک worker مبتنی بر QuickJS-WASI اجرا می‌شود.

هر دو سطح اجرای JavaScript هستند، نه سطح اجرای فرمان‌های shell. آن‌ها را قابلیت‌هایی مستقل با پیاده‌سازی‌های متفاوت در نظر بگیرید که صرفاً ابزارهای هم‌نام exec/wait را ارائه می‌کنند.

چه کاری انجام می‌دهد

  • فهرست ابزارهای قابل‌مشاهده برای مدل به exec، wait و هر ابزار فقط‌مستقیمی مانند computer یا بارگذار بینایی بومی image محدود می‌شود که نتیجهٔ تصویری آن نمی‌تواند از پل مهمان عبور کند.
  • exec کد JavaScript یا TypeScript تولیدشده توسط مدل را در یک رشتهٔ worker ایزولهٔ QuickJS-WASI ارزیابی می‌کند.
  • هر ابزار فعال واجد شرایط کاتالوگ (هستهٔ OpenClaw، plugin، MCP، کلاینت) به‌عنوان یک ابزار مستقل مدل پنهان و از طریق ALL_TOOLS و tools در برنامهٔ مهمان ارائه می‌شود.
  • توضیح exec یک نمایهٔ سریع و محدود از شناسه‌های دقیق کاتالوگ OpenClaw/plugin، راهنمای فشردهٔ ورودی و، هنگامی که ابزار معتبری طرح‌وارهٔ خروجی ارائه کند، راهنمای فشردهٔ خروجی اعلام‌شده را در بر دارد. این نما توضیحات، طرح‌واره‌های کامل، ورودی‌های MCP و ورودی‌های مازاد را حذف می‌کند؛ جست‌وجوی کاتالوگ در سمت مهمان همچنان راهکار جایگزین است.
  • کد مهمان کاتالوگ پنهان را جست‌وجو می‌کند، طرح‌وارهٔ یک ابزار را توصیف می‌کند و ابزار را از همان مسیر اجرایی فرامی‌خواند که نوبت‌های عادی عامل استفاده می‌کنند (خط‌مشی، تأییدها، hookها و تله‌متری همچنان اعمال می‌شوند).
  • ابزارهای MCP زیر فضای نام MCP گروه‌بندی می‌شوند؛ در حالت کد، این تنها روش پشتیبانی‌شده برای فراخوانی آن‌ها است.
  • wait هنگامی که فراخوانی‌های ابزار تودرتو هنوز در انتظارند، اجرای تعلیق‌شدهٔ حالت کد را از سر می‌گیرد.

حالت کد فقط سطح هماهنگ‌سازی رو‌به‌مدل را تغییر می‌دهد. این حالت جایگزین ابزارها، ابزارهای plugin، ابزارهای MCP، احراز هویت، خط‌مشی تأیید، رفتار کانال یا انتخاب مدل نمی‌شود.

چرا از آن استفاده کنیم

  • سطح prompt کوچک‌تر: ارائه‌دهندگان به‌جای ده‌ها یا صدها طرح‌وارهٔ کامل ابزار، دو ابزار کنترلی، یک نمایهٔ محدود از ابزارهای بومی و فقط چند ابزار مستقیم ضروری دریافت می‌کنند.
  • هماهنگ‌سازی بهتر: مدل می‌تواند درون یک سلول کد از حلقه‌ها، joinها، تبدیل‌های کوچک، منطق شرطی و فراخوانی‌های موازی ابزار تودرتو استفاده کند.
  • رفت‌وبرگشت‌های کمتر مدل: یک قرارداد خروجی اعلام‌شده به مدل اجازه می‌دهد نتیجهٔ یک ابزار را در یک exec فراخوانی و تبدیل کند؛ خروجی‌های ناشناخته ابتدا به‌صورت خام باقی می‌مانند.
  • مستقل از ارائه‌دهنده: برای ابزارهای OpenClaw، plugin، MCP و کلاینت کار می‌کند، بدون آنکه به اجرای کد بومی ارائه‌دهنده وابسته باشد.
  • بسته شکست می‌خورد: اگر حالت کد فعال باشد اما محیط اجرای QuickJS-WASI در دسترس نباشد، اجرا شکست می‌خورد و بی‌سروصدا به ارائهٔ مستقیم و گستردهٔ ابزارها بازنمی‌گردد.

این حالت برای عامل‌هایی با کاتالوگ بزرگ ابزارهای فعال، یا گردش‌کارهایی که در آن‌ها مدل باید پیش از پاسخ‌دادن چند ابزار را جست‌وجو، ترکیب و فراخوانی کند، بیشترین کاربرد را دارد.

برای یک کاتالوگ کوچک یا مدلی که برنامه‌های کوتاه را با اطمینان نمی‌نویسد، ارائهٔ مستقیم ابزارها را حفظ کنید. وقتی کاتالوگی فشرده می‌خواهید اما کنترل‌های ساخت‌یافتهٔ جست‌وجو/توصیف/فراخوانی را به مهمان QuickJS-WASI ترجیح می‌دهید، از جست‌وجوی ابزار استفاده کنید.

شروع سریع

فعال‌کردن حالت کد

json5
{  tools: {    codeMode: {      enabled: true,    },  },}

شکل کوتاه:

json5
{  tools: {    codeMode: true,  },}

وقتی tools.codeMode حذف شده باشد، false باشد، یا شیئی بدون enabled: true باشد، حالت کد خاموش می‌ماند.

اگر از عامل‌های sandbox‌شده با سرورهای MCP پیکربندی‌شده استفاده می‌کنید، plugin همراه MCP را نیز در خط‌مشی ابزار sandbox مجاز کنید؛ برای نمونه، tools.sandbox.tools.alsoAllow: ["bundle-mcp"]. به پیکربندی — ابزارها و ارائه‌دهندگان سفارشی مراجعه کنید.

برای محدودیت‌های سخت‌گیرانه‌تر، حدهای صریح تنظیم کنید:

json5
{  tools: {    codeMode: {      enabled: true,      timeoutMs: 10000,      memoryLimitBytes: 67108864,      maxOutputBytes: 65536,      maxSnapshotBytes: 10485760,      maxPendingToolCalls: 16,      snapshotTtlSeconds: 900,      searchDefaultLimit: 8,      maxSearchLimit: 50,    },  },}

کاری که مدل انجام می‌دهد

برای ابزاری با خروجی اعلام‌شده مانند Array<{ id: string; paid: boolean; tons: number }>، یک برنامهٔ مهمان می‌تواند آن را انتخاب، فراخوانی و تبدیل کند:

javascript
const [shipmentTool] = await tools.search("list shipments");const shipments = await tools.callValue(shipmentTool.id, {});return shipments.filter((shipment) => !shipment.paid && shipment.tons > 10);

وقتی یک خط نمایهٔ سریع به -> ? ختم شود، شکل خروجی ناشناخته است. نخستین exec باید await tools.callValue(...) را بدون تغییر برگرداند. یک exec بعدی می‌تواند مقدار مشاهده‌شده را تبدیل کند. این کار یک نوبت اضافی مدل هزینه دارد، اما مانع حدس‌زدن نام فیلدها توسط مدل می‌شود.

بررسی سطح فعال

برای تأیید شکل بار دادهٔ مدل هنگام اشکال‌زدایی، Gateway را با لاگ‌گیری هدفمند اجرا کنید:

bash
OPENCLAW_DEBUG_CODE_MODE=1 \OPENCLAW_DEBUG_MODEL_TRANSPORT=1 \OPENCLAW_DEBUG_MODEL_PAYLOAD=tools \openclaw gateway

وقتی حالت کد فعال است، نام ابزارهای رو‌به‌مدل در لاگ باید exec و wait باشند. برای بار دادهٔ کامل و ویرایش‌شدهٔ ارائه‌دهنده، در یک جلسهٔ کوتاه اشکال‌زدایی OPENCLAW_DEBUG_MODEL_PAYLOAD=full-redacted را اضافه کنید.

استفاده از Swarm برای توزیع بین عامل‌ها

Swarm متغیرهای سراسری مهمان agents.run()، phase() و log() را برای هماهنگ‌سازی هم‌زمان زیرعامل‌ها از اسکریپت‌های حالت کد اضافه می‌کند. هر دو tools.codeMode و tools.swarm را فعال کنید، سپس از جریان کنترل عادی JavaScript برای توزیع، دروازه‌های تصمیم‌گیری و گردآوری ساخت‌یافته استفاده کنید. Swarm یک دروازهٔ اختیاری جداگانه است؛ فعال‌کردن حالت کد به‌تنهایی API مربوط به agents.* را ارائه نمی‌کند.

مرور فنی

بقیهٔ این صفحه قرارداد محیط اجرا و جزئیات پیاده‌سازی را برای نگه‌دارندگان، نویسندگان plugin که ارائهٔ ابزار را اشکال‌زدایی می‌کنند، و اپراتورهایی که استقرارهای پرخطر را اعتبارسنجی می‌کنند پوشش می‌دهد.

وضعیت محیط اجرا

محیط اجرا quickjs-wasi
وضعیت پیش‌فرض غیرفعال
پایداری سطح آزمایشی OpenClaw (Codex Code Mode یک سطح پایدار و جداگانه در محیط Codex است)
سطح هدف اجراهای عمومی عامل OpenClaw
رویکرد امنیتی کد مدل متخاصم است
تعهد به کاربر فعال‌کردن حالت کد هرگز بی‌سروصدا به ارائهٔ مستقیم و گستردهٔ ابزارها بازنمی‌گردد

دامنه

حالت کد مالک شکل هماهنگ‌سازی رو‌به‌مدل برای یک اجرای آماده‌شده است. این حالت مالک انتخاب مدل، رفتار کانال، احراز هویت، خط‌مشی ابزار یا پیاده‌سازی ابزارها نیست.

در دامنه: تعریف ابزارهای کنترلی/مستقیم قابل‌مشاهده برای مدل، ساخت کاتالوگ پنهان ابزار، اجرای مهمان JavaScript/TypeScript، محیط worker مبتنی بر QuickJS-WASI، callbackهای میزبان برای جست‌وجو/توصیف/فراخوانی، وضعیت قابل‌ازسرگیری برای برنامه‌های مهمان تعلیق‌شده، محدودیت‌های خروجی/مهلت زمانی/حافظه/فراخوانی معلق/snapshot و نگاشت تله‌متری/مسیر برای فراخوانی‌های تودرتوی ابزار.

خارج از دامنه: اجرای کد راه‌دور بومی ارائه‌دهنده، معناشناسی اجرای shell، تغییر مجوزدهی موجود ابزار، اسکریپت‌های پایدارِ نوشته‌شده توسط کاربر، دسترسی مدیر بسته/فایل/شبکه/ماژول در کد مهمان، و استفادهٔ مجدد مستقیم از اجزای داخلی Codex Code Mode.

ابزارهای متعلق به ارائه‌دهنده، مانند sandboxهای راه‌دور Python، ابزارهایی جداگانه‌اند. به اجرای کد مراجعه کنید.

اصطلاحات

  • حالت کد: حالت محیط اجرای OpenClaw که ابزارهای سازگار با کاتالوگ را از مدل پنهان می‌کند و exec، wait و ابزارهای فقط‌مستقیم ضروری را ارائه می‌دهد.
  • محیط اجرای مهمان: ماشین مجازی JavaScript مبتنی بر QuickJS-WASI که کد مدل را ارزیابی می‌کند.
  • پل میزبان: سطح محدود callback سازگار با JSON از کد مهمان به OpenClaw.
  • کاتالوگ: فهرست مختص اجرا از ابزارهای مؤثر پس از اعمال خط‌مشی عادی ابزار و تفکیک plugin، MCP و ابزار کلاینت.
  • فراخوانی تودرتوی ابزار: فراخوانی ابزاری که از کد مهمان و از طریق پل میزبان انجام می‌شود.
  • Snapshot: وضعیت سریال‌شدهٔ ماشین مجازی QuickJS-WASI که ذخیره می‌شود تا wait بتواند یک اجرای تعلیق‌شدهٔ حالت کد را ادامه دهد.

پیکربندی

tools.codeMode.enabled دروازهٔ فعال‌سازی است؛ تنظیم سایر فیلدها به‌تنهایی این قابلیت را فعال نمی‌کند.

فیلد پیش‌فرض محدودسازی
enabled false بولی؛ فقط true حالت کد را فعال می‌کند
runtime "quickjs-wasi" تنها مقدار پشتیبانی‌شده
mode "only" ابزارهای کنترلی/مستقیم را ارائه و بقیه را کاتالوگ‌بندی می‌کند
languages ["javascript", "typescript"] هر زیرمجموعه‌ای از این دو
timeoutMs 10000 100-60000
memoryLimitBytes 67108864 1048576-1073741824
maxOutputBytes 65536 1024-10485760
maxSnapshotBytes 10485760 1024-268435456
maxPendingToolCalls 16 1-128
snapshotTtlSeconds 900 1-86400
searchDefaultLimit 8 به maxSearchLimit محدود می‌شود
maxSearchLimit 50 1-50

اگر حالت کد فعال باشد اما QuickJS-WASI بارگذاری نشود، OpenClaw برای آن اجرا به‌صورت بسته شکست می‌خورد؛ ابزارهای عادی را بی‌سروصدا به‌عنوان راهکار جایگزین ارائه نمی‌کند.

فعال‌سازی

حالت کد پس از مشخص‌شدن خط‌مشی مؤثر ابزار و پیش از سرهم‌شدن درخواست نهایی مدل ارزیابی می‌شود:

  1. عامل، مدل، ارائه‌دهنده، سندباکس، کانال، فرستنده و خط‌مشی اجرا را تعیین کنید.
  2. فهرست مؤثر ابزارهای OpenClaw را بسازید و ابزارهای واجد شرایط Plugin، MCP و کلاینت را به آن بیفزایید.
  3. خط‌مشی مجاز/غیرمجاز را اعمال کنید.
  4. اگر tools.codeMode.enabled نادرست است، نمایش عادی ابزارها را ادامه دهید.
  5. اگر فعال است و ابزارها برای اجرا فعال‌اند، ابزارهای الزامیِ فقط‌مستقیم را نگه دارید و هر ابزار مؤثرِ واجد شرایط کاتالوگ را در کاتالوگ حالت کد ثبت کنید.
  6. ابزارهای ثبت‌شده در کاتالوگ را از فهرست قابل‌مشاهده برای مدل حذف کنید؛ exec و wait را در کنار ابزارهای فقط‌مستقیمِ نگه‌داشته‌شده بیفزایید.

اجراهایی که عمداً هیچ ابزاری ندارند (فراخوانی‌های خام مدل، disableTools: true، یا فهرست خالی tools.allow) سطح حالت کد را فعال نمی‌کنند، حتی وقتی tools.codeMode.enabled: true پیکربندی شده باشد. حالت کد و جست‌وجوی ابزار OpenClaw برای یک اجرا مانعةالجمع‌اند؛ اگر حالت کد فعال شود، Compaction جست‌وجوی ابزار انجام نمی‌شود.

کاتالوگ حالت کد محدود به اجرا است و نباید ابزارهای عامل، نشست، فرستنده یا اجرای دیگری را نشت دهد.

ابزارهای قابل‌مشاهده برای مدل

وقتی حالت کد فعال است، مدل exec، wait و هر ابزار الزامیِ فقط‌مستقیم را می‌بیند. هر ابزار فعال دیگر از فهرست ابزارهای روبه‌مدل پنهان و در کاتالوگ حالت کد ثبت می‌شود.

از exec برای هماهنگ‌سازی ابزارها، پیوند داده‌ها، حلقه‌ها، فراخوانی‌های تودرتوی موازی و تبدیل‌های ساخت‌یافته استفاده کنید. از wait فقط زمانی استفاده کنید که exec یک نتیجه waiting قابل‌ازسرگیری برگرداند.

exec

exec یک سلول حالت کد را آغاز می‌کند و یک نتیجه برمی‌گرداند. کد ورودی توسط مدل تولید می‌شود و باید خصمانه تلقی شود.

ورودی:

typescript
type CodeModeExecInput = {  code?: string;  command?: string;  language?: "javascript" | "typescript";};

قواعد:

  • یکی از code یا command باید غیرخالی باشد.
  • code فیلد مستندشده و روبه‌مدل است.
  • command به‌عنوان نام مستعار سازگار با exec برای خط‌مشی‌های هوک و بازنویسی‌های مورداعتماد پذیرفته می‌شود (ابزار عادی shell exec در OpenClaw نیز از فیلد command استفاده می‌کند)؛ وقتی هر دو موجود باشند، مقادیر باید یکسان باشند.
  • language به‌طور پیش‌فرض "javascript" است؛ شِما آن را به‌صورت enum رشته‌ای تخت ("javascript" | "typescript") نمایش می‌دهد، نه اجتماع oneOf/anyOf، زیرا برخی ارائه‌دهندگان این ساختارها را رد می‌کنند.
  • اگر language برابر "typescript" باشد، OpenClaw پیش از ارزیابی آن را ترنسپایل می‌کند.
  • exec موارد import، require، import پویا و الگوهای بارگذار ماژول را رد می‌کند.
  • exec هرگز پیاده‌سازی عادی exec در shell را به‌صورت بازگشتی در معرض دسترس قرار نمی‌دهد.
  • رویدادهای هوک exec در حالت کد بیرونی، toolKind: "code_mode_exec" و toolInputKind: "javascript" | "typescript" را (در صورت مشخص‌بودن) حمل می‌کنند تا خط‌مشی‌ها بتوانند سلول‌های حالت کد را از فراخوانی‌های سبک shellِ exec که نام ابزار یکسانی دارند متمایز کنند.

نتیجه:

typescript
type CodeModeResult = CodeModeCompletedResult | CodeModeWaitingResult | CodeModeFailedResult; type CodeModeCompletedResult = {  status: "completed";  value: unknown;  output?: CodeModeOutput[];  telemetry: CodeModeTelemetry;}; type CodeModeWaitingResult = {  status: "waiting";  runId: string;  reason: "pending_tools" | "yield";  pendingToolCalls?: CodeModePendingToolCall[];  output?: CodeModeOutput[];  telemetry: CodeModeTelemetry;}; type CodeModeFailedResult = {  status: "failed";  error: string;  code?: CodeModeErrorCode;  output?: CodeModeOutput[];  telemetry: CodeModeTelemetry;};

exec زمانی waiting را برمی‌گرداند که مهمان با حالت قابل‌ازسرگیری معلق شود که همچنان به ادامه‌ای قابل‌مشاهده برای مدل نیاز دارد — یک yield_control(...) صریح، یا فراخوانی ابزار پل که در مهلت exec حل‌وفصل نشده باشد. نتیجه شامل یک runId برای wait است. فراخوانی‌های ابزار پل — tools.search/describe/ call و فراخوانی‌های فضای نام، از جمله فراخوانی‌های فضای نام MCP — تا زمانی که در مهلت مقرر حل‌وفصل شوند، درون همان فراخوانی exec/wait به‌طور خودکار تخلیه می‌شوند؛ بنابراین یک بلوک کد فشرده که منتظر چند ابزار می‌ماند، در یک نوبت مدل تا پایان اجرا می‌شود، به‌جای آنکه برای هر await یک فراخوانی ابزار مدل تحمیل کند. اجراهای ایمن در برابر راه‌اندازی مجدد هرگز به‌طور خودکار تخلیه نمی‌شوند؛ کارهای در انتظار آن‌ها همچنان از بررسی‌های ایمن برای بازپخش عبور می‌کنند.

exec فقط زمانی completed را برمی‌گرداند که ماشین مجازی مهمان هیچ کار در انتظاری نداشته باشد و مقدار نهایی پس از اجرای آداپتور خروجی OpenClaw با JSON سازگار باشد.

wait

wait یک ماشین مجازی معلق‌شده حالت کد را ادامه می‌دهد.

ورودی:

typescript
type CodeModeWaitInput = {  runId: string;};

خروجی همان اجتماع CodeModeResult است که exec برمی‌گرداند.

wait وجود دارد زیرا ابزارهای تودرتوی OpenClaw ممکن است کند، تعاملی، مشروط به تأیید یا در حال پخش به‌روزرسانی‌های جزئی باشند؛ مدل نباید هنگام انتظار میزبان برای کار خارجی، یک فراخوانی طولانی exec را باز نگه دارد.

سازوکار ازسرگیری، اسنپ‌شات/بازیابی QuickJS-WASI است:

  1. exec کد را تا تکمیل، شکست یا تعلیق ارزیابی می‌کند.
  2. هنگام تعلیق، OpenClaw از ماشین مجازی QuickJS اسنپ‌شات می‌گیرد و کارهای در انتظار میزبان را ثبت می‌کند.
  3. وقتی کار در انتظار تعیین‌تکلیف شد، wait اسنپ‌شات ماشین مجازی را بازیابی و callbackهای میزبان را با نام‌های پایدار دوباره ثبت می‌کند.
  4. OpenClaw نتایج ابزارهای تودرتو را به ماشین مجازی بازیابی‌شده تحویل می‌دهد و کارهای در انتظار QuickJS را تخلیه می‌کند.
  5. wait نتیجه completed، failed یا نتیجه دیگری از نوع waiting را برمی‌گرداند.

اسنپ‌شات‌ها حالت زمان اجرا هستند، نه مصنوعات کاربر: آن‌ها فقط در یک نگاشت درون‌فرایندی نگهداری می‌شوند (بدون نوشتن در پایگاه داده یا دیسک)، محدودیت اندازه دارند، منقضی می‌شوند و به اجرا و نشستی که آن‌ها را ایجاد کرده محدودند.

wait در موارد زیر (به‌صورت نتیجه failed) شکست می‌خورد:

  • runId ناشناخته است یا اسنپ‌شات آن از قبل منقضی شده است.
  • فراخواننده در همان محدوده اجرا/نشستِ اجرای معلق‌شده نیست.
  • یک wait از قبل برای آن runId در حال اجرا است.
  • بازیابی QuickJS-WASI شکست می‌خورد.
  • ازسرگیری از maxOutputBytes یا maxSnapshotBytes فراتر می‌رود.

API زمان اجرای مهمان

typescript
declare const ALL_TOOLS: ToolCatalogEntry[];declare const tools: ToolCatalog;declare const MCP: Record<string, unknown>;declare const namespaces: Record<string, unknown>; declare function text(value: unknown): void;declare function json(value: unknown): void;declare function yield_control(reason?: string): Promise<void>;

ALL_TOOLS فراداده فشرده کاتالوگ محدود به اجرا است؛ به‌طور پیش‌فرض شامل شِماهای کامل نمی‌شود. توضیح قابل‌مشاهده برای مدلِ exec نیز شامل یک زیرمجموعه محدود و قطعی از شناسه‌های دقیق OpenClaw/Plugin، راهنمای فشرده ورودی و راهنمای خروجی اعلام‌شده و مورداعتماد است. توضیحات همچنان به تعویق می‌افتند تا نثر خصمانه کاتالوگ نتواند مدل را هدایت کند. وقتی آن نمایه ابزاری را حذف می‌کند، ALL_TOOLS را بخوانید یا درون برنامه مهمان tools.search(...) را فراخوانی کنید.

فلش در هر خط نمایه سریع، مقدار tools.callValue(...) را توصیف می‌کند. -> Array<{ id: string }> راهنمای خروجی اعلام‌شده است؛ -> ? یعنی خروجی ناشناخته است. خروجی‌های ناشناخته ابتدا به‌صورت خام باقی می‌مانند: مقدار را بدون تغییر برگردانید، آن را مشاهده کنید، سپس در یک exec بعدی آن را فیلتر یا نگاشت کنید، به‌جای آنکه نام فیلدها را حدس بزنید. این قاعده وقتی خواندن خروجی اعلام‌شده ورودی یک فراخوانی نهایی -> ? را فراهم می‌کند نیز اعمال می‌شود: مقدار خام آن فراخوانی را بدون پیچیدن در قالب پاسخ درخواستی برگردانید.

typescript
type ToolCatalogEntry = {  id: string;  name: string;  label?: string;  description: string;  source: "openclaw" | "mcp" | "client";  sourceName?: string;  input: string;  output?: string;};

input یک امضای محدود به سبک TypeScript برای حالت رایج است. وقتی هنوز شِمای کامل و دقیق لازم است، از tools.describe(...) استفاده کنید. ورودی‌های MCP راه‌دور و کلاینت از input: "unknown" استفاده می‌کنند تا شِماهای نامطمئن آن‌ها تا زمان describe به تعویق بماند. output فقط برای راهنمای فشرده و کاملی موجود است که از یک outputSchema مورداعتمادِ هسته OpenClaw یا Plugin مشتق شده باشد. ادعاهای شِمای خروجی MCP و کلاینت به این راهنمای مورداعتماد کاتالوگ ارتقا نمی‌یابند.

ابزارهای Plugin از source: "openclaw" استفاده می‌کنند و sourceName روی شناسه Plugin مالک تنظیم می‌شود؛ مقدار منبع جداگانه‌ای برای "plugin" وجود ندارد. source: "mcp" فقط برای ورودی‌های MCP در فراداده sourceName/mcp استفاده می‌شود (و از ALL_TOOLS/tools.* فیلتر می‌شود، به بخش زیر مراجعه کنید).

شِمای کامل فقط هنگام نیاز بارگذاری می‌شود:

typescript
type ToolCatalogEntryWithSchema = ToolCatalogEntry & {  parameters: unknown;  outputSchema?: unknown;};

توابع کمکی کاتالوگ:

typescript
type ToolCatalog = {  search(query: string, options?: { limit?: number }): Promise&lt;ToolCatalogEntry[]&gt;;  describe(id: string): Promise&lt;ToolCatalogEntryWithSchema&gt;;  callValue(id: string, input?: unknown): Promise<unknown>;  call(id: string, input?: unknown): Promise<unknown>;  [safeToolName: string]: unknown;};

توابع ابزار تسهیلی فقط برای نام‌های امن و بدون ابهام نصب می‌شوند:

typescript
const files = await tools.search("خواندن فایل محلی");const fileRead = await tools.describe(files[0].id);const content = await tools.callValue(fileRead.id, { path: "README.md" }); // اگر کاتالوگ پنهان یک ورودی بدون ابهام `web_search` داشته باشد:const hits = await tools.web_search({ query: "حالت کد OpenClaw" });

tools.callValue(...) مقدار JSONِ details یک ابزار عادی را مستقیماً برمی‌گرداند. tools.call(...) پوشش خام { tool, result } را برای فراخوانندگانی که به بلوک‌های محتوا یا دیگر فراداده‌های نتیجه نیاز دارند، حفظ می‌کند.

قراردادهای خروجی اعلام‌شده

ابزارهای OpenClaw می‌توانند outputSchema را برای مقدار ساخت‌یافته‌ای که در AgentToolResult.details قرار می‌گیرد اعلام کنند. این برای حالت کد و جست‌وجوی ابزار مفید است؛ شِمای پاسخ ابزار بومی ارائه‌دهنده نیست و نمایش مستقیم ابزار را تغییر نمی‌دهد.

برای ابزاری که با defineToolPlugin ساخته شده است، شِما را در کنار parameters اعلام کنید:

typescript
  const Shipment = Type.Object(  {    id: Type.String(),    paid: Type.Boolean(),    tons: Type.Number(),  },  { additionalProperties: false },); export default defineToolPlugin({  id: "shipping",  name: "Shipping",  description: "ابزارهای محموله.",  tools: (tool) => [    tool({      name: "shipping_list",      description: "فهرست‌کردن محموله‌ها.",      parameters: Type.Object({}),      outputSchema: Type.Array(Shipment),      execute: async () => loadShipments(),    }),  ],});

برای api.registerTool(...) یا یک ابزار کارخانه‌ای، همان ویژگی outputSchema را روی شیء AnyAgentTool برگشتی قرار دهید.

قراردادهای داخلی کنونی شامل agents_list، apply_patch، conversations_list، conversations_send، conversations_turn، edit، openclaw، read، screen، sessions_history، sessions_list، sessions_search، sessions_send، session_status، spawn_task، terminal، web_fetch و web_search هستند. عبورهای دقیق می‌توانند به‌جای تکرار قراردادی مختص مدل، طرح‌واره پروتکل مالک خود را دوباره استفاده کنند. برای مثال، ابزارهای مکالمه همان طرح‌واره‌های نتیجه Gateway را ارائه می‌کنند که conversations.list، conversations.send و conversations.turn استفاده می‌کنند؛ web_fetch مالک یک طرح‌واره محلی ابزار است که راهنمای آن فراداده پایدار، متن، وضعیت کش و فراداده سرریز تودرتو را ارائه می‌کند؛ web_search اجتماع دقیق نتیجه‌های نرمال‌شده/پاسخ/خطا/خام خود را به‌عنوان یک راهنمای کامل نمایه سریع اعلام می‌کند. قراردادهای سیستم فایل، متن خوانده‌شده ساخت‌یافته، تصویر، برش و نتایج اختیاریِ پیدا‌نشدن؛ وضعیت صریح تغییر ویرایش به‌همراه داده‌های diff/patch؛ و خلاصه‌های مسیر اعمال patch را برمی‌گردانند. هنگامی که نمایه سریع فیلدها را اعلام می‌کند، یک سلول می‌تواند کشف و تحویل را بدون نوبت بازرسی جداگانه ترکیب کند:

javascript
const listed = await tools.conversations_list({ query: "build bot" });const target = listed.conversations.find((item) => item.label === "Build bot");if (!target) throw new Error("conversation not found");return await tools.conversations_send({  conversationRef: target.conversationRef,  message: "Build finished.",});

فراخوانی‌های تودرتو همچنان از سیاست عادی ابزار، هوک‌ها و تأییدها استفاده می‌کنند. اگر قراردادی کامل و دقیق باشد اما برای نمایه سریع محدودشده بیش‌ازحد بزرگ باشد، همچنان از طریق tools.describe(...) در دسترس می‌ماند و پیکان -> ? باقی می‌ماند.

قواعد قرارداد سخت‌گیرانه‌اند:

  • مقدار دقیق details سازگار با JSON را توصیف کنید، نه بلوک‌های رندرشده content یا پوشش ارائه‌دهنده را.
  • همه گونه‌های موفقیت یا خطای بدون throw را بگنجانید. وقتی ابزار نتیجه ساخت‌یافته پایداری ندارد، outputSchema را حذف کنید.
  • برای یک راهنمای کامل نمایه سریع، لایه‌های شیء را با { additionalProperties: false } ببندید. طرح‌واره‌های باز، بیش‌ازحد بزرگ یا به‌شکل دیگری ناقص از طریق tools.describe(...) در دسترس می‌مانند، اما استفاده یک‌نوبتی از فیلدها را فعال نمی‌کنند.
  • OpenClaw پیش از اجرای ابزار، طرح‌واره را کامپایل می‌کند و سپس details نهایی را پس از هوک‌های عادی ابزار و پیش از بازگشت فراخوانی کاتالوگ اعتبارسنجی می‌کند. طرح‌واره نامعتبر نمی‌تواند ابزار را اجرا کند؛ عدم تطابق بدون چاپ مقدار شکست می‌خورد.
  • راهنماهای فشرده قطعی و محدود هستند. tools.describe(...) هنگامی که راهنمای فشرده کافی نیست، طرح‌واره کامل و مورداعتماد را ارائه می‌کند.
  • کد Plugin نصب‌شده از قبل کد محلی مورداعتماد است. فراداده MCP راه‌دور و کلاینت همچنان نامطمئن باقی می‌ماند و نمی‌تواند این راهنماهای نمایه سریع را فعال کند.

برای جزئیات نگارش Plugin، به Pluginهای ابزار مراجعه کنید.

ورودی‌های کاتالوگ MCP از طریق tools.callValue(...)، tools.call(...) یا توابع کمکی در حالت کد قابل فراخوانی نیستند؛ آن‌ها فقط از طریق فضای نام تولیدشده MCP ارائه می‌شوند. فایل‌های اعلان به‌سبک TypeScript از طریق سطح فایل مجازی فقط‌خواندنی API در دسترس‌اند تا عامل‌ها بتوانند امضاهای MCP را بدون افزودن طرح‌واره‌های MCP به پرامپت بررسی کنند:

typescript
const files = await API.list("mcp");const githubApi = await API.read("mcp/github.d.ts"); const issue = await MCP.github.createIssue({  owner: "openclaw",  repo: "openclaw",  title: "Investigate gateway logs",}); const snapshot = await MCP.chromeDevtools.takeSnapshot({ output: "markdown" });const resource = await MCP.docs.resources.read({ uri: "memo://one" });const prompt = await MCP.docs.prompts.get({  name: "brief",  arguments: { topic: "release" },});

API.read("mcp/<server>.d.ts") اعلان‌های فشرده استنتاج‌شده از فراداده ابزار MCP را برمی‌گرداند:

typescript
type McpToolResult = {  content?: unknown[];  structuredContent?: unknown;  isError?: boolean;  [key: string]: unknown;}; declare namespace MCP.github {  /** این سرآیند API به‌سبک TypeScript را برگردانید. */  function $api(toolName?: string, options?: { schema?: boolean }): Promise&lt;McpApiHeader&gt;;   /**   * یک issue در GitHub ایجاد کنید.   * @param owner مالک مخزن   * @param repo نام مخزن   * @param title عنوان issue   */  function createIssue(input: {    owner: string;    repo: string;    title: string;    body?: string;  }): Promise&lt;McpToolResult&gt;;}

فایل‌های اعلان مجازی‌اند و زیر فضای کاری یا پوشه وضعیت نوشته نمی‌شوند. برای هر فراخوانی exec در حالت کد، OpenClaw کاتالوگ ابزار محدود به اجرا را می‌سازد، ورودی‌های قابل‌مشاهده MCP را نگه می‌دارد، mcp/index.d.ts به‌علاوه یک mcp/<server>.d.ts برای هر سرور قابل‌مشاهده رندر می‌کند و آن جدول کوچک فقط‌خواندنی را به worker مربوط به QuickJS تزریق می‌کند. کد مهمان فقط شیء API را می‌بیند: API.list(prefix?) فراداده فایل را برمی‌گرداند و API.read(path) محتوای اعلان انتخاب‌شده را بازمی‌گرداند. مسیرهای ناشناخته و بخش‌های ./.. رد می‌شوند.

این کار طرح‌واره‌های بزرگ MCP را از پرامپت مدل بیرون نگه می‌دارد: عامل از توضیح ابزار exec درمی‌یابد API مجازی وجود دارد، فقط فایل اعلان موردنیاز را می‌خواند، سپس MCP.<server>.<tool>() را با یک آرگومان شیء فراخوانی می‌کند. MCP.<server>.$api() همچنان به‌عنوان جایگزین درون‌خطی برای پاسخ طرح‌واره یک ابزار درون برنامه در دسترس می‌ماند.

محیط اجرای مهمان هرگز اشیای میزبان را مستقیماً نمی‌بیند. ورودی‌ها و خروجی‌ها به‌صورت مقادیر سازگار با JSON و با سقف‌های اندازه صریح از پل عبور می‌کنند.

فضاهای نام داخلی

فضاهای نام داخلی، بدون افزودن ابزارهای قابل‌مشاهده بیشتر برای مدل، یک API دامنه‌ای مختصر در اختیار حالت کد قرار می‌دهند. یک یکپارچه‌سازی تحت مالکیت بارگذار، فضای نامی مانند Issues یا Calendar را ثبت می‌کند؛ سپس کد مهمان آن فضای نام را درون برنامه QuickJS فراخوانی می‌کند، درحالی‌که مدل همچنان سطح فشرده کنترل/مستقیم را می‌بیند.

فضاهای نام فعلاً داخلی هستند. API عمومی فضای نام در SDK مربوط به Plugin وجود ندارد: فضاهای نام Plugin خارجی به قراردادی تحت مالکیت بارگذار نیاز دارند تا هویت Plugin، مانیفست‌های نصب‌شده، وضعیت احراز هویت و توصیفگرهای کاتالوگ کش‌شده نتوانند از ابزارهای Plugin پشتیبان فضای نام منحرف شوند. حالت کد هسته فقط مالک sandbox، سریال‌سازی، دروازه‌بانی کاتالوگ و ارسال پل است.

کد مهمان می‌تواند از global مستقیم یا نگاشت namespaces استفاده کند:

javascript
const open = await Issues.list({ state: "open" });const alsoOpen = await namespaces.Issues.list({ state: "open" });return { count: open.length, alsoCount: alsoOpen.length };

چرخه عمر رجیستری

رجیستری فضای نام محلیِ فرایند است و با شناسه فضای نام کلیدگذاری می‌شود:

  1. یک بارگذار مورداعتماد registerCodeModeNamespaceForPlugin(pluginId, registration) را فراخوانی می‌کند.
  2. حالت کد، ToolSearchRuntime پنهان را برای اجرا ایجاد و کاتالوگ محدود به اجرای آن را می‌خواند.
  3. createCodeModeNamespaceRuntime(ctx, catalog) فقط ثبت‌هایی را نگه می‌دارد که همه requiredToolNames آن‌ها قابل‌مشاهده و تحت مالکیت همان pluginId باشند.
  4. هر فضای نام قابل‌مشاهده، createScope(ctx) را برای اجرای کنونی فراخوانی می‌کند و زمینه اجرا، مانند agentId، sessionKey، sessionId، runId، پیکربندی و وضعیت لغو را دریافت می‌کند.
  5. داده دامنه به یک توصیفگر ساده سریال‌سازی می‌شود و به‌صورت globalهای مستقیم و namespaces.<globalName> به QuickJS تزریق می‌شود.
  6. فراخوانی‌های مهمان از طریق پل worker معلق می‌شوند، مسیر فضای نام را روی میزبان تفکیک می‌کنند، فراخوانی را به ابزار کاتالوگ اعلام‌شده و تحت مالکیت Plugin نگاشت می‌کنند و آن ابزار را از طریق ToolSearchRuntime.callExactId اجرا می‌کنند.
  7. فراخوانی‌های آماده پل فضای نام به‌طور خودکار درون فراخوانی فعال exec/wait تخلیه می‌شوند؛ اگر کار فضای نام هنگام پایان مهلت همچنان معلق باشد یا مهمان صراحتاً کنترل را واگذار کند، wait همان محیط اجرای فضای نام را بعداً از سر می‌گیرد.
  8. بازگردانی یا حذف نصب Plugin، clearCodeModeNamespacesForPlugin(pluginId) را فراخوانی می‌کند تا globalهای منسوخ از بارگذاری ناموفق Plugin باقی نمانند.

فراخوانی‌های فضای نام، فراخوانی ابزار کاتالوگ هستند: آن‌ها از همان هوک‌های سیاست، تأییدها، مدیریت لغو، تله‌متری، نگاشت رونوشت و رفتار تعلیق/ازسرگیری tools.call(...) استفاده می‌کنند.

ساختار ثبت

فضاهای نام را از یکپارچه‌سازی مالک ابزارهای پشتیبان ثبت کنید. دامنه را کوچک نگه دارید و فقط فعل‌های دامنه‌ای را ارائه کنید که به ابزارهای کاتالوگ اعلام‌شده نگاشت می‌شوند.

typescript
   createCodeModeNamespaceTool,  registerCodeModeNamespaceForPlugin,} from "../agents/code-mode-namespaces.js"; const pluginId = "github"; registerCodeModeNamespaceForPlugin(pluginId, {  id: "github-issues",  globalName: "Issues",  description: "GitHub issue helpers for the current repository.",  requiredToolNames: ["github_list_issues", "github_update_issue"],  prompt: "Use Issues.list(params) and Issues.update(number, patch).",  createScope: (ctx) => ({    repository: ctx.config,    list: createCodeModeNamespaceTool("github_list_issues", ([params]) => params ?? {}),    update: createCodeModeNamespaceTool("github_update_issue", ([number, patch]) => ({      number,      patch,    })),  }),});

createCodeModeNamespaceTool(toolName, inputMapper) یک عضو دامنه را به‌عنوان تابع قابل‌فراخوانی فضای نام علامت‌گذاری می‌کند. inputMapper اختیاری، آرگومان‌های مهمان را دریافت می‌کند و شیء ورودی ابزار کاتالوگ پشتیبان را برمی‌گرداند؛ بدون آن، نخستین آرگومان مهمان یا در صورت حذف، {} استفاده می‌شود.

توابع خام میزبان پیش از اجرای کد مهمان رد می‌شوند:

typescript
createScope: () => ({  // نادرست: این کار چرخه عمر ابزار کاتالوگ را دور می‌زند و رد خواهد شد.  list: async () => githubClient.listIssues(),});

مالکیت و قابلیت مشاهده

مالکیت فضای نام به pluginId فراخوان ثبت متصل است. requiredToolNames هم دروازه قابلیت مشاهده و هم بررسی مالکیت است:

  • هر ابزار الزامی باید در کاتالوگ اجرا وجود داشته باشد
  • هر ابزار الزامی باید sourceName === pluginId داشته باشد
  • اگر هر ابزار الزامی وجود نداشته باشد یا متعلق به Plugin دیگری باشد، فضای نام پنهان می‌شود
  • هر مسیر قابل‌فراخوانی فقط می‌تواند ابزاری را هدف بگیرد که نامش در requiredToolNames آمده است

این کار مانع می‌شود Plugin دیگری با ثبت ابزاری هم‌نام، فضای نامی را ارائه کند و فضاهای نام را با سیاست عادی عامل هم‌راستا نگه می‌دارد: اگر اجرا نتواند ابزارهای پشتیبان را ببیند، نمی‌تواند فضای نام را نیز ببیند.

برای مثال، یک فضای نام GitHub باید پشت Plugin تحت مالکیت GitHub قرار گیرد که مالک احراز هویت GitHub، کلاینت‌های REST/GraphQL، محدودیت نرخ، تأییدهای نوشتن و آزمون‌هاست. حالت کد هسته نباید APIهای خاص GitHub، مدیریت توکن یا سیاست ارائه‌دهنده را در خود جاسازی کند.

قواعد سریال‌سازی دامنه

createScope(ctx) می‌تواند یک شیء ساده شامل مقادیر سازگار با JSON، آرایه‌ها، اشیای تودرتو و نشانگرهای فراخوانی createCodeModeNamespaceTool(...) را برگرداند. اشیای میزبان هرگز مستقیماً وارد QuickJS نمی‌شوند.

سریال‌ساز موارد زیر را رد می‌کند:

  • توابع خام
  • گراف‌های شیء حلقوی
  • بخش‌های ناامن مسیر: __proto__، constructor، prototype، کلیدهای خالی یا کلیدهای حاوی جداکننده داخلی مسیر
  • مقادیر globalName که شناسه JavaScript نیستند
  • تداخل‌های globalName با globalهای داخلی حالت کد مانند tools، namespaces، text، json، yield_control، MCP، API، ALL_TOOLS یا __openclaw*

مقادیری که نمی‌توان آن‌ها را به JSON سریال‌سازی کرد، پیش از عبور از پل به مقادیر جایگزین و ایمن برای JSON تبدیل می‌شوند. داده دودویی، handleها، socketها، کلاینت‌ها و نمونه‌های کلاس باید پشت ابزارهای عادی کاتالوگ باقی بمانند.

پرامپت‌ها

description فضای نام و prompt اختیاری فقط هنگامی به طرح‌واره exec قابل‌مشاهده برای مدل افزوده می‌شوند که فضای نام برای آن اجرا قابل‌مشاهده باشد. از آن‌ها برای آموزش کوچک‌ترین سطح مفید استفاده کنید:

typescript
{  description: "توابع کمکی سرویس تولید داستان.",  prompt:    "از Fictions.riskAudit()، Fictions.promoteIfReady(id, status) و Fictions.unpaidOver(amount) استفاده کنید.",}

پرامپت‌ها را درباره قرارداد فضای نام نگه دارید، نه راه‌اندازی احراز هویت، تاریخچه پیاده‌سازی یا رفتار نامرتبط Plugin.

پاک‌سازی

فضاهای نام ثبت‌های محلیِ فرایند هستند. وقتی Plugin مالک غیرفعال، حذف یا به نسخه قبلی بازگردانده می‌شود، آن‌ها را حذف کنید:

typescript
clearCodeModeNamespacesForPlugin(pluginId);

پاک‌سازی حالت کد بر عهده Plugin است؛ هنگام پایان چرخه حیات آن، ثبت‌های فضای نام Plugin را پاک کنید، به‌جای اینکه برای هر فضای نام هندل‌های جداسازی نگه دارید. آزمون‌ها می‌توانند برای جلوگیری از نشت ثبت‌ها میان موارد از clearCodeModeNamespacesForTest() استفاده کنند.

چک‌لیست آزمون

تغییرات فضای نام باید مرز امنیتی و رفتار مهمان را پوشش دهند:

  • متن پرامپت فضای نام فقط زمانی ظاهر می‌شود که ابزارهای پشتیبان قابل‌مشاهده باشند
  • ابزارهای هم‌نام از یک sourceName دیگر فضای نام را افشا نمی‌کنند
  • توابع خام محدوده رد می‌شوند
  • شناسه‌های جعلی فضای نام و مسیرهای جعلی رد می‌شوند
  • مسیرهای قابل‌فراخوانی نمی‌توانند ابزارهای اعلام‌نشده را هدف قرار دهند
  • اشیای تو‌در‌تو و ارجاع‌های مشترک به‌درستی سریال‌سازی می‌شوند
  • فراخوانی‌های فضای نام از طریق ابزارهای کاتالوگ اجرا می‌شوند و جزئیات سازگار با JSON را برمی‌گردانند
  • کد مهمان می‌تواند خطاها را دریافت کند
  • فراخوانی‌های معلق فضای نام از طریق wait از سر گرفته می‌شوند
  • بازگردانی Plugin، ثبت‌های فضای نام متعلق به آن را پاک می‌کند

فضاهای نام مکمل کاتالوگ عمومی tools.search/tools.call هستند: برای ابزارهای دلخواهِ فعال OpenClaw، Plugin و کلاینت از کاتالوگ استفاده کنید؛ برای ابزارهای MCP از MCP استفاده کنید؛ برای APIهای دامنه مستند و تحت مالکیت Plugin که در آن‌ها کد مختصر از جست‌وجوهای مکرر شِما قابل‌اعتمادتر است، از فضاهای نام دیگر استفاده کنید.

API خروجی

  • text(value) خروجی خوانا برای انسان را به آرایه output اضافه می‌کند.
  • json(value) پس از سریال‌سازی سازگار با JSON، یک مورد خروجی ساخت‌یافته اضافه می‌کند.
  • مقدار نهایی برگردانده‌شده کد مهمان، در نتیجه completed به value تبدیل می‌شود.
typescript
type CodeModeOutput = { type: "text"; text: string } | { type: "json"; value: unknown };

قواعد: ترتیب خروجی با فراخوانی‌های مهمان مطابقت دارد؛ خروجی به maxOutputBytes محدود است؛ مقادیر غیرقابل‌سریال‌سازی به رشته‌های ساده یا خطا تبدیل می‌شوند؛ مقادیر دودویی پشتیبانی نمی‌شوند. تصاویر و فایل‌ها از طریق ابزارهای معمول OpenClaw منتقل می‌شوند، نه از طریق پل حالت کد.

کاتالوگ ابزار

کاتالوگ پنهان، ابزارها را پس از اعمال مؤثر فیلتر سیاست و به این ترتیب شامل می‌شود: ابزارهای هسته OpenClaw، ابزارهای Plugin همراه، ابزارهای Plugin خارجی، ابزارهای MCP و سپس ابزارهای ارائه‌شده توسط کلاینت برای اجرای جاری.

شناسه‌های کاتالوگ در یک اجرا پایدار و در صورت امکان، میان مجموعه‌ابزارهای معادل قطعی هستند. ساختار واقعی:

text
<source>:<owner>:<tool-name>

که در آن <source> برابر با openclaw، mcp یا client است (ابزارهای Plugin از openclaw با شناسه Plugin به‌عنوان <owner> استفاده می‌کنند؛ ابزارهای هسته از openclaw:core:* استفاده می‌کنند). نمونه‌ها:

text
openclaw:core:messageopenclaw:browser:browser_requestmcp:github:create_issueclient:app:select_file

کاتالوگ ابزارهای کنترل حالت کد (exec، wait، tool_search_code، tool_search، tool_describe، tool_call) و ابزارهای فقط‌مستقیم را حذف می‌کند. کنترل‌ها نباید از طریق کاتالوگ به‌صورت بازگشتی فراخوانی شوند؛ ابزارهای فقط‌مستقیم برای مدل قابل‌مشاهده می‌مانند، زیرا نتایج ساخت‌یافته آن‌ها نمی‌توانند از پل QuickJS عبور کنند.

ورودی‌های MCP در کاتالوگ محدود به اجرا باقی می‌مانند تا سیاست، تأییدها، هوک‌ها، تله‌متری، نمایش رونوشت و شناسه‌های دقیق ابزار با اجرای عادی ابزار مشترک بمانند. نماهای روبه‌مهمان ALL_TOOLS، tools.search(...)، tools.describe(...)، tools.callValue(...) و tools.call(...) ورودی‌های MCP را حذف می‌کنند. فضای نام تولیدشده MCP.<server>.<tool>({ ...input }) دوباره به شناسه دقیق کاتالوگ نگاشت می‌شود و از طریق همان مسیر اجراکننده ارسال می‌شود.

تعامل با جست‌وجوی ابزار

در اجراهایی که حالت کد فعال است، این حالت جایگزین سطح مدل جست‌وجوی ابزار OpenClaw می‌شود.

وقتی tools.codeMode.enabled درست باشد و حالت کد فعال شود:

  • OpenClaw ابزارهای tool_search_code، tool_search، tool_describe یا tool_call را به‌عنوان ابزارهای قابل‌مشاهده برای مدل ارائه نمی‌کند.
  • همان ایده کاتالوگ‌سازی به داخل زمان‌اجرای مهمان منتقل می‌شود.
  • زمان‌اجرای مهمان، فراداده فشرده ALL_TOOLS و توابع کمکی جست‌وجو/توصیف/ فراخوانی را برای ابزارهای غیر MCP دریافت می‌کند.
  • فراخوانی‌های MCP به‌جای tools.call(...) از فضای نام تولیدشده MCP و سرآیندهای $api() آن استفاده می‌کنند.
  • فراخوانی‌های تو‌در‌تو از همان مسیر اجراکننده OpenClaw ارسال می‌شوند که جست‌وجوی ابزار استفاده می‌کند.

برای پل کاتالوگ فشرده OpenClaw که حالت کد در اجراهای فعال جایگزین آن می‌شود، به جست‌وجوی ابزار مراجعه کنید.

نام ابزارها و تداخل‌ها

ابزار exec قابل‌مشاهده برای مدل، ابزار حالت کد است. اگر ابزار پوسته عادی exec در OpenClaw فعال باشد، از مدل پنهان و مانند هر ابزار دیگری فهرست‌بندی می‌شود.

درون زمان‌اجرای مهمان:

  • tools.call("openclaw:core:exec", input) در صورت اجازه سیاست می‌تواند ابزار اجرای پوسته را فراخوانی کند.
  • tools.exec(...) فقط زمانی نصب می‌شود که ورودی کاتالوگ اجرای پوسته نام امن و بدون ابهامی داشته باشد.
  • ابزار حالت کد exec هرگز از طریق tools به‌صورت بازگشتی در دسترس نیست.

اگر دو ابزار به یک نام میان‌بر امن یکسان نرمال‌سازی شوند، OpenClaw تابع میان‌بر را حذف می‌کند و استفاده از tools.call(id, input) را الزامی می‌سازد.

اجرای تو‌در‌توی ابزار

هر فراخوانی تو‌در‌توی ابزار از پل میزبان عبور می‌کند و دوباره وارد OpenClaw می‌شود و این موارد را حفظ می‌کند: شناسه عامل فعال، شناسه و کلید نشست، زمینه فرستنده و کانال، سیاست سندباکس، سیاست تأیید، هوک‌های before_tool_call مربوط به Plugin، سیگنال لغو، به‌روزرسانی‌های جریانی در صورت وجود، و رویدادهای مسیر/ممیزی.

فراخوانی‌های تو‌در‌تو به‌عنوان فراخوانی‌های واقعی ابزار در رونوشت نمایش داده می‌شوند تا بسته‌های پشتیبانی آنچه رخ داده است را نشان دهند؛ این نمایش، فراخوانی ابزار حالت کد والد و شناسه ابزار تو‌در‌تو را مشخص می‌کند.

فراخوانی‌های تو‌در‌توی موازی تا سقف maxPendingToolCalls مجاز هستند.

چرخه حیات اجرا و اسنپ‌شات

هر اجرای حالت کد در یک نگاشت درون‌فرایندی با کلید runId ردیابی می‌شود (در دیسک یا پایگاه داده پایدار نمی‌شود). exec/wait یکی از سه وضعیت نتیجه را برمی‌گردانند: completed، waiting یا failed.

  • نتیجه waiting، اسنپ‌شات QuickJS، درخواست‌های معلق پل و فراداده محدوده‌بندی (شناسه اجرای عامل، شناسه/کلید نشست) را تا زمانی ذخیره می‌کند که wait آن را از سر بگیرد یا منقضی شود.
  • مقادیر runId منقضی، متعلق به نشست اشتباه، متعلق به اجرای اشتباه و ناشناخته/در حال ازسرگیری وضعیت پایانی مجزایی تولید نمی‌کنند؛ آن‌ها به‌صورت نتیجه failed (code: "invalid_input") با پیامی مانند code mode run is unavailable or expired. یا code mode run belongs to a different session. ظاهر می‌شوند.
  • اسنپ‌شات یک اجرا به‌محض رسیدن به وضعیت completed یا failed از نگاشت حذف می‌شود، یا هنگام خاموش‌شدن Gateway کنار گذاشته می‌شود (هیچ‌چیز پس از راه‌اندازی مجدد باقی نمی‌ماند: این حالت گذرای زمان‌اجرا است).
  • برای کار فقط‌خواندنی، exec می‌تواند restartSafe: true را تنظیم کند. سپس OpenClaw فراخوانی‌های کاتالوگ دارای اثر جانبی و فضاهای نام Plugin را پیش از اجرا رد می‌کند و نتایج معلق را قابل‌بازپخش علامت می‌زند. اگر راه‌اندازی مجدد، wait را قطع کند، بازیابی پس از راه‌اندازی مجدد نوبت را از روی رونوشت بازسازی می‌کند، به‌جای اینکه اسنپ‌شات محلیِ فرایند را بازیابی کند. خود نوبت بازیابی همچنان به ابزارهای هسته فقط‌خواندنی ممیزی‌شده و ابزارهای Plugin که صراحتاً قابل‌بازپخش هستند محدود می‌ماند.
  • OpenClaw تعداد اجراهای معلق هم‌زمان در هر فرایند را به (64) محدود می‌کند و تعلیق‌های جدید فراتر از این سقف را با too many suspended code mode runs. رد می‌کند.

ذخیره‌سازی اسنپ‌شات با maxSnapshotBytes برای هر اجرا، سقف اجراهای معلق در هر فرایند در بالا، و snapshotTtlSeconds محدود می‌شود.

زمان‌اجرای QuickJS-WASI

OpenClaw، ‏quickjs-wasi را به‌عنوان وابستگی مستقیم در بسته مالک بارگذاری می‌کند؛ به نسخه انتقالی نصب‌شده برای وابستگی نامرتبط متکی نیست.

مسئولیت‌های زمان‌اجرا: کامپایل/بارگذاری ماژول WebAssembly مربوط به QuickJS-WASI؛ ایجاد یک ماشین مجازی ایزوله برای هر اجرا یا ازسرگیری حالت کد؛ ثبت callbackهای میزبان با نام‌های پایدار؛ تنظیم محدودیت‌های حافظه و وقفه؛ ارزیابی JavaScript؛ تخلیه کارهای معلق؛ گرفتن اسنپ‌شات از وضعیت ماشین مجازی معلق؛ بازیابی اسنپ‌شات‌ها برای wait؛ آزادسازی هندل‌های ماشین مجازی و اسنپ‌شات‌ها پس از وضعیت‌های پایانی.

زمان‌اجرا در یک رشته worker مربوط به Node.js و خارج از حلقه رویداد اصلی OpenClaw اجرا می‌شود. یک حلقه بی‌نهایت مهمان نباید فرایند Gateway را برای مدت نامحدود مسدود کند؛ کنترل‌کننده وقفه worker، مهلت زمانی ساعت دیواری را مستقل از همکاری کد مهمان اعمال می‌کند.

TypeScript

پشتیبانی از TypeScript فقط تبدیل منبع است: ورودی پذیرفته‌شده یک رشته کد TypeScript است؛ خروجی یک رشته JavaScript است که توسط QuickJS-WASI ارزیابی می‌شود. هیچ بررسی نوع، تفکیک ماژول یا import/require وجود ندارد. عیب‌یابی‌ها به‌صورت نتایج failed برگردانده می‌شوند.

کامپایلر TypeScript فقط برای سلول‌های TypeScript و به‌صورت تنبل بارگذاری می‌شود؛ سلول‌های JavaScript ساده و حالت کد غیرفعال هرگز آن را بارگذاری نمی‌کنند.

مرز امنیتی

کد مدل خصمانه است. زمان‌اجرا از دفاع چندلایه استفاده می‌کند:

  • اجرای QuickJS-WASI خارج از حلقه رویداد اصلی و در یک رشته worker
  • بارگذاری quickjs-wasi به‌عنوان وابستگی مستقیم، نه از طریق Codex یا یک بسته انتقالی
  • نبود دسترسی به فایل‌سیستم، شبکه، زیرفرایند، واردکردن ماژول، متغیرهای محیطی یا اشیای سراسری میزبان در مهمان
  • استفاده از محدودیت‌های حافظه و وقفه QuickJS به‌همراه مهلت زمانی ساعت دیواری فرایند والد
  • اعمال سقف‌های خروجی، اسنپ‌شات، گزارش و فراخوانی معلق
  • سریال‌سازی مقادیر پل میزبان از طریق یک آداپتور محدود JSON
  • تبدیل خطاهای میزبان به خطاهای ساده مهمان، و هرگز اشیای قلمرو میزبان
  • حذف اسنپ‌شات‌ها در صورت پایان مهلت، لغو، پایان نشست یا انقضا
  • رد دسترسی بازگشتی به exec، wait و ابزارهای کنترل جست‌وجوی ابزار
  • جلوگیری از جایگزین‌شدن توابع کمکی کاتالوگ بر اثر تداخل نام‌های میان‌بر

سندباکس یکی از لایه‌های امنیتی است؛ اپراتورها ممکن است برای استقرارهای پرخطر همچنان به سخت‌سازی در سطح سیستم‌عامل نیاز داشته باشند.

کدهای خطا

typescript
type CodeModeErrorCode =  | "invalid_input"  | "runtime_unavailable"  | "timeout"  | "output_limit_exceeded"  | "snapshot_limit_exceeded"  | "internal_error";

invalid_input آرگومان‌های نامعتبر exec/wait، زبان‌های غیرفعال، دسترسی ردشده به ماژول، شکست‌های تبدیل TypeScript، مقادیر runId ناشناخته/منقضی/ متعلق به محدوده اشتباه، و تعداد بیش‌ازحد اجراهای معلق را پوشش می‌دهد. runtime_unavailable یک worker مربوط به QuickJS را پوشش می‌دهد که راه‌اندازی نمی‌شود یا با کد غیرصفر خارج می‌شود.

خطاهایی که به مهمان برگردانده می‌شوند داده‌های ساده هستند؛ نمونه‌های Error میزبان، اشیای پشته، پروتوتایپ‌ها و توابع میزبان وارد QuickJS نمی‌شوند.

تله‌متری

فیلد telemetry هر نتیجه این موارد را گزارش می‌کند: اندازه کاتالوگ پنهان و تفکیک منبع (تعدادهای openclaw/mcp/client)؛ تعداد تجمعی جست‌وجو/توصیف/فراخوانی برای کاتالوگ اجرا؛ و نام ابزارهای قابل‌مشاهده برای مدل (exec، wait و ابزارهای فقط‌مستقیم حفظ‌شده).

تله‌متری نباید شامل اطلاعات محرمانه، مقادیر خام محیط یا ورودی‌های ابزارِ بدون حذف اطلاعات حساس، فراتر از سیاست مسیر موجود OpenClaw باشد.

اشکال‌زدایی

وقتی حالت کد رفتاری متفاوت از اجرای عادی ابزار دارد، از گزارش‌گیری هدفمند انتقال مدل استفاده کنید:

bash
OPENCLAW_DEBUG_CODE_MODE=1 \OPENCLAW_DEBUG_MODEL_TRANSPORT=1 \OPENCLAW_DEBUG_MODEL_PAYLOAD=tools \OPENCLAW_DEBUG_SSE=events \openclaw gateway

برای اشکال‌زدایی شکل payload، از OPENCLAW_DEBUG_MODEL_PAYLOAD=full-redacted استفاده کنید. این گزینه یک تصویر لحظه‌ای JSON با اندازه محدود و اطلاعات ویرایش‌شده از درخواست مدل ثبت می‌کند؛ فقط هنگام اشکال‌زدایی از آن استفاده کنید، زیرا promptها و متن پیام همچنان ممکن است نمایش داده شوند.

برای اشکال‌زدایی جریان، از OPENCLAW_DEBUG_SSE=peek استفاده کنید تا پنج رویداد نخست SSE با اطلاعات ویرایش‌شده ثبت شوند. حالت کد همچنین در صورتی به‌شکل بسته شکست می‌خورد که payload نهایی ارائه‌دهنده، پس از فعال‌شدن سطح حالت کد، دقیقاً شامل یک exec، یک wait و فقط ابزارهای تأییدشده direct-only نباشد.

چیدمان پیاده‌سازی

  • قرارداد پیکربندی: tools.codeMode
  • سازنده کاتالوگ: تبدیل ابزارهای مؤثر به ورودی‌های فشرده و نگاشت شناسه
  • آداپتور سطح مدل: جایگزینی ابزارهای قابل‌مشاهده با ابزارهای کنترلی/مستقیم
  • آداپتور زمان‌اجرای QuickJS-WASI: بارگذاری، ارزیابی، گرفتن تصویر لحظه‌ای، بازیابی، آزادسازی
  • ناظر worker: مهلت زمانی، لغو، جداسازی خرابی
  • آداپتور پل: callbackهای میزبانِ ایمن برای JSON و تحویل نتیجه
  • آداپتور تبدیل TypeScript
  • ذخیره‌گاه تصویر لحظه‌ای: TTL، سقف اندازه، محدوده‌بندی اجرا/نشست
  • فرافکنی مسیر برای فراخوانی‌های تو‌در‌توی ابزار
  • شمارنده‌های تله‌متری و عیب‌یابی

این پیاده‌سازی مفاهیم کاتالوگ و اجراکننده را از جست‌وجوی ابزار بازاستفاده می‌کند، اما از یک فرزند node:vm به‌عنوان sandbox استفاده نمی‌کند.

چک‌لیست اعتبارسنجی

پوشش حالت کد باید موارد زیر را اثبات کند:

  • پیکربندی غیرفعال، ارائه ابزارهای موجود را بدون تغییر باقی می‌گذارد
  • پیکربندی شیء بدون enabled: true، حالت کد را غیرفعال باقی می‌گذارد
  • پیکربندی فعال، هنگامی که ابزارها برای اجرا فعال‌اند، exec، wait و فقط ابزارهای direct-only موردنیاز را در معرض مدل قرار می‌دهد
  • اجراهای خام بدون ابزار، disableTools و فهرست‌های مجاز خالی باعث اجرای الزامات payload حالت کد نمی‌شوند
  • همه ابزارهای مؤثر غیر-MCP واجد شرایط کاتالوگ در ALL_TOOLS ظاهر می‌شوند
  • ابزارهای direct-only برای مدل قابل‌مشاهده باقی می‌مانند و در ALL_TOOLS ظاهر نمی‌شوند
  • ابزارهای ردشده در ALL_TOOLS ظاهر نمی‌شوند
  • tools.search، tools.describe، tools.callValue و tools.call برای ابزارهای OpenClaw کار می‌کنند
  • API.list("mcp") و API.read("mcp/<server>.d.ts") اعلان‌های MCP به سبک TypeScript را بدون فراخوانی پل/ابزار در معرض قرار می‌دهند
  • فضای نام MCP با نام $api() به‌عنوان جایگزین درون‌خطی برای schemaها در دسترس باقی می‌ماند
  • فراخوانی‌های فضای نام MCP برای ابزارهای MCP قابل‌مشاهده با یک ورودی شیء کار می‌کنند، درحالی‌که ورودی‌های مستقیم کاتالوگ MCP در tools.* وجود ندارند
  • ابزارهای کنترلی جست‌وجوی ابزار هم از سطح مدل و هم از کاتالوگ پنهان مخفی هستند
  • فراخوانی‌های تو‌در‌تو رفتار تأیید و hook را حفظ می‌کنند
  • پوسته exec از مدل مخفی است، اما در صورت مجازبودن از طریق شناسه کاتالوگ قابل‌فراخوانی است
  • exec و wait بازگشتی حالت کد از کد مهمان قابل‌فراخوانی نیستند
  • ورودی TypeScript بدون بارگذاری TypeScript در مسیرهای غیرفعال یا فقط JavaScript تبدیل و ارزیابی می‌شود
  • دسترسی به import، require، سامانه فایل، شبکه و محیط شکست می‌خورد
  • حلقه‌های بی‌نهایت به مهلت زمانی می‌رسند و نمی‌توانند Gateway را مسدود کنند
  • شکست‌های سقف حافظه، ماشین مجازی مهمان را خاتمه می‌دهند
  • سقف‌های خروجی و تصویر لحظه‌ای برای فراخوانی‌های تکمیل‌شده و تعلیق‌شده اعمال می‌شوند
  • wait یک تصویر لحظه‌ای تعلیق‌شده را از سر می‌گیرد و مقدار نهایی را بازمی‌گرداند
  • مقادیر runId منقضی‌شده، لغوشده، متعلق به نشست نادرست و ناشناخته شکست می‌خورند
  • بازپخش و ماندگاری رونوشت، فراخوانی‌های کنترلی حالت کد را حفظ می‌کنند
  • رونوشت و تله‌متری، فراخوانی‌های تو‌در‌توی ابزار را به‌وضوح نمایش می‌دهند

برنامه آزمون E2E

هنگام تغییر زمان‌اجرا، این موارد را به‌عنوان آزمون‌های یکپارچه‌سازی یا سرتاسری اجرا کنید:

  1. یک Gateway را با tools.codeMode.enabled: false راه‌اندازی کنید.
  2. یک نوبت عامل با مجموعه کوچکی از ابزارهای مستقیم ارسال کنید.
  3. تأیید کنید ابزارهای قابل‌مشاهده برای مدل تغییری نکرده‌اند.
  4. با tools.codeMode.enabled: true دوباره راه‌اندازی کنید.
  5. یک نوبت عامل با ابزارهای آزمایشی OpenClaw، Plugin، MCP و کلاینت ارسال کنید.
  6. تأیید کنید فهرست ابزارهای قابل‌مشاهده برای مدل شامل exec، wait و فقط ابزارهای direct-only پیکربندی‌شده است.
  7. در exec، ALL_TOOLS را بخوانید و تأیید کنید ابزارهای آزمایشی مؤثرِ واجد شرایط کاتالوگ وجود دارند، درحالی‌که ابزارهای direct-only وجود ندارند.
  8. در exec، ابزارهای OpenClaw/Plugin/کلاینت را از طریق tools.search، tools.describe و tools.callValue (یا tools.call خام) فراخوانی کنید.
  9. در exec، API.list("mcp") و API.read("mcp/<server>.d.ts") را فراخوانی کنید و تأیید کنید فایل‌های اعلان، ابزارهای MCP قابل‌مشاهده را توصیف می‌کنند.
  10. در exec، ابزارهای MCP را از طریق MCP.<server>.<tool>({ ...input }) فراخوانی کنید و تأیید کنید ورودی‌های مستقیم کاتالوگ MCP در ALL_TOOLS و tools.* وجود ندارند.
  11. تأیید کنید ابزارهای ردشده وجود ندارند و با شناسه حدس‌زده‌شده قابل‌فراخوانی نیستند.
  12. یک فراخوانی تو‌در‌توی ابزار آغاز کنید که پس از بازگرداندن waiting توسط exec حل شود.
  13. wait را فراخوانی کنید و تأیید کنید ماشین مجازی بازیابی‌شده نتیجه ابزار را دریافت می‌کند.
  14. تأیید کنید پاسخ نهایی شامل خروجی تولیدشده پس از بازیابی است.
  15. تأیید کنید مهلت زمانی، لغو و انقضای تصویر لحظه‌ای، وضعیت زمان‌اجرا را پاک‌سازی می‌کنند.
  16. مسیر را برون‌بری کنید و تأیید کنید فراخوانی‌های تو‌در‌تو زیر فراخوانی والد حالت کد قابل‌مشاهده‌اند.

تغییرات صرفاً مستنداتی در این صفحه همچنان باید pnpm check:docs را اجرا کنند.

مرتبط

Was this useful?
On this page

On this page