summaryrefslogtreecommitdiffhomepage
path: root/packages
diff options
context:
space:
mode:
authorFilip <[email protected]>2026-02-01 01:25:06 +0100
committerGitHub <[email protected]>2026-01-31 18:25:06 -0600
commite5f677dfb5fc0e7470f1be1c03de42876d4a48c8 (patch)
treecbc4ace864799b4a12c8c04cc03ed93f38e53ca8 /packages
parent6a96810249e7caa86951bc7ca07c8c9d94a5c63b (diff)
downloadopencode-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.css16
-rw-r--r--packages/ui/src/components/session-turn.tsx62
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() : ""}