Skip to content

Copilot: migrate tool-use from custom XML format to provider's standard tool-call API#2922

Draft
nighca wants to merge 1 commit intogoplus:devfrom
nighca:issue-2901
Draft

Copilot: migrate tool-use from custom XML format to provider's standard tool-call API#2922
nighca wants to merge 1 commit intogoplus:devfrom
nighca:issue-2901

Conversation

@nighca
Copy link
Collaborator

@nighca nighca commented Mar 9, 2026

close #2901

@gemini-code-assist
Copy link

Summary of Changes

Hello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request modernizes the main Copilot's interaction with AI providers by transitioning its tool invocation from a custom XML format to a standard tool-call API. This change introduces a new SSE-based streaming endpoint for structured data, decouples tool definitions from prompt text, and refines message handling to support more flexible assistant responses. The migration prioritizes a safe rollout with backward compatibility for existing sessions and includes comprehensive updates to the API documentation.

Highlights

  • Tool-Use API Migration: The main Copilot's custom XML-based tool invocation format has been migrated to use the AI provider's standard tool-call API, enhancing compatibility and robustness.
  • New Streaming Endpoint (SSE): A new Server-Sent Events (SSE) endpoint, POST /copilot/sse/message, has been introduced to support structured streaming of both text and tool-call data, replacing the old plain text stream for new clients.
  • Decoupled Tool Definitions: Tool definitions are now passed via the API request payload instead of being embedded directly into the prompt text, leading to cleaner and more efficient prompt construction.
  • Enhanced Message Handling: The system now supports assistant messages that contain only tool calls (without text content) and ensures proper pairing of assistant tool calls with their corresponding tool results during history sampling.
  • Backward Compatibility: Mechanisms have been implemented to ensure backward compatibility for existing persisted sessions that use the legacy XML tool-use format, allowing for a smooth rollout.
  • OpenAPI Specification Update: The OpenAPI specification (docs/openapi.yaml) has been thoroughly updated to reflect the new SSE endpoint, structured message variants, and the relationship with the legacy streaming endpoint.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • docs/develop/copilot-tool-call-migration-design.md
    • Added a new design document detailing the migration plan for Copilot's tool-use from custom XML to standard API.
  • docs/develop/copilot-tool-call-migration-progress.md
    • Added a new document to track the implementation progress of the Copilot tool-call migration.
  • docs/openapi.yaml
    • Updated the schema for POST /copilot/stream/message to reference CopilotMessageRequest.
    • Added a new endpoint POST /copilot/sse/message for structured SSE streaming, including detailed descriptions of event types and examples.
    • Updated the description of POST /copilot/stream/message to clarify its legacy status during rollout.
    • Refactored CopilotMessage into a oneOf structure with CopilotUserMessage, CopilotCopilotMessage, and CopilotToolMessage.
    • Defined new schemas for CopilotMessageContent, CopilotUserMessage, CopilotCopilotMessage, CopilotToolMessage, CopilotMessageRequest, CopilotRequestMessage, CopilotRequestToolCall, CopilotRequestToolCallFunction, CopilotSSETextDeltaEvent, CopilotSSEToolCallDeltaEvent, CopilotSSEToolCallDeltaFunction, CopilotSSEDoneEvent, and CopilotSSEErrorEvent.
  • spx-gui/src/apis/common/client.ts
    • Added a new postJSONSSE method to handle POST requests with JSON payloads and SSE responses.
  • spx-gui/src/apis/copilot.test.ts
    • Added new test file for copilot.ts API functions, specifically testing generateStreamMessage for SSE streaming behavior, error handling, and tool definition passing.
  • spx-gui/src/apis/copilot.ts
    • Extended Message types to include ToolCallFunction, ToolCallInfo, and CopilotMessage variants supporting optional content and tool calls.
    • Introduced StreamEvent types for text_delta, tool_call_delta, done, and error events.
    • Implemented utility functions (isRecord, parseRequiredString, etc.) for robust parsing of SSE stream events.
    • Updated generateStreamMessage to use the new POST /copilot/sse/message endpoint and process structured StreamEvent objects.
  • spx-gui/src/components/copilot/CopilotRoot.vue
    • Marked the tool-use custom element with includeInPrompt: false to prevent its description from being injected into the prompt context.
  • spx-gui/src/components/copilot/CopilotRound.vue
    • Modified resultContent computation to safely handle copilot messages where content might be null or undefined.
  • spx-gui/src/components/copilot/MarkdownView.test.ts
    • Added a new test file for MarkdownView.vue to verify that non-legacy custom elements continue to render and are discoverable when tool-use is registered but excluded from prompt context.
  • spx-gui/src/components/copilot/copilot.test.ts
    • Updated MockMessageStreamGenerator to handle apis.StreamEvent batches instead of raw strings.
    • Added new test cases for sampleApiMessages to ensure correct handling of copilot messages without text content and proper pairing of tool calls and results during truncation.
    • Added tests for loading legacy persisted sessions with XML tool history and user-side tool-result history.
    • Added tests for safely loading older persisted sessions with partial legacy round data.
    • Introduced MockStreamEventGenerator and MockBatchedStreamEventGenerator for more granular control over streamed events in tests.
    • Added tests for toApiMessage conversion of copilot messages with text and/or tool calls, and tool messages.
    • Added extensive tests for streamed assistant responses, including text-only, mixed text and tool calls, tool-call-only, tool loop continuation, history sampling with tool pairing, prompt context generation without injected tools, and exclusion of legacy tool-use elements from prompts.
    • Added tests for handling empty assistant responses and ignoring legacy tool-use markup during tool execution.
  • spx-gui/src/components/copilot/copilot.ts
    • Updated Message types to support structured CopilotMessage with optional content and toolCalls, and ToolMessage with callId and execution.
    • Implemented loadUserMessage, loadToolCallInfo, loadCopilotMessage, loadToolExecution, loadToolMessage, loadLegacyToolResultMessage, loadResultMessage, and loadResultMessages for robust loading of persisted session data.
    • Added finalizeToolCalls to convert ToolCallDraft objects into apis.ToolCallInfo.
    • Introduced toToolExecutionInput and stringifyToolMessageContent for converting tool call information.
    • Refactored toApiMessage to correctly map internal message types to the new API message structures, including structured tool calls and tool results.
    • Modified Round.load to use the new message loading functions for backward compatibility.
    • Updated sealInProgressCopilotMessage to handle optional content and finalize accumulated tool calls.
    • Adjusted handleResponseError to clear inProgressCopilotMessageContentRef on error.
    • Modified handleCopilotMessage to process structured toolCalls directly instead of parsing XML from content.
    • Updated generateCopilotMessage to consume apis.StreamEvent objects, accumulate text_delta and tool_call_delta events, and pass apis.Tool definitions via request options.
    • Added includeInPrompt property to CustomElementDefinition and shouldIncludeCustomElementInPrompt logic to filter elements from prompt context.
    • Removed getToolPrompt and getToolsPrompt functions, as tool definitions are now passed separately.
    • Added getApiTools to convert internal tool definitions to API-compatible format.
    • Updated sampleApiMessages to account for structured tool calls and their corresponding tool result messages, ensuring they are sampled as a coherent block.
  • spx-gui/src/components/copilot/tool-call-delta.test.ts
    • Added a new test file for tool-call-delta.ts to verify the accumulation logic for incremental tool call fragments.
  • spx-gui/src/components/copilot/tool-call-delta.ts
    • Added a new utility file defining ToolCallDraft and accumulateToolCallDelta for incrementally building tool call objects from stream deltas.
  • spx-gui/src/components/tutorials/TutorialRoot.vue
    • Updated the condition for provideQuickInput to check lastCopilotMessage?.content != null to safely handle copilot messages without text content.
