fix: resolve TypeScript type errors in search-the-web extension (#204) (#210)

- Add .js extensions to all relative imports for NodeNext module resolution
- Cast pi.writeTempFile to (pi as any) since it exists at runtime but not on ExtensionAPI type
- Add details: undefined as unknown to return objects missing the required details field
- Fix onUpdate calls to include details field required by AgentToolResult

Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
TÂCHES 2026-03-13 11:34:07 -06:00 committed by GitHub
parent 8ecd8f6360
commit 5896cd2e2a
5 changed files with 34 additions and 34 deletions

View file

@ -3,7 +3,7 @@
* and LLM context responses.
*/
import { extractDomain } from "./url-utils";
import { extractDomain } from "./url-utils.js";
export interface SearchResultFormatted {
title: string;

View file

@ -45,11 +45,11 @@
*/
import type { ExtensionAPI } from "@gsd/pi-coding-agent";
import { registerSearchTool } from "./tool-search";
import { registerFetchPageTool } from "./tool-fetch-page";
import { registerLLMContextTool } from "./tool-llm-context";
import { registerSearchProviderCommand } from "./command-search-provider.ts";
import { registerNativeSearchHooks } from "./native-search";
import { registerSearchTool } from "./tool-search.js";
import { registerFetchPageTool } from "./tool-fetch-page.js";
import { registerLLMContextTool } from "./tool-llm-context.js";
import { registerSearchProviderCommand } from "./command-search-provider.js";
import { registerNativeSearchHooks } from "./native-search.js";
export default function (pi: ExtensionAPI) {
registerSearchTool(pi);

View file

@ -13,10 +13,10 @@ import { truncateHead, DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES } from "@gsd/pi-codi
import { Text } from "@gsd/pi-tui";
import { Type } from "@sinclair/typebox";
import { LRUTTLCache } from "./cache";
import { fetchSimple, HttpError } from "./http";
import { extractDomain } from "./url-utils";
import { formatPageContent, type FormatPageOptions } from "./format";
import { LRUTTLCache } from "./cache.js";
import { fetchSimple, HttpError } from "./http.js";
import { extractDomain } from "./url-utils.js";
import { formatPageContent, type FormatPageOptions } from "./format.js";
// =============================================================================
// Cache
@ -336,7 +336,7 @@ export function registerFetchPageTool(pi: ExtensionAPI) {
async execute(toolCallId, params, signal, onUpdate, ctx) {
if (signal?.aborted) {
return { content: [{ type: "text", text: "Fetch cancelled." }] };
return { content: [{ type: "text", text: "Fetch cancelled." }], details: undefined as unknown };
}
const maxChars = params.maxChars ?? 8000;
@ -392,7 +392,7 @@ export function registerFetchPageTool(pi: ExtensionAPI) {
}
const domain = extractDomain(url);
onUpdate?.({ content: [{ type: "text", text: `Fetching ${domain}...` }] });
onUpdate?.({ content: [{ type: "text", text: `Fetching ${domain}...` }], details: undefined as unknown });
// ------------------------------------------------------------------
// Fetch page content
@ -439,7 +439,7 @@ export function registerFetchPageTool(pi: ExtensionAPI) {
const finalTruncation = truncateHead(output, { maxLines: DEFAULT_MAX_LINES, maxBytes: DEFAULT_MAX_BYTES });
let content = finalTruncation.content;
if (finalTruncation.truncated) {
const tempFile = await pi.writeTempFile(output, { prefix: "fetch-page-" });
const tempFile = await (pi as any).writeTempFile(output, { prefix: "fetch-page-" });
content += `\n\n[Truncated to fit context. Full content: ${tempFile}]`;
}

View file

@ -21,13 +21,13 @@ import { Text } from "@gsd/pi-tui";
import { Type } from "@sinclair/typebox";
import { StringEnum } from "@gsd/pi-ai";
import { LRUTTLCache } from "./cache";
import { fetchWithRetryTimed, HttpError, classifyError, type RateLimitInfo } from "./http";
import { normalizeQuery, extractDomain } from "./url-utils";
import { formatLLMContext, type LLMContextSnippet, type LLMContextSource } from "./format";
import type { TavilyResult, TavilySearchResponse } from "./tavily";
import { publishedDateToAge } from "./tavily";
import { getTavilyApiKey, resolveSearchProvider } from "./provider";
import { LRUTTLCache } from "./cache.js";
import { fetchWithRetryTimed, HttpError, classifyError, type RateLimitInfo } from "./http.js";
import { normalizeQuery, extractDomain } from "./url-utils.js";
import { formatLLMContext, type LLMContextSnippet, type LLMContextSource } from "./format.js";
import type { TavilyResult, TavilySearchResponse } from "./tavily.js";
import { publishedDateToAge } from "./tavily.js";
import { getTavilyApiKey, resolveSearchProvider } from "./provider.js";
// =============================================================================
// Types
@ -286,7 +286,7 @@ export function registerLLMContextTool(pi: ExtensionAPI) {
async execute(toolCallId, params, signal, onUpdate, ctx) {
if (signal?.aborted) {
return { content: [{ type: "text", text: "Search cancelled." }] };
return { content: [{ type: "text", text: "Search cancelled." }], details: undefined as unknown };
}
// ------------------------------------------------------------------
@ -321,7 +321,7 @@ export function registerLLMContextTool(pi: ExtensionAPI) {
const truncation = truncateHead(output, { maxLines: DEFAULT_MAX_LINES, maxBytes: DEFAULT_MAX_BYTES });
let content = truncation.content;
if (truncation.truncated) {
const tempFile = await pi.writeTempFile(output, { prefix: "llm-context-" });
const tempFile = await (pi as any).writeTempFile(output, { prefix: "llm-context-" });
content += `\n\n[Truncated. Full content: ${tempFile}]`;
}
@ -340,7 +340,7 @@ export function registerLLMContextTool(pi: ExtensionAPI) {
return { content: [{ type: "text", text: content }], details };
}
onUpdate?.({ content: [{ type: "text", text: `Searching & reading about "${params.query}"...` }] });
onUpdate?.({ content: [{ type: "text", text: `Searching & reading about "${params.query}"...` }], details: undefined as unknown });
try {
// ------------------------------------------------------------------
@ -483,7 +483,7 @@ export function registerLLMContextTool(pi: ExtensionAPI) {
let content = truncation.content;
if (truncation.truncated) {
const tempFile = await pi.writeTempFile(output, { prefix: "llm-context-" });
const tempFile = await (pi as any).writeTempFile(output, { prefix: "llm-context-" });
content += `\n\n[Truncated. Full content: ${tempFile}]`;
}

View file

@ -16,12 +16,12 @@ import { Text } from "@gsd/pi-tui";
import { Type } from "@sinclair/typebox";
import { StringEnum } from "@gsd/pi-ai";
import { LRUTTLCache } from "./cache";
import { fetchWithRetryTimed, fetchWithRetry, classifyError, type RateLimitInfo } from "./http";
import { normalizeQuery, toDedupeKey, detectFreshness } from "./url-utils";
import { formatSearchResults, type SearchResultFormatted, type FormatSearchOptions } from "./format";
import { getTavilyApiKey, resolveSearchProvider } from "./provider";
import { normalizeTavilyResult, mapFreshnessToTavily, type TavilySearchResponse } from "./tavily";
import { LRUTTLCache } from "./cache.js";
import { fetchWithRetryTimed, fetchWithRetry, classifyError, type RateLimitInfo } from "./http.js";
import { normalizeQuery, toDedupeKey, detectFreshness } from "./url-utils.js";
import { formatSearchResults, type SearchResultFormatted, type FormatSearchOptions } from "./format.js";
import { getTavilyApiKey, resolveSearchProvider } from "./provider.js";
import { normalizeTavilyResult, mapFreshnessToTavily, type TavilySearchResponse } from "./tavily.js";
// =============================================================================
// Types
@ -291,7 +291,7 @@ export function registerSearchTool(pi: ExtensionAPI) {
async execute(toolCallId, params, signal, onUpdate, ctx) {
if (signal?.aborted) {
return { content: [{ type: "text", text: "Search cancelled." }] };
return { content: [{ type: "text", text: "Search cancelled." }], details: undefined as unknown };
}
// ------------------------------------------------------------------
@ -365,7 +365,7 @@ export function registerSearchTool(pi: ExtensionAPI) {
const truncation = truncateHead(output, { maxLines: DEFAULT_MAX_LINES, maxBytes: DEFAULT_MAX_BYTES });
let content = truncation.content;
if (truncation.truncated) {
const tempFile = await pi.writeTempFile(output, { prefix: "web-search-" });
const tempFile = await (pi as any).writeTempFile(output, { prefix: "web-search-" });
content += `\n\n[Truncated: ${truncation.outputLines}/${truncation.totalLines} lines (${formatSize(truncation.outputBytes)}/${formatSize(truncation.totalBytes)}). Full results: ${tempFile}]`;
}
@ -387,7 +387,7 @@ export function registerSearchTool(pi: ExtensionAPI) {
return { content: [{ type: "text", text: content }], details };
}
onUpdate?.({ content: [{ type: "text", text: `Searching for "${params.query}"...` }] });
onUpdate?.({ content: [{ type: "text", text: `Searching for "${params.query}"...` }], details: undefined as unknown });
try {
// ------------------------------------------------------------------
@ -484,7 +484,7 @@ export function registerSearchTool(pi: ExtensionAPI) {
let content = truncation.content;
if (truncation.truncated) {
const tempFile = await pi.writeTempFile(output, { prefix: "web-search-" });
const tempFile = await (pi as any).writeTempFile(output, { prefix: "web-search-" });
content += `\n\n[Truncated: ${truncation.outputLines}/${truncation.totalLines} lines (${formatSize(truncation.outputBytes)}/${formatSize(truncation.totalBytes)}). Full results: ${tempFile}]`;
}