Skip to content

[Early POC] Add a third-party Canvas MVP for Copilot agent sessions - #335640

Draft
Joaquín Ruales (jruales) wants to merge 1 commit into
mainfrom
jruales/canvas-mvp
Draft

[Early POC] Add a third-party Canvas MVP for Copilot agent sessions#335640
Joaquín Ruales (jruales) wants to merge 1 commit into
mainfrom
jruales/canvas-mvp

Conversation

@jruales

@jruales Joaquín Ruales (jruales) commented Sep 11, 2026

Copy link
Copy Markdown
Contributor

Summary

Add a desktop MVP for third-party Copilot Canvases using the existing Copilot runtime extension format and VS Code's Integrated Browser, with the normal browser navigation bar left visible.

Architecture

The Node SDK runs in Agent Host and talks to the Copilot runtime. The runtime discovers compatible extensions, launches their backend processes, and owns their Canvas tools and lifecycle. An extension supplies an HTTP(S) URL, which VS Code renders in the Integrated Browser. This change adds the host/client plumbing and UI; it does not reimplement Canvas execution or modify the runtime.

  • Project live SDK Canvas events and snapshots into typed per-chat session metadata, including reopen revisions and unavailable instances.
  • Add ownership-validated catalog/open/close operations. Local clients use the management channel; remote clients use capability-gated extension RPCs.
  • Reuse existing provisional-chat materialization and dormant-chat resume for direct opening, without synthesizing a prompt or starting a model turn.
  • Present local Canvases in transient, ephemeral-storage browser tabs. Hiding a tab does not close the runtime instance; explicit Close Canvas does. Runtime URLs are not persisted as normal browser tabs.
  • Add editor + > Canvas > Open Canvas... / Reopen Canvas... / Close Canvas..., plus corresponding Chat commands.
  • Use a native picker for the runtime catalog, with explicit Refresh and JSON input when an extension declares an input schema. Runtime schema validation remains authoritative.
  • Include AI-disabled and new-chat menu gating, accessibility help, tests, and architecture documentation.

SDK prerequisite

Companion SDK change: github/copilot-sdk#2618.

The current installed Node SDK (1.0.13) does not expose a usable extension-launch callback. The companion SDK draft adds onExtensionLaunch and startup registration of the existing runtime launch-provider protocol.

VS Code's copilotExtensionLaunch.ts only supplies an executable, the runtime's own bundled bootstrap, and the extension entrypoint. Discovery, permission enforcement, spawning, and termination remain runtime-owned.

Standalone extension loading is enabled only when the SDK advertises supportsExtensionLaunchProvider. This draft does not update the package dependency and will not provide standalone Canvas extensions with the stock SDK. It needs the companion SDK built locally for testing, then a dependency update after that change ships.

The local demo used VSCODE_DEV_INJECT_NODE_MODULE_LOOKUP_PATH with an ignored node-modules overlay pointing @github/copilot-sdk at the built sibling SDK checkout. No machine-specific dependency paths or overlay files are committed. Setup details are documented in src/vs/platform/agentHost/AGENTS.md.

Validation performed during implementation

  • 320 focused backend tests passed.
  • 86 focused UI/presentation/accessibility/terminal tests passed; 45 directly affected tests passed again after the final menu-gating update. These runs overlap and are not additive.
  • Core typecheck/editor diagnostics, npm run valid-layers-check, and git diff --check passed.
  • Live OSS validation with the patched SDK: menu opening without a chat turn, actual rendered counter with the standard navigation bar, tab hide/reopen, supported window reload/reopen, and explicit runtime close with server shutdown.
  • Fresh-chat model-driven validation: list_canvas_capabilities, open_canvas, and one approved invoke_canvas_action increment completed; the server and assistant both returned count 1.

Known limitations / follow-up

  • One restored demo conversation stalls after accepting messages. This remains unresolved. A fresh conversation in the same profile successfully completed both normal chat and Canvas-tool requests; the restored conversation was preserved for investigation. This draft is not claiming all restore/turn lifecycle cases are ready to ship.
  • An earlier raw automation page.reload() was followed by aborted browser-navigation notifications. A full app restart and supported Developer: Reload Window validation did not reproduce those errors; the raw-reload behavior has not been fixed.
  • Desktop/local presentation only. Remote catalog/open/close plumbing exists, but remote Canvas presentation and loopback forwarding are intentionally unsupported.
  • Opening from the menu requires an existing local Copilot chat; an uncreated new-chat composer is not implicitly turned into a runtime session.
  • App-native Canvas types, installation/import/discovery management UI, and navigation-bar hiding are deferred.
  • No privileged page bridge is introduced; Canvas pages remain untrusted browser content.

