feat: separate reasoning blocks in responses

- Extract reasoning/thinking parts from response parts
- Wrap reasoning in Markdown details/summary collapsible
- Add horizontal divider between reasoning and main text
- Log part types for debugging
This commit is contained in:
Бородин Роман 2026-09-25 18:03:53 +03:00
parent cae866fec6
commit 26e28361cc
1 changed files with 42 additions and 12 deletions

View File

@ -164,24 +164,54 @@ async function runPlugin(ctx: any, options: any, sdkClient?: any) {
})
log(`V1: prompt result keys=${Object.keys(result || {})}`)
log(`V1: prompt result.data.keys=${result?.data ? Object.keys(result.data).join(",") : "null"}`)
log(`V1: prompt result.data.info.keys=${result?.data?.info ? Object.keys(result.data.info).join(",") : "null"}`)
log(`V1: prompt result.data.info.parts=${result?.data?.info?.parts ? JSON.stringify(result.data.info.parts).slice(0, 500) : "null"}`)
log(`V1: prompt result.data.message=${result?.data?.message ? JSON.stringify(result.data.message).slice(0, 500) : "null"}`)
// Try to extract content from various locations
let responseText = ""
if (result?.data?.parts) {
responseText = result.data.parts.map((p: any) => p.content || p.text || "").join("")
log(`V1: data.parts count=${result.data.parts.length}`)
log(`V1: data.parts.types=${result.data.parts.map((p: any) => p.type).join(",")}`)
log(`V1: data.parts[0]=${JSON.stringify(result.data.parts[0]).slice(0, 200)}`)
}
// Try to extract content from various locations, separating reasoning from main text
let reasoningText = ""
let mainText = ""
const reasoningTypes = new Set(["reasoning", "thinking", "redwood", "reason"])
if (result?.data?.parts) {
for (const p of result.data.parts) {
const content = p.content || p.text || ""
if (reasoningTypes.has(p.type)) {
reasoningText += content
} else {
mainText += content
}
}
} else if (result?.data?.info?.parts) {
responseText = result.data.info.parts.map((p: any) => p.content || p.text || "").join("")
for (const p of result.data.info.parts) {
const content = p.content || p.text || ""
if (reasoningTypes.has(p.type)) {
reasoningText += content
} else {
mainText += content
}
}
} else if (result?.data?.message?.parts) {
responseText = result.data.message.parts.map((p: any) => p.content || p.text || "").join("")
for (const p of result.data.message.parts) {
const content = p.content || p.text || ""
if (reasoningTypes.has(p.type)) {
reasoningText += content
} else {
mainText += content
}
}
} else if (result?.data?.content) {
responseText = result.data.content
mainText = result.data.content
} else if (result?.response?.content) {
responseText = result.response.content
mainText = result.response.content
} else if (result?.content) {
responseText = result.content
mainText = result.content
}
let responseText = mainText
if (reasoningText.trim()) {
responseText = `<details><summary>Thoughts</summary>\n\n${reasoningText.trim()}\n\n</details>\n\n---\n\n${mainText}`
}
session.outputChars += responseText.length