Skip to content

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

Merged
nighca merged 1 commit intogoplus:devfrom
nighca:issue-2901-impl
Mar 12, 2026
Merged

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

Conversation

@nighca
Copy link
Copy Markdown
Collaborator

@nighca nighca commented Mar 10, 2026

close #2901.

Related API spec update: #2922

@gemini-code-assist
Copy link
Copy Markdown

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 implements a significant upgrade to the main Copilot's interaction model by transitioning from a proprietary XML-based tool invocation system to a standard tool-call API. This change introduces a new Server-Sent Events (SSE) streaming endpoint, allowing for more structured and efficient communication between the frontend and backend. The primary goal is to improve the robustness and flexibility of Copilot's tool-use capabilities, support more complex conversational flows, and ensure a smooth, backward-compatible rollout across different deployment environments.

Highlights

  • Standardized Tool-Call API Migration: The main Copilot's custom XML-based tool invocation format has been migrated to use the provider's standard tool-call API, enhancing interoperability and reducing custom parsing logic.
  • New SSE Streaming Endpoint: A new Server-Sent Events (SSE) endpoint, POST /copilot/sse/message, has been introduced to provide structured streaming responses, including incremental text deltas and tool-call data. The legacy streaming endpoint remains unchanged for phased rollout safety.
  • Decoupled Tool Definitions: Tool definitions are now passed directly via the API request payload, rather than being embedded in the prompt text, leading to cleaner prompts and more robust tool handling.
  • Flexible Assistant Message Structure: Assistant messages now support responses that are text-only, tool-calls-only, or a combination of both, aligning with modern LLM capabilities.
  • Enhanced History Sampling: The message history sampling logic has been updated to preserve the pairing of assistant tool calls and their corresponding tool results, ensuring conversational context is maintained during truncation.
  • Backward Compatibility & Phased Rollout: The migration includes strategies for backward compatibility with existing persisted sessions and a phased rollout plan, ensuring a smooth transition without breaking older client versions.
  • OpenAPI Specification Update: The OpenAPI specification (docs/openapi.yaml) has been thoroughly updated to reflect the new SSE endpoint, structured message types, and the relationship with the legacy 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 comprehensive design document outlining the migration plan for Copilot's tool-call mechanism.
  • docs/develop/copilot-tool-call-migration-progress.md
    • Added a progress tracking document for the Copilot tool-call migration, detailing completed and pending tasks across various phases.
  • docs/openapi.yaml
    • Added a new POST /copilot/sse/message endpoint definition for structured SSE streaming.
    • Updated the description of the legacy POST /copilot/stream/message endpoint to clarify its role during rollout.
    • Refactored CopilotMessage schema to use oneOf and discriminator for different message roles (user, copilot, tool).
    • Introduced new schemas for CopilotUserMessage, CopilotCopilotMessage, CopilotToolMessage, and CopilotMessageRequest to support structured tool calls and optional content.
    • Defined new schemas for SSE event payloads: CopilotSSETextDeltaEvent, CopilotSSEToolCallDeltaEvent, CopilotSSEDoneEvent, and CopilotSSEErrorEvent.
    • Removed enum constraint from CopilotTool function name to allow more flexible tool definitions.
  • spx-gui/src/apis/common/client.ts
    • Added a postJSONSSE method to facilitate making POST requests that return Server-Sent Events with JSON data.
  • spx-gui/src/apis/copilot.test.ts
    • Added new test utilities for creating SSE stream batches and collecting message events.
    • Updated sampleApiMessages tests to include scenarios with copilot messages containing only tool calls and to ensure tool-call blocks are truncated correctly.
    • Added tests for toApiMessage to verify correct conversion of copilot messages with text and/or tool calls, and tool messages.
    • Updated createCopilotWithStorage to use IMessageEventGenerator and handle apis.MessageEvent batches.
    • Added tests for streamed assistant text-only responses, mixed text and tool-call responses, and tool-call-only responses.
    • Included tests for tool loop continuation after tool execution and history sampling with tool pairing.
    • Added tests to confirm custom element descriptions are included in prompt context while tool definitions are sent via API options.
    • Added a test to ensure legacy tool-use custom elements are excluded from new prompt context.
    • Added a test for the in-progress state of tool-call-only assistant turns.
    • Added a test to reject empty assistant responses.
    • Added a test to ignore legacy tool-use markup in assistant text during tool execution.
  • spx-gui/src/apis/copilot.ts
    • Introduced new TypeScript types: ToolCallFunction, ToolCallInfo, CopilotMessage (union type for flexible content/toolCalls), and MessageEvent (union type for SSE event payloads).
    • Modified Message type to be a union of user, tool, and CopilotMessage types.
    • Added GenerateSSEMessageOptions to include tools in the SSE request options.
    • Renamed generateStreamMessage to generateSSEMessage and updated its implementation to use client.postJSONSSE and process structured MessageEvents.
    • Updated toApiMessage to correctly map internal Message types to the new apis.Message structure, handling optional content and structured toolCalls and toolCallId.
  • spx-gui/src/components/agent-copilot/copilot.ts
    • Adjusted chatMessage2Message to explicitly set role: 'user' for user messages and role: 'copilot' for agent messages, ensuring correct role mapping.
  • spx-gui/src/components/copilot/CopilotRoot.vue
    • Added includeInPrompt: false to the registration of the tool-use custom element, preventing its description from being injected into the prompt context.
  • spx-gui/src/components/copilot/CopilotRound.vue
    • Updated the resultContent computed property to safely check for message.content being non-null before accessing its text, accommodating copilot messages with only tool calls.
  • spx-gui/src/components/copilot/copilot.ts
    • Removed imports related to legacy XML tool parsing (toolUseTagName, findCustomComponentUsages).
    • Imported new accumulateToolCallDelta and ToolCallDraft for structured tool call accumulation.
    • Added helper functions finalizeToolCalls, toToolExecutionInput, and stringifyToolMessageContent for processing tool calls and results.
    • Refactored toApiMessage to handle the new structured CopilotMessage and ToolMessage types, including toolCalls and toolCallId.
    • Changed IMessageStreamGenerator interface to IMessageEventGenerator to reflect the shift to structured SSE events.
    • Updated Round class methods: sealInProgressCopilotMessage now handles optional content and ToolCallDraft arrays, handleCopilotMessage uses structured toolCalls for execution, and generateCopilotMessage now uses generateSSEMessage to process structured events and pass API tools.
    • Introduced includeInPrompt property to CustomElementDefinition and a shouldIncludeCustomElementInPrompt helper to control prompt injection.
    • Removed getToolPrompt and getToolsPrompt as tool definitions are now passed via API options.
    • Added getApiTools method to convert internal tool definitions to the API-compatible format.
    • Modified sampleApiMessages to correctly group copilot messages with their associated tool messages during history truncation, preventing partial context loss.
  • spx-gui/src/components/copilot/tool-call-delta.test.ts
    • Added a new test file to verify the functionality of accumulateToolCallDelta for incrementally building tool call objects.
  • spx-gui/src/components/copilot/tool-call-delta.ts
    • Added a new file defining ToolCallDraft type and accumulateToolCallDelta function, which is responsible for accumulating partial tool call information received via SSE into a complete tool call object.
  • spx-gui/src/components/tutorials/TutorialRoot.vue
    • Updated provideQuickInput to safely check if lastCopilotMessage.content exists before attempting to test against tutorialCourseSuccessPattern, accommodating copilot messages that might only contain tool calls.
