( mcpConfigs: Record<string, ScopedMcpServerConfig>, toolPermissionContext: ToolPermissionContext, )
| 477 | * Log metrics about context and system prompt size |
| 478 | */ |
| 479 | export async function logContextMetrics( |
| 480 | mcpConfigs: Record<string, ScopedMcpServerConfig>, |
| 481 | toolPermissionContext: ToolPermissionContext, |
| 482 | ): Promise<void> { |
| 483 | // Early return if logging is disabled |
| 484 | if (isAnalyticsDisabled()) { |
| 485 | return |
| 486 | } |
| 487 | const [{ tools: mcpTools }, tools, userContext, systemContext] = |
| 488 | await Promise.all([ |
| 489 | prefetchAllMcpResources(mcpConfigs), |
| 490 | getTools(toolPermissionContext), |
| 491 | getUserContext(), |
| 492 | getSystemContext(), |
| 493 | ]) |
| 494 | // Extract individual context sizes and calculate total |
| 495 | const gitStatusSize = systemContext.gitStatus?.length ?? 0 |
| 496 | const claudeMdSize = userContext.claudeMd?.length ?? 0 |
| 497 | |
| 498 | // Calculate total context size |
| 499 | const totalContextSize = gitStatusSize + claudeMdSize |
| 500 | |
| 501 | // Get file count using ripgrep (rounded to nearest power of 10 for privacy) |
| 502 | const currentDir = getCwd() |
| 503 | const ignorePatternsByRoot = getFileReadIgnorePatterns(toolPermissionContext) |
| 504 | const normalizedIgnorePatterns = normalizePatternsToPath( |
| 505 | ignorePatternsByRoot, |
| 506 | currentDir, |
| 507 | ) |
| 508 | const fileCount = await countFilesRoundedRg( |
| 509 | currentDir, |
| 510 | AbortSignal.timeout(1000), |
| 511 | normalizedIgnorePatterns, |
| 512 | ) |
| 513 | |
| 514 | // Calculate tool metrics |
| 515 | let mcpToolsCount = 0 |
| 516 | let mcpServersCount = 0 |
| 517 | let mcpToolsTokens = 0 |
| 518 | let nonMcpToolsCount = 0 |
| 519 | let nonMcpToolsTokens = 0 |
| 520 | |
| 521 | const nonMcpTools = tools.filter(tool => !tool.isMcp) |
| 522 | mcpToolsCount = mcpTools.length |
| 523 | nonMcpToolsCount = nonMcpTools.length |
| 524 | |
| 525 | // Extract unique server names from MCP tool names (format: mcp__servername__toolname) |
| 526 | const serverNames = new Set<string>() |
| 527 | for (const tool of mcpTools) { |
| 528 | const parts = tool.name.split('__') |
| 529 | if (parts.length >= 3 && parts[1]) { |
| 530 | serverNames.add(parts[1]) |
| 531 | } |
| 532 | } |
| 533 | mcpServersCount = serverNames.size |
| 534 | |
| 535 | // Estimate tool tokens locally for analytics (avoids N API calls per session) |
| 536 | // Use inputJSONSchema (plain JSON Schema) when available, otherwise convert Zod schema |
no test coverage detected