feat(web_search): truncate results in TUI view, expand with ctrl+o
Add renderResult showing a collapsed preview (count + first 3 results) until expanded via Ctrl+O. The full markdown still goes to the model via content, so only the display is affected.
This commit is contained in:
@@ -1,7 +1,12 @@
|
||||
// Pi-Web Extension - Registers `web_search` and `web_fetch` tools backed by
|
||||
// a shared headless Firefox session. Provider config lives in
|
||||
// ~/.pi/pi-web/config.json (env overrides supported).
|
||||
import type { ExtensionAPI } from "@mariozechner/pi-coding-agent";
|
||||
import {
|
||||
keyHint,
|
||||
type AgentToolResult,
|
||||
type ExtensionAPI,
|
||||
type Theme,
|
||||
} from "@mariozechner/pi-coding-agent";
|
||||
import { Text } from "@mariozechner/pi-tui";
|
||||
import { Type } from "typebox";
|
||||
import { ConfigError, loadConfig, resolveSettings } from "./src/config.ts";
|
||||
@@ -10,6 +15,9 @@ import { searchKagi } from "./src/providers/kagi.ts";
|
||||
import { searchSearxng } from "./src/providers/searxng.ts";
|
||||
import { SearchError, type SearchResult } from "./src/types.ts";
|
||||
|
||||
// Collapsed-view preview cap. The full list still goes to the model via `content`.
|
||||
const PREVIEW_RESULTS = 3;
|
||||
|
||||
function formatResults(results: SearchResult[]): string {
|
||||
if (results.length === 0) return "(no results)";
|
||||
return results
|
||||
@@ -17,6 +25,30 @@ function formatResults(results: SearchResult[]): string {
|
||||
.join("\n\n");
|
||||
}
|
||||
|
||||
function renderSearchResult(
|
||||
result: AgentToolResult<unknown>,
|
||||
expanded: boolean,
|
||||
theme: Theme,
|
||||
): Text {
|
||||
const fullText = result.content[0]?.type === "text" ? result.content[0].text : "";
|
||||
const raw = (result.details as { raw?: SearchResult[] } | undefined)?.raw;
|
||||
|
||||
// Expanded or unavailable details: show the full markdown the model received.
|
||||
if (expanded || !raw || raw.length === 0) {
|
||||
return new Text(fullText, 0, 0);
|
||||
}
|
||||
|
||||
let text = theme.fg("muted", `${raw.length} result(s):`);
|
||||
for (const r of raw.slice(0, PREVIEW_RESULTS)) {
|
||||
text += `\n${theme.fg("toolTitle", r.title)} ${theme.fg("dim", r.url)}`;
|
||||
}
|
||||
const more = raw.length - PREVIEW_RESULTS;
|
||||
if (more > 0) {
|
||||
text += `\n${theme.fg("dim", `... ${more} more (${keyHint("app.tools.expand", "to expand")})`)}`;
|
||||
}
|
||||
return new Text(text, 0, 0);
|
||||
}
|
||||
|
||||
function formatFetch(r: FetchResult): string {
|
||||
const header =
|
||||
r.title && r.title.trim()
|
||||
@@ -55,6 +87,9 @@ export default function (pi: ExtensionAPI) {
|
||||
text.setText(theme.fg("toolTitle", theme.bold(`web_search "${display}"`)));
|
||||
return text;
|
||||
},
|
||||
renderResult(result, { expanded }, theme) {
|
||||
return renderSearchResult(result, expanded, theme);
|
||||
},
|
||||
async execute(_toolCallId, params) {
|
||||
try {
|
||||
const results = await runSearch(params.query);
|
||||
|
||||
Reference in New Issue
Block a user