Get started
هارنس SDK Copilot
Plugin خارجی @openclaw/copilot به OpenClaw اجازه میدهد نوبتهای agent مربوط به Copilot اشتراکیِ تعبیهشده را از طریق GitHub Copilot CLI (@github/copilot-sdk) بهجای harness داخلی PI اجرا کند.
وقتی میخواهید نشست Copilot CLI مالک حلقه سطح پایین agent باشد، از harness مربوط به Copilot SDK استفاده کنید: اجرای بومی ابزار، compaction بومی (infiniteSessions)، و وضعیت thread مدیریتشده توسط CLI زیر copilotHome.
OpenClaw همچنان مالک کانالهای چت، فایلهای نشست، انتخاب مدل، ابزارهای پویای OpenClaw (bridge شده)، تأییدها، تحویل رسانه، آینه transcript قابل مشاهده، پرسشهای جانبی /btw (که با fallback درختی PI مدیریت میشوند — ببینید
پرسشهای جانبی (/btw))، و openclaw doctor است.
برای تفکیک گستردهتر مدل/ارائهدهنده/runtime، از runtimeهای agent شروع کنید.
الزامات
- OpenClaw با Plugin نصبشده
@openclaw/copilot. - اگر config شما از
plugins.allowاستفاده میکند،copilot(شناسه manifest اعلامشده توسط Plugin) را اضافه کنید. allowlist محدودکنندهای که از نام بسته npm-style یعنی@openclaw/copilotاستفاده کند، Plugin را مسدود باقی میگذارد و runtime حتی باagentRuntime.id: "copilot"بارگذاری نمیشود. - اشتراک GitHub Copilot که بتواند Copilot CLI را هدایت کند (یا یک ورودی env / auth-profile برای
gitHubTokenبرای اجراهای headless / cron). - یک دایرکتوری قابل نوشتن
copilotHome. مقدار پیشفرض harness وقتی OpenClaw یک دایرکتوری agent فراهم کند،<agentDir>/copilotاست؛ در غیر این صورت برای ایزولهسازی کامل بهازای هر agent،~/.openclaw/agents/<agentId>/copilotاست.
openclaw doctor برای مالکیت اعلامی وضعیت نشست و مهاجرتهای سازگاری آینده، قرارداد doctor مربوط به Plugin را اجرا میکند. این دستور probeهای محیط Copilot CLI را اجرا نمیکند.
نصب Plugin
runtime مربوط به Copilot یک Plugin خارجی است، بنابراین بسته اصلی openclaw وابستگی @github/copilot-sdk یا باینری CLI وابسته به پلتفرم آن، یعنی @github/copilot-<platform>-<arch>، را حمل نمیکند. اینها با هم حدود 260 MB اضافه میکنند، پس آنها را فقط برای agentهایی نصب کنید که به این runtime opt-in میکنند:
openclaw plugins install @openclaw/copilotwizard اولین بار که یک مدل github-copilot/* را انتخاب کنید و config شما مدل (یا provider آن) را از طریق agentRuntime: { id: "copilot" } وارد runtime مربوط به Copilot agent کند، Plugin را نصب میکند (پایینتر شروع سریع را ببینید).
بدون opt-in، openclaw از provider داخلی GitHub Copilot خودش استفاده میکند و هرگز Plugin runtime را نصب نمیکند.
runtime، SDK را به این ترتیب resolve میکند:
import("@github/copilot-sdk")از بسته نصبشده@openclaw/copilot.- دایرکتوری fallback شناختهشده
~/.openclaw/npm-runtime/copilot/(هدف نصب on-demand قدیمی).
نبودن SDK یک خطای واحد با کد COPILOT_SDK_MISSING و دستور نصب مجدد Plugin در بالا نشان میدهد.
شروع سریع
یک مدل (یا یک provider) را به harness پین کنید:
{ agents: { defaults: { model: "github-copilot/auto", models: { "github-copilot/auto": { agentRuntime: { id: "copilot" }, }, }, }, },}هر دو مسیر معادلاند. وقتی فقط همان مدل باید از طریق harness مسیریابی شود، از agentRuntime.id روی یک ورودی مدل استفاده کنید؛ وقتی همه مدلهای زیر آن provider باید از آن استفاده کنند، agentRuntime.id را روی یک provider تنظیم کنید.
github-copilot/auto نقطه شروع قابل حمل است. مدلهای نامدار Copilot به account و policy سازمان وابستهاند، پس فقط پس از تأیید اینکه Copilot CLI احرازشده آن را ارائه میکند، یک مدل را پین کنید.
providerهای پشتیبانیشده
harness پشتیبانی از provider canonical یعنی github-copilot را اعلام میکند (همان شناسهای که مالک آن extensions/github-copilot است):
github-copilot
همچنین از ورودیهای سفارشی models.providers پشتیبانی میکند، وقتی مدل انتخابشده یک baseUrl غیرخالی و یکی از این شکلهای API را داشته باشد:
openai-responsesopenai-completionsollama(تکمیلهای سازگار با OpenAI)azure-openai-responsesanthropic-messages
شناسههای provider بومی مانند openai، anthropic، google، و ollama همچنان در مالکیت runtimeهای بومی خود میمانند. هنگام مسیریابی یک endpoint از طریق Copilot BYOK از یک شناسه provider سفارشی متمایز استفاده کنید.
endpointهای Copilot BYOK باید URLهای HTTPS شبکه عمومی باشند. harness به Copilot SDK برای هر تلاش یک URL پروکسی loopback میدهد، سپس ترافیک provider را از مسیر fetch محافظتشده OpenClaw عبور میدهد تا DNS pinning و policy مربوط به SSRF همچنان در مالکیت OpenClaw بمانند. برای Ollama محلی، LM Studio، یا سرورهای مدل LAN از runtime بومی OpenClaw استفاده کنید.
BYOK
Copilot BYOK از قرارداد custom provider در سطح نشست SDK استفاده میکند. OpenClaw endpoint مدل resolveشده، کلید API، حالت bearer-token، headerها، شناسه مدل، و محدودیتهای context/output را بدون انتقال منطق transport مربوط به provider به core ارسال میکند.
برای مثال:
{ agents: { defaults: { model: "custom-proxy/llama-3.1-8b", models: { "custom-proxy/llama-3.1-8b": { agentRuntime: { id: "copilot" }, }, }, }, }, models: { mode: "merge", providers: { "custom-proxy": { baseUrl: "https://api.example.com/v1", apiKey: "${CUSTOM_PROXY_API_KEY}", api: "openai-responses", authHeader: true, models: [{ id: "llama-3.1-8b", name: "Llama 3.1 8B" }], }, }, },}نشستهای BYOK جدا از نشستهای اشتراکی و جدا از endpointها یا fingerprintهای credential دیگر کلیدگذاری میشوند. چرخاندن کلید، headerها، مدل، یا endpoint بهجای از سرگیری وضعیت ناسازگار، یک نشست تازه Copilot SDK میسازد.
Auth
اولویت بهازای هر agent، که هنگام runCopilotAttempt اعمال میشود:
-
useLoggedInUser: trueصریح روی ورودی تلاش. از کاربر logged-in مربوط به Copilot CLI که زیرcopilotHomeآن agent resolve شده استفاده میکند. -
gitHubTokenصریح روی ورودی تلاش (باprofileId+profileVersion). برای فراخوانیهای مستقیم CLI و تستهایی مفید است که caller میخواهد resolve شدن auth-profile را دور بزند. -
resolvedApiKey+authProfileIdresolveشده توسط قرارداد از شکلEmbeddedRunAttemptParams. این مسیر اصلی production است: core پیش از فراخوانی harness، auth profile پیکربندیشدهgithub-copilotمربوط به agent را (از طریقsrc/infra/provider-usage.auth.ts:resolveProviderAuths) resolve میکند، و harness هر دو field را مستقیماً مصرف میکند. این باعث میشود یک auth profile به شکلgithub-copilot:<profile>برای setupهای headless / cron / multi-profile بدون env varها، end-to-end کار کند. -
fallback متغیر محیطی برای اجراهای مستقیم CLI / dogfood که هیچ auth profileای پیکربندی نشده است. runtime متغیرهای زیر را به ترتیب اولویت بررسی میکند و با provider منتشرشده
github-copilot(extensions/github-copilot/auth.ts) و setup مستندشده Copilot SDK همسو است:OPENCLAW_GITHUB_TOKEN-- override مخصوص harness؛ این را تنظیم کنید تا بدون دستزدن به config سراسری سیستم برایgh/ Copilot CLI، یک token را برای harness OpenClaw پین کنید.COPILOT_GITHUB_TOKEN-- متغیر env استاندارد Copilot SDK / CLI.GH_TOKEN-- متغیر env استانداردghCLI (با اولویت provider موجودgithub-copilotمطابقت دارد).GITHUB_TOKEN-- fallback عمومی token مربوط به GitHub.
اولین مقدار غیرخالی برنده است؛ رشتههای خالی غایب در نظر گرفته میشوند. شناسه pool profile ساختهشده
env:<NAME>است و profileVersion یک fingerprint غیرقابل بازگشت sha256 از token است، بنابراین چرخاندن مقدار env بهطور تمیز pool کلاینت را باطل میکند. -
useLoggedInUserپیشفرض وقتی هیچ سیگنال token در دسترس نیست.
هر agent یک copilotHome اختصاصی میگیرد تا tokenها، نشستها، و config مربوط به Copilot CLI بین agentهای روی یک ماشین نشت نکنند. مقدار پیشفرض وقتی host یک دایرکتوری agent به harness میدهد، <agentDir>/copilot است (که وضعیت SDK را از models.json / auth-profiles.json متعلق به OpenClaw در همان دایرکتوری ایزوله میکند)، و در غیر این صورت ~/.openclaw/agents/<agentId>/copilot است.
وقتی به یک مکان سفارشی نیاز دارید (برای مثال، یک mount مشترک برای migration)، روی ورودی تلاش با copilotHome: <path> override کنید.
تستهای زنده harness وقتی یک token مستقیم لازم باشد از OPENCLAW_COPILOT_AGENT_LIVE_TOKEN استفاده میکنند. setup مشترک live-test عمداً پس از stage کردن auth profileهای واقعی در test home ایزوله، COPILOT_GITHUB_TOKEN، GH_TOKEN، و GITHUB_TOKEN را پاک میکند؛ بنابراین عبور دادن مقدار gh auth token از طریق متغیر اختصاصی live-test از skipهای کاذب جلوگیری میکند بدون اینکه token را در معرض suiteهای نامرتبط قرار دهد.
سطح پیکربندی
harness پیکربندی خود را از ورودی بهازای هر تلاش (runCopilotAttempt({...})) بهعلاوه مجموعه کوچکی از پیشفرضهای env داخل extensions/copilot/src/ میخواند:
copilotHome— دایرکتوری وضعیت CLI بهازای هر agent (پیشفرضها در بالا مستند شدهاند).model— رشته یا{ provider, id, api?, baseUrl?, headers?, authHeader? }. وقتی حذف شود، OpenClaw از انتخاب مدل عادی agent استفاده میکند و harness تأیید میکند provider resolveشده پشتیبانی میشود.reasoningEffort—"low" | "medium" | "high" | "xhigh". از resolve شدنThinkLevel/ReasoningLevelمتعلق به OpenClaw درauto-reply/thinking.tsmap میشود.infiniteSessionConfig— override اختیاری برای بلوکinfiniteSessionsدر SDK که توسطharness.compactهدایت میشود. گذاشتن پیشفرضها به همان شکل امن است.hooksConfig— config اختیاری سازگاریSessionHooksبومی Copilot SDK برای callbackهای tool/MCP، user-prompt، session، و error. این از hookهای lifecycle قابل حمل OpenClaw جدا است.permissionPolicy— override اختیاری برای handler مربوط بهonPermissionRequestدر SDK که برای گونههای ابزار داخلی SDK (shell،write،read،url،mcp،memory،hook) استفاده میشود. بهعنوان یک safety net مقدار پیشفرض آنrejectAllPolicyاست؛ در عمل SDK هرگز هیچکدام از آن گونهها را فراخوانی نمیکند، چون هر ابزار bridgeشده OpenClaw باoverridesBuiltInTool: trueوskipPermission: trueثبت میشود تا 100٪ فراخوانیهای ابزار ازexecute()پیچیدهشده OpenClaw عبور کنند. ببینید مجوزها و ask_user.enableSessionTelemetry— flag اختیاری telemetry نشست SDK.
hookهای Plugin در OpenClaw به پیکربندی تلاش مخصوص Copilot نیاز ندارند. harness، before_prompt_build (و hook سازگاری قدیمی before_agent_start)، llm_input، llm_output، و agent_end را از طریق helperهای استاندارد harness اجرا میکند. compactionهای موفق SDK همچنین before_compaction و after_compaction را اجرا میکنند. ابزارهای bridgeشده OpenClaw همچنان before_tool_call را اجرا میکنند و after_tool_call را گزارش میدهند؛ hooksConfig برای callbackهای فقط SDK بومی که معادل قابل حمل ندارند باقی میماند.
هیچ چیز در بقیه OpenClaw لازم نیست درباره این fieldها بداند. سایر Pluginها، کانالها، و کد core فقط شکل استاندارد AgentHarnessAttemptParams / AgentHarnessAttemptResult را میبینند.
Compaction
وقتی harness.compact اجرا میشود، harness مربوط به Copilot SDK:
- نشست SDK ردیابیشده را بدون ادامه دادن کار معلق از سر میگیرد.
- RPC مربوط به compaction تاریخچه در محدوده نشست SDK را فراخوانی میکند.
- نتیجه compaction SDK را بدون نوشتن فایلهای marker سازگاری زیر workspace برمیگرداند.
آینه transcript سمت OpenClaw (پایینتر ببینید) همچنان پیامهای پس از compaction را دریافت میکند، بنابراین تاریخچه چت قابل مشاهده برای کاربر سازگار میماند.
آینهسازی transcript
runCopilotAttempt پیامهای قابل آینهسازی هر turn را از طریق extensions/copilot/src/dual-write-transcripts.ts بهصورت dual-write در audit transcript متعلق به OpenClaw مینویسد. آینه در محدوده هر نشست است (copilot:${sessionId}) و از یک هویت بهازای هر پیام (${role}:${sha256_16(role,content)}) استفاده میکند تا انتشارهای مجدد ورودیهای turn قبلی با کلیدهای موجود روی دیسک برخورد کنند و تکراری نشوند.
آینه در دو لایه containment خطا پیچیده شده تا شکست در نوشتن transcript نتواند تلاش را شکست دهد: یک wrapper داخلی best-effort و یک .catch(...) دفاعی عمیق در سطح تلاش. شکستها log میشوند اما نمایش داده نمیشوند.
پرسشهای جانبی (/btw)
/btw در این هارنس بومی نیست. createCopilotAgentHarness()
عمدا harness.runSideQuestion را تعریفنشده میگذارد، بنابراین توزیعکننده /btw
در OpenClaw (src/agents/btw.ts) به همان مسیر fallback دروندرختی PI میافتد
که برای هر زماناجرای غیر Codex استفاده میکند: ارائهدهنده مدل پیکربندیشده
مستقیما با یک پرامپت کوتاه پرسش جانبی فراخوانی میشود و از طریق
streamSimple بازپخش میشود (بدون نشست CLI، بدون اسلات اضافی pool).
این کار نشستهای Copilot CLI را برای چرخه اصلی نوبت عامل رزرو نگه میدارد و
رفتار /btw را با دیگر زماناجراهای مبتنی بر PI یکسان نگه میدارد. این قرارداد در
extensions/copilot/harness.test.ts
زیر describe("runSideQuestion") تصریح شده است.
Doctor
extensions/copilot/doctor-contract-api.ts بهطور خودکار توسط
src/plugins/doctor-contract-registry.ts بارگذاری میشود. این موارد را فراهم میکند:
- یک
legacyConfigRulesخالی (بدون فیلد بازنشسته در MVP). - یک
normalizeCompatibilityConfigبدون عملیات (نگه داشته شده تا بازنشستگیهای فیلد در آینده یک خانه پایدار دروندرختی داشته باشند). - یک ورودی
sessionRouteStateOwnersکه ارائهدهندهgithub-copilot؛ زماناجرایcopilot؛ کلید نشست CLI با مقدارcopilot؛ و پیشوند پروفایل احراز هویتgithub-copilot:را مطالبه میکند.
محدودیتها
- هارنس،
github-copilotبهعلاوه شناسههای ارائهدهنده BYOK سفارشی بدون مالک را مطالبه میکند. شناسههای ارائهدهنده بومیِ متعلق به manifest حتی وقتیagentRuntime.idبهاجبارcopilotشود، روی زماناجرای مالک خود باقی میمانند. - هارنس TUI را تحویل نمیدهد؛ TUI مربوط به PI بدون تغییر است و برای هر زماناجرایی که سطح همتا ندارد، fallback باقی میماند.
- وقتی یک عامل به
copilotتغییر میکند، وضعیت نشست PI مهاجرت داده نمیشود. انتخاب بهازای هر تلاش است؛ نشستهای PI موجود معتبر باقی میمانند. ask_userاز همان مسیر پرامپتوپاسخ OpenClaw استفاده میکند که هارنس Codex استفاده میکند. وقتی Copilot SDK از کاربر ورودی میخواهد، OpenClaw یک پرامپت مسدودکننده به کانال/TUI فعال ارسال میکند و پیام کاربر بعدی در صف، درخواست SDK را حل میکند.
مجوزها و ask_user
اعمال مجوز برای ابزارهای پلزده OpenClaw داخل wrapper ابزار انجام میشود،
نه از طریق callback با نام onPermissionRequest در SDK. همان
wrapToolWithBeforeToolCallHook که PI استفاده میکند
(src/agents/pi-tools.before-tool-call.ts) توسط createOpenClawCodingTools
روی هر ابزار کدنویسی اعمال میشود: تشخیص loop، سیاستهای Plugin معتمد،
hookهای پیش از فراخوانی ابزار، و تاییدهای دومرحلهای Plugin از طریق Gateway
(plugin.approval.request) همگی با دقیقا همان مسیر کدی اجرا میشوند که تلاشهای
PI بومی استفاده میکنند.
برای اینکه آن wrapper مالک تصمیم باشد، ابزار SDK برگشتی از
convertOpenClawToolToSdkTool با این موارد علامتگذاری میشود:
overridesBuiltInTool: true— ابزار داخلی همنام Copilot CLI (edit، read، write، bash، …) را جایگزین میکند تا هر فراخوانی ابزار دوباره به OpenClaw مسیریابی شود.skipPermission: true— به SDK میگوید پیش از فراخوانی ابزار،onPermissionRequest({kind: "custom-tool"})را اجرا نکند.execute()بستهبندیشده، بررسی سیاست غنیتر OpenClaw را بهصورت داخلی انجام میدهد؛ یک پرامپت در سطح SDK یا اعمال OpenClaw را دور میزند (اگر allow-all کنیم) یا هر فراخوانی ابزار را مسدود میکند (اگر reject-all کنیم) — هیچکدام با همارزی PI سازگار نیست.
هارنس codex دروندرختی از همین تفکیک استفاده میکند: ابزارهای پلزده OpenClaw
بستهبندی میشوند (extensions/codex/src/app-server/dynamic-tools.ts) و گونههای
تایید بومیِ خود codex-app-server
(item/commandExecution/requestApproval,
item/fileChange/requestApproval,
item/permissions/requestApproval) از طریق
plugin.approval.request
(extensions/codex/src/app-server/approval-bridge.ts) مسیریابی میشوند. معادل آن
در Copilot SDK — rejectAllPolicy fail-closed برای هر گونه غیر custom-tool
که به onPermissionRequest برسد — همان شبکه ایمنی است، و در عمل اجرا نمیشود
چون overridesBuiltInTool: true هر ابزار داخلی را کنار میزند.
برای اینکه لایه ابزار بستهبندیشده تصمیمهای سیاستی همارز PI بگیرد، هارنس
کل زمینه ابزارِ تلاش PI را به createOpenClawCodingTools منتقل میکند — هویت
(senderIsOwner, memberRoleIds, ownerOnlyToolAllowlist, …)، کانال/مسیریابی
(groupId, currentChannelId, replyToMode, تغییر وضعیتهای message-tool)،
احراز هویت (authProfileStore)، هویت اجرا
(sessionKey/runSessionKey مشتقشده از sandboxSessionKey,
runId)، زمینه مدل (modelApi, modelContextWindowTokens,
modelCompat, modelHasVision)، و hookهای اجرا (onToolOutcome,
onYield). بدون این فیلدها، allowlistهای فقط-مالک بهصورت بیصدا مانند
deny-by-default رفتار میکنند، سیاستهای اعتماد Plugin نمیتوانند به دامنه درست
حل شوند، و session_status: "current" به یک کلید sandbox کهنه حل میشود.
سازنده bridge در extensions/copilot/src/tool-bridge.ts است و فراخوانی مرجع PI
را در src/agents/pi-embedded-runner/run/attempt.ts:1029-1117 بازتاب میدهد.
runAttempt از قبل زمینه sandbox را از طریق درز مشترک resolveSandboxContext
حل میکند، یک دایرکتوری کاری موثر را به SDK میدهد، و sandbox بهعلاوه فضای
کاری spawn زیرعامل را به tool bridge منتقل میکند. bridge همچنین کنترلهای
محدود ساخت ابزار را که میتواند در مرز SDK اعمال کند منتقل میکند: includeCoreTools،
allowlist ابزار زماناجرا، و toolConstructionPlan.
bridge همچنین برای همارزی PI از helper سطح ابزار هارنس مشترک در
openclaw/plugin-sdk/agent-harness-tool-runtime استفاده میکند. وقتی tool-search
فعال باشد، SDK بهجای هر schema ابزار OpenClaw، ابزارهای کنترلی فشرده بههمراه
یک اجراکننده catalog پنهان را میبیند. وقتی code mode فعال باشد، helper همان
سطح کنترل code-mode و چرخه عمر catalog را میسازد که دیگر هارنسهای عامل استفاده
میکنند. پیشفرضهای سبک برای مدل محلی، فیلتر کردن schema سازگار با زماناجرا،
آبرسانی دایرکتوری، و پاکسازی catalog همگی در helper مشترک میمانند تا هارنسهای
Copilot و مجاور Codex دچار انحراف نشوند.
توکن GitHub در سطح نشست
قرارداد Copilot SDK بین توکن GitHub در سطح کلاینت
(CopilotClientOptions.gitHubToken، استفادهشده برای احراز هویت خود فرایند
CLI) و توکن در سطح نشست (SessionConfig.gitHubToken، که exclusion محتوا،
مسیریابی مدل، و quota را برای آن نشست تعیین میکند و هم در createSession و هم
در resumeSession رعایت میشود) تمایز میگذارد. هارنس احراز هویت را یکبار از
طریق resolveCopilotAuth حل میکند و وقتی حالت احراز هویت gitHubToken باشد
(یک auth.gitHubToken صریح یا یک resolvedApiKey حلشده طبق قرارداد از یک
پروفایل احراز هویت github-copilot پیکربندیشده)، هر دو فیلد را تنظیم میکند.
وقتی حالت حلشده useLoggedInUser باشد، فیلد سطح نشست حذف میشود تا SDK همچنان
هویت را از هویت واردشده استخراج کند.
ask_user از SessionConfig.onUserInputRequest استفاده میکند. bridge برای
درخواستهای با گزینه ثابت، اندیسها یا برچسبهای گزینه را میپذیرد، وقتی درخواست
SDK اجازه دهد پاسخهای آزاد را میپذیرد، و وقتی تلاش OpenClaw لغو شود، درخواست
در انتظار را لغو میکند.