Activity
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request is a significant and well-executed migration of the main copilot's tool-use mechanism from a custom XML format to the provider's standard tool-call API. The changes span across documentation, OpenAPI specifications, and frontend logic, including a new SSE-based streaming implementation. The implementation is robust, with thorough handling of backward compatibility for persisted sessions and a comprehensive new test suite. My review found one area for improvement in the OpenAPI specification to reduce duplication.

Comment on lines +3027 to +3041
CopilotRequestMessage:
description: |
Message supplied in a copilot request.

This uses the same structured `user`, `copilot`, and `tool` variants as conversation history.
oneOf:
- $ref: "#/components/schemas/CopilotUserMessage"
- $ref: "#/components/schemas/CopilotCopilotMessage"
- $ref: "#/components/schemas/CopilotToolMessage"
discriminator:
propertyName: role
mapping:
user: "#/components/schemas/CopilotUserMessage"
copilot: "#/components/schemas/CopilotCopilotMessage"
tool: "#/components/schemas/CopilotToolMessage"

Choose a reason for hiding this comment

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

medium

The CopilotRequestMessage schema is identical to the CopilotMessage schema. To reduce duplication and improve maintainability, you can remove CopilotRequestMessage and have CopilotMessageRequest's messages array directly reference CopilotMessage.

This would involve changing line 2997 from:

          items:
            $ref: "#/components/schemas/CopilotRequestMessage"

to:

          items:
            $ref: "#/components/schemas/CopilotMessage"

And then this CopilotRequestMessage schema definition would no longer be needed.

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.

Copilot: migrate tool-use from custom XML format to provider's standard tool-call API

1 participant