fix(tui): stabilize websearch labels
This commit is contained in:
parent
7b8d8b8861
commit
1f842fa654
3 changed files with 39 additions and 3 deletions
|
|
@ -37,7 +37,7 @@ import type {
|
||||||
} from "@opencode-ai/sdk/v2"
|
} from "@opencode-ai/sdk/v2"
|
||||||
import { useLocal } from "../../context/local"
|
import { useLocal } from "../../context/local"
|
||||||
import { Locale } from "../../util/locale"
|
import { Locale } from "../../util/locale"
|
||||||
import { webSearchProviderLabel } from "../../util/tool-display"
|
import { selectedWebSearchProvider, webSearchProviderLabel } from "../../util/tool-display"
|
||||||
import { useRenderer, useTerminalDimensions, type JSX } from "@opentui/solid"
|
import { useRenderer, useTerminalDimensions, type JSX } from "@opentui/solid"
|
||||||
import { useSDK } from "../../context/sdk"
|
import { useSDK } from "../../context/sdk"
|
||||||
import { useEditorContext } from "../../context/editor"
|
import { useEditorContext } from "../../context/editor"
|
||||||
|
|
@ -2345,9 +2345,18 @@ function WebFetch(props: ToolProps) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function WebSearch(props: ToolProps) {
|
function WebSearch(props: ToolProps) {
|
||||||
|
const data = useData()
|
||||||
|
const [provider, setProvider] = createSignal(
|
||||||
|
selectedWebSearchProvider(data.location.integration.list() ?? []) ?? stringValue(props.metadata.provider),
|
||||||
|
)
|
||||||
|
createEffect(() => {
|
||||||
|
if (provider()) return
|
||||||
|
const next = selectedWebSearchProvider(data.location.integration.list() ?? [])
|
||||||
|
if (next) setProvider(next)
|
||||||
|
})
|
||||||
return (
|
return (
|
||||||
<InlineTool icon="◈" pending="Searching web..." complete={stringValue(props.input.query)} part={props.part}>
|
<InlineTool icon="◈" pending="Searching web..." complete={stringValue(props.input.query)} part={props.part}>
|
||||||
{webSearchProviderLabel(props.metadata.provider)} "{stringValue(props.input.query)}"{" "}
|
{webSearchProviderLabel(provider())} "{stringValue(props.input.query)}"{" "}
|
||||||
<Show when={numberValue(props.metadata.numResults)}>({numberValue(props.metadata.numResults)} results)</Show>
|
<Show when={numberValue(props.metadata.numResults)}>({numberValue(props.metadata.numResults)} results)</Show>
|
||||||
</InlineTool>
|
</InlineTool>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,17 @@
|
||||||
|
import type { IntegrationInfo } from "@opencode-ai/sdk/v2"
|
||||||
|
|
||||||
export function webSearchProviderLabel(provider: unknown) {
|
export function webSearchProviderLabel(provider: unknown) {
|
||||||
if (provider === "parallel") return "Parallel Web Search"
|
if (provider === "parallel") return "Parallel Web Search"
|
||||||
if (provider === "exa") return "Exa Web Search"
|
if (provider === "exa") return "Exa Web Search"
|
||||||
return "Web Search"
|
return "Web Search"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function selectedWebSearchProvider(integrations: readonly Pick<IntegrationInfo, "id" | "capabilities">[]) {
|
||||||
|
return integrations.find((integration) =>
|
||||||
|
integration.capabilities.some((capability) => capability.type === "search" && capability.selected),
|
||||||
|
)?.id
|
||||||
|
}
|
||||||
|
|
||||||
export function toolDisplayMetadata(state: unknown): Record<string, unknown> {
|
export function toolDisplayMetadata(state: unknown): Record<string, unknown> {
|
||||||
if (!state || typeof state !== "object" || Array.isArray(state)) return {}
|
if (!state || typeof state !== "object" || Array.isArray(state)) return {}
|
||||||
if (!("status" in state) || state.status === "pending") return {}
|
if (!("status" in state) || state.status === "pending") return {}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
import { describe, expect, test } from "bun:test"
|
import { describe, expect, test } from "bun:test"
|
||||||
import { toolDisplayMetadata, webSearchProviderLabel } from "../../src/util/tool-display"
|
import { selectedWebSearchProvider, toolDisplayMetadata, webSearchProviderLabel } from "../../src/util/tool-display"
|
||||||
|
|
||||||
describe("webSearchProviderLabel", () => {
|
describe("webSearchProviderLabel", () => {
|
||||||
test("labels known providers", () => {
|
test("labels known providers", () => {
|
||||||
|
|
@ -21,6 +21,25 @@ describe("webSearchProviderLabel", () => {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
describe("selectedWebSearchProvider", () => {
|
||||||
|
test("returns the selected search integration", () => {
|
||||||
|
expect(
|
||||||
|
selectedWebSearchProvider([
|
||||||
|
{ id: "exa", capabilities: [{ type: "search", connection: "optional", selected: false }] },
|
||||||
|
{ id: "parallel", capabilities: [{ type: "search", connection: "optional", selected: true }] },
|
||||||
|
]),
|
||||||
|
).toBe("parallel")
|
||||||
|
})
|
||||||
|
|
||||||
|
test("ignores unselected and unrelated capabilities", () => {
|
||||||
|
expect(
|
||||||
|
selectedWebSearchProvider([
|
||||||
|
{ id: "exa", capabilities: [{ type: "search", connection: "optional", selected: false }] },
|
||||||
|
]),
|
||||||
|
).toBeUndefined()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
describe("toolDisplayMetadata", () => {
|
describe("toolDisplayMetadata", () => {
|
||||||
test("returns structured metadata for non-pending states", () => {
|
test("returns structured metadata for non-pending states", () => {
|
||||||
const structured = { provider: "parallel", numResults: 3 }
|
const structured = { provider: "parallel", numResults: 3 }
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue