@anyul/koishi-plugin-rss 5.2.3 → 5.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/README.md +92 -37
  2. package/lib/commands/error-handler.js +13 -1
  3. package/lib/commands/index.d.ts +3 -0
  4. package/lib/commands/index.js +7 -1
  5. package/lib/commands/runtime.d.ts +17 -0
  6. package/lib/commands/runtime.js +27 -0
  7. package/lib/commands/subscription-create.d.ts +23 -0
  8. package/lib/commands/subscription-create.js +145 -0
  9. package/lib/commands/web-monitor.d.ts +15 -0
  10. package/lib/commands/web-monitor.js +222 -0
  11. package/lib/config.js +7 -1
  12. package/lib/constants.d.ts +1 -1
  13. package/lib/constants.js +46 -83
  14. package/lib/core/ai-cache.d.ts +27 -0
  15. package/lib/core/ai-cache.js +169 -0
  16. package/lib/core/ai-client.d.ts +12 -0
  17. package/lib/core/ai-client.js +65 -0
  18. package/lib/core/ai-selector.d.ts +2 -0
  19. package/lib/core/ai-selector.js +80 -0
  20. package/lib/core/ai-summary.d.ts +10 -0
  21. package/lib/core/ai-summary.js +73 -0
  22. package/lib/core/ai-utils.d.ts +10 -0
  23. package/lib/core/ai-utils.js +104 -0
  24. package/lib/core/ai.d.ts +3 -91
  25. package/lib/core/ai.js +13 -522
  26. package/lib/core/feeder-arg.d.ts +17 -0
  27. package/lib/core/feeder-arg.js +234 -0
  28. package/lib/core/feeder-runtime.d.ts +96 -0
  29. package/lib/core/feeder-runtime.js +233 -0
  30. package/lib/core/feeder.d.ts +3 -5
  31. package/lib/core/feeder.js +61 -358
  32. package/lib/core/item-processor-runtime.d.ts +46 -0
  33. package/lib/core/item-processor-runtime.js +215 -0
  34. package/lib/core/item-processor-template.d.ts +16 -0
  35. package/lib/core/item-processor-template.js +158 -0
  36. package/lib/core/item-processor.d.ts +1 -15
  37. package/lib/core/item-processor.js +44 -319
  38. package/lib/core/notification-queue-retry.d.ts +25 -0
  39. package/lib/core/notification-queue-retry.js +78 -0
  40. package/lib/core/notification-queue-sender.d.ts +20 -0
  41. package/lib/core/notification-queue-sender.js +118 -0
  42. package/lib/core/notification-queue-store.d.ts +19 -0
  43. package/lib/core/notification-queue-store.js +137 -0
  44. package/lib/core/notification-queue-types.d.ts +49 -0
  45. package/lib/core/notification-queue-types.js +2 -0
  46. package/lib/core/notification-queue.d.ts +11 -72
  47. package/lib/core/notification-queue.js +81 -258
  48. package/lib/core/search-format.d.ts +3 -0
  49. package/lib/core/search-format.js +36 -0
  50. package/lib/core/search-providers.d.ts +13 -0
  51. package/lib/core/search-providers.js +175 -0
  52. package/lib/core/search-rotation.d.ts +4 -0
  53. package/lib/core/search-rotation.js +55 -0
  54. package/lib/core/search-service.d.ts +3 -0
  55. package/lib/core/search-service.js +100 -0
  56. package/lib/core/search-types.d.ts +39 -0
  57. package/lib/core/search-types.js +2 -0
  58. package/lib/core/search.d.ts +4 -101
  59. package/lib/core/search.js +10 -508
  60. package/lib/index.js +27 -381
  61. package/lib/tsconfig.tsbuildinfo +1 -1
  62. package/lib/types.d.ts +27 -6
  63. package/lib/utils/legacy-config.d.ts +12 -0
  64. package/lib/utils/legacy-config.js +56 -0
  65. package/lib/utils/logger.js +50 -29
  66. package/lib/utils/proxy.d.ts +3 -0
  67. package/lib/utils/proxy.js +14 -0
  68. package/lib/utils/structured-logger.d.ts +7 -3
  69. package/lib/utils/structured-logger.js +26 -19
  70. package/package.json +1 -1
