Compare commits
2 Commits
v0.9.2
...
fix/questi
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
abe96a7a8b | ||
|
|
01921e3454 |
@@ -1,4 +1,4 @@
|
|||||||
import { createMemo, Show, For, type Accessor } from "solid-js"
|
import { createMemo, Show, For, createEffect, type Accessor } from "solid-js"
|
||||||
import type { ToolState } from "@opencode-ai/sdk"
|
import type { ToolState } from "@opencode-ai/sdk"
|
||||||
import type { QuestionRequest } from "@opencode-ai/sdk/v2"
|
import type { QuestionRequest } from "@opencode-ai/sdk/v2"
|
||||||
import { useI18n } from "../../lib/i18n"
|
import { useI18n } from "../../lib/i18n"
|
||||||
@@ -28,6 +28,13 @@ export type QuestionToolBlockProps = {
|
|||||||
|
|
||||||
export function QuestionToolBlock(props: QuestionToolBlockProps) {
|
export function QuestionToolBlock(props: QuestionToolBlockProps) {
|
||||||
const { t } = useI18n()
|
const { t } = useI18n()
|
||||||
|
let firstInputRef: HTMLInputElement | undefined
|
||||||
|
|
||||||
|
createEffect(() => {
|
||||||
|
if (props.active() && firstInputRef) {
|
||||||
|
firstInputRef.focus()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
const requestId = createMemo(() => {
|
const requestId = createMemo(() => {
|
||||||
const state = props.toolState()
|
const state = props.toolState()
|
||||||
@@ -105,7 +112,6 @@ export function QuestionToolBlock(props: QuestionToolBlockProps) {
|
|||||||
if (!props.active()) return
|
if (!props.active()) return
|
||||||
const rawValue = input?.value ?? ""
|
const rawValue = input?.value ?? ""
|
||||||
const value = rawValue
|
const value = rawValue
|
||||||
if (value.trim().length === 0) return
|
|
||||||
|
|
||||||
const info = questions()[questionIndex]
|
const info = questions()[questionIndex]
|
||||||
const multi = info?.multiple === true
|
const multi = info?.multiple === true
|
||||||
@@ -114,6 +120,19 @@ export function QuestionToolBlock(props: QuestionToolBlockProps) {
|
|||||||
updateAnswer(questionIndex, [])
|
updateAnswer(questionIndex, [])
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the custom field is empty, treat it as unanswered.
|
||||||
|
// This prevents submitting a previously selected option when the user
|
||||||
|
// has explicitly switched focus to the custom input.
|
||||||
|
if (value.trim().length === 0) return
|
||||||
|
|
||||||
|
if (multi) {
|
||||||
|
const existing = answers()[questionIndex] ?? []
|
||||||
|
if (!existing.includes(value)) {
|
||||||
|
updateAnswer(questionIndex, [...existing, value])
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
toggleOption(questionIndex, value)
|
toggleOption(questionIndex, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -206,7 +225,7 @@ export function QuestionToolBlock(props: QuestionToolBlockProps) {
|
|||||||
|
|
||||||
<div class="mt-3 flex flex-col gap-1">
|
<div class="mt-3 flex flex-col gap-1">
|
||||||
<For each={q?.options ?? []}>
|
<For each={q?.options ?? []}>
|
||||||
{(opt) => {
|
{(opt, optIndex) => {
|
||||||
const checked = () => selected().includes(opt.label)
|
const checked = () => selected().includes(opt.label)
|
||||||
return (
|
return (
|
||||||
<label
|
<label
|
||||||
@@ -214,6 +233,9 @@ export function QuestionToolBlock(props: QuestionToolBlockProps) {
|
|||||||
title={opt.description}
|
title={opt.description}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
|
ref={(el) => {
|
||||||
|
if (i() === 0 && optIndex() === 0) firstInputRef = el
|
||||||
|
}}
|
||||||
type={inputType()}
|
type={inputType()}
|
||||||
name={groupName()}
|
name={groupName()}
|
||||||
checked={checked()}
|
checked={checked()}
|
||||||
@@ -234,6 +256,9 @@ export function QuestionToolBlock(props: QuestionToolBlockProps) {
|
|||||||
title={t("toolCall.question.custom.title")}
|
title={t("toolCall.question.custom.title")}
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
|
ref={(el) => {
|
||||||
|
if (i() === 0 && (q?.options?.length ?? 0) === 0) firstInputRef = el
|
||||||
|
}}
|
||||||
type={inputType()}
|
type={inputType()}
|
||||||
name={groupName()}
|
name={groupName()}
|
||||||
checked={customChecked()}
|
checked={customChecked()}
|
||||||
@@ -266,6 +291,16 @@ export function QuestionToolBlock(props: QuestionToolBlockProps) {
|
|||||||
toggleFromCustomInput(i(), e.currentTarget)
|
toggleFromCustomInput(i(), e.currentTarget)
|
||||||
}}
|
}}
|
||||||
onInput={(e) => handleCustomTyping(i(), e.currentTarget)}
|
onInput={(e) => handleCustomTyping(i(), e.currentTarget)}
|
||||||
|
onKeyDown={(e) => {
|
||||||
|
if (e.key === "Enter" && !e.isComposing) {
|
||||||
|
// Don't submit if the custom field is empty (common when switching to it).
|
||||||
|
if (e.currentTarget.value.trim().length === 0) return
|
||||||
|
e.preventDefault()
|
||||||
|
if (!submitDisabled()) {
|
||||||
|
props.onSubmit()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
|
|||||||
Reference in New Issue
Block a user