feat(websearch): add parallel provider rollout (#26227)

This commit is contained in:
Shoubhit Dash
2026-05-08 14:19:36 +05:30
committed by GitHub
parent ae25278eda
commit a43d3e0e1e
13 changed files with 276 additions and 44 deletions

View File

@@ -9,6 +9,7 @@ import { TextAttributes, type BoxRenderable, type SyntaxStyle } from "@opentui/c
import { useBindings } from "../../keymap"
import { Locale } from "@/util/locale"
import { LANGUAGE_EXTENSIONS } from "@/lsp/language"
import { webSearchProviderLabel } from "@/tool/websearch"
import path from "path"
import stripAnsi from "strip-ansi"
import type {
@@ -89,6 +90,7 @@ function View(props: { api: TuiPluginApi; sessionID: string }) {
<Match when={message.type === "assistant"}>
<AssistantMessage
message={message as SessionMessageAssistant}
sessionID={props.sessionID}
last={lastAssistant()?.id === message.id}
syntax={syntax()}
subtleSyntax={subtleSyntax()}
@@ -286,6 +288,7 @@ function UnknownMessage(props: { message: SessionMessage }) {
function AssistantMessage(props: {
message: SessionMessageAssistant
sessionID: string
last: boolean
syntax: SyntaxStyle
subtleSyntax: SyntaxStyle
@@ -314,7 +317,7 @@ function AssistantMessage(props: {
<AssistantReasoning part={part as SessionMessageAssistantReasoning} subtleSyntax={props.subtleSyntax} />
</Match>
<Match when={part.type === "tool"}>
<AssistantTool part={part as SessionMessageAssistantTool} />
<AssistantTool part={part as SessionMessageAssistantTool} sessionID={props.sessionID} />
</Match>
</Switch>
)}
@@ -400,7 +403,7 @@ function AssistantReasoning(props: { part: SessionMessageAssistantReasoning; sub
)
}
function AssistantTool(props: { part: SessionMessageAssistantTool }) {
function AssistantTool(props: { part: SessionMessageAssistantTool; sessionID: string }) {
const input = createMemo(() => toolInputRecord(props.part.state.input))
const toolprops = {
get input() {
@@ -412,6 +415,7 @@ function AssistantTool(props: { part: SessionMessageAssistantTool }) {
get output() {
return props.part.state.status === "pending" ? undefined : toolOutput(props.part.state.content)
},
sessionID: props.sessionID,
part: props.part,
}
return (
@@ -469,6 +473,7 @@ type ToolProps = {
input: Record<string, unknown>
metadata: Record<string, unknown>
output?: string
sessionID: string
part: SessionMessageAssistantTool
}
@@ -775,9 +780,10 @@ function CodeSearch(props: ToolProps) {
}
function WebSearch(props: ToolProps) {
const label = createMemo(() => webSearchProviderLabel(props.metadata.provider))
return (
<InlineTool icon="◈" pending="Searching web..." complete={toolComplete(props.part)} part={props.part}>
Exa Web Search "{stringValue(props.input.query) ?? pendingInput(props.part)}"{" "}
{label()} "{stringValue(props.input.query) ?? pendingInput(props.part)}"{" "}
<Show when={numberValue(props.metadata.numResults)}>{(results) => <>({results()} results)</>}</Show>
</InlineTool>
)

View File

@@ -45,7 +45,7 @@ import type { GrepTool } from "@/tool/grep"
import type { EditTool } from "@/tool/edit"
import type { ApplyPatchTool } from "@/tool/apply_patch"
import type { WebFetchTool } from "@/tool/webfetch"
import type { WebSearchTool } from "@/tool/websearch"
import { webSearchProviderLabel, type WebSearchTool } from "@/tool/websearch"
import type { TaskTool } from "@/tool/task"
import type { QuestionTool } from "@/tool/question"
import type { SkillTool } from "@/tool/skill"
@@ -1933,10 +1933,11 @@ function WebFetch(props: ToolProps<typeof WebFetchTool>) {
}
function WebSearch(props: ToolProps<typeof WebSearchTool>) {
const metadata = props.metadata as { numResults?: number }
const metadata = props.metadata as { numResults?: number; provider?: unknown }
return (
<InlineTool icon="◈" pending="Searching web..." complete={props.input.query} part={props.part}>
Exa Web Search "{props.input.query}" <Show when={metadata.numResults}>({metadata.numResults} results)</Show>
{webSearchProviderLabel(metadata.provider)} "{props.input.query}"{" "}
<Show when={metadata.numResults}>({metadata.numResults} results)</Show>
</InlineTool>
)
}

View File

@@ -13,6 +13,7 @@ import { LANGUAGE_EXTENSIONS } from "@/lsp/language"
import { Locale } from "@/util/locale"
import { Global } from "@opencode-ai/core/global"
import { ShellID } from "@/tool/shell/id"
import { webSearchProviderLabel } from "@/tool/websearch"
import { useDialog } from "../../ui/dialog"
import { getScrollAcceleration } from "../../util/scroll"
import { useTuiConfig } from "../../context/tui-config"
@@ -338,7 +339,7 @@ export function PermissionPrompt(props: { request: PermissionRequest }) {
const query = typeof data.query === "string" ? data.query : ""
return {
icon: "◈",
title: `Exa Web Search "${query}"`,
title: `${webSearchProviderLabel(data.provider)} "${query}"`,
body: (
<Show when={query}>
<box paddingLeft={1}>