@@ -0,0 +1,4 @@
1
+ import { Config, SearchConfig } from '../types';
2
+ export declare function getNextVolcengineModel(config: Config, searchConfig: SearchConfig): string;
3
+ export declare function markVolcengineModelFailure(config: Config, searchConfig: SearchConfig, model: string): void;
4
+ export declare function clearSearchRotationStates(): void;
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getNextVolcengineModel = getNextVolcengineModel;
4
+ exports.markVolcengineModelFailure = markVolcengineModelFailure;
5
+ exports.clearSearchRotationStates = clearSearchRotationStates;
6
+ const logger_1 = require("../utils/logger");
7
+ const modelRotationStates = new Map();
8
+ function getModelRotationState(key, models) {
9
+ if (!modelRotationStates.has(key)) {
10
+ modelRotationStates.set(key, {
11
+ currentIndex: 0,
12
+ models,
13
+ lastFailureTime: 0,
14
+ failureCount: 0
15
+ });
16
+ }
17
+ return modelRotationStates.get(key);
18
+ }
19
+ function getNextVolcengineModel(config, searchConfig) {
20
+ if (searchConfig.volcengine?.models && searchConfig.volcengine.models.length > 0) {
21
+ const state = getModelRotationState('volcengine', searchConfig.volcengine.models);
22
+ const now = Date.now();
23
+ if (state.lastFailureTime > 0 && now - state.lastFailureTime < 60000) {
24
+ state.currentIndex = (state.currentIndex + 1) % state.models.length;
25
+ (0, logger_1.debug)(config, `模型轮询: 上次失败,切换到模型 ${state.models[state.currentIndex]}`, 'Search-Volcengine', 'info');
26
+ }
27
+ const model = state.models[state.currentIndex];
28
+ state.lastFailureTime = 0;
29
+ return model;
30
+ }
31
+ if (searchConfig.volcengine?.useAiModel !== false && config.ai?.model) {
32
+ return config.ai.model;
33
+ }
34
+ const defaultModels = [
35
+ 'doubao-seed-1-6-lite-251015',
36
+ 'doubao-seed-1-6-flash-250828'
37
+ ];
38
+ const state = getModelRotationState('volcengine-default', defaultModels);
39
+ const model = defaultModels[state.currentIndex];
40
+ state.currentIndex = (state.currentIndex + 1) % defaultModels.length;
41
+ return model;
42
+ }
43
+ function markVolcengineModelFailure(config, searchConfig, model) {
44
+ const key = searchConfig.volcengine?.models ? 'volcengine' : 'volcengine-default';
45
+ const state = modelRotationStates.get(key);
46
+ if (state) {
47
+ state.lastFailureTime = Date.now();
48
+ state.failureCount++;
49
+ state.currentIndex = (state.currentIndex + 1) % state.models.length;
50
+ (0, logger_1.debug)(config, `模型 ${model} 失败,切换到下一个模型 ${state.models[state.currentIndex]} (失败次数: ${state.failureCount})`, 'Search-Volcengine', 'info');
51
+ }
52
+ }
53
+ function clearSearchRotationStates() {
54
+ modelRotationStates.clear();
55
+ }
@@ -0,0 +1,3 @@
1
+ import { Config, SearchConfig } from '../types';
2
+ import { SearchResponse } from './search-types';
3
+ export declare function webSearch(config: Config, query: string, searchConfig: SearchConfig): Promise<SearchResponse>;
@@ -0,0 +1,100 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.webSearch = webSearch;
4
+ const logger_1 = require("../utils/logger");
5
+ const search_providers_1 = require("./search-providers");
6
+ function createErrorResponse(query, engine, error) {
7
+ return {
8
+ success: false,
9
+ results: [],
10
+ query,
11
+ engine,
12
+ error
13
+ };
14
+ }
15
+ function getAvailableAutoEngines(searchConfig) {
16
+ const enginePriority = searchConfig.enginePriority || ['tavily', 'volcengine', 'searxng'];
17
+ return enginePriority.filter(engine => {
18
+ switch (engine) {
19
+ case 'tavily':
20
+ return !!searchConfig.tavily?.apiKey;
21
+ case 'searxng':
22
+ return !!searchConfig.searxng?.instanceUrl;
23
+ case 'volcengine':
24
+ return !!searchConfig.volcengine?.apiKey;
25
+ default:
26
+ return false;
27
+ }
28
+ });
29
+ }
30
+ async function webSearch(config, query, searchConfig) {
31
+ if (!searchConfig.enabled) {
32
+ return createErrorResponse(query, 'none', '联网搜索未启用');
33
+ }
34
+ if (searchConfig.engine === 'auto') {
35
+ return autoSelectEngineAndSearch(config, query, searchConfig);
36
+ }
37
+ switch (searchConfig.engine) {
38
+ case 'tavily':
39
+ if (!searchConfig.tavily?.apiKey) {
40
+ return createErrorResponse(query, 'tavily', 'Tavily API Key 未配置');
41
+ }
42
+ return (0, search_providers_1.searchWithTavily)(config, query, searchConfig.tavily.apiKey, {
43
+ maxResults: searchConfig.maxResults || 5,
44
+ searchDepth: searchConfig.tavily.searchDepth || 'basic',
45
+ includeAnswer: searchConfig.tavily.includeAnswer !== false
46
+ });
47
+ case 'searxng':
48
+ if (!searchConfig.searxng?.instanceUrl) {
49
+ return createErrorResponse(query, 'searxng', 'SearXNG 实例 URL 未配置');
50
+ }
51
+ return (0, search_providers_1.searchWithSearxng)(config, query, searchConfig.searxng.instanceUrl, {
52
+ maxResults: searchConfig.maxResults || 5,
53
+ language: searchConfig.searxng.language || 'all',
54
+ categories: searchConfig.searxng.categories || ['general']
55
+ });
56
+ case 'volcengine':
57
+ if (!searchConfig.volcengine?.apiKey) {
58
+ return createErrorResponse(query, 'volcengine', '火山引擎 API Key 未配置');
59
+ }
60
+ return (0, search_providers_1.searchWithVolcengine)(config, query, config.ai?.baseUrl || 'https://ark.cn-beijing.volces.com/api/v3', searchConfig.volcengine.apiKey, undefined, searchConfig);
61
+ default:
62
+ return createErrorResponse(query, 'unknown', `未知的搜索引擎: ${searchConfig.engine}`);
63
+ }
64
+ }
65
+ async function autoSelectEngineAndSearch(config, query, searchConfig) {
66
+ const availableEngines = getAvailableAutoEngines(searchConfig);
67
+ if (availableEngines.length === 0) {
68
+ return createErrorResponse(query, 'auto', '没有配置任何可用的搜索引擎');
69
+ }
70
+ (0, logger_1.debug)(config, `自动选择搜索引擎,可用引擎: ${availableEngines.join(', ')}`, 'Search-Auto', 'info');
71
+ for (const engine of availableEngines) {
72
+ (0, logger_1.debug)(config, `尝试使用搜索引擎: ${engine}`, 'Search-Auto', 'info');
73
+ let result;
74
+ switch (engine) {
75
+ case 'tavily':
76
+ result = await (0, search_providers_1.searchWithTavily)(config, query, searchConfig.tavily.apiKey, {
77
+ maxResults: searchConfig.maxResults || 5,
78
+ searchDepth: searchConfig.tavily?.searchDepth || 'basic',
79
+ includeAnswer: searchConfig.tavily?.includeAnswer !== false
80
+ });
81
+ break;
82
+ case 'searxng':
83
+ result = await (0, search_providers_1.searchWithSearxng)(config, query, searchConfig.searxng.instanceUrl, {
84
+ maxResults: searchConfig.maxResults || 5,
85
+ language: searchConfig.searxng?.language || 'all',
86
+ categories: searchConfig.searxng?.categories || ['general']
87
+ });
88
+ break;
89
+ case 'volcengine':
90
+ result = await (0, search_providers_1.searchWithVolcengine)(config, query, config.ai?.baseUrl || 'https://ark.cn-beijing.volces.com/api/v3', searchConfig.volcengine.apiKey, undefined, searchConfig);
91
+ break;
92
+ }
93
+ if (result.success && result.results.length > 0) {
94
+ (0, logger_1.debug)(config, `搜索引擎 ${engine} 成功返回 ${result.results.length} 条结果`, 'Search-Auto', 'info');
95
+ return result;
96
+ }
97
+ (0, logger_1.debug)(config, `搜索引擎 ${engine} 失败: ${result.error || '无结果'},尝试下一个引擎`, 'Search-Auto', 'info');
98
+ }
99
+ return createErrorResponse(query, 'auto', '所有搜索引擎都失败了');
100
+ }
@@ -0,0 +1,39 @@
1
+ export interface SearchResult {
2
+ title: string;
3
+ url: string;
4
+ snippet?: string;
5
+ content?: string;
6
+ score?: number;
7
+ publishedDate?: string;
8
+ source?: string;
9
+ }
10
+ export interface SearchResponse {
11
+ success: boolean;
12
+ results: SearchResult[];
13
+ query: string;
14
+ engine: string;
15
+ model?: string;
16
+ error?: string;
17
+ }
18
+ export interface TavilyResponse {
19
+ answer?: string;
20
+ query: string;
21
+ results: Array<{
22
+ title: string;
23
+ url: string;
24
+ content: string;
25
+ score: number;
26
+ published_date?: string;
27
+ }>;
28
+ }
29
+ export interface SearxngResponse {
30
+ query: string;
31
+ results: Array<{
32
+ title: string;
33
+ url: string;
34
+ content: string;
35
+ snippet?: string;
36
+ engine?: string;
37
+ score?: number;
38
+ }>;
39
+ }
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,101 +1,4 @@
1
- /**
2
- * 联网搜索模块
3
- *
4
- * 支持多种搜索引擎:
5
- * - Tavily: 专业的 AI 搜索引擎
6
- * - Searxng: 开源隐私友好的元搜索引擎
7
- * - Volcengine: 火山引擎联网搜索(支持模型轮询)
8
- *
9
- * @module core/search
10
- */
11
- import { Config, SearchConfig } from '../types';
12
- /**
13
- * 搜索结果接口
14
- */
15
- export interface SearchResult {
16
- title: string;
17
- url: string;
18
- snippet?: string;
19
- content?: string;
20
- score?: number;
21
- publishedDate?: string;
22
- source?: string;
23
- }
24
- /**
25
- * 搜索响应接口
26
- */
27
- export interface SearchResponse {
28
- success: boolean;
29
- results: SearchResult[];
30
- query: string;
31
- engine: string;
32
- model?: string;
33
- error?: string;
34
- }
35
- /**
36
- * Tavily 搜索引擎
37
- *
38
- * @param config - 插件配置
39
- * @param query - 搜索查询
40
- * @param apiKey - Tavily API Key
41
- * @returns 搜索结果
42
- */
43
- export declare function searchWithTavily(config: Config, query: string, apiKey: string, options?: {
44
- maxResults?: number;
45
- searchDepth?: 'basic' | 'advanced';
46
- includeAnswer?: boolean;
47
- }): Promise<SearchResponse>;
48
- /**
49
- * SearXNG 搜索引擎
50
- *
51
- * @param config - 插件配置
52
- * @param query - 搜索查询
53
- * @param instanceUrl - SearXNG 实例 URL
54
- * @returns 搜索结果
55
- */
56
- export declare function searchWithSearxng(config: Config, query: string, instanceUrl: string, options?: {
57
- maxResults?: number;
58
- language?: string;
59
- categories?: Array<'general' | 'news' | 'images' | 'videos'>;
60
- }): Promise<SearchResponse>;
61
- /**
62
- * 火山引擎联网搜索(支持模型轮询)
63
- *
64
- * @param config - 插件配置
65
- * @param query - 搜索查询
66
- * @param baseUrl - API Base URL
67
- * @param apiKey - API Key
68
- * @param model - 模型名称(可选,如果不指定则使用轮询)
69
- * @param searchConfig - 搜索配置(用于模型轮询)
70
- * @returns 搜索结果
71
- */
72
- export declare function searchWithVolcengine(config: Config, query: string, baseUrl: string, apiKey: string, model?: string, searchConfig?: SearchConfig): Promise<SearchResponse>;
73
- /**
74
- * 统一搜索接口
75
- *
76
- * 根据配置自动选择搜索引擎并执行搜索
77
- * - 如果 engine 为 'auto',则根据配置的 API Keys 按优先级自动选择
78
- * - 支持多引擎配置时智能选择
79
- *
80
- * @param config - 插件配置
81
- * @param query - 搜索查询
82
- * @param searchConfig - 搜索配置
83
- * @returns 搜索结果
84
- */
85
- export declare function webSearch(config: Config, query: string, searchConfig: SearchConfig): Promise<SearchResponse>;
86
- /**
87
- * 将搜索结果格式化为 AI 可读的文本
88
- *
89
- * @param response - 搜索响应
90
- * @returns 格式化的文本
91
- */
92
- export declare function formatSearchResults(response: SearchResponse): string;
93
- /**
94
- * 构建带搜索上下文的 AI Prompt
95
- *
96
- * @param originalPrompt - 原始提示词
97
- * @param searchResults - 搜索结果
98
- * @param searchQuery - 搜索查询
99
- * @returns 增强后的提示词
100
- */
101
- export declare function buildPromptWithSearchContext(originalPrompt: string, searchResults: SearchResponse, searchQuery: string): string;
1
+ export { buildPromptWithSearchContext, formatSearchResults } from './search-format';
2
+ export { searchWithSearxng, searchWithTavily, searchWithVolcengine } from './search-providers';
3
+ export { webSearch } from './search-service';
4
+ export type { SearchResponse, SearchResult } from './search-types';