Kept as a draft to share the architecture and MVP for review before SDK/API stabilization and lifecycle hardening.

Reuse the Copilot runtime Canvas lifecycle and expose local desktop Canvas opening, reopening, and closing through the Integrated Browser.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings September 11, 2026 07:42
@jruales Joaquín Ruales (jruales) changed the title Add a third-party Canvas MVP for Copilot agent sessions [Early POC] Add a third-party Canvas MVP for Copilot agent sessions Sep 11, 2026

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot review overview

🟡 Changes recommended

Transient URLs can become persistent when copied, and connection replacement races can target the wrong host.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review tier: Balanced
Findings: 2 High severity · 1 Medium severity · 1 Low severity

New issues introduced by this change (4)
Severity Finding
High severity src/​vs/​workbench/​contrib/​browserView/​common/​browserEditorInput.ts — Copying bypasses transient URL protection
High severity src/​vs/​workbench/​contrib/​chat/​electron-browser/​agentHostCanvas.contribution.ts — Revalidate the connection after the open request
Medium severity src/​vs/​workbench/​contrib/​chat/​electron-browser/​agentHostCanvas.contribution.ts — Do not route a stale close selection to a new host
Low severity src/​vs/​workbench/​contrib/​chat/​browser/​agentSessions/​agentHost/​agentHostCanvasPicker.ts — Distinguish invalid values from invalid JSON syntax
What changed in this PR

Adds a desktop proof of concept for third-party Copilot Canvases, integrating runtime-managed Canvas instances with Agent Host sessions and Integrated Browser tabs.

Changes:

  • Adds Canvas discovery, lifecycle metadata, launch plumbing, and local/remote management APIs.
  • Adds transient Integrated Browser presentation plus open, reopen, and close commands.
  • Adds focused backend, UI, accessibility, protocol, and persistence tests.
