豆豆友情提示:这是一个非官方 GitHub 代理镜像,主要用于网络测试或访问加速。请勿在此进行登录、注册或处理任何敏感信息。进行这些操作请务必访问官方网站 github.com。 Raw 内容也通过此代理提供。
Skip to content

Commit c29d097

Browse files
authored
chore: extract issue formatter in preparation to structured content (#794)
This makes it easier to add JSON-format as the output for issues. Console formatter will be changed next.
1 parent 24d15a9 commit c29d097

File tree

8 files changed

+448
-354
lines changed

8 files changed

+448
-354
lines changed

src/DevtoolsUtils.ts

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
*/
66

77
import {PuppeteerDevToolsConnection} from './DevToolsConnectionAdapter.js';
8-
import {ISSUE_UTILS} from './issue-descriptions.js';
9-
import {logger} from './logger.js';
108
import {Mutex} from './Mutex.js';
119
import {DevTools} from './third_party/index.js';
1210
import type {
@@ -81,50 +79,6 @@ export class FakeIssuesManager extends DevTools.Common.ObjectWrapper
8179
}
8280
}
8381

84-
export function mapIssueToMessageObject(issue: DevTools.AggregatedIssue) {
85-
const count = issue.getAggregatedIssuesCount();
86-
const markdownDescription = issue.getDescription();
87-
const filename = markdownDescription?.file;
88-
if (!markdownDescription) {
89-
logger(`no description found for issue:` + issue.code);
90-
return null;
91-
}
92-
const rawMarkdown = filename
93-
? ISSUE_UTILS.getIssueDescription(filename)
94-
: null;
95-
if (!rawMarkdown) {
96-
logger(`no markdown ${filename} found for issue:` + issue.code);
97-
return null;
98-
}
99-
let processedMarkdown: string;
100-
let title: string | null;
101-
102-
try {
103-
processedMarkdown =
104-
DevTools.MarkdownIssueDescription.substitutePlaceholders(
105-
rawMarkdown,
106-
markdownDescription.substitutions,
107-
);
108-
const markdownAst = DevTools.Marked.Marked.lexer(processedMarkdown);
109-
title =
110-
DevTools.MarkdownIssueDescription.findTitleFromMarkdownAst(markdownAst);
111-
} catch {
112-
logger('error parsing markdown for issue ' + issue.code());
113-
return null;
114-
}
115-
if (!title) {
116-
logger('cannot read issue title from ' + filename);
117-
return null;
118-
}
119-
return {
120-
type: 'issue',
121-
item: issue,
122-
message: title,
123-
count,
124-
description: processedMarkdown,
125-
};
126-
}
127-
12882
// DevTools CDP errors can get noisy.
12983
DevTools.ProtocolClient.InspectorBackend.test.suppressRequestErrors = true;
13084

src/McpResponse.ts

Lines changed: 61 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,12 @@
44
* SPDX-License-Identifier: Apache-2.0
55
*/
66

7-
import {mapIssueToMessageObject} from './DevtoolsUtils.js';
87
import type {ConsoleMessageData} from './formatters/consoleFormatter.js';
98
import {
109
formatConsoleEventShort,
1110
formatConsoleEventVerbose,
1211
} from './formatters/consoleFormatter.js';
12+
import {IssueFormatter} from './formatters/IssueFormatter.js';
1313
import {NetworkFormatter} from './formatters/NetworkFormatter.js';
1414
import {SnapshotFormatter} from './formatters/SnapshotFormatter.js';
1515
import type {McpContext} from './McpContext.js';
@@ -233,7 +233,7 @@ export class McpResponse implements Response {
233233
detailedNetworkRequest = formatter;
234234
}
235235

236-
let consoleData: ConsoleMessageData | undefined;
236+
let consoleData: ConsoleMessageData | IssueFormatter | undefined;
237237

