mirror of
https://github.com/carlrobertoh/ProxyAI.git
synced 2026-05-19 16:28:46 +00:00
fix: improve thought process parsing and displaying
This commit is contained in:
parent
e348e53242
commit
33760001d7
9 changed files with 130 additions and 54 deletions
|
|
@ -123,11 +123,12 @@ public class ChatMessageResponseBody extends JPanel {
|
|||
return;
|
||||
}
|
||||
|
||||
if (handleThinking(partialMessage)) {
|
||||
var processedPartialMessage = processThinkingOutput(partialMessage);
|
||||
if (processedPartialMessage.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (var item : streamParser.parse(partialMessage)) {
|
||||
for (var item : streamParser.parse(processedPartialMessage)) {
|
||||
processResponse(item.response(), CODE.equals(item.type()), true);
|
||||
}
|
||||
}
|
||||
|
|
@ -240,9 +241,8 @@ public class ChatMessageResponseBody extends JPanel {
|
|||
revalidate();
|
||||
}
|
||||
|
||||
private boolean handleThinking(String partialMessage) {
|
||||
thinkingOutputParser.processChunk(partialMessage);
|
||||
|
||||
private String processThinkingOutput(String partialMessage) {
|
||||
var processedChunk = thinkingOutputParser.processChunk(partialMessage);
|
||||
var thoughtProcessPanel = getExistingThoughtProcessPanel();
|
||||
|
||||
if (thinkingOutputParser.isThinking()) {
|
||||
|
|
@ -254,14 +254,13 @@ public class ChatMessageResponseBody extends JPanel {
|
|||
} else {
|
||||
thoughtProcessPanel.updateText(thinkingOutputParser.getThoughtProcess());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (thoughtProcessPanel != null && !thoughtProcessPanel.getFinished()) {
|
||||
if (thoughtProcessPanel != null && thinkingOutputParser.isFinished()) {
|
||||
thoughtProcessPanel.setFinished();
|
||||
}
|
||||
|
||||
return false;
|
||||
return processedChunk;
|
||||
}
|
||||
|
||||
private ThoughtProcessPanel getExistingThoughtProcessPanel() {
|
||||
|
|
|
|||
|
|
@ -1,39 +1,54 @@
|
|||
package ee.carlrobert.codegpt.toolwindow.chat
|
||||
|
||||
import java.util.regex.Pattern
|
||||
|
||||
class ThinkingOutputParser {
|
||||
|
||||
private val buffer = StringBuilder()
|
||||
|
||||
var isThinking: Boolean = false
|
||||
private set
|
||||
|
||||
var isFinished: Boolean = false
|
||||
private set
|
||||
companion object {
|
||||
private const val OPEN_TAG = "<think>"
|
||||
private const val CLOSE_TAG = "</think>"
|
||||
}
|
||||
|
||||
var thoughtProcess: String = ""
|
||||
private set
|
||||
var isThinking: Boolean = false
|
||||
private set
|
||||
var isFinished: Boolean = false
|
||||
private set
|
||||
|
||||
fun processChunk(chunk: String) {
|
||||
private val buffer = StringBuilder()
|
||||
|
||||
fun processChunk(chunk: String): String {
|
||||
if (isFinished) {
|
||||
return
|
||||
return chunk
|
||||
}
|
||||
|
||||
if (buffer.isEmpty() && chunk.isNotEmpty() && !OPEN_TAG.contains(chunk.take(OPEN_TAG.length))) {
|
||||
isFinished = true
|
||||
return chunk
|
||||
}
|
||||
|
||||
buffer.append(chunk)
|
||||
val current = buffer.toString()
|
||||
|
||||
val thinkPattern = Pattern.compile("<think>(.*?)</think>", Pattern.DOTALL)
|
||||
val matcher = thinkPattern.matcher(buffer.toString())
|
||||
if (matcher.find()) {
|
||||
|
||||
val indexOpen = current.indexOf(OPEN_TAG)
|
||||
if (indexOpen == -1) {
|
||||
return ""
|
||||
}
|
||||
|
||||
isThinking = true
|
||||
val startContent = indexOpen + OPEN_TAG.length
|
||||
|
||||
val indexClose = current.indexOf(CLOSE_TAG, startContent)
|
||||
if (indexClose != -1) {
|
||||
thoughtProcess = current.substring(startContent, indexClose).trim()
|
||||
isFinished = true
|
||||
isThinking = false
|
||||
thoughtProcess = matcher.group(1).trim { it <= ' ' }
|
||||
} else if (buffer.isNotBlank() && "<think>".contains(buffer)) {
|
||||
thoughtProcess = ""
|
||||
isThinking = true
|
||||
} else if (buffer.toString().startsWith("<think>")) {
|
||||
thoughtProcess = buffer.toString().replaceFirst("<think>".toRegex(), "")
|
||||
isThinking = true
|
||||
|
||||
val responseStart = indexClose + CLOSE_TAG.length
|
||||
return current.substring(responseStart)
|
||||
} else {
|
||||
thoughtProcess = current.substring(startContent)
|
||||
return ""
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,11 +23,14 @@ class ResponseBodyProgressPanel : JPanel() {
|
|||
|
||||
init {
|
||||
layout = BoxLayout(this, BoxLayout.Y_AXIS)
|
||||
border = JBUI.Borders.empty(4, 0, 8, 0)
|
||||
border = JBUI.Borders.empty(4, 0)
|
||||
isVisible = false
|
||||
}
|
||||
|
||||
fun updateProgressContainer(text: String, icon: Icon?) {
|
||||
runInEdt {
|
||||
isVisible = true
|
||||
|
||||
removeAll()
|
||||
val wrapper = if (icon != null) {
|
||||
JBLabel(
|
||||
|
|
|
|||
|
|
@ -16,5 +16,8 @@ open class ResponseMessagePanel : BaseMessagePanel() {
|
|||
)
|
||||
.setAllowAutoWrapping(true)
|
||||
.withFont(JBFont.label().asBold())
|
||||
.apply {
|
||||
iconTextGap = 6
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -51,7 +51,7 @@ class UserMessagePanel(
|
|||
Icons.User
|
||||
} else {
|
||||
val originalIcon = ImageIcon(Base64.getDecoder().decode(avatarBase64))
|
||||
val resizedImage = originalIcon.image.getScaledInstance(20, 20, Image.SCALE_SMOOTH)
|
||||
val resizedImage = originalIcon.image.getScaledInstance(24, 24, Image.SCALE_SMOOTH)
|
||||
RoundedIcon(resizedImage, 1.0)
|
||||
}
|
||||
} catch (ex: Exception) {
|
||||
|
|
@ -67,6 +67,9 @@ class UserMessagePanel(
|
|||
)
|
||||
.setAllowAutoWrapping(true)
|
||||
.withFont(JBFont.label().asBold())
|
||||
.apply {
|
||||
iconTextGap = 6
|
||||
}
|
||||
}
|
||||
|
||||
fun addReloadAction(onReload: Runnable) {
|
||||
|
|
|
|||
|
|
@ -11,10 +11,10 @@ import javax.swing.*
|
|||
|
||||
class ThoughtProcessPanel : JPanel(BorderLayout()) {
|
||||
|
||||
var finished: Boolean = false
|
||||
private set
|
||||
|
||||
private val responseBodyContent = UIUtil.createTextPane("", false)
|
||||
private var finished: Boolean = false
|
||||
private val responseBodyContent = UIUtil.createTextPane("", false).apply {
|
||||
foreground = JBUI.CurrentTheme.Label.disabledForeground()
|
||||
}
|
||||
private val contentPanel = createContentPanel()
|
||||
private val toggleButton: JToggleButton = createToggleButton()
|
||||
|
||||
|
|
@ -26,6 +26,8 @@ class ThoughtProcessPanel : JPanel(BorderLayout()) {
|
|||
}
|
||||
|
||||
fun setFinished() {
|
||||
if (finished) return
|
||||
|
||||
toggleButton.text = "Thought Process"
|
||||
toggleButton.isSelected = false
|
||||
finished = true
|
||||
|
|
@ -58,21 +60,18 @@ class ThoughtProcessPanel : JPanel(BorderLayout()) {
|
|||
return panel
|
||||
}
|
||||
|
||||
private fun createToggleButton(): JToggleButton {
|
||||
return JToggleButton("Thinking...", AllIcons.General.ArrowUp)
|
||||
.apply {
|
||||
isFocusPainted = false
|
||||
isContentAreaFilled = false
|
||||
background = background
|
||||
selectedIcon = AllIcons.General.ArrowDown
|
||||
border = null
|
||||
isSelected = true
|
||||
horizontalAlignment = SwingConstants.LEFT
|
||||
horizontalTextPosition = SwingConstants.RIGHT
|
||||
iconTextGap = 4
|
||||
addItemListener { e: ItemEvent ->
|
||||
contentPanel.isVisible = e.stateChange == ItemEvent.SELECTED
|
||||
}
|
||||
private fun createToggleButton() =
|
||||
JToggleButton("Thinking...", AllIcons.General.ArrowUp, true).apply {
|
||||
isFocusPainted = false
|
||||
isContentAreaFilled = false
|
||||
background = background
|
||||
selectedIcon = AllIcons.General.ArrowDown
|
||||
border = null
|
||||
horizontalAlignment = SwingConstants.LEFT
|
||||
horizontalTextPosition = SwingConstants.RIGHT
|
||||
iconTextGap = 4
|
||||
addItemListener { e: ItemEvent ->
|
||||
contentPanel.isVisible = e.stateChange == ItemEvent.SELECTED
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,256,256" width="20px" height="20px" fill-rule="nonzero"><defs><linearGradient x1="32" y1="7" x2="32" y2="58" gradientUnits="userSpaceOnUse" id="color-1"><stop offset="0" stop-color="#000000"></stop><stop offset="0.699" stop-color="#000000"></stop></linearGradient><linearGradient x1="32" y1="0.872" x2="32" y2="62.679" gradientUnits="userSpaceOnUse" id="color-2"><stop offset="0" stop-color="#ffffff"></stop><stop offset="1" stop-color="#ffffff"></stop></linearGradient></defs><g transform="translate(-16,-16) scale(1.125,1.125)"><g fill="#000000" fill-rule="nonzero" stroke="#000000" stroke-width="4" stroke-linecap="butt" stroke-linejoin="round" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" style="mix-blend-mode: normal"><path transform="scale(4,4)" d="M56.96,35.77c0,3.26677 -1.24798,6.23506 -3.30276,8.44932c-1.99429,2.15164 -4.75072,3.59119 -7.86757,3.90222c-0.88208,4.1799 -3.85802,7.55012 -7.70667,9.04414c-1.38917,0.53944 -2.8918,0.83432 -4.45001,0.83432c-0.0005,0 -0.00101,0 -0.00151,0c-0.0005,0 -0.00099,0 -0.00149,0c-3.7,0 -7.13,-1.61 -9.51,-4.44c-0.17355,0.02083 -0.33988,0.03683 -0.50148,0.04886c-0.30513,0.02465 -0.59103,0.03614 -0.87352,0.03614c-3.67218,0 -6.97773,-1.60053 -9.2559,-4.14039c-1.97547,-2.20076 -3.1791,-5.10856 -3.1791,-8.29461c0,-1.35992 0.21997,-2.69984 0.65992,-3.99977c-0.14403,-0.1355 -0.28449,-0.27402 -0.4213,-0.41542c-2.23865,-2.3122 -3.50863,-5.40357 -3.50863,-8.65481c0,-6.09 4.39,-11.24 10.32,-12.25c1.22799,-4.14839 4.4698,-7.27438 8.50115,-8.41707c1.08917,-0.30894 2.23614,-0.47293 3.41685,-0.47293c0.00033,0 0.00067,0 0.001,0c0.00033,0 0.00066,0 0.001,0c0.29833,0 0.59479,0.0104 0.88899,0.031c2.29405,0.16031 4.44707,0.93829 6.27413,2.23974c0.91063,0.64757 1.74044,1.42439 2.4662,2.31841c0.05659,-0.01106 0.11314,-0.02173 0.16963,-0.03201c0.24688,-0.04603 0.49363,-0.08341 0.73963,-0.11274c0.48506,-0.05945 0.96473,-0.08941 1.43643,-0.08941c0.11876,0 0.23715,0.00167 0.35512,0.005c3.5298,0.09951 6.69629,1.67767 8.90078,4.13539c1.97547,2.20076 3.1791,5.10856 3.1791,8.29461c0,0.67861 -0.05738,1.35723 -0.17214,2.03322c-0.06371,0.37884 -0.14508,0.7564 -0.24386,1.13178c1.12918,1.12101 2.02385,2.43767 2.6483,3.87003c0.6764,1.54524 1.0377,3.22623 1.0377,4.94497z" id="strokeMainSVG"></path></g><g fill="none" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" style="mix-blend-mode: normal"><g transform="scale(4,4)"><path d="M53.27,26.96c0.28,-1.05 0.42,-2.11 0.42,-3.17c0,-6.86 -5.58,-12.43 -12.43,-12.43c-0.77,0 -1.56,0.07 -2.35,0.23c-2.37,-2.92 -5.85,-4.59 -9.63,-4.59c-5.55,0 -10.36,3.62 -11.92,8.89c-5.93,1.01 -10.32,6.16 -10.32,12.25c0,3.45 1.43,6.72 3.93,9.07c-0.44,1.3 -0.66,2.64 -0.66,4c0,6.86 5.58,12.43 12.43,12.43c0.44,0 0.88,-0.02 1.38,-0.08c2.38,2.83 5.81,4.44 9.51,4.44c5.88,0 10.96,-4.19 12.16,-9.88c6.32,-0.63 11.17,-5.91 11.17,-12.35c0,-3.31 -1.34,-6.48 -3.69,-8.81zM38.25,35.88l-6.63,4l-6.5,-4v-7.26l6.63,-3.87l6.63,3.75z" fill="url(#color-1)"></path><path d="M53.274,26.955c0.275,-1.045 0.415,-2.107 0.415,-3.166c0,-6.855 -5.578,-12.434 -12.434,-12.434c-0.766,0 -1.553,0.079 -2.35,0.235c-2.369,-2.925 -5.843,-4.59 -9.627,-4.59c-5.549,0 -10.353,3.622 -11.913,8.891c-5.93,1.012 -10.32,6.163 -10.32,12.254c0,3.448 1.424,6.715 3.93,9.07c-0.44,1.299 -0.664,2.64 -0.664,3.996c0,6.855 5.578,12.434 12.434,12.434c0.433,0 0.874,-0.027 1.38,-0.087c2.376,2.831 5.809,4.442 9.508,4.442c5.875,0 10.96,-4.192 12.152,-9.878c6.327,-0.629 11.17,-5.908 11.17,-12.355c0.001,-3.304 -1.333,-6.481 -3.681,-8.812zM51.689,23.789c0,0.646 -0.07,1.293 -0.193,1.937l-12.293,-7.185l-13.146,7.991v-4.91l12.814,-7.972c0.813,-0.191 1.615,-0.295 2.383,-0.295c5.754,0 10.435,4.681 10.435,10.434zM37.397,35.171l-5.563,3.316l-5.776,-3.303v-6.311l5.465,-3.322l-0.031,0.052l5.905,3.48zM29.278,9c2.997,0 5.755,1.251 7.728,3.457l-12.948,8.054v13.529l-4.898,-2.801v-14.317c1.159,-4.668 5.302,-7.922 10.118,-7.922zM9.044,28.145c0,-4.923 3.419,-9.109 8.116,-10.169v14.424l12.701,7.264l-5.227,3.115l-11.897,-6.674c-2.345,-1.998 -3.693,-4.894 -3.693,-7.96zM12.311,41.211c0,-0.955 0.138,-1.902 0.4,-2.828l11.954,6.706l12.732,-7.588v6.27l-13.172,7.754c-0.57,0.078 -1.043,0.12 -1.48,0.12c-5.753,0 -10.434,-4.681 -10.434,-10.434zM33.633,56c-2.886,0 -5.578,-1.175 -7.546,-3.252l13.31,-7.835v-14.652l4.539,2.675v14.154c-0.744,5.083 -5.163,8.91 -10.303,8.91zM45.936,46.091v-14.298l-6.539,-3.853v-0.068h-0.115l-5.879,-3.465l5.821,-3.538l12.309,7.195c2.174,1.981 3.422,4.782 3.422,7.703c0.001,5.288 -3.885,9.639 -9.019,10.324z" fill="url(#color-2)"></path></g></g></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,256,256" width="24px" height="24px" fill-rule="nonzero"><defs><linearGradient x1="32" y1="7" x2="32" y2="58" gradientUnits="userSpaceOnUse" id="color-1"><stop offset="0" stop-color="#000000"></stop><stop offset="0.699" stop-color="#000000"></stop></linearGradient><linearGradient x1="32" y1="0.872" x2="32" y2="62.679" gradientUnits="userSpaceOnUse" id="color-2"><stop offset="0" stop-color="#ffffff"></stop><stop offset="1" stop-color="#ffffff"></stop></linearGradient></defs><g transform="translate(-16,-16) scale(1.125,1.125)"><g fill="#000000" fill-rule="nonzero" stroke="#000000" stroke-width="4" stroke-linecap="butt" stroke-linejoin="round" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" style="mix-blend-mode: normal"><path transform="scale(4,4)" d="M56.96,35.77c0,3.26677 -1.24798,6.23506 -3.30276,8.44932c-1.99429,2.15164 -4.75072,3.59119 -7.86757,3.90222c-0.88208,4.1799 -3.85802,7.55012 -7.70667,9.04414c-1.38917,0.53944 -2.8918,0.83432 -4.45001,0.83432c-0.0005,0 -0.00101,0 -0.00151,0c-0.0005,0 -0.00099,0 -0.00149,0c-3.7,0 -7.13,-1.61 -9.51,-4.44c-0.17355,0.02083 -0.33988,0.03683 -0.50148,0.04886c-0.30513,0.02465 -0.59103,0.03614 -0.87352,0.03614c-3.67218,0 -6.97773,-1.60053 -9.2559,-4.14039c-1.97547,-2.20076 -3.1791,-5.10856 -3.1791,-8.29461c0,-1.35992 0.21997,-2.69984 0.65992,-3.99977c-0.14403,-0.1355 -0.28449,-0.27402 -0.4213,-0.41542c-2.23865,-2.3122 -3.50863,-5.40357 -3.50863,-8.65481c0,-6.09 4.39,-11.24 10.32,-12.25c1.22799,-4.14839 4.4698,-7.27438 8.50115,-8.41707c1.08917,-0.30894 2.23614,-0.47293 3.41685,-0.47293c0.00033,0 0.00067,0 0.001,0c0.00033,0 0.00066,0 0.001,0c0.29833,0 0.59479,0.0104 0.88899,0.031c2.29405,0.16031 4.44707,0.93829 6.27413,2.23974c0.91063,0.64757 1.74044,1.42439 2.4662,2.31841c0.05659,-0.01106 0.11314,-0.02173 0.16963,-0.03201c0.24688,-0.04603 0.49363,-0.08341 0.73963,-0.11274c0.48506,-0.05945 0.96473,-0.08941 1.43643,-0.08941c0.11876,0 0.23715,0.00167 0.35512,0.005c3.5298,0.09951 6.69629,1.67767 8.90078,4.13539c1.97547,2.20076 3.1791,5.10856 3.1791,8.29461c0,0.67861 -0.05738,1.35723 -0.17214,2.03322c-0.06371,0.37884 -0.14508,0.7564 -0.24386,1.13178c1.12918,1.12101 2.02385,2.43767 2.6483,3.87003c0.6764,1.54524 1.0377,3.22623 1.0377,4.94497z" id="strokeMainSVG"></path></g><g fill="none" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" style="mix-blend-mode: normal"><g transform="scale(4,4)"><path d="M53.27,26.96c0.28,-1.05 0.42,-2.11 0.42,-3.17c0,-6.86 -5.58,-12.43 -12.43,-12.43c-0.77,0 -1.56,0.07 -2.35,0.23c-2.37,-2.92 -5.85,-4.59 -9.63,-4.59c-5.55,0 -10.36,3.62 -11.92,8.89c-5.93,1.01 -10.32,6.16 -10.32,12.25c0,3.45 1.43,6.72 3.93,9.07c-0.44,1.3 -0.66,2.64 -0.66,4c0,6.86 5.58,12.43 12.43,12.43c0.44,0 0.88,-0.02 1.38,-0.08c2.38,2.83 5.81,4.44 9.51,4.44c5.88,0 10.96,-4.19 12.16,-9.88c6.32,-0.63 11.17,-5.91 11.17,-12.35c0,-3.31 -1.34,-6.48 -3.69,-8.81zM38.25,35.88l-6.63,4l-6.5,-4v-7.26l6.63,-3.87l6.63,3.75z" fill="url(#color-1)"></path><path d="M53.274,26.955c0.275,-1.045 0.415,-2.107 0.415,-3.166c0,-6.855 -5.578,-12.434 -12.434,-12.434c-0.766,0 -1.553,0.079 -2.35,0.235c-2.369,-2.925 -5.843,-4.59 -9.627,-4.59c-5.549,0 -10.353,3.622 -11.913,8.891c-5.93,1.012 -10.32,6.163 -10.32,12.254c0,3.448 1.424,6.715 3.93,9.07c-0.44,1.299 -0.664,2.64 -0.664,3.996c0,6.855 5.578,12.434 12.434,12.434c0.433,0 0.874,-0.027 1.38,-0.087c2.376,2.831 5.809,4.442 9.508,4.442c5.875,0 10.96,-4.192 12.152,-9.878c6.327,-0.629 11.17,-5.908 11.17,-12.355c0.001,-3.304 -1.333,-6.481 -3.681,-8.812zM51.689,23.789c0,0.646 -0.07,1.293 -0.193,1.937l-12.293,-7.185l-13.146,7.991v-4.91l12.814,-7.972c0.813,-0.191 1.615,-0.295 2.383,-0.295c5.754,0 10.435,4.681 10.435,10.434zM37.397,35.171l-5.563,3.316l-5.776,-3.303v-6.311l5.465,-3.322l-0.031,0.052l5.905,3.48zM29.278,9c2.997,0 5.755,1.251 7.728,3.457l-12.948,8.054v13.529l-4.898,-2.801v-14.317c1.159,-4.668 5.302,-7.922 10.118,-7.922zM9.044,28.145c0,-4.923 3.419,-9.109 8.116,-10.169v14.424l12.701,7.264l-5.227,3.115l-11.897,-6.674c-2.345,-1.998 -3.693,-4.894 -3.693,-7.96zM12.311,41.211c0,-0.955 0.138,-1.902 0.4,-2.828l11.954,6.706l12.732,-7.588v6.27l-13.172,7.754c-0.57,0.078 -1.043,0.12 -1.48,0.12c-5.753,0 -10.434,-4.681 -10.434,-10.434zM33.633,56c-2.886,0 -5.578,-1.175 -7.546,-3.252l13.31,-7.835v-14.652l4.539,2.675v14.154c-0.744,5.083 -5.163,8.91 -10.303,8.91zM45.936,46.091v-14.298l-6.539,-3.853v-0.068h-0.115l-5.879,-3.465l5.821,-3.538l12.309,7.195c2.174,1.981 3.422,4.782 3.422,7.703c0.001,5.288 -3.885,9.639 -9.019,10.324z" fill="url(#color-2)"></path></g></g></g></svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
|
@ -1 +1 @@
|
|||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,256,256" width="20px" height="20px" fill-rule="nonzero"><defs><linearGradient x1="32" y1="7" x2="32" y2="58" gradientUnits="userSpaceOnUse" id="color-1"><stop offset="0" stop-color="#ffffff"></stop><stop offset="0.699" stop-color="#ffffff"></stop></linearGradient><linearGradient x1="32" y1="0.872" x2="32" y2="62.679" gradientUnits="userSpaceOnUse" id="color-2"><stop offset="0" stop-color="#000000"></stop><stop offset="1" stop-color="#000000"></stop></linearGradient></defs><g transform="translate(-16,-16) scale(1.125,1.125)"><g fill="#ffffff" fill-rule="nonzero" stroke="#ffffff" stroke-width="4" stroke-linecap="butt" stroke-linejoin="round" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" style="mix-blend-mode: normal"><path transform="scale(4,4)" d="M56.96,35.77c0,3.26677 -1.24798,6.23506 -3.30276,8.44932c-1.99429,2.15164 -4.75072,3.59119 -7.86757,3.90222c-0.88208,4.1799 -3.85802,7.55012 -7.70667,9.04414c-1.38917,0.53944 -2.8918,0.83432 -4.45001,0.83432c-0.0005,0 -0.00101,0 -0.00151,0c-0.0005,0 -0.00099,0 -0.00149,0c-3.7,0 -7.13,-1.61 -9.51,-4.44c-0.17355,0.02083 -0.33988,0.03683 -0.50148,0.04886c-0.30513,0.02465 -0.59103,0.03614 -0.87352,0.03614c-3.67218,0 -6.97773,-1.60053 -9.2559,-4.14039c-1.97547,-2.20076 -3.1791,-5.10856 -3.1791,-8.29461c0,-1.35992 0.21997,-2.69984 0.65992,-3.99977c-0.14403,-0.1355 -0.28449,-0.27402 -0.4213,-0.41542c-2.23865,-2.3122 -3.50863,-5.40357 -3.50863,-8.65481c0,-6.09 4.39,-11.24 10.32,-12.25c1.22799,-4.14839 4.4698,-7.27438 8.50115,-8.41707c1.08917,-0.30894 2.23614,-0.47293 3.41685,-0.47293c0.00033,0 0.00067,0 0.001,0c0.00033,0 0.00066,0 0.001,0c0.29833,0 0.59479,0.0104 0.88899,0.031c2.29405,0.16031 4.44707,0.93829 6.27413,2.23974c0.91063,0.64757 1.74044,1.42439 2.4662,2.31841c0.05659,-0.01106 0.11314,-0.02173 0.16963,-0.03201c0.24688,-0.04603 0.49363,-0.08341 0.73963,-0.11274c0.48506,-0.05945 0.96473,-0.08941 1.43643,-0.08941c0.11876,0 0.23715,0.00167 0.35512,0.005c3.5298,0.09951 6.69629,1.67767 8.90078,4.13539c1.97547,2.20076 3.1791,5.10856 3.1791,8.29461c0,0.67861 -0.05738,1.35723 -0.17214,2.03322c-0.06371,0.37884 -0.14508,0.7564 -0.24386,1.13178c1.12918,1.12101 2.02385,2.43767 2.6483,3.87003c0.6764,1.54524 1.0377,3.22623 1.0377,4.94497z" id="strokeMainSVG"></path></g><g fill="none" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" style="mix-blend-mode: normal"><g transform="scale(4,4)"><path d="M53.27,26.96c0.28,-1.05 0.42,-2.11 0.42,-3.17c0,-6.86 -5.58,-12.43 -12.43,-12.43c-0.77,0 -1.56,0.07 -2.35,0.23c-2.37,-2.92 -5.85,-4.59 -9.63,-4.59c-5.55,0 -10.36,3.62 -11.92,8.89c-5.93,1.01 -10.32,6.16 -10.32,12.25c0,3.45 1.43,6.72 3.93,9.07c-0.44,1.3 -0.66,2.64 -0.66,4c0,6.86 5.58,12.43 12.43,12.43c0.44,0 0.88,-0.02 1.38,-0.08c2.38,2.83 5.81,4.44 9.51,4.44c5.88,0 10.96,-4.19 12.16,-9.88c6.32,-0.63 11.17,-5.91 11.17,-12.35c0,-3.31 -1.34,-6.48 -3.69,-8.81zM38.25,35.88l-6.63,4l-6.5,-4v-7.26l6.63,-3.87l6.63,3.75z" fill="url(#color-1)"></path><path d="M53.274,26.955c0.275,-1.045 0.415,-2.107 0.415,-3.166c0,-6.855 -5.578,-12.434 -12.434,-12.434c-0.766,0 -1.553,0.079 -2.35,0.235c-2.369,-2.925 -5.843,-4.59 -9.627,-4.59c-5.549,0 -10.353,3.622 -11.913,8.891c-5.93,1.012 -10.32,6.163 -10.32,12.254c0,3.448 1.424,6.715 3.93,9.07c-0.44,1.299 -0.664,2.64 -0.664,3.996c0,6.855 5.578,12.434 12.434,12.434c0.433,0 0.874,-0.027 1.38,-0.087c2.376,2.831 5.809,4.442 9.508,4.442c5.875,0 10.96,-4.192 12.152,-9.878c6.327,-0.629 11.17,-5.908 11.17,-12.355c0.001,-3.304 -1.333,-6.481 -3.681,-8.812zM51.689,23.789c0,0.646 -0.07,1.293 -0.193,1.937l-12.293,-7.185l-13.146,7.991v-4.91l12.814,-7.972c0.813,-0.191 1.615,-0.295 2.383,-0.295c5.754,0 10.435,4.681 10.435,10.434zM37.397,35.171l-5.563,3.316l-5.776,-3.303v-6.311l5.465,-3.322l-0.031,0.052l5.905,3.48zM29.278,9c2.997,0 5.755,1.251 7.728,3.457l-12.948,8.054v13.529l-4.898,-2.801v-14.317c1.159,-4.668 5.302,-7.922 10.118,-7.922zM9.044,28.145c0,-4.923 3.419,-9.109 8.116,-10.169v14.424l12.701,7.264l-5.227,3.115l-11.897,-6.674c-2.345,-1.998 -3.693,-4.894 -3.693,-7.96zM12.311,41.211c0,-0.955 0.138,-1.902 0.4,-2.828l11.954,6.706l12.732,-7.588v6.27l-13.172,7.754c-0.57,0.078 -1.043,0.12 -1.48,0.12c-5.753,0 -10.434,-4.681 -10.434,-10.434zM33.633,56c-2.886,0 -5.578,-1.175 -7.546,-3.252l13.31,-7.835v-14.652l4.539,2.675v14.154c-0.744,5.083 -5.163,8.91 -10.303,8.91zM45.936,46.091v-14.298l-6.539,-3.853v-0.068h-0.115l-5.879,-3.465l5.821,-3.538l12.309,7.195c2.174,1.981 3.422,4.782 3.422,7.703c0.001,5.288 -3.885,9.639 -9.019,10.324z" fill="url(#color-2)"></path></g></g></g></svg>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0,0,256,256" width="24px" height="24px" fill-rule="nonzero"><defs><linearGradient x1="32" y1="7" x2="32" y2="58" gradientUnits="userSpaceOnUse" id="color-1"><stop offset="0" stop-color="#ffffff"></stop><stop offset="0.699" stop-color="#ffffff"></stop></linearGradient><linearGradient x1="32" y1="0.872" x2="32" y2="62.679" gradientUnits="userSpaceOnUse" id="color-2"><stop offset="0" stop-color="#000000"></stop><stop offset="1" stop-color="#000000"></stop></linearGradient></defs><g transform="translate(-16,-16) scale(1.125,1.125)"><g fill="#ffffff" fill-rule="nonzero" stroke="#ffffff" stroke-width="4" stroke-linecap="butt" stroke-linejoin="round" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" style="mix-blend-mode: normal"><path transform="scale(4,4)" d="M56.96,35.77c0,3.26677 -1.24798,6.23506 -3.30276,8.44932c-1.99429,2.15164 -4.75072,3.59119 -7.86757,3.90222c-0.88208,4.1799 -3.85802,7.55012 -7.70667,9.04414c-1.38917,0.53944 -2.8918,0.83432 -4.45001,0.83432c-0.0005,0 -0.00101,0 -0.00151,0c-0.0005,0 -0.00099,0 -0.00149,0c-3.7,0 -7.13,-1.61 -9.51,-4.44c-0.17355,0.02083 -0.33988,0.03683 -0.50148,0.04886c-0.30513,0.02465 -0.59103,0.03614 -0.87352,0.03614c-3.67218,0 -6.97773,-1.60053 -9.2559,-4.14039c-1.97547,-2.20076 -3.1791,-5.10856 -3.1791,-8.29461c0,-1.35992 0.21997,-2.69984 0.65992,-3.99977c-0.14403,-0.1355 -0.28449,-0.27402 -0.4213,-0.41542c-2.23865,-2.3122 -3.50863,-5.40357 -3.50863,-8.65481c0,-6.09 4.39,-11.24 10.32,-12.25c1.22799,-4.14839 4.4698,-7.27438 8.50115,-8.41707c1.08917,-0.30894 2.23614,-0.47293 3.41685,-0.47293c0.00033,0 0.00067,0 0.001,0c0.00033,0 0.00066,0 0.001,0c0.29833,0 0.59479,0.0104 0.88899,0.031c2.29405,0.16031 4.44707,0.93829 6.27413,2.23974c0.91063,0.64757 1.74044,1.42439 2.4662,2.31841c0.05659,-0.01106 0.11314,-0.02173 0.16963,-0.03201c0.24688,-0.04603 0.49363,-0.08341 0.73963,-0.11274c0.48506,-0.05945 0.96473,-0.08941 1.43643,-0.08941c0.11876,0 0.23715,0.00167 0.35512,0.005c3.5298,0.09951 6.69629,1.67767 8.90078,4.13539c1.97547,2.20076 3.1791,5.10856 3.1791,8.29461c0,0.67861 -0.05738,1.35723 -0.17214,2.03322c-0.06371,0.37884 -0.14508,0.7564 -0.24386,1.13178c1.12918,1.12101 2.02385,2.43767 2.6483,3.87003c0.6764,1.54524 1.0377,3.22623 1.0377,4.94497z" id="strokeMainSVG"></path></g><g fill="none" fill-rule="nonzero" stroke="none" stroke-width="1" stroke-linecap="butt" stroke-linejoin="miter" stroke-miterlimit="10" stroke-dasharray="" stroke-dashoffset="0" style="mix-blend-mode: normal"><g transform="scale(4,4)"><path d="M53.27,26.96c0.28,-1.05 0.42,-2.11 0.42,-3.17c0,-6.86 -5.58,-12.43 -12.43,-12.43c-0.77,0 -1.56,0.07 -2.35,0.23c-2.37,-2.92 -5.85,-4.59 -9.63,-4.59c-5.55,0 -10.36,3.62 -11.92,8.89c-5.93,1.01 -10.32,6.16 -10.32,12.25c0,3.45 1.43,6.72 3.93,9.07c-0.44,1.3 -0.66,2.64 -0.66,4c0,6.86 5.58,12.43 12.43,12.43c0.44,0 0.88,-0.02 1.38,-0.08c2.38,2.83 5.81,4.44 9.51,4.44c5.88,0 10.96,-4.19 12.16,-9.88c6.32,-0.63 11.17,-5.91 11.17,-12.35c0,-3.31 -1.34,-6.48 -3.69,-8.81zM38.25,35.88l-6.63,4l-6.5,-4v-7.26l6.63,-3.87l6.63,3.75z" fill="url(#color-1)"></path><path d="M53.274,26.955c0.275,-1.045 0.415,-2.107 0.415,-3.166c0,-6.855 -5.578,-12.434 -12.434,-12.434c-0.766,0 -1.553,0.079 -2.35,0.235c-2.369,-2.925 -5.843,-4.59 -9.627,-4.59c-5.549,0 -10.353,3.622 -11.913,8.891c-5.93,1.012 -10.32,6.163 -10.32,12.254c0,3.448 1.424,6.715 3.93,9.07c-0.44,1.299 -0.664,2.64 -0.664,3.996c0,6.855 5.578,12.434 12.434,12.434c0.433,0 0.874,-0.027 1.38,-0.087c2.376,2.831 5.809,4.442 9.508,4.442c5.875,0 10.96,-4.192 12.152,-9.878c6.327,-0.629 11.17,-5.908 11.17,-12.355c0.001,-3.304 -1.333,-6.481 -3.681,-8.812zM51.689,23.789c0,0.646 -0.07,1.293 -0.193,1.937l-12.293,-7.185l-13.146,7.991v-4.91l12.814,-7.972c0.813,-0.191 1.615,-0.295 2.383,-0.295c5.754,0 10.435,4.681 10.435,10.434zM37.397,35.171l-5.563,3.316l-5.776,-3.303v-6.311l5.465,-3.322l-0.031,0.052l5.905,3.48zM29.278,9c2.997,0 5.755,1.251 7.728,3.457l-12.948,8.054v13.529l-4.898,-2.801v-14.317c1.159,-4.668 5.302,-7.922 10.118,-7.922zM9.044,28.145c0,-4.923 3.419,-9.109 8.116,-10.169v14.424l12.701,7.264l-5.227,3.115l-11.897,-6.674c-2.345,-1.998 -3.693,-4.894 -3.693,-7.96zM12.311,41.211c0,-0.955 0.138,-1.902 0.4,-2.828l11.954,6.706l12.732,-7.588v6.27l-13.172,7.754c-0.57,0.078 -1.043,0.12 -1.48,0.12c-5.753,0 -10.434,-4.681 -10.434,-10.434zM33.633,56c-2.886,0 -5.578,-1.175 -7.546,-3.252l13.31,-7.835v-14.652l4.539,2.675v14.154c-0.744,5.083 -5.163,8.91 -10.303,8.91zM45.936,46.091v-14.298l-6.539,-3.853v-0.068h-0.115l-5.879,-3.465l5.821,-3.538l12.309,7.195c2.174,1.981 3.422,4.782 3.422,7.703c0.001,5.288 -3.885,9.639 -9.019,10.324z" fill="url(#color-2)"></path></g></g></g></svg>
|
||||
|
|
|
|||
|
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 4.6 KiB |
|
|
@ -0,0 +1,54 @@
|
|||
package ee.carlrobert.codegpt.toolwindow.chat
|
||||
|
||||
import org.assertj.core.api.Assertions.assertThat
|
||||
import org.junit.Test
|
||||
|
||||
class ThinkingOutputParserTest {
|
||||
|
||||
@Test
|
||||
fun `when not processing then return empty string`() {
|
||||
val parser = ThinkingOutputParser()
|
||||
assertThat(parser.processChunk("Some text")).isEmpty()
|
||||
assertThat(parser.thoughtProcess).isEmpty()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when processing chunk but thinking not finished then return empty string`() {
|
||||
val parser = ThinkingOutputParser()
|
||||
assertThat(parser.processChunk("<think>starting")).isEmpty()
|
||||
assertThat(parser.thoughtProcess).isEqualTo("starting")
|
||||
|
||||
val finalOutput = parser.processChunk(" some processing...")
|
||||
|
||||
assertThat(finalOutput).isEmpty()
|
||||
assertThat(parser.thoughtProcess).isEqualTo("starting some processing...")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `when thinking finished then return everything after the last closing think tag`() {
|
||||
val parser = ThinkingOutputParser()
|
||||
parser.processChunk("<think>the internal thought</think>")
|
||||
assertThat(parser.thoughtProcess).isEqualTo("the internal thought")
|
||||
|
||||
val finalOutput = parser.processChunk("Here is the user response.")
|
||||
|
||||
assertThat(finalOutput).isEqualTo("Here is the user response.")
|
||||
assertThat(parser.thoughtProcess).isEqualTo("the internal thought")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `accumulate chunks and return response only after final chunk with closing tag`() {
|
||||
val parser = ThinkingOutputParser()
|
||||
assertThat(parser.processChunk("<think>")).isEmpty()
|
||||
assertThat(parser.thoughtProcess).isEqualTo("")
|
||||
assertThat(parser.processChunk("some internal processing")).isEmpty()
|
||||
assertThat(parser.thoughtProcess).isEqualTo("some internal processing")
|
||||
assertThat(parser.processChunk(" with even more details... ")).isEmpty()
|
||||
assertThat(parser.thoughtProcess).isEqualTo("some internal processing with even more details... ")
|
||||
|
||||
val finalOutput = parser.processChunk("</think>The final answer.")
|
||||
|
||||
assertThat(finalOutput).isEqualTo("The final answer.")
|
||||
assertThat(parser.thoughtProcess).isEqualTo("some internal processing with even more details...")
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue