feat(webmcp): expose WebMCPToolCall in WebMCPToolCallResult (#14848)

This commit is contained in:
François Beaufort
2026-04-08 16:07:36 +00:00
committed by GitHub
parent 9ec95eae15
commit 606b2e1270
5 changed files with 43 additions and 15 deletions
+1 -1
View File
@@ -1434,7 +1434,7 @@ The TouchHandle interface exposes methods to manipulate touches that have been s
</td></tr>
<tr><td>
<span id="webmcptoolresponse">[WebMCPToolResponse](./puppeteer.webmcptoolresponse.md)</span>
<span id="webmcptoolcallresult">[WebMCPToolCallResult](./puppeteer.webmcptoolcallresult.md)</span>
</td><td>
+2 -2
View File
@@ -13,11 +13,11 @@ export declare class WebMCP extends EventEmitter<{
toolsadded: WebMCPToolsAddedEvent;
toolsremoved: WebMCPToolsRemovedEvent;
toolinvoked: WebMCPToolCall;
toolresponded: WebMCPToolResponse;
toolresponded: WebMCPToolCallResult;
}>
```
**Extends:** [EventEmitter](./puppeteer.eventemitter.md)&lt;&#123; toolsadded: [WebMCPToolsAddedEvent](./puppeteer.webmcptoolsaddedevent.md); toolsremoved: [WebMCPToolsRemovedEvent](./puppeteer.webmcptoolsremovedevent.md); toolinvoked: [WebMCPToolCall](./puppeteer.webmcptoolcall.md); toolresponded: [WebMCPToolResponse](./puppeteer.webmcptoolresponse.md); &#125;&gt;
**Extends:** [EventEmitter](./puppeteer.eventemitter.md)&lt;&#123; toolsadded: [WebMCPToolsAddedEvent](./puppeteer.webmcptoolsaddedevent.md); toolsremoved: [WebMCPToolsRemovedEvent](./puppeteer.webmcptoolsremovedevent.md); toolinvoked: [WebMCPToolCall](./puppeteer.webmcptoolcall.md); toolresponded: [WebMCPToolCallResult](./puppeteer.webmcptoolcallresult.md); &#125;&gt;
## Remarks
@@ -1,13 +1,13 @@
---
sidebar_label: WebMCPToolResponse
sidebar_label: WebMCPToolCallResult
---
# WebMCPToolResponse interface
# WebMCPToolCallResult interface
### Signature
```typescript
export interface WebMCPToolResponse
export interface WebMCPToolCallResult
```
## Properties
@@ -35,6 +35,23 @@ Default
</th></tr></thead>
<tbody><tr><td>
<span id="call">call</span>
</td><td>
`optional`
</td><td>
[WebMCPToolCall](./puppeteer.webmcptoolcall.md)
</td><td>
</td><td>
</td></tr>
<tr><td>
<span id="errortext">errorText</span>
</td><td>
+13 -5
View File
@@ -172,8 +172,9 @@ export class WebMCPToolCall {
/**
* @public
*/
export interface WebMCPToolResponse {
export interface WebMCPToolCallResult {
id: string;
call?: WebMCPToolCall;
status: WebMCPInvocationStatus;
output?: any;
errorText?: string;
@@ -194,11 +195,12 @@ export class WebMCP extends EventEmitter<{
/** Emitted when a tool invocation starts. */
toolinvoked: WebMCPToolCall;
/** Emitted when a tool invocation completes or fails. */
toolresponded: WebMCPToolResponse;
toolresponded: WebMCPToolCallResult;
}> {
#client: CDPSession;
#frameManager: FrameManager;
#tools: Map<string, Map<string, WebMCPTool>>;
#tools = new Map<string, Map<string, WebMCPTool>>();
#pendingCalls = new Map<string, WebMCPToolCall>();
#onToolsAdded = (event: ProtocolWebMCPToolsAddedEvent) => {
const tools: WebMCPTool[] = [];
@@ -239,13 +241,19 @@ export class WebMCP extends EventEmitter<{
return;
}
const call = new WebMCPToolCall(event.invocationId, tool, event.input);
this.#pendingCalls.set(call.id, call);
tool.emit('toolinvoked', call);
this.emit('toolinvoked', call);
};
#onToolResponded = (event: ProtocolWebMCPToolRespondedEvent) => {
const response: WebMCPToolResponse = {
const call = this.#pendingCalls.get(event.invocationId);
if (call) {
this.#pendingCalls.delete(event.invocationId);
}
const response: WebMCPToolCallResult = {
id: event.invocationId,
call: call,
status: event.status,
output: event.output,
errorText: event.errorText,
@@ -255,6 +263,7 @@ export class WebMCP extends EventEmitter<{
};
#onFrameNavigated = (frame: Frame) => {
this.#pendingCalls.clear();
const frameTools = this.#tools.get(frame._id);
if (!frameTools) {
return;
@@ -278,7 +287,6 @@ export class WebMCP extends EventEmitter<{
this.#onFrameNavigated,
);
this.#bindListeners();
this.#tools = new Map();
}
/**
+7 -4
View File
@@ -8,7 +8,7 @@ import expect from 'expect';
import type {
WebMCPTool,
WebMCPToolCall,
WebMCPToolResponse,
WebMCPToolCallResult,
} from 'puppeteer-core/internal/cdp/WebMCP.js';
import {setupSeparateTestBrowserHooks} from '../mocha-utils.js';
@@ -372,7 +372,7 @@ describe('Page.webmcp', function () {
page.webmcp.once('toolinvoked', resolve);
});
const toolResponded = new Promise<WebMCPToolResponse>(resolve => {
const toolResponded = new Promise<WebMCPToolCallResult>(resolve => {
page.webmcp.once('toolresponded', resolve);
});
@@ -388,6 +388,7 @@ describe('Page.webmcp', function () {
const response = await toolResponded;
expect(response.id).toBe(call.id);
expect(response.call).toBe(call);
expect(response.status).toBe('Success');
expect(response.output).toBe('hello world');
expect(response.errorText).toBeUndefined();
@@ -415,7 +416,7 @@ describe('Page.webmcp', function () {
page.webmcp.once('toolinvoked', resolve);
});
const toolResponded = new Promise<WebMCPToolResponse>(resolve => {
const toolResponded = new Promise<WebMCPToolCallResult>(resolve => {
page.webmcp.once('toolresponded', resolve);
});
@@ -431,6 +432,7 @@ describe('Page.webmcp', function () {
const response = await toolResponded;
expect(response.id).toBe(call.id);
expect(response.call).toBe(call);
expect(response.status).toBe('Error');
expect(response.output).toBeUndefined();
expect(response.errorText).toBe('');
@@ -460,7 +462,7 @@ describe('Page.webmcp', function () {
});
});
const toolResponded = new Promise<WebMCPToolResponse>(resolve => {
const toolResponded = new Promise<WebMCPToolCallResult>(resolve => {
page.webmcp.once('toolresponded', resolve);
});
@@ -475,6 +477,7 @@ describe('Page.webmcp', function () {
const response = await toolResponded;
expect(response.id).toBeDefined();
expect(response.call).toBeUndefined();
expect(response.status).toBe('Error');
expect(response.output).toBeUndefined();
expect(response.errorText).toBe('Tool not found: unknown-tool-name');