238238
if (this.#attachedConsoleMessageId) {
239239
const message = context.getConsoleMessageById(
@@ -258,16 +258,17 @@ export class McpResponse implements Response {
258258
),
259259
};
260260
} else if (message instanceof DevTools.AggregatedIssue) {
261-
const mappedIssueMessage = mapIssueToMessageObject(message);
262-
if (!mappedIssueMessage) {
261+
const formatter = new IssueFormatter(message, {
262+
id: consoleMessageStableId,
263+
requestIdResolver: context.resolveCdpRequestId.bind(context),
264+
elementIdResolver: context.resolveCdpElementId.bind(context),
265+
});
266+
if (!formatter.isValid()) {
263267
throw new Error(
264268
"Can't provide detals for the msgid " + consoleMessageStableId,
265269
);
266270
}
267-
consoleData = {
268-
consoleMessageStableId,
269-
...mappedIssueMessage,
270-
};
271+
consoleData = formatter;
271272
} else {
272273
consoleData = {
273274
consoleMessageStableId,
@@ -278,7 +279,7 @@ export class McpResponse implements Response {
278279
}
279280
}
280281

281-
let consoleListData: ConsoleMessageData[] | undefined;
282+
let consoleListData: Array<ConsoleMessageData | IssueFormatter> | undefined;
282283
if (this.#consoleDataOptions?.include) {
283284
let messages = context.getConsoleData(
284285
this.#consoleDataOptions.includePreservedMessages,
@@ -299,44 +300,47 @@ export class McpResponse implements Response {
299300

300301
consoleListData = (
301302
await Promise.all(
302-
messages.map(async (item): Promise<ConsoleMessageData | null> => {
303-
const consoleMessageStableId =
304-
context.getConsoleMessageStableId(item);
305-
if ('args' in item) {
306-
const consoleMessage = item as ConsoleMessage;
307-
return {
308-
consoleMessageStableId,
309-
type: consoleMessage.type(),
310-
message: consoleMessage.text(),
311-
args: await Promise.all(
312-
consoleMessage.args().map(async arg => {
313-
const stringArg = await arg.jsonValue().catch(() => {
314-
// Ignore errors.
315-
});
316-
return typeof stringArg === 'object'
317-
? JSON.stringify(stringArg)
318-
: String(stringArg);
319-
}),
320-
),
321-
};
322-
}
323-
if (item instanceof DevTools.AggregatedIssue) {
324-
const mappedIssueMessage = mapIssueToMessageObject(item);
325-
if (!mappedIssueMessage) {
326-
return null;
303+
messages.map(
304+
async (
305+
item,
306+
): Promise<ConsoleMessageData | IssueFormatter | null> => {
307+
const consoleMessageStableId =
308+
context.getConsoleMessageStableId(item);
309+
if ('args' in item) {
310+
const consoleMessage = item as ConsoleMessage;
311+
return {
312+
consoleMessageStableId,
313+
type: consoleMessage.type(),
314+
message: consoleMessage.text(),
315+
args: await Promise.all(
316+
consoleMessage.args().map(async arg => {
317+
const stringArg = await arg.jsonValue().catch(() => {
318+
// Ignore errors.
319+
});
320+
return typeof stringArg === 'object'
321+
? JSON.stringify(stringArg)
322+
: String(stringArg);
323+
}),
324+
),
325+
};
326+
}
327+
if (item instanceof DevTools.AggregatedIssue) {
328+
const formatter = new IssueFormatter(item, {
329+
id: consoleMessageStableId,
330+
});
331+
if (!formatter.isValid()) {
332+
return null;
333+
}
334+
return formatter;
327335
}
328336
return {
329337
consoleMessageStableId,
330-
...mappedIssueMessage,
338+
type: 'error',
339+
message: (item as Error).message,
340+
args: [],
331341
};
332-
}
333-
return {
334-
consoleMessageStableId,
335-
type: 'error',
336-
message: (item as Error).message,
337-
args: [],
338-
};
339-
}),
342+
},
343+
),
340344
)
341345
).filter(item => item !== null);
342346
}
@@ -392,8 +396,8 @@ export class McpResponse implements Response {
392396
toolName: string,
393397
context: McpContext,
394398
data: {
395-
consoleData: ConsoleMessageData | undefined;
396-
consoleListData: ConsoleMessageData[] | undefined;
399+
consoleData: ConsoleMessageData | IssueFormatter | undefined;
400+
consoleListData: Array<ConsoleMessageData | IssueFormatter> | undefined;
397401
snapshot: SnapshotFormatter | string | undefined;
398402
detailedNetworkRequest?: NetworkFormatter;
399403
networkRequests?: NetworkFormatter[];
@@ -516,7 +520,12 @@ Call ${handleDialog.name} to handle it before continuing.`);
516520
);
517521
response.push(...data.info);
518522
response.push(
519-
...data.items.map(message => formatConsoleEventShort(message)),
523+
...data.items.map(message => {
524+
if (message instanceof IssueFormatter) {
525+
return message.toString();
526+
}
527+
return formatConsoleEventShort(message);
528+
}),
520529
);
521530
} else {
522531
response.push('<no console messages found>');
@@ -568,14 +577,18 @@ Call ${handleDialog.name} to handle it before continuing.`);
568577

569578
#formatConsoleData(
570579
context: McpContext,
571-
data: ConsoleMessageData | undefined,
580+
data: ConsoleMessageData | IssueFormatter | undefined,
572581
): string[] {
573582
const response: string[] = [];
574583
if (!data) {
575584
return response;
576585
}
577586

578-
response.push(formatConsoleEventVerbose(data, context));
587+
if (data instanceof IssueFormatter) {
588+
response.push(data.toStringDetailed());
589+
} else {
590+
response.push(formatConsoleEventVerbose(data, context));
591+
}
579592
return response;
580593
}
581594

0 commit comments

Comments
 (0)