diff options
| author | Filip <[email protected]> | 2026-02-01 01:25:06 +0100 |
|---|---|---|
| committer | GitHub <[email protected]> | 2026-01-31 18:25:06 -0600 |
| commit | e5f677dfb5fc0e7470f1be1c03de42876d4a48c8 (patch) | |
| tree | cbc4ace864799b4a12c8c04cc03ed93f38e53ca8 /packages | |
| parent | 6a96810249e7caa86951bc7ca07c8c9d94a5c63b (diff) | |
| download | opencode-e5f677dfb5fc0e7470f1be1c03de42876d4a48c8.tar.gz opencode-e5f677dfb5fc0e7470f1be1c03de42876d4a48c8.zip | |
fix(app): rendering question tool when the step are collapsed (#11539)
Diffstat (limited to 'packages')
| -rw-r--r-- | packages/ui/src/components/session-turn.css | 16 | ||||
| -rw-r--r-- | packages/ui/src/components/session-turn.tsx | 62 |
2 files changed, 78 insertions, 0 deletions
diff --git a/packages/ui/src/components/session-turn.css b/packages/ui/src/components/session-turn.css index d1ade879e..82b57d13d 100644 --- a/packages/ui/src/components/session-turn.css +++ b/packages/ui/src/components/session-turn.css @@ -569,4 +569,20 @@ flex-direction: column; gap: 12px; } + + [data-slot="session-turn-question-parts"] { + width: 100%; + min-width: 0; + display: flex; + flex-direction: column; + gap: 12px; + } + + [data-slot="session-turn-answered-question-parts"] { + width: 100%; + min-width: 0; + display: flex; + flex-direction: column; + gap: 12px; + } } diff --git a/packages/ui/src/components/session-turn.tsx b/packages/ui/src/components/session-turn.tsx index 3f176db70..f1c62c0af 100644 --- a/packages/ui/src/components/session-turn.tsx +++ b/packages/ui/src/components/session-turn.tsx @@ -4,6 +4,7 @@ import { Message as MessageType, Part as PartType, type PermissionRequest, + type QuestionRequest, TextPart, ToolPart, } from "@opencode-ai/sdk/v2/client" @@ -150,6 +151,8 @@ export function SessionTurn( const emptyAssistant: AssistantMessage[] = [] const emptyPermissions: PermissionRequest[] = [] const emptyPermissionParts: { part: ToolPart; message: AssistantMessage }[] = [] + const emptyQuestions: QuestionRequest[] = [] + const emptyQuestionParts: { part: ToolPart; message: AssistantMessage }[] = [] const emptyDiffs: FileDiff[] = [] const idle = { type: "idle" as const } @@ -281,6 +284,51 @@ export function SessionTurn( return emptyPermissionParts }) + const questions = createMemo(() => data.store.question?.[props.sessionID] ?? emptyQuestions) + const nextQuestion = createMemo(() => questions()[0]) + + const questionParts = createMemo(() => { + if (props.stepsExpanded) return emptyQuestionParts + + const next = nextQuestion() + if (!next || !next.tool) return emptyQuestionParts + + const message = findLast(assistantMessages(), (m) => m.id === next.tool!.messageID) + if (!message) return emptyQuestionParts + + const parts = data.store.part[message.id] ?? emptyParts + for (const part of parts) { + if (part?.type !== "tool") continue + const tool = part as ToolPart + if (tool.callID === next.tool?.callID) return [{ part: tool, message }] + } + + return emptyQuestionParts + }) + + const answeredQuestionParts = createMemo(() => { + if (props.stepsExpanded) return emptyQuestionParts + if (questions().length > 0) return emptyQuestionParts + + const result: { part: ToolPart; message: AssistantMessage }[] = [] + + for (const msg of assistantMessages()) { + const parts = data.store.part[msg.id] ?? emptyParts + for (const part of parts) { + if (part?.type !== "tool") continue + const tool = part as ToolPart + if (tool.tool !== "question") continue + // @ts-expect-error metadata may not exist on all tool states + const answers = tool.state?.metadata?.answers + if (answers && answers.length > 0) { + result.push({ part: tool, message: msg }) + } + } + } + + return result + }) + const shellModePart = createMemo(() => { const p = parts() if (p.length === 0) return @@ -640,6 +688,20 @@ export function SessionTurn( </For> </div> </Show> + <Show when={!props.stepsExpanded && questionParts().length > 0}> + <div data-slot="session-turn-question-parts"> + <For each={questionParts()}> + {({ part, message }) => <Part part={part} message={message} />} + </For> + </div> + </Show> + <Show when={!props.stepsExpanded && answeredQuestionParts().length > 0}> + <div data-slot="session-turn-answered-question-parts"> + <For each={answeredQuestionParts()}> + {({ part, message }) => <Part part={part} message={message} />} + </For> + </div> + </Show> {/* Response */} <div class="sr-only" aria-live="polite"> {!working() && response() ? response() : ""} |
