Skip to content

Commit c135477

Browse files
committed
Enhance tool call and add new models
* Refine tool call UX for MCP * Add new claude 4 and Gemini 2.5 Pro models * Fix tool call schema issues for OpenAI/AzureOpenAI o-series models
1 parent f674f87 commit c135477

11 files changed

+1626
-139
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,11 @@
11
# CHANGELOG
22

3+
## v4.9.0
4+
5+
* Refine tool call UX for MCP
6+
* Add new claude 4 and Gemini 2.5 Pro models
7+
* Fix tool call schema issues for OpenAI/AzureOpenAI o-series models
8+
39
## v4.8.3
410

511
* Add request headers

media/main.css

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -721,4 +721,113 @@ h2.mb-5 {
721721

722722
h2.mb-3 {
723723
margin-bottom: 0.1rem !important;
724+
}
725+
726+
/* Tool Call Block Styles */
727+
.tool-call-block {
728+
background: var(--vscode-textCodeBlock-background);
729+
border-radius: 6px;
730+
margin: 1em 0;
731+
border: 1px solid var(--vscode-input-border);
732+
}
733+
734+
.tool-call-header {
735+
padding: 8px 12px;
736+
cursor: pointer;
737+
display: flex;
738+
align-items: center;
739+
gap: 8px;
740+
user-select: none;
741+
background: rgba(255, 255, 255, 0.05);
742+
border-radius: 6px 6px 0 0;
743+
}
744+
745+
.tool-call-header:hover {
746+
background: rgba(255, 255, 255, 0.08);
747+
}
748+
749+
.tool-name {
750+
font-weight: 500;
751+
}
752+
753+
.tool-call-content {
754+
padding: 12px;
755+
display: block;
756+
}
757+
758+
.tool-call-collapsed {
759+
display: none;
760+
}
761+
762+
.tool-call-caret {
763+
transition: transform 0.2s ease;
764+
width: 12px;
765+
height: 12px;
766+
}
767+
768+
.tool-call-header.collapsed .tool-call-caret {
769+
transform: rotate(-90deg);
770+
}
771+
772+
.tool-call-args,
773+
.tool-call-result {
774+
margin-bottom: 12px;
775+
}
776+
777+
.tool-section-label {
778+
font-size: 0.9em;
779+
color: var(--vscode-descriptionForeground);
780+
margin-bottom: 4px;
781+
font-weight: 500;
782+
}
783+
784+
.tool-result-pending {
785+
font-style: italic;
786+
color: var(--vscode-disabledForeground);
787+
}
788+
789+
.tool-result-empty {
790+
font-style: italic;
791+
color: var(--vscode-disabledForeground);
792+
padding: 4px 0;
793+
}
794+
795+
.tool-call-content pre {
796+
margin: 0.5em 0;
797+
}
798+
799+
.tool-call-content code {
800+
font-family: var(--vscode-editor-font-family);
801+
font-size: 0.9em;
802+
}
803+
804+
/* Styles for tool result content */
805+
.tool-call-result img {
806+
max-width: 100%;
807+
}
808+
809+
.tool-call-result p {
810+
margin: 0.5em 0;
811+
}
812+
813+
.tool-call-result ul,
814+
.tool-call-result ol {
815+
margin: 0.5em 0;
816+
padding-left: 2em;
817+
}
818+
819+
.tool-name {
820+
display: flex;
821+
align-items: center;
822+
gap: 4px;
823+
}
824+
825+
.tool-icon {
826+
width: 14px;
827+
height: 14px;
828+
}
829+
830+
/* Hide tool-result elements */
831+
tool-result {
832+
display: none;
724833
}

media/main.js

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -139,29 +139,33 @@
139139

140140
case "addResponse":
141141
let existingMessage = message.id && document.getElementById(message.id);
142-
let updatedValue = "";
143142

144143
const unEscapeHtml = (unsafe) => {
145144
return unsafe.replaceAll('&amp;', '&').replaceAll('&lt;', '<').replaceAll('&gt;', '>').replaceAll('&quot;', '"').replaceAll('&#039;', "'");
146145
};
147146

148-
if (!message.responseInMarkdown) {
149-
updatedValue = "```\r\n" + unEscapeHtml(message.value) + " \r\n ```";
150-
} else {
151-
updatedValue = message.value.split("```").length % 2 === 1 ? message.value : message.value + "\n\n```\n\n";
152-
}
153-
154-
const markedResponse = marked.parse(updatedValue.trim().replace(/^\s+|\s+$/g, ''));
147+
// Check if this update contains any tool-result tags
148+
const tempDiv = document.createElement('div');
149+
tempDiv.innerHTML = message.value;
150+
const hasToolResult = tempDiv.querySelector('tool-result');
155151

152+
let updatedValue = message.value.split("```").length % 2 === 1 ? message.value : message.value + "\n\n```\n\n";
153+
let formattedResponse = marked.parse(updatedValue.trim().replace(/^\s+|\s+$/g, ''));
156154
if (existingMessage) {
157-
existingMessage.innerHTML = markedResponse;
155+
existingMessage.innerHTML = formattedResponse;
158156
} else {
159157
list.innerHTML +=
160158
`<div class="p-4 self-end mt-2 pb-4 answer-element-ext">
161-
<div class="result-streaming" id="${message.id}">${markedResponse}</div>
159+
<div class="result-streaming" id="${message.id}">${formattedResponse}</div>
162160
</div>`;
163161
}
164162

163+
// Initialize tool call blocks with collapsed state
164+
const toolCallBlocks = list.querySelectorAll('.tool-call-header:not(.initialized)');
165+
toolCallBlocks.forEach(header => {
166+
header.classList.add('collapsed', 'initialized');
167+
});
168+
165169
if (message.done) {
166170
const preCodeList = list.lastChild.querySelectorAll("pre > code");
167171

0 commit comments

Comments
 (0)