fix(app): websearch and codesearch tool rendering
This commit is contained in:
@@ -203,6 +203,41 @@ export function BasicTool(props: BasicToolProps) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export function GenericTool(props: { tool: string; status?: string; hideDetails?: boolean }) {
|
function label(input: Record<string, unknown> | undefined) {
|
||||||
return <BasicTool icon="mcp" status={props.status} trigger={{ title: props.tool }} hideDetails={props.hideDetails} />
|
const keys = ["description", "query", "url", "filePath", "path", "pattern", "name"]
|
||||||
|
return keys.map((key) => input?.[key]).find((value): value is string => typeof value === "string" && value.length > 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
function args(input: Record<string, unknown> | undefined) {
|
||||||
|
if (!input) return []
|
||||||
|
const skip = new Set(["description", "query", "url", "filePath", "path", "pattern", "name"])
|
||||||
|
return Object.entries(input)
|
||||||
|
.filter(([key]) => !skip.has(key))
|
||||||
|
.flatMap(([key, value]) => {
|
||||||
|
if (typeof value === "string") return [`${key}=${value}`]
|
||||||
|
if (typeof value === "number") return [`${key}=${value}`]
|
||||||
|
if (typeof value === "boolean") return [`${key}=${value}`]
|
||||||
|
return []
|
||||||
|
})
|
||||||
|
.slice(0, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
export function GenericTool(props: {
|
||||||
|
tool: string
|
||||||
|
status?: string
|
||||||
|
hideDetails?: boolean
|
||||||
|
input?: Record<string, unknown>
|
||||||
|
}) {
|
||||||
|
return (
|
||||||
|
<BasicTool
|
||||||
|
icon="mcp"
|
||||||
|
status={props.status}
|
||||||
|
trigger={{
|
||||||
|
title: `Called \`${props.tool}\``,
|
||||||
|
subtitle: label(props.input),
|
||||||
|
args: args(props.input),
|
||||||
|
}}
|
||||||
|
hideDetails={props.hideDetails}
|
||||||
|
/>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -577,6 +577,46 @@
|
|||||||
justify-content: center;
|
justify-content: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[data-component="exa-tool-output"] {
|
||||||
|
width: 100%;
|
||||||
|
padding-top: 8px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-slot="basic-tool-tool-subtitle"].exa-tool-query {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-slot="exa-tool-links"] {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
gap: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
|
[data-slot="exa-tool-link"] {
|
||||||
|
display: block;
|
||||||
|
max-width: 100%;
|
||||||
|
color: var(--text-interactive-base);
|
||||||
|
text-decoration: underline;
|
||||||
|
text-underline-offset: 2px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
white-space: nowrap;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: var(--text-interactive-base);
|
||||||
|
}
|
||||||
|
|
||||||
|
&:visited {
|
||||||
|
color: var(--text-interactive-base);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[data-component="todos"] {
|
[data-component="todos"] {
|
||||||
padding: 10px 0 24px 0;
|
padding: 10px 0 24px 0;
|
||||||
display: flex;
|
display: flex;
|
||||||
|
|||||||
@@ -243,6 +243,18 @@ export function getToolInfo(tool: string, input: any = {}): ToolInfo {
|
|||||||
title: i18n.t("ui.tool.webfetch"),
|
title: i18n.t("ui.tool.webfetch"),
|
||||||
subtitle: input.url,
|
subtitle: input.url,
|
||||||
}
|
}
|
||||||
|
case "websearch":
|
||||||
|
return {
|
||||||
|
icon: "window-cursor",
|
||||||
|
title: i18n.t("ui.tool.websearch"),
|
||||||
|
subtitle: input.query,
|
||||||
|
}
|
||||||
|
case "codesearch":
|
||||||
|
return {
|
||||||
|
icon: "code",
|
||||||
|
title: i18n.t("ui.tool.codesearch"),
|
||||||
|
subtitle: input.query,
|
||||||
|
}
|
||||||
case "task":
|
case "task":
|
||||||
return {
|
return {
|
||||||
icon: "task",
|
icon: "task",
|
||||||
@@ -303,6 +315,18 @@ export function getToolInfo(tool: string, input: any = {}): ToolInfo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function urls(text: string | undefined) {
|
||||||
|
if (!text) return []
|
||||||
|
const seen = new Set<string>()
|
||||||
|
return [...text.matchAll(/https?:\/\/[^\s<>"'`)\]]+/g)]
|
||||||
|
.map((item) => item[0].replace(/[),.;:!?]+$/g, ""))
|
||||||
|
.filter((item) => {
|
||||||
|
if (seen.has(item)) return false
|
||||||
|
seen.add(item)
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
const CONTEXT_GROUP_TOOLS = new Set(["read", "glob", "grep", "list"])
|
const CONTEXT_GROUP_TOOLS = new Set(["read", "glob", "grep", "list"])
|
||||||
const HIDDEN_TOOLS = new Set(["todowrite", "todoread"])
|
const HIDDEN_TOOLS = new Set(["todowrite", "todoread"])
|
||||||
|
|
||||||
@@ -598,6 +622,32 @@ function contextToolSummary(parts: ToolPart[]) {
|
|||||||
return { read, search, list }
|
return { read, search, list }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function ExaOutput(props: { output?: string }) {
|
||||||
|
const links = createMemo(() => urls(props.output))
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Show when={links().length > 0}>
|
||||||
|
<div data-component="exa-tool-output">
|
||||||
|
<div data-slot="exa-tool-links">
|
||||||
|
<For each={links()}>
|
||||||
|
{(url) => (
|
||||||
|
<a
|
||||||
|
data-slot="exa-tool-link"
|
||||||
|
href={url}
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
onClick={(event) => event.stopPropagation()}
|
||||||
|
>
|
||||||
|
{url}
|
||||||
|
</a>
|
||||||
|
)}
|
||||||
|
</For>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</Show>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
export function registerPartComponent(type: string, component: PartComponent) {
|
export function registerPartComponent(type: string, component: PartComponent) {
|
||||||
PART_MAPPING[type] = component
|
PART_MAPPING[type] = component
|
||||||
}
|
}
|
||||||
@@ -1467,6 +1517,58 @@ ToolRegistry.register({
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
ToolRegistry.register({
|
||||||
|
name: "websearch",
|
||||||
|
render(props) {
|
||||||
|
const i18n = useI18n()
|
||||||
|
const query = createMemo(() => {
|
||||||
|
const value = props.input.query
|
||||||
|
if (typeof value !== "string") return ""
|
||||||
|
return value
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BasicTool
|
||||||
|
{...props}
|
||||||
|
icon="window-cursor"
|
||||||
|
trigger={{
|
||||||
|
title: i18n.t("ui.tool.websearch"),
|
||||||
|
subtitle: query(),
|
||||||
|
subtitleClass: "exa-tool-query",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ExaOutput output={props.output} />
|
||||||
|
</BasicTool>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
ToolRegistry.register({
|
||||||
|
name: "codesearch",
|
||||||
|
render(props) {
|
||||||
|
const i18n = useI18n()
|
||||||
|
const query = createMemo(() => {
|
||||||
|
const value = props.input.query
|
||||||
|
if (typeof value !== "string") return ""
|
||||||
|
return value
|
||||||
|
})
|
||||||
|
|
||||||
|
return (
|
||||||
|
<BasicTool
|
||||||
|
{...props}
|
||||||
|
icon="code"
|
||||||
|
trigger={{
|
||||||
|
title: i18n.t("ui.tool.codesearch"),
|
||||||
|
subtitle: query(),
|
||||||
|
subtitleClass: "exa-tool-query",
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<ExaOutput output={props.output} />
|
||||||
|
</BasicTool>
|
||||||
|
)
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
ToolRegistry.register({
|
ToolRegistry.register({
|
||||||
name: "task",
|
name: "task",
|
||||||
render(props) {
|
render(props) {
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ export const dict = {
|
|||||||
"ui.tool.glob": "Glob",
|
"ui.tool.glob": "Glob",
|
||||||
"ui.tool.grep": "Grep",
|
"ui.tool.grep": "Grep",
|
||||||
"ui.tool.webfetch": "جلب الويب",
|
"ui.tool.webfetch": "جلب الويب",
|
||||||
|
"ui.tool.websearch": "بحث الويب",
|
||||||
|
"ui.tool.codesearch": "بحث الكود",
|
||||||
"ui.tool.shell": "Shell",
|
"ui.tool.shell": "Shell",
|
||||||
"ui.tool.patch": "تصحيح",
|
"ui.tool.patch": "تصحيح",
|
||||||
"ui.tool.todos": "المهام",
|
"ui.tool.todos": "المهام",
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ export const dict = {
|
|||||||
"ui.tool.glob": "Glob",
|
"ui.tool.glob": "Glob",
|
||||||
"ui.tool.grep": "Grep",
|
"ui.tool.grep": "Grep",
|
||||||
"ui.tool.webfetch": "Buscar Web",
|
"ui.tool.webfetch": "Buscar Web",
|
||||||
|
"ui.tool.websearch": "Pesquisa na Web",
|
||||||
|
"ui.tool.codesearch": "Pesquisa de Código",
|
||||||
"ui.tool.shell": "Shell",
|
"ui.tool.shell": "Shell",
|
||||||
"ui.tool.patch": "Patch",
|
"ui.tool.patch": "Patch",
|
||||||
"ui.tool.todos": "Tarefas",
|
"ui.tool.todos": "Tarefas",
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ export const dict = {
|
|||||||
"ui.tool.glob": "Glob",
|
"ui.tool.glob": "Glob",
|
||||||
"ui.tool.grep": "Grep",
|
"ui.tool.grep": "Grep",
|
||||||
"ui.tool.webfetch": "Web preuzimanje",
|
"ui.tool.webfetch": "Web preuzimanje",
|
||||||
|
"ui.tool.websearch": "Pretraga weba",
|
||||||
|
"ui.tool.codesearch": "Pretraga koda",
|
||||||
"ui.tool.shell": "Shell",
|
"ui.tool.shell": "Shell",
|
||||||
"ui.tool.patch": "Patch",
|
"ui.tool.patch": "Patch",
|
||||||
"ui.tool.todos": "Lista zadataka",
|
"ui.tool.todos": "Lista zadataka",
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ export const dict = {
|
|||||||
"ui.tool.glob": "Glob",
|
"ui.tool.glob": "Glob",
|
||||||
"ui.tool.grep": "Grep",
|
"ui.tool.grep": "Grep",
|
||||||
"ui.tool.webfetch": "Webhentning",
|
"ui.tool.webfetch": "Webhentning",
|
||||||
|
"ui.tool.websearch": "Websøgning",
|
||||||
|
"ui.tool.codesearch": "Kodesøgning",
|
||||||
"ui.tool.shell": "Shell",
|
"ui.tool.shell": "Shell",
|
||||||
"ui.tool.patch": "Patch",
|
"ui.tool.patch": "Patch",
|
||||||
"ui.tool.todos": "Opgaver",
|
"ui.tool.todos": "Opgaver",
|
||||||
|
|||||||
@@ -99,6 +99,8 @@ export const dict = {
|
|||||||
"ui.tool.glob": "Glob",
|
"ui.tool.glob": "Glob",
|
||||||
"ui.tool.grep": "Grep",
|
"ui.tool.grep": "Grep",
|
||||||
"ui.tool.webfetch": "Webabruf",
|
"ui.tool.webfetch": "Webabruf",
|
||||||
|
"ui.tool.websearch": "Websuche",
|
||||||
|
"ui.tool.codesearch": "Codesuche",
|
||||||
"ui.tool.shell": "Shell",
|
"ui.tool.shell": "Shell",
|
||||||
"ui.tool.patch": "Patch",
|
"ui.tool.patch": "Patch",
|
||||||
"ui.tool.todos": "Aufgaben",
|
"ui.tool.todos": "Aufgaben",
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ export const dict: Record<string, string> = {
|
|||||||
"ui.tool.glob": "Glob",
|
"ui.tool.glob": "Glob",
|
||||||
"ui.tool.grep": "Grep",
|
"ui.tool.grep": "Grep",
|
||||||
"ui.tool.webfetch": "Webfetch",
|
"ui.tool.webfetch": "Webfetch",
|
||||||
|
"ui.tool.websearch": "Web Search",
|
||||||
|
"ui.tool.codesearch": "Code Search",
|
||||||
"ui.tool.shell": "Shell",
|
"ui.tool.shell": "Shell",
|
||||||
"ui.tool.patch": "Patch",
|
"ui.tool.patch": "Patch",
|
||||||
"ui.tool.todos": "To-dos",
|
"ui.tool.todos": "To-dos",
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ export const dict = {
|
|||||||
"ui.tool.glob": "Glob",
|
"ui.tool.glob": "Glob",
|
||||||
"ui.tool.grep": "Grep",
|
"ui.tool.grep": "Grep",
|
||||||
"ui.tool.webfetch": "Webfetch",
|
"ui.tool.webfetch": "Webfetch",
|
||||||
|
"ui.tool.websearch": "Búsqueda web",
|
||||||
|
"ui.tool.codesearch": "Búsqueda de código",
|
||||||
"ui.tool.shell": "Shell",
|
"ui.tool.shell": "Shell",
|
||||||
"ui.tool.patch": "Parche",
|
"ui.tool.patch": "Parche",
|
||||||
"ui.tool.todos": "Tareas",
|
"ui.tool.todos": "Tareas",
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ export const dict = {
|
|||||||
"ui.tool.glob": "Glob",
|
"ui.tool.glob": "Glob",
|
||||||
"ui.tool.grep": "Grep",
|
"ui.tool.grep": "Grep",
|
||||||
"ui.tool.webfetch": "Webfetch",
|
"ui.tool.webfetch": "Webfetch",
|
||||||
|
"ui.tool.websearch": "Recherche Web",
|
||||||
|
"ui.tool.codesearch": "Recherche de code",
|
||||||
"ui.tool.shell": "Shell",
|
"ui.tool.shell": "Shell",
|
||||||
"ui.tool.patch": "Patch",
|
"ui.tool.patch": "Patch",
|
||||||
"ui.tool.todos": "Tâches",
|
"ui.tool.todos": "Tâches",
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ export const dict = {
|
|||||||
"ui.tool.glob": "Glob",
|
"ui.tool.glob": "Glob",
|
||||||
"ui.tool.grep": "Grep",
|
"ui.tool.grep": "Grep",
|
||||||
"ui.tool.webfetch": "Webfetch",
|
"ui.tool.webfetch": "Webfetch",
|
||||||
|
"ui.tool.websearch": "Web検索",
|
||||||
|
"ui.tool.codesearch": "コード検索",
|
||||||
"ui.tool.shell": "Shell",
|
"ui.tool.shell": "Shell",
|
||||||
"ui.tool.patch": "Patch",
|
"ui.tool.patch": "Patch",
|
||||||
"ui.tool.todos": "Todo",
|
"ui.tool.todos": "Todo",
|
||||||
|
|||||||
@@ -94,6 +94,8 @@ export const dict = {
|
|||||||
"ui.tool.glob": "Glob",
|
"ui.tool.glob": "Glob",
|
||||||
"ui.tool.grep": "Grep",
|
"ui.tool.grep": "Grep",
|
||||||
"ui.tool.webfetch": "웹 가져오기",
|
"ui.tool.webfetch": "웹 가져오기",
|
||||||
|
"ui.tool.websearch": "웹 검색",
|
||||||
|
"ui.tool.codesearch": "코드 검색",
|
||||||
"ui.tool.shell": "셸",
|
"ui.tool.shell": "셸",
|
||||||
"ui.tool.patch": "패치",
|
"ui.tool.patch": "패치",
|
||||||
"ui.tool.todos": "할 일",
|
"ui.tool.todos": "할 일",
|
||||||
|
|||||||
@@ -97,6 +97,8 @@ export const dict: Record<Keys, string> = {
|
|||||||
"ui.tool.glob": "Glob",
|
"ui.tool.glob": "Glob",
|
||||||
"ui.tool.grep": "Grep",
|
"ui.tool.grep": "Grep",
|
||||||
"ui.tool.webfetch": "Webhenting",
|
"ui.tool.webfetch": "Webhenting",
|
||||||
|
"ui.tool.websearch": "Nettsøk",
|
||||||
|
"ui.tool.codesearch": "Kodesøk",
|
||||||
"ui.tool.shell": "Shell",
|
"ui.tool.shell": "Shell",
|
||||||
"ui.tool.patch": "Patch",
|
"ui.tool.patch": "Patch",
|
||||||
"ui.tool.todos": "Gjøremål",
|
"ui.tool.todos": "Gjøremål",
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ export const dict = {
|
|||||||
"ui.tool.glob": "Glob",
|
"ui.tool.glob": "Glob",
|
||||||
"ui.tool.grep": "Grep",
|
"ui.tool.grep": "Grep",
|
||||||
"ui.tool.webfetch": "Pobieranie sieciowe",
|
"ui.tool.webfetch": "Pobieranie sieciowe",
|
||||||
|
"ui.tool.websearch": "Wyszukiwanie w sieci",
|
||||||
|
"ui.tool.codesearch": "Wyszukiwanie kodu",
|
||||||
"ui.tool.shell": "Terminal",
|
"ui.tool.shell": "Terminal",
|
||||||
"ui.tool.patch": "Patch",
|
"ui.tool.patch": "Patch",
|
||||||
"ui.tool.todos": "Zadania",
|
"ui.tool.todos": "Zadania",
|
||||||
|
|||||||
@@ -93,6 +93,8 @@ export const dict = {
|
|||||||
"ui.tool.glob": "Glob",
|
"ui.tool.glob": "Glob",
|
||||||
"ui.tool.grep": "Grep",
|
"ui.tool.grep": "Grep",
|
||||||
"ui.tool.webfetch": "Webfetch",
|
"ui.tool.webfetch": "Webfetch",
|
||||||
|
"ui.tool.websearch": "Веб-поиск",
|
||||||
|
"ui.tool.codesearch": "Поиск кода",
|
||||||
"ui.tool.shell": "Оболочка",
|
"ui.tool.shell": "Оболочка",
|
||||||
"ui.tool.patch": "Патч",
|
"ui.tool.patch": "Патч",
|
||||||
"ui.tool.todos": "Задачи",
|
"ui.tool.todos": "Задачи",
|
||||||
|
|||||||
@@ -95,6 +95,8 @@ export const dict = {
|
|||||||
"ui.tool.glob": "Glob",
|
"ui.tool.glob": "Glob",
|
||||||
"ui.tool.grep": "Grep",
|
"ui.tool.grep": "Grep",
|
||||||
"ui.tool.webfetch": "ดึงจากเว็บ",
|
"ui.tool.webfetch": "ดึงจากเว็บ",
|
||||||
|
"ui.tool.websearch": "ค้นหาเว็บ",
|
||||||
|
"ui.tool.codesearch": "ค้นหาโค้ด",
|
||||||
"ui.tool.shell": "เชลล์",
|
"ui.tool.shell": "เชลล์",
|
||||||
"ui.tool.patch": "แพตช์",
|
"ui.tool.patch": "แพตช์",
|
||||||
"ui.tool.todos": "รายการงาน",
|
"ui.tool.todos": "รายการงาน",
|
||||||
|
|||||||
@@ -90,6 +90,8 @@ export const dict = {
|
|||||||
"ui.tool.glob": "Glob",
|
"ui.tool.glob": "Glob",
|
||||||
"ui.tool.grep": "Grep",
|
"ui.tool.grep": "Grep",
|
||||||
"ui.tool.webfetch": "Web getir",
|
"ui.tool.webfetch": "Web getir",
|
||||||
|
"ui.tool.websearch": "Web Araması",
|
||||||
|
"ui.tool.codesearch": "Kod Araması",
|
||||||
"ui.tool.shell": "Kabuk",
|
"ui.tool.shell": "Kabuk",
|
||||||
"ui.tool.patch": "Yama",
|
"ui.tool.patch": "Yama",
|
||||||
"ui.tool.todos": "Görevler",
|
"ui.tool.todos": "Görevler",
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ export const dict = {
|
|||||||
"ui.tool.glob": "Glob",
|
"ui.tool.glob": "Glob",
|
||||||
"ui.tool.grep": "Grep",
|
"ui.tool.grep": "Grep",
|
||||||
"ui.tool.webfetch": "Webfetch",
|
"ui.tool.webfetch": "Webfetch",
|
||||||
|
"ui.tool.websearch": "网络搜索",
|
||||||
|
"ui.tool.codesearch": "代码搜索",
|
||||||
"ui.tool.shell": "Shell",
|
"ui.tool.shell": "Shell",
|
||||||
"ui.tool.patch": "补丁",
|
"ui.tool.patch": "补丁",
|
||||||
"ui.tool.todos": "待办",
|
"ui.tool.todos": "待办",
|
||||||
|
|||||||
@@ -98,6 +98,8 @@ export const dict = {
|
|||||||
"ui.tool.glob": "Glob",
|
"ui.tool.glob": "Glob",
|
||||||
"ui.tool.grep": "Grep",
|
"ui.tool.grep": "Grep",
|
||||||
"ui.tool.webfetch": "Webfetch",
|
"ui.tool.webfetch": "Webfetch",
|
||||||
|
"ui.tool.websearch": "網頁搜尋",
|
||||||
|
"ui.tool.codesearch": "程式碼搜尋",
|
||||||
"ui.tool.shell": "Shell",
|
"ui.tool.shell": "Shell",
|
||||||
"ui.tool.patch": "修補",
|
"ui.tool.patch": "修補",
|
||||||
"ui.tool.todos": "待辦",
|
"ui.tool.todos": "待辦",
|
||||||
|
|||||||
Reference in New Issue
Block a user