feat(工具): 秘塔搜索支持视频搜索功能

- metasoSearch.ts 添加视频搜索支持:
  - 新增 MetasoVideoResult 接口定义视频搜索结果
  - scope 参数支持 'video' 类型
  - 添加视频搜索结果解析逻辑
  - formatMetasoSearchResults 支持视频结果格式化
  - formatMetasoSearchResultsShort 添加视频结果简短格式
- executor.ts 工具执行器更新:
  - ToolExecutionResult 新增 searchVideos 字段
  - mita_search 工具支持视频搜索 scope
  - 视频搜索默认返回5条结果
This commit is contained in:
gaoziman 2025-12-22 21:56:42 +08:00
parent 159009dd56
commit 1e81e9151b
2 changed files with 86 additions and 8 deletions

View File

@ -33,6 +33,7 @@ import {
type MetasoSearchInput, type MetasoSearchInput,
type MetasoSearchResponse, type MetasoSearchResponse,
type MetasoImageResult, type MetasoImageResult,
type MetasoVideoResult,
} from './metasoSearch'; } from './metasoSearch';
import { import {
metasoReader, metasoReader,
@ -58,6 +59,8 @@ export interface ToolExecutionResult {
images?: string[]; images?: string[];
/** 搜索到的图片数组(图片搜索时产生) */ /** 搜索到的图片数组(图片搜索时产生) */
searchImages?: MetasoImageResult[]; searchImages?: MetasoImageResult[];
/** 搜索到的视频数组(视频搜索时产生) */
searchVideos?: MetasoVideoResult[];
/** 是否需要浏览器端 Pyodide 执行 */ /** 是否需要浏览器端 Pyodide 执行 */
requiresPyodide?: boolean; requiresPyodide?: boolean;
/** 代码内容(当 requiresPyodide 为 true 时) */ /** 代码内容(当 requiresPyodide 为 true 时) */
@ -148,12 +151,12 @@ export async function executeTool(
case 'mita_search': { case 'mita_search': {
const query = String(input.query || ''); const query = String(input.query || '');
const scope = (input.scope as 'webpage' | 'image') || 'webpage'; const scope = (input.scope as 'webpage' | 'image' | 'video') || 'webpage';
// 图片搜索时请求更多图片用于验证筛选,网页搜索保持原有逻辑 // 图片搜索时请求更多图片用于验证筛选,视频和网页搜索保持原有逻辑
const requestSize = scope === 'image' const requestSize = scope === 'image'
? ImageValidationConfig.REQUEST_SIZE ? ImageValidationConfig.REQUEST_SIZE
: (input.size ? Number(input.size) : 10); : (input.size ? Number(input.size) : (scope === 'video' ? 5 : 10));
const searchInput: MetasoSearchInput = { const searchInput: MetasoSearchInput = {
query, query,
@ -185,6 +188,8 @@ export async function executeTool(
rawData: response, rawData: response,
// 如果是图片搜索,返回验证后的图片数据 // 如果是图片搜索,返回验证后的图片数据
searchImages: scope === 'image' ? validatedImages : undefined, searchImages: scope === 'image' ? validatedImages : undefined,
// 如果是视频搜索,返回视频数据
searchVideos: scope === 'video' ? response.videos : undefined,
}; };
} }

View File

@ -1,6 +1,6 @@
/** /**
* AI搜索工具服务 * AI搜索工具服务
* 使AI API * 使AI API
*/ */
// ============ 图片验证相关常量 ============ // ============ 图片验证相关常量 ============
@ -9,6 +9,9 @@ const IMAGE_VALIDATION_CONCURRENCY = 5; // 并发验证数量
const IMAGE_REQUEST_SIZE = 15; // 图片搜索时请求的数量 const IMAGE_REQUEST_SIZE = 15; // 图片搜索时请求的数量
const IMAGE_TARGET_COUNT = 10; // 返回给前端的图片数量前端会显示5张+5张备用 const IMAGE_TARGET_COUNT = 10; // 返回给前端的图片数量前端会显示5张+5张备用
// ============ 视频搜索相关常量 ============
const VIDEO_DEFAULT_SIZE = 5; // 视频搜索默认数量
// 网页搜索结果 // 网页搜索结果
export interface MetasoSearchResult { export interface MetasoSearchResult {
title: string; title: string;
@ -31,23 +34,38 @@ export interface MetasoImageResult {
sourceUrl?: string; sourceUrl?: string;
} }
// 视频搜索结果
export interface MetasoVideoResult {
title: string;
link: string;
snippet: string;
score: string;
position: number;
authors: string[];
date: string;
duration: string;
coverImage: string;
}
// 搜索响应 // 搜索响应
export interface MetasoSearchResponse { export interface MetasoSearchResponse {
success: boolean; success: boolean;
credits?: number; credits?: number;
total?: number; total?: number;
scope?: 'webpage' | 'image'; scope?: 'webpage' | 'image' | 'video';
// 网页搜索结果 // 网页搜索结果
results?: MetasoSearchResult[]; results?: MetasoSearchResult[];
// 图片搜索结果 // 图片搜索结果
images?: MetasoImageResult[]; images?: MetasoImageResult[];
// 视频搜索结果
videos?: MetasoVideoResult[];
error?: string; error?: string;
} }
// 搜索输入参数 // 搜索输入参数
export interface MetasoSearchInput { export interface MetasoSearchInput {
query: string; query: string;
scope?: 'webpage' | 'image'; scope?: 'webpage' | 'image' | 'video';
size?: number; size?: number;
/** 页码用于获取不同页的结果从1开始 */ /** 页码用于获取不同页的结果从1开始 */
page?: number; page?: number;
@ -71,7 +89,8 @@ export async function metasoSearch(
} }
const scope = input.scope || 'webpage'; const scope = input.scope || 'webpage';
const size = input.size || (scope === 'image' ? 5 : 10); // 图片默认5张 // 根据 scope 设置默认 size
const size = input.size || (scope === 'image' ? 5 : scope === 'video' ? VIDEO_DEFAULT_SIZE : 10);
try { try {
const response = await fetch('https://metaso.cn/api/v1/search', { const response = await fetch('https://metaso.cn/api/v1/search', {
@ -111,7 +130,36 @@ export async function metasoSearch(
const data = await response.json(); const data = await response.json();
// 根据 scope 解析不同的结果 // 根据 scope 解析不同的结果
if (scope === 'image') { if (scope === 'video') {
// 视频搜索结果
return {
success: true,
credits: data.credits,
total: data.total,
scope: 'video',
videos: data.videos?.map((item: {
title: string;
link: string;
snippet: string;
score: string;
position: number;
authors?: string[];
date?: string;
duration?: string;
coverImage?: string;
}) => ({
title: item.title,
link: item.link,
snippet: item.snippet,
score: item.score,
position: item.position,
authors: item.authors || [],
date: item.date || '',
duration: item.duration || '0',
coverImage: item.coverImage || '',
})),
};
} else if (scope === 'image') {
// 图片搜索结果 // 图片搜索结果
return { return {
success: true, success: true,
@ -179,6 +227,25 @@ export function formatMetasoSearchResults(response: MetasoSearchResponse): strin
return `搜索失败: ${response.error}`; return `搜索失败: ${response.error}`;
} }
// 视频搜索结果
if (response.scope === 'video' && response.videos) {
let result = `## 秘塔视频搜索结果 (共${response.total}个)\n\n`;
response.videos.forEach((item, index) => {
result += `${index + 1}. **${item.title}**\n`;
result += ` - 链接: ${item.link}\n`;
result += ` - 时长: ${item.duration}\n`;
if (item.authors && item.authors.length > 0) {
result += ` - 作者: ${item.authors.join(', ')}\n`;
}
if (item.date) {
result += ` - 发布日期: ${item.date}\n`;
}
result += ` - 摘要: ${item.snippet}\n`;
result += '\n';
});
return result;
}
// 图片搜索结果 // 图片搜索结果
if (response.scope === 'image' && response.images) { if (response.scope === 'image' && response.images) {
let result = `## 秘塔图片搜索结果 (共${response.total}张)\n\n`; let result = `## 秘塔图片搜索结果 (共${response.total}张)\n\n`;
@ -339,6 +406,12 @@ export function formatMetasoSearchResultsShort(
return `搜索失败: ${response.error}`; return `搜索失败: ${response.error}`;
} }
// 视频搜索结果
if (response.scope === 'video' && response.videos) {
const videoCount = response.videos.length;
return `> 🎬 秘塔搜索「${query}」视频,找到 ${response.total || videoCount} 个相关视频`;
}
// 图片搜索结果 // 图片搜索结果
if (response.scope === 'image' && response.images) { if (response.scope === 'image' && response.images) {
const imageCount = response.images.length; const imageCount = response.images.length;