Repository navigation
Add local-coding plugin: on-device offload to MAI Code 1.1 Flash for Copilot CLI 🤖 - #6388
Conversation
Offload agent v12 with the DONE double-check, the on-device-delegate skill and its worker agent, plus Set-LocalOutputCap.ps1 and Update-LocalCodingPlugin.ps1 bundled under the skill's scripts folder. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🚦 Submission status: 👀 Ready for reviewRisk tier: Why this tier
Automated checks
Review
Commands
Updated for |
🔒 PR Risk Scan ResultsScanned 8 changed file(s).
|
🔍 Vally Lint Results
Summary
Full linter output |
There was a problem hiding this comment.
🟡 Changes recommended
Unresolved critical flaws can discard user edits, execute scripts from unrelated plugins, and expose provider configuration through unsafe file handling.
8 open issues
Rollback can discard pre-existing user changes · New Predictable temporary path can expose config through a hard link · New Replacement and backup may weaken file permissions · New Recursive search can execute an unrelated plugin's script · New Worker script requirement conflicts with the no-write contract · New Standalone cap command ignores the provider config override · New Declined confirmation can uninstall the existing plugin · New Cap failures are swallowed instead of reported · New
What changed in this PR
Adds the experimental local-coding plugin for Windows Copilot CLI, enabling a cloud session to delegate large reads and mechanical edits to the on-device MAI Code 1.1 Flash model.
Changes:
- Adds two agents and a delegation skill with task limits, result checks, and fallback instructions.
- Bundles PowerShell scripts for plugin setup and reversible output-token capping.
- Documents prerequisites, usage, limitations, and dogfooding results, and registers the resources in the catalogs.
| File | Description |
|---|---|
skills/on-device-delegate/SKILL.md |
Defines bounded delegation and result checking. |
skills/on-device-delegate/scripts/Update-LocalCodingPlugin.ps1 |
Installs or updates the plugin and applies the output cap. |
skills/on-device-delegate/scripts/Set-LocalOutputCap.ps1 |
Changes and restores local-model output limits. |
plugins/local-coding/README.md |
Documents setup, usage, results, and limitations. |
plugins/local-coding/plugin.json |
Declares plugin metadata and resource composition. |
docs/README.skills.md |
Lists the delegation skill and bundled scripts. |
docs/README.plugins.md |
Adds the plugin to the catalog. |
docs/README.agents.md |
Lists both on-device agents. |
agents/on-device-worker.agent.md |
Defines the bounded worker’s instructions. |
agents/on-device-offload.agent.md |
Defines whole-task offloading and recovery instructions. |
.github/plugin/marketplace.json |
Registers plugin version 0.3.2 for discovery. |
Review effort: Balanced (auto)
| @@ -0,0 +1,58 @@ | |||
| --- | |||
| name: On-Device Offload | |||
| description: 'Experimental. Worker on the local MAI Code 1.1 Flash model. Its tokens do not use GitHub AI Credits. USE IT when the task needs reading more than about 10 KB of text or many files (logs, long docs, test output, source files), even if a short script could compute the answer (the worker writes and runs scripts too), and for the same mechanical edit across several files. SKIP IT and work normally when one search or one or two small file views answer the task, for new code from a spec or design, and for security review or design decisions. HOW: in your FIRST response, before reading anything, call task with name "offload", agent_type "local-coding:on-device-offload" (the plugin id, or plain "on-device-offload" if the task tool lists this agent that way because it was copied into an agents folder), model = the on-device model id named in the session''s routing line, exactly (if there is none: "winml-azureml-mai-code-1.1-flash-on-device/MAI-Code-1.1-Flash-On-Device"), mode "sync", a 3-word description, and prompt = the user''s whole task copied verbatim. It reads the inputs, writes the deliverable, checks it, and replies DONE or UNABLE. Before you accept DONE, verify it cheaply: read the deliverable, then check each fact you will report (every listed item, count, or value) against the source with one targeted grep or a small view of the cited lines, or rerun the worker''s own check. Never re-read the whole input or redo the task. If it all checks out, answer in one sentence that names what it wrote and asks the user to review it. If any fact is wrong or missing, treat the reply as UNABLE. Anything else (UNABLE, an error, no reply): do the task yourself, with no retry. Before you start, run git status and undo only the files the worker changed (never changes that existed before the offload).' | |||
| $tmp = "$ProvidersJson.tmp" | ||
| [IO.File]::WriteAllText($tmp, ($doc | ConvertTo-Json -Depth 32), (New-Object System.Text.UTF8Encoding($false))) |
| $tmp = "$ProvidersJson.tmp" | ||
| [IO.File]::WriteAllText($tmp, ($doc | ConvertTo-Json -Depth 32), (New-Object System.Text.UTF8Encoding($false))) | ||
| $null = [IO.File]::ReadAllText($tmp) | ConvertFrom-Json | ||
| Move-Item -LiteralPath $tmp -Destination $ProvidersJson -Force |
| $cap = Get-ChildItem -LiteralPath $root -Recurse -Filter 'Set-LocalOutputCap.ps1' -ErrorAction SilentlyContinue | | ||
| Where-Object { $_.FullName -match "[\\/]$([regex]::Escape($PluginName))[\\/]skills[\\/]" } | | ||
| Sort-Object LastWriteTime -Descending | Select-Object -First 1 |
| - For counting or extracting across many lines or files, write a short | ||
| script with the create tool and run it. The shell is PowerShell: no | ||
| heredocs and no multi-line `python -c`. |
| $ErrorActionPreference = 'Stop' | ||
| if (-not $ProvidersJson) { | ||
| $homeDir = if ($env:COPILOT_HOME) { $env:COPILOT_HOME } else { Join-Path $HOME '.copilot' } | ||
| $ProvidersJson = Join-Path $homeDir 'providers.json' |
| } else { | ||
| $installedFrom = 'Marketplace' | ||
| } | ||
| } | ||
| if (-not $installedFrom -and $Source -ne 'Marketplace' -and $PluginPath) { | ||
| if ($PSCmdlet.ShouldProcess($PluginPath, "install $PluginName from the local folder")) { | ||
| $r = Invoke-Copilot @('plugin', 'install', $PluginPath) | ||
| $r.Output | Where-Object { $_ -and $_ -notmatch 'deprecated' } | ForEach-Object { Write-Note $_ } | ||
| if ($r.Code -eq 0) { $installedFrom = 'Local' } | ||
| } else { | ||
| $installedFrom = 'Local' | ||
| } |
| Write-Note "Using $capPath" | ||
| $capArgs = @{ ProvidersJson = $providers; Model = $Model; MaxOutputTokens = $MaxOutputTokens } | ||
| if ($Restore) { $capArgs.Restore = $true } | ||
| try { & $capPath @capArgs -WhatIf:$WhatIfPreference } catch { Write-Note "Set-LocalOutputCap.ps1: $($_.Exception.Message)" } |


Pull Request Checklist
npm startand verified thatREADME.mdis up to date.mainbranch for this pull request.Description
Adds
local-coding0.3.2, an experimental plugin for GitHub Copilot CLI on Windows that lets acloud main session hand large, mechanical sub-tasks (big reads, log and test triage, and the same
edit across many files) to MAI Code 1.1 Flash installed locally from
/model. Those tokens stayout of the main context and do not use GitHub AI Credits.
On-Device Offloadagent (local-coding:on-device-offload): owns a whole read-heavy ormechanical task on the local model and replies
DONEorUNABLE. Before the main sessionaccepts
DONE, it checks each reported fact against the source with one targeted search or asmall view (the DONE double-check). On anything else it undoes the worker's files and does the
task itself.
on-device-delegateskill: briefs one bounded sub-task (GOAL, INPUTS, RULES, OUTPUT, andANSWER) to the
On-Device Workeragent and checks the result once.On-Device Workeragent (local-coding:on-device-worker): the skill's bounded worker.scripts/folder:Set-LocalOutputCap.ps1caps thelocal model's output tokens in the user's
providers.json(with a backup and-Restore), andUpdate-LocalCodingPlugin.ps1installs or updates the plugin from this marketplace and then runsthe cap.
Uplift over a plain local-model custom agent (as in the docs' "Delegating focused tasks to a
specific model"): a size gate for when to offload (and what never to offload), a worker prompt
tuned for a small local model (tool-call budget, scripts instead of reading whole files, every
count or extraction computed two independent ways, in-place edits with a diff check, and an
explicit loop stop), a cheap check of every
DONEbefore the main session accepts it, and a briefformat that keeps the big input out of the main context. Both agents use
strict-tools-listwithout the task tool. The main session passes the model on the task call (a frontmatter model pin
is rejected on Copilot CLI 1.0.105). Copilot Fusion (Fusion Standard) is the automatic
alternative. This plugin is the explicit, per-task one.
How it was tested: dogfooded on one Windows test PC (RTX, 66 GB) with Copilot CLI 1.0.108 and MAI
Code 1.1 Flash (CLI-managed, 8,192 output cap), on a 12-task offload set (log triage,
long-document extraction, and multi-file edits), 3 runs per task: 33/36 under Claude Sonnet 5.5
and 35/36 under GPT-6.1 Sol as the main model (pure cloud 36/36 each), about 10x to 11x slower
than pure cloud, and with no measurable cost saving (Sonnet 29.4% dearer per success, Sol 4.4%
cheaper with an interval that spans zero). The README reports the cost per success and frames
these as dogfooding numbers. The plugin installs cleanly
on Copilot CLI 1.0.105 from the materialized layout (
copilot plugin install, tempCOPILOT_HOME):copilot plugin listshowslocal-coding (v0.3.2),copilot skill listshowson-device-delegate, and both agents load aslocal-coding:on-device-offloadandlocal-coding:on-device-worker.Update-LocalCodingPlugin.ps1andSet-LocalOutputCap.ps1ranend to end against a temp Copilot home.
npm run skill:validate,npm run plugin:validate,npm run build, andvally linton the skill pass.Type of Contribution
Additional Notes
Experimental and Windows-only, like the local model itself (public preview,
--experimental).The README lists the public prerequisites and the limits: the output cap is opt-in, the first
offload waits for the model to load, and the local model can return a confident but wrong
DONEthat the double-check does not always catch, so results should be reviewed.
This listing ships no hooks. This repository materializes a plugin's hooks to
com.github.copilot/hooks/<name>/hooks.json, and Copilot CLI 1.0.105 reads a spec plugin's hooksonly from
com.github.copilot/hooks/hooks.json, so they would not run. The agent text covers theno-hooks case (the user types a one-line routing hint, and the main session undoes a failed
offload's files with
git status).By submitting this pull request, I confirm that my contribution abides by the Code of Conduct and will be licensed under the MIT License.