From e3b7579500be67c18585b37d42daa32dcb09eb02 Mon Sep 17 00:00:00 2001 From: Copilot CLI Date: Tue, 9 Jun 2026 15:00:22 +0800 Subject: [PATCH 1/2] fix(lmtool): reframe timeout messages as transient + retry-friendly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The two timeout-path response messages previously led with '❌ Debug session failed to start' and listed root-cause hypotheses (compilation errors, ClassNotFoundException, ...) as 'This usually indicates a problem'. Telemetry shows that interpretation is wrong: - 30d retry analysis: success rate climbs from 17.7% (1 invoke) to 64.9% (6-10 invokes) — a 3.7x lift - Started latency P95 = 100s vs the 45s / 15s thresholds — many timeouts are just slow-starting JVMs that DO eventually attach - 66% of users invoke only once, suggesting the model treats the ❌ wording as a permanent failure and gives up Rewrite both timeout messages to: 1. Lead with ⏳ (transient) instead of ❌ / ⚠️ (terminal) 2. State explicitly 'this is often transient' 3. Cite the retry-success pattern 4. Put 'call debug_java_application again' as the first recommended action 5. Keep the diagnostic checklist as a fallback (steps 3-4) for genuinely broken cases No behavior change in the extension — only the natural-language string returned to the language model is changed. This is a targeted nudge for the model's retry policy. Companion PR #1650 will give us per-invoke retry telemetry (retryCount / previousOutcome) to verify the lift after this lands. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --- src/languageModelTool.ts | 46 +++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 20 deletions(-) diff --git a/src/languageModelTool.ts b/src/languageModelTool.ts index 85b28855..c8eaafbf 100644 --- a/src/languageModelTool.ts +++ b/src/languageModelTool.ts @@ -275,17 +275,21 @@ async function debugJavaApplication( resolve({ success: false, status: 'timeout', - message: `❌ Debug session failed to start within ${CONSTANTS.SESSION_WAIT_TIMEOUT / 1000} seconds for ${targetInfo}.\n\n` + - `This usually indicates a problem:\n` + - `• Compilation errors preventing startup\n` + - `• ClassNotFoundException or NoClassDefFoundError\n` + - `• Application crashed during initialization\n` + - `• Incorrect main class or classpath configuration\n\n` + - `Action required:\n` + - `1. Check terminal '${terminal.name}' for error messages\n` + - `2. Verify the target class name is correct\n` + - `3. Ensure the project is compiled successfully\n` + - `4. Use get_debug_session_info() to confirm session status${warningNote}`, + message: `⏳ Debug session not yet detected for ${targetInfo} after ` + + `${CONSTANTS.SESSION_WAIT_TIMEOUT / 1000} seconds.\n\n` + + `This is often transient — the JVM may still be starting up (large ` + + `projects, cold class-loading, or remote workspaces can need additional ` + + `time). Telemetry shows that retrying a timed-out launch succeeds for ` + + `the majority of cases.\n\n` + + `Recommended next actions (in order):\n` + + `1. Call debug_java_application again — most timeout cases recover on retry.\n` + + `2. Call get_debug_session_info() to check whether the session has since ` + + `become active.\n` + + `3. If retrying still times out, inspect terminal '${terminal.name}' for ` + + `compilation errors, ClassNotFoundException, NoClassDefFoundError, or ` + + `other startup failures.\n` + + `4. Verify the target class name and classpath are correct, then retry.` + + `${warningNote}`, terminalName: terminal.name }); } @@ -335,15 +339,17 @@ async function debugJavaApplication( return { success: true, status: 'timeout', - message: `⚠️ Debug command sent for ${targetInfo}, but session not detected within ${CONSTANTS.SMART_POLLING_MAX_WAIT / 1000} seconds.\n\n` + - `Possible reasons:\n` + - `• Application is still starting (large projects may take longer)\n` + - `• Compilation errors (check terminal '${terminal.name}' for errors)\n` + - `• Application may have started and already terminated\n\n` + - `Next steps:\n` + - `• Use get_debug_session_info() to check if session is now active\n` + - `• Check terminal '${terminal.name}' for error messages\n` + - `• If starting slowly, wait a bit longer and check again${warningNote}`, + message: `⏳ Debug command sent for ${targetInfo}; session not yet detected within ` + + `${CONSTANTS.SMART_POLLING_MAX_WAIT / 1000} seconds.\n\n` + + `This is often transient — the application may still be starting in terminal ` + + `'${terminal.name}'. Telemetry shows that retrying or polling for status is more ` + + `likely to succeed than treating this as a permanent failure.\n\n` + + `Recommended next actions (in order):\n` + + `1. Call get_debug_session_info() to check whether the session has since become active.\n` + + `2. Call debug_java_application again — most timeout cases recover on retry. ` + + `Pass waitForSession=true to extend the wait window for slow-starting apps.\n` + + `3. If retrying still times out, inspect terminal '${terminal.name}' for compilation ` + + `errors or startup failures, then retry.${warningNote}`, terminalName: terminal.name }; } From 71ce1279651882fbacc6f33f3ed5bae3c78dea02 Mon Sep 17 00:00:00 2001 From: Copilot CLI Date: Tue, 9 Jun 2026 16:22:27 +0800 Subject: [PATCH 2/2] review: clarify JSON object syntax for waitForSession in smart-polling timeout message --- src/languageModelTool.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/languageModelTool.ts b/src/languageModelTool.ts index c8eaafbf..055103b2 100644 --- a/src/languageModelTool.ts +++ b/src/languageModelTool.ts @@ -347,7 +347,8 @@ async function debugJavaApplication( + `Recommended next actions (in order):\n` + `1. Call get_debug_session_info() to check whether the session has since become active.\n` + `2. Call debug_java_application again — most timeout cases recover on retry. ` - + `Pass waitForSession=true to extend the wait window for slow-starting apps.\n` + + `In the input arguments, set "waitForSession": true (JSON object syntax) to ` + + `extend the wait window for slow-starting apps.\n` + `3. If retrying still times out, inspect terminal '${terminal.name}' for compilation ` + `errors or startup failures, then retry.${warningNote}`, terminalName: terminal.name