Files
memind/mindsearch-prefetch.test.mjs
T
John 58909a21a7 fix(search): 实时问答先预取 SearXNG,避免热榜整页截断崩溃
Portal 在 web 技能提交 Goose 前注入专用搜索结果,并要求先 tkmind_search、禁止先 fetch_url 抓热榜整页。
2026-09-12 11:04:23 +08:00

88 lines
3.3 KiB
JavaScript

import assert from 'node:assert/strict';
import test from 'node:test';
import {
appendAgentVisibleText,
formatPrefetchedSearchContext,
prefetchLiveSearchResults,
resolvePortalSearxngEndpoint,
shouldPrefetchLiveSearch,
} from './mindsearch-prefetch.mjs';
test('resolvePortalSearxngEndpoint rewrites docker host for in-process Portal', () => {
assert.equal(
resolvePortalSearxngEndpoint({
TKMIND_SEARCH_SEARXNG_URL: 'http://host.docker.internal:20080/search',
}),
'http://127.0.0.1:20080/search',
);
assert.equal(resolvePortalSearxngEndpoint({}), '');
});
test('shouldPrefetchLiveSearch only runs for web skills and can be disabled', () => {
assert.equal(shouldPrefetchLiveSearch({ suggestedSkill: 'web' }), true);
assert.equal(shouldPrefetchLiveSearch({ selectedSkill: 'search-enhanced' }), true);
assert.equal(shouldPrefetchLiveSearch({ suggestedSkill: 'static-page-publish' }), false);
assert.equal(shouldPrefetchLiveSearch({
suggestedSkill: 'web',
env: { MEMIND_LIVE_SEARCH_PREFETCH: '0' },
}), false);
});
test('formatPrefetchedSearchContext asks the agent not to scrape hot-list pages first', () => {
const text = formatPrefetchedSearchContext([
{ rank: 1, title: '今日热榜', url: 'https://example.com/hot', snippet: '话题' },
], { query: '抖音今天的热门话题是什么' });
assert.match(text, /联网搜索预取/);
assert.match(text, /抖音今天的热门话题是什么/);
assert.match(text, /禁止先 fetch_url/);
assert.match(text, /tkmind_search/);
assert.match(text, /https:\/\/example.com\/hot/);
});
test('appendAgentVisibleText keeps displayText and appends to the first text part', () => {
const next = appendAgentVisibleText({
role: 'user',
content: [{ type: 'text', text: '请使用 web 技能:问题' }],
metadata: { displayText: '抖音今天的热门话题是什么' },
}, '【联网搜索预取】result');
assert.equal(next.metadata.displayText, '抖音今天的热门话题是什么');
assert.match(next.content[0].text, /请使用 web 技能:问题/);
assert.match(next.content[0].text, /联网搜索预取/);
});
test('prefetchLiveSearchResults calls SearXNG and fails open on errors', async () => {
const hits = await prefetchLiveSearchResults({
query: '抖音热门话题',
suggestedSkill: 'web',
env: { TKMIND_SEARCH_SEARXNG_URL: 'http://127.0.0.1:20080/search' },
searchImpl: async (query, options) => {
assert.equal(query, '抖音热门话题');
assert.equal(options.endpoint, 'http://127.0.0.1:20080/search');
return [{ rank: 1, title: '话题A', url: 'https://a.example', snippet: '摘要' }];
},
});
assert.equal(hits.provider, 'searxng');
assert.equal(hits.resultCount, 1);
assert.match(hits.injectionText, /话题A/);
const skipped = await prefetchLiveSearchResults({
query: '抖音热门话题',
suggestedSkill: 'web',
env: {},
searchImpl: async () => {
throw new Error('should not run');
},
});
assert.equal(skipped, null);
const failed = await prefetchLiveSearchResults({
query: '抖音热门话题',
suggestedSkill: 'web',
env: { TKMIND_SEARCH_SEARXNG_URL: 'http://127.0.0.1:20080/search' },
searchImpl: async () => {
throw new Error('searxng down');
},
});
assert.equal(failed, null);
});