From fa0b6a6917f73bcb424afff625fec91e6d95954c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Oct 2025 01:38:31 +0000 Subject: [PATCH 1/5] Initial plan From 8a0ce3a2b1a2bda93bb78c3abae4a76d85e3fd07 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Oct 2025 01:49:51 +0000 Subject: [PATCH 2/5] Update parse_copilot_log to extract tools from debug format Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/js/parse_copilot_log.cjs | 86 ++++++++++++++++++++++++++- 1 file changed, 85 insertions(+), 1 deletion(-) diff --git a/pkg/workflow/js/parse_copilot_log.cjs b/pkg/workflow/js/parse_copilot_log.cjs index 7289777adf..fc2fb5bf2d 100644 --- a/pkg/workflow/js/parse_copilot_log.cjs +++ b/pkg/workflow/js/parse_copilot_log.cjs @@ -312,6 +312,7 @@ function parseDebugLogFormat(logContent) { let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -372,6 +373,89 @@ function parseDebugLogFormat(logContent) { } } + // Extract tools from "[DEBUG] Tools:" section + // The format is: [DEBUG] Tools: \n[DEBUG] [\n { "type": "function", "function": { "name": "..." } }\n] + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + // Find the start of the JSON array - look for a line that starts with [DEBUG] [ + // Skip past the "Tools:" line first + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + // Find the actual '[' character after '[DEBUG] ' + toolsStart = logContent.indexOf("[", toolsStart + 7); // Skip '[DEBUG] ' which is 8 chars + } + if (toolsStart !== -1) { + // Track brackets to find the end of the JSON array + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + + if (escapeNext) { + escapeNext = false; + continue; + } + + if (char === "\\") { + escapeNext = true; + continue; + } + + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + + if (inString) continue; + + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + + if (toolsEnd !== -1) { + // Remove [DEBUG] prefixes from each line in the JSON + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + + try { + const toolsArray = JSON.parse(toolsJson); + // Extract tool names from the OpenAI function format + // Format: [{ "type": "function", "function": { "name": "bash", ... } }, ...] + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + // Convert github-* names to mcp__github__* format for consistency + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; // Keep safe_outputs names as-is + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + // Failed to parse tools, continue without them + } + } + } + } + // Find all JSON response blocks in the debug logs let inDataBlock = false; let currentJsonLines = []; @@ -606,7 +690,7 @@ function parseDebugLogFormat(logContent) { subtype: "init", session_id: sessionId, model: model, - tools: [], // We don't have tool info from debug logs + tools: tools, // Tools extracted from [DEBUG] Tools: section }; // Add model info if available From c0161baeecb9fd0d1e5b1416d302824bdfa5d9c7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Oct 2025 01:52:39 +0000 Subject: [PATCH 3/5] Add test for tools extraction from debug log format Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- pkg/workflow/js/parse_copilot_log.test.cjs | 94 ++++++++++++++++++++++ 1 file changed, 94 insertions(+) diff --git a/pkg/workflow/js/parse_copilot_log.test.cjs b/pkg/workflow/js/parse_copilot_log.test.cjs index f4c26bb0df..e3a6f63220 100644 --- a/pkg/workflow/js/parse_copilot_log.test.cjs +++ b/pkg/workflow/js/parse_copilot_log.test.cjs @@ -962,5 +962,99 @@ More log content expect(result).toContain("github::create_pull_request"); }); + + it("should extract tools from debug log format", () => { + const parseCopilotLog = extractParseFunction(); + + // Simulate the new debug log format with [DEBUG] Tools: section + const debugLogWithTools = `2025-10-18T01:34:52.534Z [INFO] Starting Copilot CLI: 0.0.343 +2025-10-18T01:34:55.314Z [DEBUG] Got model info: { + "id": "claude-sonnet-4.5", + "name": "Claude Sonnet 4.5", + "vendor": "Anthropic", + "billing": { + "is_premium": true, + "multiplier": 1, + "restricted_to": ["pro", "pro_plus", "max"] + } +} +2025-10-18T01:34:55.407Z [DEBUG] Tools: +2025-10-18T01:34:55.412Z [DEBUG] [ + { + "type": "function", + "function": { + "name": "bash", + "description": "Runs a Bash command" + } + }, + { + "type": "function", + "function": { + "name": "github-create_issue", + "description": "Creates a GitHub issue" + } + }, + { + "type": "function", + "function": { + "name": "safe_outputs-create_issue", + "description": "Safe output create issue" + } + } +2025-10-18T01:34:55.500Z [DEBUG] ] +2025-10-18T01:35:00.739Z [DEBUG] data: +2025-10-18T01:35:00.739Z [DEBUG] { + "choices": [ + { + "finish_reason": "tool_calls", + "message": { + "content": "I'll help you with this task.", + "role": "assistant" + } + }, + { + "finish_reason": "tool_calls", + "message": { + "role": "assistant", + "tool_calls": [ + { + "function": { + "arguments": "{\\"command\\":\\"echo test\\"}", + "name": "bash" + }, + "id": "tool_123", + "type": "function" + } + ] + } + } + ], + "model": "Claude Sonnet 4.5", + "usage": { + "completion_tokens": 50, + "prompt_tokens": 100 + } +2025-10-18T01:35:00.800Z [DEBUG] }`; + + const result = parseCopilotLog(debugLogWithTools); + + // Check that tools were extracted and displayed + expect(result).toContain("**Available Tools:**"); + expect(result).toContain("bash"); + // Tools are displayed in formatted form (github::create_issue) not internal form (mcp__github__create_issue) + expect(result).toContain("github::create_issue"); + expect(result).toContain("safe_outputs-create_issue"); + + // Verify tool categories are shown + expect(result).toContain("**Git/GitHub:**"); + expect(result).toContain("**Other:**"); + + // Check that the model info was extracted + expect(result).toContain("Claude Sonnet 4.5"); + expect(result).toContain("**Premium Model:** Yes"); + + // Check that tool calls are displayed + expect(result).toContain("echo test"); + }); }); }); From 41c88f822e70d32147d00a791fa21d66ae393628 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Oct 2025 01:55:36 +0000 Subject: [PATCH 4/5] Complete copilot log parser update Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com> --- .github/workflows/artifacts-summary.lock.yml | 66 ++++++++++++++++++- .github/workflows/brave.lock.yml | 66 ++++++++++++++++++- .github/workflows/ci-doctor.lock.yml | 66 ++++++++++++++++++- .github/workflows/daily-news.lock.yml | 66 ++++++++++++++++++- .github/workflows/dev.lock.yml | 66 ++++++++++++++++++- .github/workflows/mcp-inspector.lock.yml | 66 ++++++++++++++++++- .../workflows/notion-issue-summary.lock.yml | 66 ++++++++++++++++++- .github/workflows/pdf-summary.lock.yml | 66 ++++++++++++++++++- .github/workflows/plan.lock.yml | 66 ++++++++++++++++++- .github/workflows/poem-bot.lock.yml | 66 ++++++++++++++++++- .github/workflows/q.lock.yml | 66 ++++++++++++++++++- .github/workflows/repo-tree-map.lock.yml | 66 ++++++++++++++++++- .github/workflows/research.lock.yml | 66 ++++++++++++++++++- .github/workflows/scout.lock.yml | 66 ++++++++++++++++++- .github/workflows/smoke-copilot.lock.yml | 66 ++++++++++++++++++- .github/workflows/test-post-steps.lock.yml | 66 ++++++++++++++++++- .github/workflows/tidy.lock.yml | 66 ++++++++++++++++++- 17 files changed, 1105 insertions(+), 17 deletions(-) diff --git a/.github/workflows/artifacts-summary.lock.yml b/.github/workflows/artifacts-summary.lock.yml index 12e7eda650..2085f63d45 100644 --- a/.github/workflows/artifacts-summary.lock.yml +++ b/.github/workflows/artifacts-summary.lock.yml @@ -2436,6 +2436,7 @@ jobs: let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -2482,6 +2483,69 @@ jobs: } } } + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + toolsStart = logContent.indexOf("[", toolsStart + 7); + } + if (toolsStart !== -1) { + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + if (escapeNext) { + escapeNext = false; + continue; + } + if (char === "\\") { + escapeNext = true; + continue; + } + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + if (inString) continue; + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + if (toolsEnd !== -1) { + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + try { + const toolsArray = JSON.parse(toolsJson); + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + } + } + } + } let inDataBlock = false; let currentJsonLines = []; let turnCount = 0; @@ -2664,7 +2728,7 @@ jobs: subtype: "init", session_id: sessionId, model: model, - tools: [], + tools: tools, }; if (modelInfo) { initEntry.model_info = modelInfo; diff --git a/.github/workflows/brave.lock.yml b/.github/workflows/brave.lock.yml index e7d428aad5..77db9739a6 100644 --- a/.github/workflows/brave.lock.yml +++ b/.github/workflows/brave.lock.yml @@ -3514,6 +3514,7 @@ jobs: let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -3560,6 +3561,69 @@ jobs: } } } + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + toolsStart = logContent.indexOf("[", toolsStart + 7); + } + if (toolsStart !== -1) { + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + if (escapeNext) { + escapeNext = false; + continue; + } + if (char === "\\") { + escapeNext = true; + continue; + } + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + if (inString) continue; + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + if (toolsEnd !== -1) { + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + try { + const toolsArray = JSON.parse(toolsJson); + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + } + } + } + } let inDataBlock = false; let currentJsonLines = []; let turnCount = 0; @@ -3742,7 +3806,7 @@ jobs: subtype: "init", session_id: sessionId, model: model, - tools: [], + tools: tools, }; if (modelInfo) { initEntry.model_info = modelInfo; diff --git a/.github/workflows/ci-doctor.lock.yml b/.github/workflows/ci-doctor.lock.yml index 6fde528595..77cabbb2ca 100644 --- a/.github/workflows/ci-doctor.lock.yml +++ b/.github/workflows/ci-doctor.lock.yml @@ -2932,6 +2932,7 @@ jobs: let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -2978,6 +2979,69 @@ jobs: } } } + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + toolsStart = logContent.indexOf("[", toolsStart + 7); + } + if (toolsStart !== -1) { + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + if (escapeNext) { + escapeNext = false; + continue; + } + if (char === "\\") { + escapeNext = true; + continue; + } + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + if (inString) continue; + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + if (toolsEnd !== -1) { + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + try { + const toolsArray = JSON.parse(toolsJson); + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + } + } + } + } let inDataBlock = false; let currentJsonLines = []; let turnCount = 0; @@ -3160,7 +3224,7 @@ jobs: subtype: "init", session_id: sessionId, model: model, - tools: [], + tools: tools, }; if (modelInfo) { initEntry.model_info = modelInfo; diff --git a/.github/workflows/daily-news.lock.yml b/.github/workflows/daily-news.lock.yml index c7a3cc8721..98624d19fc 100644 --- a/.github/workflows/daily-news.lock.yml +++ b/.github/workflows/daily-news.lock.yml @@ -2516,6 +2516,7 @@ jobs: let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -2562,6 +2563,69 @@ jobs: } } } + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + toolsStart = logContent.indexOf("[", toolsStart + 7); + } + if (toolsStart !== -1) { + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + if (escapeNext) { + escapeNext = false; + continue; + } + if (char === "\\") { + escapeNext = true; + continue; + } + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + if (inString) continue; + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + if (toolsEnd !== -1) { + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + try { + const toolsArray = JSON.parse(toolsJson); + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + } + } + } + } let inDataBlock = false; let currentJsonLines = []; let turnCount = 0; @@ -2744,7 +2808,7 @@ jobs: subtype: "init", session_id: sessionId, model: model, - tools: [], + tools: tools, }; if (modelInfo) { initEntry.model_info = modelInfo; diff --git a/.github/workflows/dev.lock.yml b/.github/workflows/dev.lock.yml index 980dc367a3..0bdf91c4dc 100644 --- a/.github/workflows/dev.lock.yml +++ b/.github/workflows/dev.lock.yml @@ -2428,6 +2428,7 @@ jobs: let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -2474,6 +2475,69 @@ jobs: } } } + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + toolsStart = logContent.indexOf("[", toolsStart + 7); + } + if (toolsStart !== -1) { + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + if (escapeNext) { + escapeNext = false; + continue; + } + if (char === "\\") { + escapeNext = true; + continue; + } + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + if (inString) continue; + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + if (toolsEnd !== -1) { + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + try { + const toolsArray = JSON.parse(toolsJson); + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + } + } + } + } let inDataBlock = false; let currentJsonLines = []; let turnCount = 0; @@ -2656,7 +2720,7 @@ jobs: subtype: "init", session_id: sessionId, model: model, - tools: [], + tools: tools, }; if (modelInfo) { initEntry.model_info = modelInfo; diff --git a/.github/workflows/mcp-inspector.lock.yml b/.github/workflows/mcp-inspector.lock.yml index 50286cc5f6..144e16931b 100644 --- a/.github/workflows/mcp-inspector.lock.yml +++ b/.github/workflows/mcp-inspector.lock.yml @@ -3398,6 +3398,7 @@ jobs: let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -3444,6 +3445,69 @@ jobs: } } } + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + toolsStart = logContent.indexOf("[", toolsStart + 7); + } + if (toolsStart !== -1) { + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + if (escapeNext) { + escapeNext = false; + continue; + } + if (char === "\\") { + escapeNext = true; + continue; + } + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + if (inString) continue; + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + if (toolsEnd !== -1) { + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + try { + const toolsArray = JSON.parse(toolsJson); + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + } + } + } + } let inDataBlock = false; let currentJsonLines = []; let turnCount = 0; @@ -3626,7 +3690,7 @@ jobs: subtype: "init", session_id: sessionId, model: model, - tools: [], + tools: tools, }; if (modelInfo) { initEntry.model_info = modelInfo; diff --git a/.github/workflows/notion-issue-summary.lock.yml b/.github/workflows/notion-issue-summary.lock.yml index e2dfdbcf29..511b2515c0 100644 --- a/.github/workflows/notion-issue-summary.lock.yml +++ b/.github/workflows/notion-issue-summary.lock.yml @@ -2414,6 +2414,7 @@ jobs: let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -2460,6 +2461,69 @@ jobs: } } } + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + toolsStart = logContent.indexOf("[", toolsStart + 7); + } + if (toolsStart !== -1) { + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + if (escapeNext) { + escapeNext = false; + continue; + } + if (char === "\\") { + escapeNext = true; + continue; + } + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + if (inString) continue; + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + if (toolsEnd !== -1) { + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + try { + const toolsArray = JSON.parse(toolsJson); + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + } + } + } + } let inDataBlock = false; let currentJsonLines = []; let turnCount = 0; @@ -2642,7 +2706,7 @@ jobs: subtype: "init", session_id: sessionId, model: model, - tools: [], + tools: tools, }; if (modelInfo) { initEntry.model_info = modelInfo; diff --git a/.github/workflows/pdf-summary.lock.yml b/.github/workflows/pdf-summary.lock.yml index 78c449c689..e24c3b093c 100644 --- a/.github/workflows/pdf-summary.lock.yml +++ b/.github/workflows/pdf-summary.lock.yml @@ -3464,6 +3464,7 @@ jobs: let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -3510,6 +3511,69 @@ jobs: } } } + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + toolsStart = logContent.indexOf("[", toolsStart + 7); + } + if (toolsStart !== -1) { + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + if (escapeNext) { + escapeNext = false; + continue; + } + if (char === "\\") { + escapeNext = true; + continue; + } + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + if (inString) continue; + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + if (toolsEnd !== -1) { + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + try { + const toolsArray = JSON.parse(toolsJson); + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + } + } + } + } let inDataBlock = false; let currentJsonLines = []; let turnCount = 0; @@ -3692,7 +3756,7 @@ jobs: subtype: "init", session_id: sessionId, model: model, - tools: [], + tools: tools, }; if (modelInfo) { initEntry.model_info = modelInfo; diff --git a/.github/workflows/plan.lock.yml b/.github/workflows/plan.lock.yml index 2e62561aed..8e220241a5 100644 --- a/.github/workflows/plan.lock.yml +++ b/.github/workflows/plan.lock.yml @@ -3021,6 +3021,7 @@ jobs: let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -3067,6 +3068,69 @@ jobs: } } } + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + toolsStart = logContent.indexOf("[", toolsStart + 7); + } + if (toolsStart !== -1) { + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + if (escapeNext) { + escapeNext = false; + continue; + } + if (char === "\\") { + escapeNext = true; + continue; + } + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + if (inString) continue; + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + if (toolsEnd !== -1) { + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + try { + const toolsArray = JSON.parse(toolsJson); + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + } + } + } + } let inDataBlock = false; let currentJsonLines = []; let turnCount = 0; @@ -3249,7 +3313,7 @@ jobs: subtype: "init", session_id: sessionId, model: model, - tools: [], + tools: tools, }; if (modelInfo) { initEntry.model_info = modelInfo; diff --git a/.github/workflows/poem-bot.lock.yml b/.github/workflows/poem-bot.lock.yml index 338461c3a5..960b807ff7 100644 --- a/.github/workflows/poem-bot.lock.yml +++ b/.github/workflows/poem-bot.lock.yml @@ -3695,6 +3695,7 @@ jobs: let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -3741,6 +3742,69 @@ jobs: } } } + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + toolsStart = logContent.indexOf("[", toolsStart + 7); + } + if (toolsStart !== -1) { + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + if (escapeNext) { + escapeNext = false; + continue; + } + if (char === "\\") { + escapeNext = true; + continue; + } + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + if (inString) continue; + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + if (toolsEnd !== -1) { + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + try { + const toolsArray = JSON.parse(toolsJson); + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + } + } + } + } let inDataBlock = false; let currentJsonLines = []; let turnCount = 0; @@ -3923,7 +3987,7 @@ jobs: subtype: "init", session_id: sessionId, model: model, - tools: [], + tools: tools, }; if (modelInfo) { initEntry.model_info = modelInfo; diff --git a/.github/workflows/q.lock.yml b/.github/workflows/q.lock.yml index 575e4e3c96..231ceeb5f0 100644 --- a/.github/workflows/q.lock.yml +++ b/.github/workflows/q.lock.yml @@ -3763,6 +3763,7 @@ jobs: let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -3809,6 +3810,69 @@ jobs: } } } + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + toolsStart = logContent.indexOf("[", toolsStart + 7); + } + if (toolsStart !== -1) { + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + if (escapeNext) { + escapeNext = false; + continue; + } + if (char === "\\") { + escapeNext = true; + continue; + } + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + if (inString) continue; + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + if (toolsEnd !== -1) { + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + try { + const toolsArray = JSON.parse(toolsJson); + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + } + } + } + } let inDataBlock = false; let currentJsonLines = []; let turnCount = 0; @@ -3991,7 +4055,7 @@ jobs: subtype: "init", session_id: sessionId, model: model, - tools: [], + tools: tools, }; if (modelInfo) { initEntry.model_info = modelInfo; diff --git a/.github/workflows/repo-tree-map.lock.yml b/.github/workflows/repo-tree-map.lock.yml index d05ede3537..aa87c7f4ce 100644 --- a/.github/workflows/repo-tree-map.lock.yml +++ b/.github/workflows/repo-tree-map.lock.yml @@ -2456,6 +2456,7 @@ jobs: let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -2502,6 +2503,69 @@ jobs: } } } + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + toolsStart = logContent.indexOf("[", toolsStart + 7); + } + if (toolsStart !== -1) { + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + if (escapeNext) { + escapeNext = false; + continue; + } + if (char === "\\") { + escapeNext = true; + continue; + } + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + if (inString) continue; + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + if (toolsEnd !== -1) { + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + try { + const toolsArray = JSON.parse(toolsJson); + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + } + } + } + } let inDataBlock = false; let currentJsonLines = []; let turnCount = 0; @@ -2684,7 +2748,7 @@ jobs: subtype: "init", session_id: sessionId, model: model, - tools: [], + tools: tools, }; if (modelInfo) { initEntry.model_info = modelInfo; diff --git a/.github/workflows/research.lock.yml b/.github/workflows/research.lock.yml index ca9fac4f87..0ac1daf7c0 100644 --- a/.github/workflows/research.lock.yml +++ b/.github/workflows/research.lock.yml @@ -2432,6 +2432,7 @@ jobs: let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -2478,6 +2479,69 @@ jobs: } } } + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + toolsStart = logContent.indexOf("[", toolsStart + 7); + } + if (toolsStart !== -1) { + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + if (escapeNext) { + escapeNext = false; + continue; + } + if (char === "\\") { + escapeNext = true; + continue; + } + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + if (inString) continue; + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + if (toolsEnd !== -1) { + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + try { + const toolsArray = JSON.parse(toolsJson); + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + } + } + } + } let inDataBlock = false; let currentJsonLines = []; let turnCount = 0; @@ -2660,7 +2724,7 @@ jobs: subtype: "init", session_id: sessionId, model: model, - tools: [], + tools: tools, }; if (modelInfo) { initEntry.model_info = modelInfo; diff --git a/.github/workflows/scout.lock.yml b/.github/workflows/scout.lock.yml index ff5f51022e..adcb439fbc 100644 --- a/.github/workflows/scout.lock.yml +++ b/.github/workflows/scout.lock.yml @@ -3877,6 +3877,7 @@ jobs: let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -3923,6 +3924,69 @@ jobs: } } } + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + toolsStart = logContent.indexOf("[", toolsStart + 7); + } + if (toolsStart !== -1) { + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + if (escapeNext) { + escapeNext = false; + continue; + } + if (char === "\\") { + escapeNext = true; + continue; + } + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + if (inString) continue; + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + if (toolsEnd !== -1) { + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + try { + const toolsArray = JSON.parse(toolsJson); + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + } + } + } + } let inDataBlock = false; let currentJsonLines = []; let turnCount = 0; @@ -4105,7 +4169,7 @@ jobs: subtype: "init", session_id: sessionId, model: model, - tools: [], + tools: tools, }; if (modelInfo) { initEntry.model_info = modelInfo; diff --git a/.github/workflows/smoke-copilot.lock.yml b/.github/workflows/smoke-copilot.lock.yml index aaa4db4ad8..1e3cdc0324 100644 --- a/.github/workflows/smoke-copilot.lock.yml +++ b/.github/workflows/smoke-copilot.lock.yml @@ -2382,6 +2382,7 @@ jobs: let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -2428,6 +2429,69 @@ jobs: } } } + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + toolsStart = logContent.indexOf("[", toolsStart + 7); + } + if (toolsStart !== -1) { + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + if (escapeNext) { + escapeNext = false; + continue; + } + if (char === "\\") { + escapeNext = true; + continue; + } + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + if (inString) continue; + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + if (toolsEnd !== -1) { + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + try { + const toolsArray = JSON.parse(toolsJson); + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + } + } + } + } let inDataBlock = false; let currentJsonLines = []; let turnCount = 0; @@ -2610,7 +2674,7 @@ jobs: subtype: "init", session_id: sessionId, model: model, - tools: [], + tools: tools, }; if (modelInfo) { initEntry.model_info = modelInfo; diff --git a/.github/workflows/test-post-steps.lock.yml b/.github/workflows/test-post-steps.lock.yml index d1b9d42a62..65253e3f8e 100644 --- a/.github/workflows/test-post-steps.lock.yml +++ b/.github/workflows/test-post-steps.lock.yml @@ -890,6 +890,7 @@ jobs: let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -936,6 +937,69 @@ jobs: } } } + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + toolsStart = logContent.indexOf("[", toolsStart + 7); + } + if (toolsStart !== -1) { + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + if (escapeNext) { + escapeNext = false; + continue; + } + if (char === "\\") { + escapeNext = true; + continue; + } + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + if (inString) continue; + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + if (toolsEnd !== -1) { + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + try { + const toolsArray = JSON.parse(toolsJson); + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + } + } + } + } let inDataBlock = false; let currentJsonLines = []; let turnCount = 0; @@ -1118,7 +1182,7 @@ jobs: subtype: "init", session_id: sessionId, model: model, - tools: [], + tools: tools, }; if (modelInfo) { initEntry.model_info = modelInfo; diff --git a/.github/workflows/tidy.lock.yml b/.github/workflows/tidy.lock.yml index 9c3c2cc6bf..06500fc63e 100644 --- a/.github/workflows/tidy.lock.yml +++ b/.github/workflows/tidy.lock.yml @@ -2902,6 +2902,7 @@ jobs: let model = "unknown"; let sessionId = null; let modelInfo = null; + let tools = []; const modelMatch = logContent.match(/Starting Copilot CLI: ([\d.]+)/); if (modelMatch) { sessionId = `copilot-${modelMatch[1]}-${Date.now()}`; @@ -2948,6 +2949,69 @@ jobs: } } } + const toolsIndex = logContent.indexOf("[DEBUG] Tools:"); + if (toolsIndex !== -1) { + const afterToolsLine = logContent.indexOf("\n", toolsIndex); + let toolsStart = logContent.indexOf("[DEBUG] [", afterToolsLine); + if (toolsStart !== -1) { + toolsStart = logContent.indexOf("[", toolsStart + 7); + } + if (toolsStart !== -1) { + let bracketCount = 0; + let inString = false; + let escapeNext = false; + let toolsEnd = -1; + for (let i = toolsStart; i < logContent.length; i++) { + const char = logContent[i]; + if (escapeNext) { + escapeNext = false; + continue; + } + if (char === "\\") { + escapeNext = true; + continue; + } + if (char === '"' && !escapeNext) { + inString = !inString; + continue; + } + if (inString) continue; + if (char === "[") { + bracketCount++; + } else if (char === "]") { + bracketCount--; + if (bracketCount === 0) { + toolsEnd = i + 1; + break; + } + } + } + if (toolsEnd !== -1) { + let toolsJson = logContent.substring(toolsStart, toolsEnd); + toolsJson = toolsJson.replace(/^\d{4}-\d{2}-\d{2}T[\d:.]+Z \[DEBUG\] /gm, ""); + try { + const toolsArray = JSON.parse(toolsJson); + if (Array.isArray(toolsArray)) { + tools = toolsArray + .map(tool => { + if (tool.type === "function" && tool.function && tool.function.name) { + let name = tool.function.name; + if (name.startsWith("github-")) { + name = "mcp__github__" + name.substring(7); + } else if (name.startsWith("safe_outputs-")) { + name = name; + } + return name; + } + return null; + }) + .filter(name => name !== null); + } + } catch (e) { + } + } + } + } let inDataBlock = false; let currentJsonLines = []; let turnCount = 0; @@ -3130,7 +3194,7 @@ jobs: subtype: "init", session_id: sessionId, model: model, - tools: [], + tools: tools, }; if (modelInfo) { initEntry.model_info = modelInfo; From 21d9462b7509a6fed8c0c102f12f27da10756ddc Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Sat, 18 Oct 2025 03:38:36 +0000 Subject: [PATCH 5/5] Add changeset for Copilot log parser fix --- .changeset/patch-fix-copilot-log-parser.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/patch-fix-copilot-log-parser.md diff --git a/.changeset/patch-fix-copilot-log-parser.md b/.changeset/patch-fix-copilot-log-parser.md new file mode 100644 index 0000000000..45233d9202 --- /dev/null +++ b/.changeset/patch-fix-copilot-log-parser.md @@ -0,0 +1,5 @@ +--- +"gh-aw": patch +--- + +Fixed Copilot CLI log parser to extract and display tools from new debug format