feat(studio): differentiate web search and URL fetch in chat tool UI (#4802)
Differentiate web_search query searches from URL fetches in the Studio chat UI. Backend (llama_cpp.py): - Emit "Reading: hostname" for URL fetches and "Searching: query" for query searches in SSE status events - Only show hostname for valid http/https URLs; schemeless/non-http URLs get "Reading page..." generic fallback - Strip www. prefix for consistency with the frontend Frontend (tool-ui-web-search.tsx): - Tool card shows "Read hostname" / "Reading hostname..." for URL fetches - Shows "Searched query" / "Searching for query..." for query searches - Uses new URL() with protocol check; falls back to "Read page" / "Reading page..." for non-http URLs
This commit is contained in:
parent
8981e6c804
commit
5b7c0615f3
2 changed files with 39 additions and 4 deletions
|
|
@ -22,6 +22,7 @@ import threading
|
|||
import time
|
||||
from pathlib import Path
|
||||
from typing import Generator, Optional
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import httpx
|
||||
|
||||
|
|
@ -2270,7 +2271,7 @@ class LlamaCppBackend:
|
|||
Agentic loop: let the model call tools, execute them, and continue.
|
||||
|
||||
Yields dicts with:
|
||||
{"type": "status", "text": "Searching: ..."} -- tool status updates
|
||||
{"type": "status", "text": "Searching: ..."/"Reading: ..."} -- tool status updates
|
||||
{"type": "content", "text": "token"} -- streamed content tokens (cumulative)
|
||||
{"type": "reasoning", "text": "token"} -- streamed reasoning tokens (cumulative)
|
||||
"""
|
||||
|
|
@ -2837,7 +2838,18 @@ class LlamaCppBackend:
|
|||
arguments = raw_args
|
||||
|
||||
if tool_name == "web_search":
|
||||
status_text = f"Searching: {arguments.get('query', '')}"
|
||||
_ws_url = (arguments.get("url") or "").strip()
|
||||
if _ws_url:
|
||||
_parsed = urlparse(_ws_url)
|
||||
if _parsed.scheme in ("http", "https") and _parsed.hostname:
|
||||
_ws_host = _parsed.hostname
|
||||
if _ws_host.startswith("www."):
|
||||
_ws_host = _ws_host[4:]
|
||||
status_text = f"Reading: {_ws_host}"
|
||||
else:
|
||||
status_text = "Reading page..."
|
||||
else:
|
||||
status_text = f"Searching: {arguments.get('query', '')}"
|
||||
elif tool_name == "python":
|
||||
preview = (
|
||||
(arguments.get("code") or "").strip().split("\n")[0][:60]
|
||||
|
|
|
|||
|
|
@ -52,6 +52,18 @@ const WebSearchToolUIImpl: ToolCallMessagePartComponent = ({
|
|||
status,
|
||||
}) => {
|
||||
const query = (args as { query?: string })?.query ?? "";
|
||||
const url = ((args as { url?: string })?.url ?? "").trim();
|
||||
const isUrlFetch = !!url;
|
||||
const displayDomain = (() => {
|
||||
if (!url) return "";
|
||||
try {
|
||||
const parsed = new URL(url);
|
||||
if (parsed.protocol !== "http:" && parsed.protocol !== "https:") return "";
|
||||
return parsed.hostname.replace(/^www\./, "");
|
||||
} catch {
|
||||
return "";
|
||||
}
|
||||
})();
|
||||
const isRunning = status?.type === "running";
|
||||
const sources = result
|
||||
? parseSearchResults(
|
||||
|
|
@ -75,7 +87,13 @@ const WebSearchToolUIImpl: ToolCallMessagePartComponent = ({
|
|||
return (
|
||||
<ToolFallbackRoot open={open} onOpenChange={setOpen}>
|
||||
<ToolFallbackTrigger
|
||||
toolName={query ? `Searched "${query}"` : "Web Search"}
|
||||
toolName={
|
||||
isUrlFetch
|
||||
? displayDomain ? `Read ${displayDomain}` : "Read page"
|
||||
: query
|
||||
? `Searched "${query}"`
|
||||
: "Web Search"
|
||||
}
|
||||
status={status}
|
||||
icon={GlobeIcon}
|
||||
/>
|
||||
|
|
@ -83,7 +101,12 @@ const WebSearchToolUIImpl: ToolCallMessagePartComponent = ({
|
|||
{isRunning ? (
|
||||
<div className="flex items-center gap-2 text-sm text-muted-foreground">
|
||||
<LoaderIcon className="size-3.5 animate-spin" />
|
||||
<span>Searching for “{query}”…</span>
|
||||
<span>
|
||||
{isUrlFetch
|
||||
? <>Reading {displayDomain || "page"}…</>
|
||||
: <>Searching for “{query}”…</>
|
||||
}
|
||||
</span>
|
||||
</div>
|
||||
) : sources.length > 0 ? (
|
||||
<div className="flex flex-wrap gap-1.5">
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue