|
4 | 4 | Message as MessageType, |
5 | 5 | Part as PartType, |
6 | 6 | type PermissionRequest, |
| 7 | + type QuestionRequest, |
7 | 8 | TextPart, |
8 | 9 | ToolPart, |
9 | 10 | } from "@opencode-ai/sdk/v2/client" |
@@ -150,6 +151,8 @@ export function SessionTurn( |
150 | 151 | const emptyAssistant: AssistantMessage[] = [] |
151 | 152 | const emptyPermissions: PermissionRequest[] = [] |
152 | 153 | const emptyPermissionParts: { part: ToolPart; message: AssistantMessage }[] = [] |
| 154 | + const emptyQuestions: QuestionRequest[] = [] |
| 155 | + const emptyQuestionParts: { part: ToolPart; message: AssistantMessage }[] = [] |
153 | 156 | const emptyDiffs: FileDiff[] = [] |
154 | 157 | const idle = { type: "idle" as const } |
155 | 158 |
|
@@ -281,6 +284,51 @@ export function SessionTurn( |
281 | 284 | return emptyPermissionParts |
282 | 285 | }) |
283 | 286 |
|
| 287 | + const questions = createMemo(() => data.store.question?.[props.sessionID] ?? emptyQuestions) |
| 288 | + const nextQuestion = createMemo(() => questions()[0]) |
| 289 | + |
| 290 | + const questionParts = createMemo(() => { |
| 291 | + if (props.stepsExpanded) return emptyQuestionParts |
| 292 | + |
| 293 | + const next = nextQuestion() |
| 294 | + if (!next || !next.tool) return emptyQuestionParts |
| 295 | + |
| 296 | + const message = findLast(assistantMessages(), (m) => m.id === next.tool!.messageID) |
| 297 | + if (!message) return emptyQuestionParts |
| 298 | + |
| 299 | + const parts = data.store.part[message.id] ?? emptyParts |
| 300 | + for (const part of parts) { |
| 301 | + if (part?.type !== "tool") continue |
| 302 | + const tool = part as ToolPart |
| 303 | + if (tool.callID === next.tool?.callID) return [{ part: tool, message }] |
| 304 | + } |
| 305 | + |
| 306 | + return emptyQuestionParts |
| 307 | + }) |
| 308 | + |
| 309 | + const answeredQuestionParts = createMemo(() => { |
| 310 | + if (props.stepsExpanded) return emptyQuestionParts |
| 311 | + if (questions().length > 0) return emptyQuestionParts |
| 312 | + |
| 313 | + const result: { part: ToolPart; message: AssistantMessage }[] = [] |
| 314 | + |
| 315 | + for (const msg of assistantMessages()) { |
| 316 | + const parts = data.store.part[msg.id] ?? emptyParts |
| 317 | + for (const part of parts) { |
| 318 | + if (part?.type !== "tool") continue |
| 319 | + const tool = part as ToolPart |
| 320 | + if (tool.tool !== "question") continue |
| 321 | + // @ts-expect-error metadata may not exist on all tool states |
| 322 | + const answers = tool.state?.metadata?.answers |
| 323 | + if (answers && answers.length > 0) { |
| 324 | + result.push({ part: tool, message: msg }) |
| 325 | + } |
| 326 | + } |
| 327 | + } |
| 328 | + |
| 329 | + return result |
| 330 | + }) |
| 331 | + |
284 | 332 | const shellModePart = createMemo(() => { |
285 | 333 | const p = parts() |
286 | 334 | if (p.length === 0) return |
@@ -640,6 +688,20 @@ export function SessionTurn( |
640 | 688 | </For> |
641 | 689 | </div> |
642 | 690 | </Show> |
| 691 | + <Show when={!props.stepsExpanded && questionParts().length > 0}> |
| 692 | + <div data-slot="session-turn-question-parts"> |
| 693 | + <For each={questionParts()}> |
| 694 | + {({ part, message }) => <Part part={part} message={message} />} |
| 695 | + </For> |
| 696 | + </div> |
| 697 | + </Show> |
| 698 | + <Show when={!props.stepsExpanded && answeredQuestionParts().length > 0}> |
| 699 | + <div data-slot="session-turn-answered-question-parts"> |
| 700 | + <For each={answeredQuestionParts()}> |
| 701 | + {({ part, message }) => <Part part={part} message={message} />} |
| 702 | + </For> |
| 703 | + </div> |
| 704 | + </Show> |
643 | 705 | {/* Response */} |
644 | 706 | <div class="sr-only" aria-live="polite"> |
645 | 707 | {!working() && response() ? response() : ""} |
|
0 commit comments