IJPL-233396 misc [mcp-server]: improve execute_run_configuration output for agent consumption

Default truncation kept the beginning of output (build logs) and
discarded the end (test failures, stack traces). Switch default to
TruncateMode.END.
When truncation occurs, write full output to a temp file and return
its path so agents can read_file the complete log.

(cherry picked from commit 1ebbed734bb85d1d2d2e343da0c3a8c0aadfa6fe)

GitOrigin-RevId: a964ca4b7dcb288481ddd75d996ff5c15a8c5e48
This commit is contained in:
Dmitry Zhuravlev
2026-03-13 01:13:29 +00:00
committed by intellij-monorepo-bot
parent ff0adfa126
commit 1b1917e342
@@ -24,6 +24,7 @@ import com.intellij.mcpserver.util.TruncateMode
import com.intellij.mcpserver.util.checkUserConfirmationIfNeeded
import com.intellij.mcpserver.util.truncateText
import com.intellij.openapi.application.EDT
import com.intellij.openapi.application.PathManager
import com.intellij.openapi.application.readAction
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.diagnostic.rethrowControlFlowException
@@ -37,6 +38,7 @@ import kotlinx.coroutines.withTimeoutOrNull
import kotlinx.serialization.EncodeDefault
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.Serializable
import java.nio.file.Files
import kotlin.time.Duration.Companion.milliseconds
private val logger = logger<ExecutionToolset>()
@@ -157,14 +159,31 @@ class ExecutionToolset : McpToolset {
mcpFail("Execution failed: ${e.message}")
}
}
val output = truncateText(outputBuilder.toString(), maxLinesCount = maxLinesCount, truncateMode = truncateMode)
val fullOutput = outputBuilder.toString()
val output = truncateText(fullOutput, maxLinesCount = maxLinesCount, truncateMode = truncateMode)
val fullOutputPath = if (output.length != fullOutput.length) createTmpFile(fullOutput) else null
return RunConfigurationResult(
exitCode = exitCode,
timedOut = exitCode == null,
output = output
output = output,
fullOutputPath = fullOutputPath,
)
}
private fun createTmpFile(fullOutput: String): String? {
return try {
val tmpFile = Files.createTempFile(PathManager.getTempDir(), "run-config-output", ".log")
Files.writeString(tmpFile, fullOutput)
tmpFile.toAbsolutePath().toString()
}
catch (e: Exception) {
rethrowControlFlowException(e)
logger.trace { "Failed to write full output to temp file: ${e.message}" }
null
}
}
@Serializable
data class RunConfigurationsList(
val configurations: List<RunConfigurationInfo>,
@@ -184,12 +203,15 @@ class ExecutionToolset : McpToolset {
)
@Serializable
data class RunConfigurationResult(
data class RunConfigurationResult @JvmOverloads constructor(
@EncodeDefault(mode = EncodeDefault.Mode.NEVER)
val exitCode: Int? = null,
@property:McpDescription(Constants.TIMED_OUT_DESCRIPTION)
@EncodeDefault(mode = EncodeDefault.Mode.NEVER)
val timedOut: Boolean? = false,
val output: String
val output: String,
@property:McpDescription("Path to a temp file containing the full untruncated output. Present only when output was truncated. Use read_file to access the complete log.")
@EncodeDefault(mode = EncodeDefault.Mode.NEVER)
val fullOutputPath: String? = null,
)
}
}