src / tools / searchWeb.ts
src / tools / searchWeb.ts
import { tool } from "@lmstudio/sdk";
import { z } from "zod";
import { defaultConfigurationService } from "../config/ConfigurationService";
import { defaultSearchEngine } from "../bootstrap";
import { SearchEngine } from "../engine/SearchEngine";
import { formatSearchResult } from "../engine/budget/SearchPayloadLimiter";
import { BrowseError } from "../models/errors";
/**
* Creates the search_web tool instance with dependency-injected SearchEngine.
* Mapped from Python `server.py` search_web tool and _execute_search helper.
*
* @param searchEngine Injected SearchEngine instance (defaults to defaultSearchEngine from bootstrap).
*/
export function createSearchWebTool(searchEngine: SearchEngine = defaultSearchEngine) {
return tool({
name: "Web Search",
description: "Searches the web using configured web provider settings.",
parameters: {
query: z.string().describe("Search query string"),
provider: z.string().optional().describe("Optional explicit search provider name identifier"),
},
implementation: async ({ query, provider }) => {
// 1. Request Validation
if (!query || !query.trim()) {
return { error: "Query parameter must be a non-empty string.", results: [] };
}
const count = defaultConfigurationService.getMaxWebResults();
// 2. Search Engine Invocation & Response Serialization (mapped from Python server.py lines 84-103)
try {
const results = await searchEngine.search(query.trim(), {
provider: provider ? provider.toLowerCase().trim() : undefined,
numResults: count,
});
return {
query: query.trim(),
count: results.length,
results: results.map(formatSearchResult),
};
} catch (err: unknown) {
if (err instanceof BrowseError) {
return { error: err.message, results: [] };
}
return {
error: "An unexpected server error occurred during search execution.",
results: [],
};
}
},
});
}
export const searchWebTool = createSearchWebTool();
import { tool } from "@lmstudio/sdk";
import { z } from "zod";
import { defaultConfigurationService } from "../config/ConfigurationService";
import { defaultSearchEngine } from "../bootstrap";
import { SearchEngine } from "../engine/SearchEngine";
import { formatSearchResult } from "../engine/budget/SearchPayloadLimiter";
import { BrowseError } from "../models/errors";
/**
* Creates the search_web tool instance with dependency-injected SearchEngine.
* Mapped from Python `server.py` search_web tool and _execute_search helper.
*
* @param searchEngine Injected SearchEngine instance (defaults to defaultSearchEngine from bootstrap).
*/
export function createSearchWebTool(searchEngine: SearchEngine = defaultSearchEngine) {
return tool({
name: "Web Search",
description: "Searches the web using configured web provider settings.",
parameters: {
query: z.string().describe("Search query string"),
provider: z.string().optional().describe("Optional explicit search provider name identifier"),
},
implementation: async ({ query, provider }) => {
// 1. Request Validation
if (!query || !query.trim()) {
return { error: "Query parameter must be a non-empty string.", results: [] };
}
const count = defaultConfigurationService.getMaxWebResults();
// 2. Search Engine Invocation & Response Serialization (mapped from Python server.py lines 84-103)
try {
const results = await searchEngine.search(query.trim(), {
provider: provider ? provider.toLowerCase().trim() : undefined,
numResults: count,
});
return {
query: query.trim(),
count: results.length,
results: results.map(formatSearchResult),
};
} catch (err: unknown) {
if (err instanceof BrowseError) {
return { error: err.message, results: [] };
}
return {
error: "An unexpected server error occurred during search execution.",
results: [],
};
}
},
});
}
export const searchWebTool = createSearchWebTool();