File Description
src/​vs/​workbench/​workbench.desktop.main.ts Loads the Canvas contribution.
src/​vs/​workbench/​services/​agentHost/​browser/​editorRemoteAgentHostServiceClient.ts Forwards remote Canvas operations.
src/​vs/​workbench/​contrib/​terminal/​test/​browser/​agentHostPty.test.ts Updates the Agent connection mock.
src/​vs/​workbench/​contrib/​chat/​test/​browser/​agentSessions/​agentHostCanvasPicker.test.ts Tests Canvas selection and JSON input.
src/​vs/​workbench/​contrib/​chat/​test/​browser/​agentSessions/​agentHostCanvas.test.ts Tests browser presentation lifecycle.
src/​vs/​workbench/​contrib/​chat/​test/​browser/​accessibility/​chatAccessibilityHelp.test.ts Tests Canvas accessibility guidance.
src/​vs/​workbench/​contrib/​chat/​electron-browser/​agentHostCanvas.contribution.ts Registers commands and session tracking.
src/​vs/​workbench/​contrib/​chat/​common/​actions/​chatActions.ts Defines Canvas command identifiers.
src/​vs/​workbench/​contrib/​chat/​browser/​agentSessions/​agentHost/​agentHostCanvasPicker.ts Implements the catalog and input picker.
src/​vs/​workbench/​contrib/​chat/​browser/​agentSessions/​agentHost/​agentHostCanvas.ts Presents Canvases in browser editors.
src/​vs/​workbench/​contrib/​chat/​browser/​actions/​chatAccessibilityHelp.ts Documents Canvas keyboard workflows.
src/​vs/​workbench/​contrib/​browserView/​test/​electron-browser/​browserEditorInput.test.ts Tests transient editor serialization.
src/​vs/​workbench/​contrib/​browserView/​electron-browser/​browserViewWorkbenchService.ts Supports caller IDs and transient views.
src/​vs/​workbench/​contrib/​browserView/​common/​browserView.ts Extends browser creation options.
src/​vs/​workbench/​contrib/​browserView/​common/​browserEditorInput.ts Adds non-persistent browser inputs.
src/​vs/​sessions/​sessions.desktop.main.ts Loads Canvas support in Agents Window.
src/​vs/​sessions/​contrib/​editor/​test/​browser/​editor.contribution.test.ts Tests Canvas action targeting and gating.
src/​vs/​sessions/​contrib/​editor/​browser/​editor.contribution.ts Registers the Canvas submenu.
src/​vs/​sessions/​contrib/​editor/​browser/​addTabActions.ts Adds Canvas tab actions.
src/​vs/​sessions/​browser/​menus.ts Defines the Canvas submenu.
src/​vs/​platform/​agentHost/​test/​node/​protocolServerHandler.test.ts Tests remote Canvas RPC routing.
src/​vs/​platform/​agentHost/​test/​node/​copilotSessionLauncher.test.ts Tests Canvas launch configuration.
src/​vs/​platform/​agentHost/​test/​node/​copilotExtensionLaunch.test.ts Tests extension launch adaptation.
src/​vs/​platform/​agentHost/​test/​node/​copilotAgentSession.test.ts Registers Canvas services in tests.
src/​vs/​platform/​agentHost/​test/​node/​copilotAgent.test.ts Tests chat materialization without turns.
src/​vs/​platform/​agentHost/​test/​node/​agentService.test.ts Tests Canvas ownership and routing.
src/​vs/​platform/​agentHost/​test/​node/​agentHostManagementService.test.ts Tests local management IPC.
src/​vs/​platform/​agentHost/​test/​node/​agentHostCanvasController.test.ts Tests Canvas state reconciliation.
src/​vs/​platform/​agentHost/​test/​electron-browser/​localAgentHostService.test.ts Tests local management-channel routing.
src/​vs/​platform/​agentHost/​test/​electron-browser/​agentHostProtocolClient.test.ts Tests capability-gated Canvas RPCs.
src/​vs/​platform/​agentHost/​test/​common/​agentCanvasMeta.test.ts Tests metadata and input validation.
src/​vs/​platform/​agentHost/​node/​protocolServerHandler.ts Handles Canvas extension RPCs.
src/​vs/​platform/​agentHost/​node/​copilot/​copilotSessionLauncher.ts Configures runtime Canvas support.
src/​vs/​platform/​agentHost/​node/​copilot/​copilotExtensionLaunch.ts Builds extension launch specifications.
src/​vs/​platform/​agentHost/​node/​copilot/​copilotAgentSession.ts Registers live SDK Canvas sessions.
src/​vs/​platform/​agentHost/​node/​copilot/​copilotAgent.ts Enables extensions and prepares chats.
src/​vs/​platform/​agentHost/​node/​agentService.ts Routes direct Canvas operations.
src/​vs/​platform/​agentHost/​node/​agentHostServices.ts Registers the Canvas controller service.
src/​vs/​platform/​agentHost/​node/​agentHostManagementService.ts Exposes local Canvas management.
src/​vs/​platform/​agentHost/​node/​agentHostCanvasController.ts Reconciles runtime Canvas state.
src/​vs/​platform/​agentHost/​electron-browser/​localAgentHostService.ts Advertises and routes local capabilities.
src/​vs/​platform/​agentHost/​common/​meta/​agentCanvasMeta.ts Defines Canvas metadata contracts.
src/​vs/​platform/​agentHost/​common/​agentService.ts Extends Agent Host service interfaces.
src/​vs/​platform/​agentHost/​common/​agentHostExtensionProtocol.ts Defines Canvas extension methods.
src/​vs/​platform/​agentHost/​common/​agent.ts Adds the Canvas preparation seam.
src/​vs/​platform/​agentHost/​browser/​nullAgentHostService.ts Implements unsupported Canvas stubs.
src/​vs/​platform/​agentHost/​browser/​agentHostProtocolClient.ts Sends Canvas extension requests.
src/​vs/​platform/​agentHost/​AGENTS.md Documents Canvas architecture and constraints.

💡 Configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

export class BrowserEditorSerializer implements IEditorSerializer {
canSerialize(editorInput: EditorInput): editorInput is BrowserEditorInput {
return editorInput instanceof BrowserEditorInput;
return editorInput instanceof BrowserEditorInput && !editorInput.transient;
Comment on lines +208 to +212
const opened = await resolution.connection.openCanvas(resolution.backendSession, chat, selection.canvas.extensionId, selection.canvas.canvasTypeId, selection.input);
const controller = this._sessions.get(resource)?.canvas;
if (controller) {
await controller.update([...controller.canvases.filter(canvas => canvas.instanceId !== opened.instanceId), opened]);
await controller.open(opened.instanceId);
Comment on lines +237 to +242
const resolution = this._connections.resolveSessionResource(resource);
if (!resolution) {
this._notificationService.error(localize('canvas.disconnected', "The agent host is disconnected. Reconnect before closing the canvas."));
return;
}
await resolution.connection.closeCanvas(resolution.backendSession, URI.parse(selection.chat), selection.instanceId);
Comment on lines +65 to +69
} catch (error) {
if (!(error instanceof SyntaxError) && !(error instanceof TypeError)) {
throw error;
}
return localize('canvas.invalidInput', "Enter valid JSON.");
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants