Chat Tools and Approvals
Purpose and Scope
Chat tools are the capabilities an agent can call while responding to a user request. In VS Code, the reader-facing model groups those capabilities into built-in tools, MCP tools, and extension-contributed tools. The important operational detail is that a tool is not just a prompt hint: it becomes a structured action with a name, input payload, and result stream that must be mediated by the editor, the extension host, and any sandbox or permission policy in force for the current session.
The source evidence for this page covers two sides of that boundary. The Copilot extension adapter types define how an agent-facing protocol represents text and tool-call blocks in a streaming response. The Codex protocol files define the permission request and approval response shapes used when an autonomous workflow needs more file-system or network access than the current sandbox grants. Together, these files explain why VS Code can offer agent autonomy while still preserving explicit review points for sensitive actions.
Sources: extensions/copilot/src/extension/agents/node/adapters/types.ts, src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionsRequestApprovalParams.ts, src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionsRequestApprovalResponse.ts
Relevant Source Files
extensions/copilot/src/extension/agents/node/adapters/types.tsdefines the Copilot agent protocol adapter surface, including parsed requests, streaming text blocks, streaming tool-call blocks, final events, response content type, and authentication key extraction.src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalFileSystemPermissions.tsdefines the file-system permission expansion shape for sandboxed agent work, including legacy read/write arrays,globScanMaxDepth, and newerentries.src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalNetworkPermissions.tsdefines whether additional network access is enabled for a permission profile.src/vs/platform/agentHost/node/codex/protocol/generated/v2/ApprovalsReviewer.tsdefines who reviews approval requests:user,auto_review, orguardian_subagent.src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionsRequestApprovalParams.tsdefines the request payload for an approval decision, including thread, turn, item, working directory, reason, and requested permissions.src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionsRequestApprovalResponse.tsdefines the response payload containing granted permissions, grant scope, and optional stricter follow-up review behavior.
Tool Invocation Model
The adapter contract separates ordinary assistant text from tool invocation. IAgentTextBlock carries a type of text and a content string, while IAgentToolCallBlock carries a type of tool_call, a callId, a name, and an object-valued input. That distinction matters for implementers because UI rendering, audit logging, approval prompts, and downstream tool dispatch can all key off a structured block instead of parsing natural language. It also matches the user experience where the agent may explain, then call one or more tools as separate visible steps.
Sources: extensions/copilot/src/extension/agents/node/adapters/types.ts
IProtocolAdapter is the boundary that converts between an external or agent-specific wire format and VS Code’s internal chat representation. It parses the incoming body into model, messages, request options, and request type; formats streaming blocks into protocol-specific events; generates initial and final stream events; returns a response content type; and extracts an authentication key from HTTP headers. For tool authors and agent integrators, the key idea is that tools remain protocol-neutral at the editor level, while adapters handle the details needed by each agent backend or local endpoint.
Sources: extensions/copilot/src/extension/agents/node/adapters/types.ts
Approval and Permission Flow
Approval starts when an agent cannot proceed under the current permission profile. The request payload contains threadId, turnId, and itemId, which let VS Code associate the prompt with the exact conversation turn and work item that triggered it. It also includes startedAtMs, cwd, an optional reason, and a permissions profile. These fields are enough for a reviewer to understand when the request started, where it applies, why it is needed, and what additional authority the agent wants before the tool or command continues.
Sources: src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionsRequestApprovalParams.ts
The response is deliberately not a bare yes-or-no. PermissionsRequestApprovalResponse returns a GrantedPermissionProfile and a PermissionGrantScope, allowing the system to grant only the permissions and duration that match the review decision. The optional strictAutoReview flag tightens the remainder of the turn by reviewing every subsequent command before normal sandboxed execution. This is a useful distinction for autonomous workflows: a reviewer can unblock a specific action without giving the agent a broad, silent capability upgrade for everything that follows.
Sources: src/vs/platform/agentHost/node/codex/protocol/generated/v2/PermissionsRequestApprovalResponse.ts
File-System, Network, and Reviewer Boundaries
File-system escalation is represented as AdditionalFileSystemPermissions. The type still carries nullable read and write arrays of absolute paths, but its comments state that those fields will be removed in favor of entries. It also includes globScanMaxDepth, which constrains scanning behavior, and entries, which can describe sandbox entries more precisely. When documenting or implementing approval UX, prefer the entry-based model where possible and treat legacy read/write arrays as compatibility fields rather than the long-term surface.
Sources: src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalFileSystemPermissions.ts
Network escalation is intentionally compact: AdditionalNetworkPermissions contains an enabled boolean that can also be null. That shape aligns with a policy-style permission profile where network access may be allowed, denied, or unspecified by a particular request layer. In practice, this is the source-level counterpart to user-facing controls for URL access, command execution, and sandboxing. It keeps network capability separate from file-system capability so a tool can receive only the authority that is relevant to the task.
Sources: src/vs/platform/agentHost/node/codex/protocol/generated/v2/AdditionalNetworkPermissions.ts
The reviewer itself is also explicit. ApprovalsReviewer can be user, auto_review, or guardian_subagent. The source comment describes approval prompts for sandbox escapes, blocked network access, MCP approval prompts, and ARC escalations, with user as the default. It also explains that auto_review uses a carefully prompted subagent to gather context and apply a risk-based decision framework. This means approval routing is part of the protocol, not an incidental UI choice.
Sources: src/vs/platform/agentHost/node/codex/protocol/generated/v2/ApprovalsReviewer.ts
Compact Reference
| Component | Contract | Notes |
|---|---|---|
IAgentToolCallBlock | { type: 'tool_call', callId, name, input } | Structured representation of a tool invocation in an agent stream. |
IProtocolAdapter.parseRequest(body) | Returns IParsedRequest | Converts an incoming request body into VS Code model, messages, options, and type fields. |
IProtocolAdapter.formatStreamResponse(block, context) | Returns IStreamEventData[] | Converts text or tool-call blocks into protocol-specific stream events. |
AdditionalFileSystemPermissions | read, write, globScanMaxDepth, entries | Represents extra sandbox file-system access, with entries replacing legacy read/write fields over time. |
AdditionalNetworkPermissions | `{ enabled: boolean | null }` |
PermissionsRequestApprovalParams | threadId, turnId, itemId, startedAtMs, cwd, reason, permissions | Carries the context needed to review an escalation. |
PermissionsRequestApprovalResponse | permissions, scope, strictAutoReview? | Carries the granted profile, grant scope, and optional stricter follow-up review. |
ApprovalsReviewer | user, auto_review, guardian_subagent | Routes review to a human user or an automated/subagent reviewer path. |
Implementation Guidance and Next Steps
When adding or integrating a chat tool, design it so its invocation can be represented by a stable name and JSON-like input object. The adapter layer can then stream the call predictably, and the approval layer can reason about what the tool is asking to do. Avoid hiding file-system writes, shell execution, or network access behind opaque text responses; those actions should surface through permission profiles so the user or reviewer can grant, narrow, or deny them with context.
For readers working through adjacent agent features, continue with mcp-servers for MCP-provided tools, agent-customization-instructions for controlling which tools are available in prompts and custom agents, and ai-troubleshooting for diagnosing failed tool calls, denied approvals, and sandbox-related behavior.