- {q.options.map((opt, optIdx) => (
-
-
- {opt.label}
-
- {opt.description ? (
-
- {opt.description}
-
- ) : null}
-
- ))}
+ const cleaned = questionAnswers.map(a => a.trim()).filter(a => a.length > 0)
+ if (cleaned.length === 0) return null
+
+ return (
+
+ {cleaned.map((answer, i) => (
+
))}
)
}
+
+export function AskUserQuestionView(props: ToolViewProps) {
+ const parsed = parseAskUserQuestionInput(props.block.tool.input)
+ const questions = parsed.questions
+ const answers = props.block.tool.permission?.answers ?? undefined
+ const hasAnswers = answers && Object.keys(answers).length > 0
+
+ // When questions array is empty but answers exist (fallback path),
+ // render the answers directly
+ if (questions.length === 0) {
+ if (hasAnswers && answers) {
+ return renderFreeformAnswers(answers, 0)
+ }
+ return null
+ }
+
+ return (
+
+ {questions.map((q, idx) => {
+ const isMulti = q.multiSelect
+
+ return (
+
+ {q.question ? (
+
+ {q.question}
+
+ ) : null}
+
+ {q.options.length > 0 ? (
+
+ {q.options.map((opt, optIdx) => {
+ const isSelected = isAnswerSelected(answers, idx, opt.label)
+ return (
+
+
+ {hasAnswers && (
+
+ {getSelectionMark(isMulti, isSelected)}
+
+ )}
+
+
+ {opt.label}
+
+ {opt.description ? (
+
+ {opt.description}
+
+ ) : null}
+
+
+
+ )
+ })}
+
+ {hasAnswers && renderOtherAnswers(answers, idx, q.options, isMulti)}
+
+ ) : hasAnswers && answers ? (
+ // Freeform question (no options) - show the answer directly
+ renderFreeformAnswers(answers, idx)
+ ) : null}
+
+ )
+ })}
+
+ )
+}
diff --git a/web/src/components/ToolCard/views/_results.tsx b/web/src/components/ToolCard/views/_results.tsx
index adc71011..525b9611 100644
--- a/web/src/components/ToolCard/views/_results.tsx
+++ b/web/src/components/ToolCard/views/_results.tsx
@@ -1,7 +1,6 @@
import type { ToolViewComponent, ToolViewProps } from '@/components/ToolCard/views/_all'
import { CodeBlock } from '@/components/CodeBlock'
import { MarkdownRenderer } from '@/components/MarkdownRenderer'
-import { extractAskUserQuestionQuestionsInfo } from '@/components/ToolCard/askUserQuestion'
import { basename, resolveDisplayPath } from '@/components/ToolCard/path'
function isObject(value: unknown): value is Record
{
@@ -196,55 +195,15 @@ function isProbablyMarkdownList(text: string): boolean {
const AskUserQuestionResultView: ToolViewComponent = (props: ToolViewProps) => {
const answers = props.block.tool.permission?.answers ?? null
- if (!answers || Object.keys(answers).length === 0) {
- return
+
+ // If answers exist, AskUserQuestionView already shows them with highlighting
+ // Return null to avoid duplicate display
+ if (answers && Object.keys(answers).length > 0) {
+ return null
}
- const questions = extractAskUserQuestionQuestionsInfo(props.block.tool.input)
- const keys = Object.keys(answers).sort((a, b) => {
- const aNum = Number.parseInt(a, 10)
- const bNum = Number.parseInt(b, 10)
- if (Number.isFinite(aNum) && Number.isFinite(bNum)) return aNum - bNum
- if (Number.isFinite(aNum)) return -1
- if (Number.isFinite(bNum)) return 1
- return a.localeCompare(b)
- })
-
- return (
-
- {keys.map((key) => {
- const idx = Number.parseInt(key, 10)
- const q = questions && Number.isFinite(idx) ? questions[idx] : null
- const header = q?.header ?? (Number.isFinite(idx) ? `Question ${idx + 1}` : `Question ${key}`)
- const values = answers[key] ?? []
- const cleaned = values.map((v) => String(v)).map((v) => v.trim()).filter((v) => v.length > 0)
-
- return (
-
-
- {header}
-
- {q?.question ? (
-
- {q.question}
-
- ) : null}
- {cleaned.length > 0 ? (
-
- {cleaned.map((v, i) => (
- - {v}
- ))}
-
- ) : (
-
- (no answer)
-
- )}
-
- )
- })}
-
- )
+ // Fallback for tools without structured answers
+ return
}
const BashResultView: ToolViewComponent = (props: ToolViewProps) => {