mirror of
https://github.com/ben4202121/buddybridge.git
synced 2026-07-22 07:48:01 +00:00
feat: 工具调用折叠 + toolResult解析修复 + 样式区分
This commit is contained in:
parent
1f2344ea40
commit
ac8fddda2b
5 changed files with 103 additions and 15 deletions
16
fix.mjs
Normal file
16
fix.mjs
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import fs from 'fs';
|
||||
|
||||
var f = fs.readFileSync('H:/obsidian/obsidian/.obsidian/plugins/buddybridge-v1.0.0/main.js', 'utf8');
|
||||
|
||||
// Swap: create header FIRST, then list
|
||||
var oldBlock = 'var tlist = toolsBlock.createDiv({ cls: "buddybridge-tools-list" });\n tlist.style.display = "none";\n var thdr = toolsBlock.createDiv({ cls: "buddybridge-tools-header" });';
|
||||
var newBlock = 'var thdr = toolsBlock.createDiv({ cls: "buddybridge-tools-header" });\n thdr.style.cursor = "pointer";\n thdr.textContent = "\\u{1F527} 工具调用 \\u25B8";\n var tlist = toolsBlock.createDiv({ cls: "buddybridge-tools-list" });\n tlist.style.display = "none";';
|
||||
|
||||
f = f.replace(oldBlock, newBlock);
|
||||
|
||||
// Remove the duplicate header setup (cursor, textContent) that was after the old header creation
|
||||
f = f.replace(' thdr.style.cursor = "pointer";\n thdr.textContent = "\\u{1F527} 工具调用 \\u25B8";\n thdr.addEventListener("click"', ' thdr.addEventListener("click"');
|
||||
|
||||
fs.writeFileSync('H:/obsidian/obsidian/.obsidian/plugins/buddybridge-v1.0.0/main.js', f);
|
||||
fs.writeFileSync('H:/Dev/claude/buddybridge/main.js', f);
|
||||
console.log('done');
|
||||
38
main.js
38
main.js
|
|
@ -199,7 +199,7 @@ function parseStreamLine(line) {
|
|||
try {
|
||||
const obj = JSON.parse(line);
|
||||
const event = obj.event || obj;
|
||||
if (obj.type === "assistant") {
|
||||
if (obj.type === "assistant" || obj.type === "user") {
|
||||
const msg = obj.message;
|
||||
if (!msg || !Array.isArray(msg.content))
|
||||
return null;
|
||||
|
|
@ -210,7 +210,16 @@ function parseStreamLine(line) {
|
|||
if (block.type === "text") {
|
||||
return { type: "text", content: block.text || "" };
|
||||
}
|
||||
if (block.type === "tool_call") {
|
||||
if (block.type === "tool_result") {
|
||||
var rt = "";
|
||||
if (Array.isArray(block.content)) {
|
||||
for (var ci = 0; ci < block.content.length; ci++) {
|
||||
if (block.content[ci].type === "text") rt += (block.content[ci].text || "");
|
||||
}
|
||||
}
|
||||
return { type: "tool", content: "", toolName: "结果", toolDetail: rt.substring(0, 200) + (rt.length > 200 ? "..." : "") };
|
||||
}
|
||||
if (block.type === "tool_call") {
|
||||
return {
|
||||
type: "tool",
|
||||
content: "",
|
||||
|
|
@ -705,10 +714,27 @@ ${text}` : text;
|
|||
}
|
||||
this.scrollToBottom();
|
||||
} else if (chunk.type === "tool") {
|
||||
bubble.createDiv({
|
||||
cls: "buddybridge-tool-call",
|
||||
text: `\u{1F527} ${chunk.toolName || ""} ${chunk.toolDetail || ""}`
|
||||
});
|
||||
let toolsBlock = bubble.querySelector(".buddybridge-tools-block");
|
||||
if (!toolsBlock) {
|
||||
toolsBlock = bubble.createDiv({ cls: "buddybridge-tools-block" });
|
||||
var thdr = toolsBlock.createDiv({ cls: "buddybridge-tools-header" });
|
||||
thdr.style.cursor = "pointer";
|
||||
thdr.textContent = "\u{1F527} 工具调用 \u25B8";
|
||||
var tlist = toolsBlock.createDiv({ cls: "buddybridge-tools-list" });
|
||||
tlist.style.display = "none";
|
||||
thdr.addEventListener("click", function() {
|
||||
var hidden = tlist.style.display === "none";
|
||||
tlist.style.display = hidden ? "" : "none";
|
||||
thdr.textContent = hidden ? "\u{1F527} 工具调用 \u25BE" : "\u{1F527} 工具调用 \u25B8";
|
||||
});
|
||||
}
|
||||
var list = toolsBlock.querySelector(".buddybridge-tools-list");
|
||||
if (list) {
|
||||
list.createDiv({
|
||||
cls: "buddybridge-tool-call",
|
||||
text: chunk.toolName ? chunk.toolName + " " + (chunk.toolDetail || "") : (chunk.toolDetail || "")
|
||||
});
|
||||
}
|
||||
} else if (chunk.type === "text") {
|
||||
textContent += chunk.content;
|
||||
this.manager.updateMessage(convId, aiMsg.id, textContent);
|
||||
|
|
|
|||
|
|
@ -181,7 +181,7 @@ function parseStreamLine(line: string): StreamChunk | null {
|
|||
const obj = JSON.parse(line);
|
||||
const event = obj.event || obj;
|
||||
|
||||
if (obj.type === 'assistant') {
|
||||
if (obj.type === 'assistant' || obj.type === 'user') {
|
||||
const msg = obj.message;
|
||||
if (!msg || !Array.isArray(msg.content)) return null;
|
||||
|
||||
|
|
|
|||
|
|
@ -251,11 +251,28 @@ ${text}`
|
|||
body.setText(thinkingContent);
|
||||
}
|
||||
} else if (chunk.type === 'tool') {
|
||||
// 工具调用行
|
||||
bubble.createDiv({
|
||||
cls: 'buddybridge-tool-call',
|
||||
text: `🔧 ${chunk.toolName || ''} ${chunk.toolDetail || ''}`
|
||||
});
|
||||
let toolsBlock = bubble.querySelector('.buddybridge-tools-block') as HTMLElement;
|
||||
if (!toolsBlock) {
|
||||
toolsBlock = bubble.createDiv({ cls: 'buddybridge-tools-block' });
|
||||
const hdr = toolsBlock.createDiv({ cls: 'buddybridge-tools-header', text: '🔧 工具调用 ▾' });
|
||||
hdr.style.cursor = 'pointer';
|
||||
hdr.addEventListener('click', () => {
|
||||
const list = toolsBlock.querySelector('.buddybridge-tools-list') as HTMLElement;
|
||||
if (list) {
|
||||
const hidden = list.style.display === 'none';
|
||||
list.style.display = hidden ? '' : 'none';
|
||||
hdr.textContent = hidden ? '🔧 工具调用 ▾' : '🔧 工具调用 ▸';
|
||||
}
|
||||
});
|
||||
toolsBlock.createDiv({ cls: 'buddybridge-tools-list' });
|
||||
}
|
||||
const list = toolsBlock.querySelector('.buddybridge-tools-list') as HTMLElement;
|
||||
if (list) {
|
||||
list.createDiv({
|
||||
cls: 'buddybridge-tool-call',
|
||||
text: `${chunk.toolName || ''} ${chunk.toolDetail || ''}`
|
||||
});
|
||||
}
|
||||
} else if (chunk.type === 'text') {
|
||||
textContent += chunk.content;
|
||||
this.manager.updateMessage(convId, aiMsg.id, textContent, true);
|
||||
|
|
@ -284,12 +301,10 @@ ${text}`
|
|||
} finally {
|
||||
this.isStreaming = false;
|
||||
this.streamingMsgId = null;
|
||||
// 不在 finally 中 renderMessages(), 避免清除思考块
|
||||
// 仅在出错时重新渲染
|
||||
}
|
||||
}
|
||||
|
||||
private scrollToBottom() {
|
||||
this.messageContainer.scrollTop = this.messageContainer.scrollHeight;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
31
styles.css
31
styles.css
|
|
@ -314,3 +314,34 @@
|
|||
|
||||
/* 不可见辅助类 */
|
||||
.buddybridge-hidden { display: none !important; }
|
||||
|
||||
/* ==================== 工具调用块 ==================== */
|
||||
.buddybridge-tools-block {
|
||||
margin: 4px 0;
|
||||
border: 1px solid var(--background-modifier-border);
|
||||
border-radius: 6px;
|
||||
overflow: hidden;
|
||||
}
|
||||
.buddybridge-tools-header {
|
||||
padding: 4px 8px;
|
||||
font-size: 11px;
|
||||
color: var(--text-faint);
|
||||
background: var(--background-primary);
|
||||
border-bottom: 1px solid var(--background-modifier-border);
|
||||
cursor: pointer;
|
||||
user-select: none;
|
||||
}
|
||||
.buddybridge-tools-list {
|
||||
padding: 4px 0;
|
||||
}
|
||||
.buddybridge-tools-list .buddybridge-tool-call {
|
||||
padding: 2px 8px;
|
||||
margin: 1px 0;
|
||||
font-size: 11px;
|
||||
color: var(--text-faint);
|
||||
border-left: 2px solid var(--text-faint);
|
||||
border-radius: 0 4px 4px 0;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue