diff --git a/packages/tui/src/routes/session/index.tsx b/packages/tui/src/routes/session/index.tsx
index d1ea5e1272..5ce997182c 100644
--- a/packages/tui/src/routes/session/index.tsx
+++ b/packages/tui/src/routes/session/index.tsx
@@ -37,7 +37,7 @@ import type {
} from "@opencode-ai/sdk/v2"
import { useLocal } from "../../context/local"
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 { useSDK } from "../../context/sdk"
import { useEditorContext } from "../../context/editor"
@@ -2345,9 +2345,18 @@ function WebFetch(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 (
- {webSearchProviderLabel(props.metadata.provider)} "{stringValue(props.input.query)}"{" "}
+ {webSearchProviderLabel(provider())} "{stringValue(props.input.query)}"{" "}
({numberValue(props.metadata.numResults)} results)
)
diff --git a/packages/tui/src/util/tool-display.ts b/packages/tui/src/util/tool-display.ts
index 18e256bd34..c8c5fca873 100644
--- a/packages/tui/src/util/tool-display.ts
+++ b/packages/tui/src/util/tool-display.ts
@@ -1,9 +1,17 @@
+import type { IntegrationInfo } from "@opencode-ai/sdk/v2"
+
export function webSearchProviderLabel(provider: unknown) {
if (provider === "parallel") return "Parallel Web Search"
if (provider === "exa") return "Exa Web Search"
return "Web Search"
}
+export function selectedWebSearchProvider(integrations: readonly Pick[]) {
+ return integrations.find((integration) =>
+ integration.capabilities.some((capability) => capability.type === "search" && capability.selected),
+ )?.id
+}
+
export function toolDisplayMetadata(state: unknown): Record {
if (!state || typeof state !== "object" || Array.isArray(state)) return {}
if (!("status" in state) || state.status === "pending") return {}
diff --git a/packages/tui/test/util/tool-display.test.ts b/packages/tui/test/util/tool-display.test.ts
index f77f54cbab..0ee2fd3b2a 100644
--- a/packages/tui/test/util/tool-display.test.ts
+++ b/packages/tui/test/util/tool-display.test.ts
@@ -1,5 +1,5 @@
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", () => {
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", () => {
test("returns structured metadata for non-pending states", () => {
const structured = { provider: "parallel", numResults: 3 }