Activity
  • The author, nighca, has implemented the design outlined in copilot-tool-call-migration-design.md to migrate the main Copilot to a standard tool-call API using SSE.
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.

gemini-code-assist[bot]

This comment was marked as outdated.

@nighca nighca changed the title Copilot SSE streaming endpoint Copilot: migrate tool-use from custom XML format to provider's standard tool-call API Mar 11, 2026
@nighca nighca marked this pull request as ready for review March 11, 2026 01:46
Copilot AI review requested due to automatic review settings March 11, 2026 01:46
Comment thread spx-gui/src/apis/copilot.ts Outdated
Comment thread spx-gui/src/components/copilot/copilot.ts
Comment thread spx-gui/src/components/copilot/copilot.ts Outdated
Comment thread spx-gui/src/components/copilot/copilot.ts Outdated
Comment thread spx-gui/src/components/copilot/tool-call.ts
@xgopilot
Copy link
Copy Markdown
Contributor

xgopilot bot commented Mar 11, 2026

Solid migration — replacing the custom XML tool-use protocol with the provider's standard tool-call API is the right architectural move. The new tool-call.ts accumulator, the sampleApiMessages group-aware sampling, and the comprehensive test suite are well-structured. Four issues worth addressing before merge: an SSE event.data spread that can silently overwrite the canonical event type (security), a backward-compatibility crash when loading old sessions missing toolCalls, an unbounded tool-call loop, and context-budget undercounting for tool-call-only messages.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR migrates the GUI Copilot tool-use flow from legacy custom XML markup parsing to a provider-style structured tool-call interface, using an SSE event stream (text_delta / tool_call_delta) and explicit tool definitions passed via request options.

Changes:

  • Replaced legacy <tool-use ... /> parsing with structured toolCalls + tool role messages, streamed via SSE events.
  • Added tool-call delta accumulation/finalization utilities and expanded unit tests to cover tool-call-only turns and tool-call/tool-result history sampling.
  • Updated tutorial and UI plumbing to handle copilot messages that may have content: null when a turn contains only tool calls.

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
spx-gui/src/components/tutorials/tutorial-course-abandon.ts Simplifies tutorial abandon/dismiss tag instructions.
spx-gui/src/components/tutorials/TutorialRoot.vue Registers tutorial custom elements/providers based on active course via watch cleanup.
spx-gui/src/components/copilot/tool-call.ts New helpers to accumulate streamed tool_call_delta fragments and finalize tool calls.
spx-gui/src/components/copilot/tool-call.test.ts Unit tests for tool-call delta accumulation and finalization errors.
spx-gui/src/components/copilot/custom-elements/ToolUse.ts Removes the legacy custom-element-based tool invocation mechanism.
spx-gui/src/components/copilot/copilot.ts Core migration: SSE event handling, structured tool calls/results, tool schema export via API options, and tool-call-aware history sampling.
spx-gui/src/components/copilot/copilot.test.ts Extensive new tests for SSE streaming, tool-call-only turns, tool loop continuation, and prompt/tool separation.
spx-gui/src/components/copilot/CopilotRound.vue Avoids rendering null copilot text content.
spx-gui/src/components/copilot/CopilotRoot.vue Stops registering the legacy tool-use custom element.
spx-gui/src/apis/copilot.ts Introduces structured message/tool-call types and SSE message generation API.
spx-gui/src/apis/copilot.test.ts Tests SSE streaming termination behavior and tool payload forwarding.
spx-gui/src/apis/common/client.ts Adds postJSONSSE helper for JSON-SSE POST requests.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread spx-gui/src/components/copilot/copilot.ts Outdated
Comment thread spx-gui/src/apis/copilot.ts Outdated
Copy link
Copy Markdown
Collaborator

@cn0809 cn0809 left a comment

Choose a reason for hiding this comment

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

lgtm

@nighca nighca enabled auto-merge (squash) March 12, 2026 12:22
@nighca nighca merged commit c2cb319 into goplus:dev Mar 12, 2026
5 checks passed
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

3 participants