mirror of
https://github.com/ChromeDevTools/chrome-devtools-mcp.git
synced 2026-09-14 19:45:30 +08:00
refactor: move transform logic to Clearcut level (#2637)
I think this makes a little bit cleaner structures. As now Clearcut holds the responsibility of how the data is formatted.
This commit is contained in:
+3
-4
@@ -11,7 +11,6 @@ import type {DataFormat} from './McpResponse.js';
|
||||
import {McpResponse} from './McpResponse.js';
|
||||
import {SlimMcpResponse} from './SlimMcpResponse.js';
|
||||
import {ClearcutLogger} from './telemetry/ClearcutLogger.js';
|
||||
import {bucketizeLatency, buildContext} from './telemetry/transformation.js';
|
||||
import type {CallToolResult} from './third_party/index.js';
|
||||
import {zod} from './third_party/index.js';
|
||||
import type {ToolCategory} from './tools/categories.js';
|
||||
@@ -383,14 +382,14 @@ export class ToolHandler {
|
||||
isError: true,
|
||||
};
|
||||
} finally {
|
||||
const context = buildContext(devToolsData, pageUrl);
|
||||
void ClearcutLogger.get()?.logToolInvocation({
|
||||
toolName: this.tool.name,
|
||||
params,
|
||||
schema: this.inputSchema,
|
||||
success,
|
||||
latencyMs: bucketizeLatency(Date.now() - startTime),
|
||||
context,
|
||||
latencyMs: Date.now() - startTime,
|
||||
devToolsData,
|
||||
pageUrl,
|
||||
});
|
||||
guard[Symbol.dispose]();
|
||||
}
|
||||
|
||||
@@ -12,16 +12,21 @@ import {logger} from '../utils/logger.js';
|
||||
|
||||
import type {ErrorCode} from './errors.js';
|
||||
import type {LocalState, Persistence} from './persistence.js';
|
||||
import {sanitizeParams, stripUnderscoreBeforeNumber} from './transformation.js';
|
||||
import {
|
||||
bucketizeLatency,
|
||||
buildContext,
|
||||
sanitizeParams,
|
||||
stripUnderscoreBeforeNumber,
|
||||
} from './transformation.js';
|
||||
import {
|
||||
McpClient,
|
||||
type FlagUsage,
|
||||
WatchdogMessageType,
|
||||
OsType,
|
||||
type ToolInvocation,
|
||||
type ToolInvocationContext,
|
||||
} from './types.js';
|
||||
import {WatchdogClient} from './WatchdogClient.js';
|
||||
import type {DevToolsData} from '../tools/ToolDefinition.js';
|
||||
|
||||
const MS_PER_DAY = 24 * 60 * 60 * 1000;
|
||||
|
||||
@@ -121,16 +126,18 @@ export class ClearcutLogger {
|
||||
schema: zod.ZodRawShape;
|
||||
success: boolean;
|
||||
latencyMs: number;
|
||||
context: ToolInvocationContext;
|
||||
devToolsData?: DevToolsData;
|
||||
pageUrl?: string;
|
||||
}): Promise<void> {
|
||||
const context = buildContext(args.devToolsData, args.pageUrl);
|
||||
const sanitizedToolName = stripUnderscoreBeforeNumber(args.toolName);
|
||||
const tool_invocation: ToolInvocation = {
|
||||
tool_name: sanitizedToolName,
|
||||
success: args.success,
|
||||
latency_ms: args.latencyMs,
|
||||
latency_ms: bucketizeLatency(args.latencyMs),
|
||||
};
|
||||
if (Object.keys(args.context).length > 0) {
|
||||
tool_invocation.context = args.context;
|
||||
if (Object.keys(context).length > 0) {
|
||||
tool_invocation.context = context;
|
||||
}
|
||||
if (Object.keys(args.params).length > 0) {
|
||||
tool_invocation.tool_params = {
|
||||
|
||||
@@ -21,6 +21,7 @@ import {ToolHandler} from '../src/ToolHandler.js';
|
||||
import {ToolCategory} from '../src/tools/categories.js';
|
||||
import type {
|
||||
DefinedPageTool,
|
||||
DevToolsData,
|
||||
ToolDefinition,
|
||||
} from '../src/tools/ToolDefinition.js';
|
||||
import {createTools} from '../src/tools/tools.js';
|
||||
@@ -165,7 +166,7 @@ describe('ToolHandler', () => {
|
||||
assert.strictEqual(result.isError, undefined);
|
||||
});
|
||||
|
||||
it('appends correct context to tool call logs', async () => {
|
||||
it('passes devToolsData and pageUrl to logger', async () => {
|
||||
const baseTool: ToolDefinition = {
|
||||
name: 'test_tool',
|
||||
description: 'A test tool',
|
||||
@@ -183,9 +184,8 @@ describe('ToolHandler', () => {
|
||||
|
||||
const testCases: Array<{
|
||||
tool: ToolDefinition | DefinedPageTool;
|
||||
devToolsData: Record<string, unknown>;
|
||||
devToolsData: DevToolsData;
|
||||
pageUrl?: string;
|
||||
expectedContext: Record<string, unknown>;
|
||||
}> = [
|
||||
{
|
||||
tool: {
|
||||
@@ -195,13 +195,6 @@ describe('ToolHandler', () => {
|
||||
},
|
||||
devToolsData: {cdpBackendNodeId: 1},
|
||||
pageUrl: 'http://localhost:9222/',
|
||||
expectedContext: {
|
||||
is_devtools_open: true,
|
||||
is_localhost: true,
|
||||
devtools_data: {
|
||||
is_dom_element_selected: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
tool: {
|
||||
@@ -210,9 +203,6 @@ describe('ToolHandler', () => {
|
||||
},
|
||||
devToolsData: {},
|
||||
pageUrl: undefined,
|
||||
expectedContext: {
|
||||
is_devtools_open: false,
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
@@ -251,9 +241,10 @@ describe('ToolHandler', () => {
|
||||
|
||||
assert.strictEqual(logSpy.calledOnce, true);
|
||||
assert.deepStrictEqual(
|
||||
logSpy.firstCall.args[0].context,
|
||||
testCase.expectedContext,
|
||||
logSpy.firstCall.args[0].devToolsData,
|
||||
testCase.devToolsData,
|
||||
);
|
||||
assert.strictEqual(logSpy.firstCall.args[0].pageUrl, testCase.pageUrl);
|
||||
assert.strictEqual(handlerCalled, true);
|
||||
|
||||
sinon.restore();
|
||||
|
||||
@@ -50,7 +50,6 @@ describe('ClearcutLogger', () => {
|
||||
schema: {},
|
||||
success: true,
|
||||
latencyMs: 123,
|
||||
context: {},
|
||||
});
|
||||
|
||||
assert(mockWatchdogClient.send.calledOnce);
|
||||
@@ -58,7 +57,7 @@ describe('ClearcutLogger', () => {
|
||||
assert.strictEqual(msg.type, WatchdogMessageType.LOG_EVENT);
|
||||
assert.strictEqual(msg.payload.tool_invocation?.tool_name, 'test_tool');
|
||||
assert.strictEqual(msg.payload.tool_invocation?.success, true);
|
||||
assert.strictEqual(msg.payload.tool_invocation?.latency_ms, 123);
|
||||
assert.strictEqual(msg.payload.tool_invocation?.latency_ms, 250);
|
||||
});
|
||||
it('sends context when provided', async () => {
|
||||
const logger = ClearcutLogger.initialize({
|
||||
@@ -72,10 +71,10 @@ describe('ClearcutLogger', () => {
|
||||
schema: {},
|
||||
success: true,
|
||||
latencyMs: 123,
|
||||
context: {
|
||||
is_devtools_open: true,
|
||||
is_localhost: false,
|
||||
devToolsData: {
|
||||
cdpBackendNodeId: 1,
|
||||
},
|
||||
pageUrl: 'https://example.com',
|
||||
});
|
||||
|
||||
assert(mockWatchdogClient.send.calledOnce);
|
||||
@@ -84,6 +83,9 @@ describe('ClearcutLogger', () => {
|
||||
assert.deepStrictEqual(msg.payload.tool_invocation?.context, {
|
||||
is_devtools_open: true,
|
||||
is_localhost: false,
|
||||
devtools_data: {
|
||||
is_dom_element_selected: true,
|
||||
},
|
||||
});
|
||||
});
|
||||
it('sends sanitized params', async () => {
|
||||
@@ -109,7 +111,6 @@ describe('ClearcutLogger', () => {
|
||||
schema,
|
||||
success: true,
|
||||
latencyMs: 123,
|
||||
context: {},
|
||||
});
|
||||
|
||||
assert(mockWatchdogClient.send.calledOnce);
|
||||
|
||||
Reference in New Issue
Block a user