ubersearch 0.0.0-development
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.
- package/LICENSE +21 -0
- package/README.md +374 -0
- package/package.json +76 -0
- package/src/app/index.ts +30 -0
- package/src/bootstrap/container.ts +157 -0
- package/src/cli.ts +380 -0
- package/src/config/defineConfig.ts +176 -0
- package/src/config/load.ts +368 -0
- package/src/config/types.ts +86 -0
- package/src/config/validation.ts +148 -0
- package/src/core/cache.ts +74 -0
- package/src/core/container.ts +268 -0
- package/src/core/credits/CreditManager.ts +158 -0
- package/src/core/credits/CreditStateProvider.ts +151 -0
- package/src/core/credits/FileCreditStateProvider.ts +137 -0
- package/src/core/credits/index.ts +3 -0
- package/src/core/docker/dockerComposeHelper.ts +177 -0
- package/src/core/docker/dockerLifecycleManager.ts +361 -0
- package/src/core/docker/index.ts +8 -0
- package/src/core/logger.ts +146 -0
- package/src/core/orchestrator.ts +103 -0
- package/src/core/paths.ts +157 -0
- package/src/core/provider/ILifecycleProvider.ts +120 -0
- package/src/core/provider/ProviderFactory.ts +120 -0
- package/src/core/provider.ts +61 -0
- package/src/core/serviceKeys.ts +45 -0
- package/src/core/strategy/AllProvidersStrategy.ts +245 -0
- package/src/core/strategy/FirstSuccessStrategy.ts +98 -0
- package/src/core/strategy/ISearchStrategy.ts +94 -0
- package/src/core/strategy/StrategyFactory.ts +204 -0
- package/src/core/strategy/index.ts +9 -0
- package/src/core/strategy/types.ts +56 -0
- package/src/core/types.ts +58 -0
- package/src/index.ts +1 -0
- package/src/plugin/PluginRegistry.ts +336 -0
- package/src/plugin/builtin.ts +130 -0
- package/src/plugin/index.ts +33 -0
- package/src/plugin/types.ts +212 -0
- package/src/providers/BaseProvider.ts +49 -0
- package/src/providers/brave.ts +66 -0
- package/src/providers/constants.ts +13 -0
- package/src/providers/helpers/index.ts +24 -0
- package/src/providers/helpers/lifecycleHelpers.ts +110 -0
- package/src/providers/helpers/resultMappers.ts +168 -0
- package/src/providers/index.ts +6 -0
- package/src/providers/linkup.ts +114 -0
- package/src/providers/retry.ts +95 -0
- package/src/providers/searchxng.ts +163 -0
- package/src/providers/tavily.ts +73 -0
- package/src/providers/types/index.ts +185 -0
- package/src/providers/utils.ts +182 -0
- package/src/tool/allSearchTool.ts +110 -0
- package/src/tool/interface.ts +71 -0
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Core search types and error handling
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
export type EngineId = string;
|
|
6
|
+
|
|
7
|
+
export interface SearchQuery {
|
|
8
|
+
query: string;
|
|
9
|
+
limit?: number;
|
|
10
|
+
includeRaw?: boolean;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
export interface SearchResultItem {
|
|
14
|
+
title: string;
|
|
15
|
+
url: string;
|
|
16
|
+
snippet: string;
|
|
17
|
+
score?: number;
|
|
18
|
+
sourceEngine: EngineId;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export interface SearchResponse {
|
|
22
|
+
engineId: EngineId;
|
|
23
|
+
items: SearchResultItem[];
|
|
24
|
+
raw?: unknown;
|
|
25
|
+
tookMs: number;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type SearchFailureReason =
|
|
29
|
+
| "network_error"
|
|
30
|
+
| "api_error"
|
|
31
|
+
| "no_results"
|
|
32
|
+
| "low_credit"
|
|
33
|
+
| "config_error"
|
|
34
|
+
| "no_provider"
|
|
35
|
+
| "provider_unavailable"
|
|
36
|
+
| "unknown";
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Error thrown when a search provider fails
|
|
40
|
+
*/
|
|
41
|
+
export class SearchError extends Error {
|
|
42
|
+
engineId: EngineId;
|
|
43
|
+
reason: SearchFailureReason;
|
|
44
|
+
statusCode?: number;
|
|
45
|
+
|
|
46
|
+
constructor(
|
|
47
|
+
engineId: EngineId,
|
|
48
|
+
reason: SearchFailureReason,
|
|
49
|
+
message: string,
|
|
50
|
+
statusCode?: number,
|
|
51
|
+
) {
|
|
52
|
+
super(message);
|
|
53
|
+
this.name = "SearchError";
|
|
54
|
+
this.engineId = engineId;
|
|
55
|
+
this.reason = reason;
|
|
56
|
+
this.statusCode = statusCode;
|
|
57
|
+
}
|
|
58
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./app/index";
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin Registry
|
|
3
|
+
*
|
|
4
|
+
* Central registry for managing search provider plugins.
|
|
5
|
+
* Handles plugin registration, lookup, and provider creation.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type { EngineConfigBase } from "../config/types";
|
|
9
|
+
import type {
|
|
10
|
+
CreateProviderOptions,
|
|
11
|
+
ManagedProvider,
|
|
12
|
+
PluginDefinition,
|
|
13
|
+
PluginInfo,
|
|
14
|
+
PluginRegistrationOptions,
|
|
15
|
+
PluginRegistrationResult,
|
|
16
|
+
} from "./types";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Central registry for search provider plugins
|
|
20
|
+
*
|
|
21
|
+
* The PluginRegistry provides:
|
|
22
|
+
* - Plugin registration with optional overwrite
|
|
23
|
+
* - Plugin lookup by type
|
|
24
|
+
* - Provider creation from registered plugins
|
|
25
|
+
* - Plugin metadata queries
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* // Get singleton instance
|
|
30
|
+
* const registry = PluginRegistry.getInstance();
|
|
31
|
+
*
|
|
32
|
+
* // Register a plugin
|
|
33
|
+
* registry.register(myPlugin);
|
|
34
|
+
*
|
|
35
|
+
* // Create a provider
|
|
36
|
+
* const provider = registry.createProvider('my-provider', config);
|
|
37
|
+
*
|
|
38
|
+
* // Check if plugin exists
|
|
39
|
+
* if (registry.has('my-provider')) { ... }
|
|
40
|
+
* ```
|
|
41
|
+
*/
|
|
42
|
+
export class PluginRegistry {
|
|
43
|
+
private static instance: PluginRegistry | null = null;
|
|
44
|
+
|
|
45
|
+
/** Registered plugins by type */
|
|
46
|
+
private plugins = new Map<string, PluginDefinition>();
|
|
47
|
+
|
|
48
|
+
/** Track which plugins are built-in */
|
|
49
|
+
private builtInTypes = new Set<string>();
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Get the singleton instance of PluginRegistry
|
|
53
|
+
*/
|
|
54
|
+
static getInstance(): PluginRegistry {
|
|
55
|
+
if (!PluginRegistry.instance) {
|
|
56
|
+
PluginRegistry.instance = new PluginRegistry();
|
|
57
|
+
}
|
|
58
|
+
return PluginRegistry.instance;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Reset the singleton instance (useful for testing)
|
|
63
|
+
*/
|
|
64
|
+
static resetInstance(): void {
|
|
65
|
+
PluginRegistry.instance = null;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* Private constructor - use getInstance()
|
|
70
|
+
*/
|
|
71
|
+
private constructor() {}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Register a plugin
|
|
75
|
+
*
|
|
76
|
+
* @param plugin - Plugin definition to register
|
|
77
|
+
* @param options - Registration options
|
|
78
|
+
* @returns Registration result
|
|
79
|
+
*
|
|
80
|
+
* @example
|
|
81
|
+
* ```typescript
|
|
82
|
+
* const result = registry.register(myPlugin);
|
|
83
|
+
* if (!result.success) {
|
|
84
|
+
* console.error(result.message);
|
|
85
|
+
* }
|
|
86
|
+
* ```
|
|
87
|
+
*/
|
|
88
|
+
async register(
|
|
89
|
+
plugin: PluginDefinition,
|
|
90
|
+
options: PluginRegistrationOptions = {},
|
|
91
|
+
): Promise<PluginRegistrationResult> {
|
|
92
|
+
const { overwrite = false } = options;
|
|
93
|
+
|
|
94
|
+
// Check for existing registration
|
|
95
|
+
if (this.plugins.has(plugin.type)) {
|
|
96
|
+
if (!overwrite) {
|
|
97
|
+
return {
|
|
98
|
+
success: false,
|
|
99
|
+
type: plugin.type,
|
|
100
|
+
message: `Plugin type '${plugin.type}' is already registered. Use overwrite option to replace.`,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
// Call onUnregister for existing plugin if it exists
|
|
105
|
+
const existing = this.plugins.get(plugin.type);
|
|
106
|
+
if (existing?.onUnregister) {
|
|
107
|
+
try {
|
|
108
|
+
await existing.onUnregister();
|
|
109
|
+
} catch (error) {
|
|
110
|
+
// Log but don't fail - we still want to register the new plugin
|
|
111
|
+
console.warn(`Error during onUnregister for plugin '${plugin.type}':`, error);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
// Register the plugin
|
|
117
|
+
this.plugins.set(plugin.type, plugin);
|
|
118
|
+
|
|
119
|
+
// Call onRegister if provided
|
|
120
|
+
if (plugin.onRegister) {
|
|
121
|
+
try {
|
|
122
|
+
await plugin.onRegister();
|
|
123
|
+
} catch (error) {
|
|
124
|
+
// Rollback registration on error
|
|
125
|
+
this.plugins.delete(plugin.type);
|
|
126
|
+
return {
|
|
127
|
+
success: false,
|
|
128
|
+
type: plugin.type,
|
|
129
|
+
message: `Plugin onRegister failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return {
|
|
135
|
+
success: true,
|
|
136
|
+
type: plugin.type,
|
|
137
|
+
overwritten: overwrite && this.plugins.has(plugin.type),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Register a plugin synchronously (no lifecycle hooks called)
|
|
143
|
+
*/
|
|
144
|
+
registerSync(
|
|
145
|
+
plugin: PluginDefinition,
|
|
146
|
+
options: PluginRegistrationOptions = {},
|
|
147
|
+
): PluginRegistrationResult {
|
|
148
|
+
const { overwrite = false } = options;
|
|
149
|
+
|
|
150
|
+
if (this.plugins.has(plugin.type) && !overwrite) {
|
|
151
|
+
return {
|
|
152
|
+
success: false,
|
|
153
|
+
type: plugin.type,
|
|
154
|
+
message: `Plugin type '${plugin.type}' is already registered.`,
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
this.plugins.set(plugin.type, plugin);
|
|
159
|
+
|
|
160
|
+
return {
|
|
161
|
+
success: true,
|
|
162
|
+
type: plugin.type,
|
|
163
|
+
overwritten: overwrite && this.plugins.has(plugin.type),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
/**
|
|
168
|
+
* Mark a plugin type as built-in
|
|
169
|
+
* Built-in plugins are identified in metadata
|
|
170
|
+
*/
|
|
171
|
+
markBuiltIn(type: string): void {
|
|
172
|
+
this.builtInTypes.add(type);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Unregister a plugin
|
|
177
|
+
*
|
|
178
|
+
* @param type - Plugin type to unregister
|
|
179
|
+
* @returns true if plugin was removed, false if not found
|
|
180
|
+
*/
|
|
181
|
+
async unregister(type: string): Promise<boolean> {
|
|
182
|
+
const plugin = this.plugins.get(type);
|
|
183
|
+
if (!plugin) {
|
|
184
|
+
return false;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
// Call onUnregister if provided
|
|
188
|
+
if (plugin.onUnregister) {
|
|
189
|
+
await plugin.onUnregister();
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
this.plugins.delete(type);
|
|
193
|
+
this.builtInTypes.delete(type);
|
|
194
|
+
return true;
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Check if a plugin type is registered
|
|
199
|
+
*/
|
|
200
|
+
has(type: string): boolean {
|
|
201
|
+
return this.plugins.has(type);
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* Get a plugin by type
|
|
206
|
+
*/
|
|
207
|
+
get(type: string): PluginDefinition | undefined {
|
|
208
|
+
return this.plugins.get(type);
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* Get all registered plugin types
|
|
213
|
+
*/
|
|
214
|
+
getTypes(): string[] {
|
|
215
|
+
return Array.from(this.plugins.keys());
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Get metadata for all registered plugins
|
|
220
|
+
*/
|
|
221
|
+
listPlugins(): PluginInfo[] {
|
|
222
|
+
return Array.from(this.plugins.values()).map((plugin) => ({
|
|
223
|
+
type: plugin.type,
|
|
224
|
+
displayName: plugin.displayName,
|
|
225
|
+
description: plugin.description,
|
|
226
|
+
docsUrl: plugin.docsUrl,
|
|
227
|
+
version: plugin.version,
|
|
228
|
+
hasLifecycle: plugin.hasLifecycle,
|
|
229
|
+
isBuiltIn: this.builtInTypes.has(plugin.type),
|
|
230
|
+
}));
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* Get metadata for a specific plugin
|
|
235
|
+
*/
|
|
236
|
+
getPluginInfo(type: string): PluginInfo | undefined {
|
|
237
|
+
const plugin = this.plugins.get(type);
|
|
238
|
+
if (!plugin) {
|
|
239
|
+
return undefined;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return {
|
|
243
|
+
type: plugin.type,
|
|
244
|
+
displayName: plugin.displayName,
|
|
245
|
+
description: plugin.description,
|
|
246
|
+
docsUrl: plugin.docsUrl,
|
|
247
|
+
version: plugin.version,
|
|
248
|
+
hasLifecycle: plugin.hasLifecycle,
|
|
249
|
+
isBuiltIn: this.builtInTypes.has(type),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Create a provider instance from a plugin
|
|
255
|
+
*
|
|
256
|
+
* @param config - Engine configuration (must include 'type' field)
|
|
257
|
+
* @param options - Creation options
|
|
258
|
+
* @returns Provider instance
|
|
259
|
+
* @throws Error if plugin not found or config validation fails
|
|
260
|
+
*
|
|
261
|
+
* @example
|
|
262
|
+
* ```typescript
|
|
263
|
+
* const config = { type: 'tavily', id: 'tavily', ... };
|
|
264
|
+
* const provider = registry.createProvider(config);
|
|
265
|
+
* ```
|
|
266
|
+
*/
|
|
267
|
+
createProvider<T extends EngineConfigBase>(
|
|
268
|
+
config: T & { type: string },
|
|
269
|
+
options: CreateProviderOptions = {},
|
|
270
|
+
): ManagedProvider {
|
|
271
|
+
const { container, skipValidation = false } = options;
|
|
272
|
+
|
|
273
|
+
const plugin = this.plugins.get(config.type);
|
|
274
|
+
if (!plugin) {
|
|
275
|
+
throw new Error(
|
|
276
|
+
`No plugin registered for type '${config.type}'. ` +
|
|
277
|
+
`Available types: ${this.getTypes().join(", ") || "none"}`,
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// Validate config if schema provided and validation not skipped
|
|
282
|
+
let validatedConfig = config;
|
|
283
|
+
if (plugin.configSchema && !skipValidation) {
|
|
284
|
+
try {
|
|
285
|
+
validatedConfig = plugin.configSchema.validate(config) as T & { type: string };
|
|
286
|
+
} catch (error) {
|
|
287
|
+
throw new Error(
|
|
288
|
+
`Config validation failed for plugin '${config.type}': ` +
|
|
289
|
+
`${error instanceof Error ? error.message : String(error)}`,
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// Create provider using factory
|
|
295
|
+
return plugin.factory(validatedConfig, container) as ManagedProvider;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Create multiple providers from configs
|
|
300
|
+
*/
|
|
301
|
+
createProviders(
|
|
302
|
+
configs: Array<EngineConfigBase & { type: string }>,
|
|
303
|
+
options: CreateProviderOptions = {},
|
|
304
|
+
): ManagedProvider[] {
|
|
305
|
+
return configs.map((config) => this.createProvider(config, options));
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
/**
|
|
309
|
+
* Clear all registered plugins
|
|
310
|
+
*/
|
|
311
|
+
async clear(): Promise<void> {
|
|
312
|
+
// Call onUnregister for all plugins
|
|
313
|
+
for (const plugin of this.plugins.values()) {
|
|
314
|
+
if (plugin.onUnregister) {
|
|
315
|
+
try {
|
|
316
|
+
await plugin.onUnregister();
|
|
317
|
+
} catch (error) {
|
|
318
|
+
console.warn(`Error during onUnregister for plugin '${plugin.type}':`, error);
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
this.plugins.clear();
|
|
324
|
+
this.builtInTypes.clear();
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/**
|
|
328
|
+
* Get count of registered plugins
|
|
329
|
+
*/
|
|
330
|
+
get size(): number {
|
|
331
|
+
return this.plugins.size;
|
|
332
|
+
}
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
// Export singleton getter as convenience
|
|
336
|
+
export const getPluginRegistry = (): PluginRegistry => PluginRegistry.getInstance();
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in Plugin Definitions
|
|
3
|
+
*
|
|
4
|
+
* Registers the core search providers as plugins:
|
|
5
|
+
* - Tavily
|
|
6
|
+
* - Brave
|
|
7
|
+
* - Linkup
|
|
8
|
+
* - SearchXNG
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import type {
|
|
12
|
+
BraveConfig,
|
|
13
|
+
EngineConfigBase,
|
|
14
|
+
LinkupConfig,
|
|
15
|
+
SearchxngConfig,
|
|
16
|
+
TavilyConfig,
|
|
17
|
+
} from "../config/types";
|
|
18
|
+
import type { SearchProvider } from "../core/provider";
|
|
19
|
+
import { BraveProvider } from "../providers/brave";
|
|
20
|
+
import { LinkupProvider } from "../providers/linkup";
|
|
21
|
+
import { SearchxngProvider } from "../providers/searchxng";
|
|
22
|
+
import { TavilyProvider } from "../providers/tavily";
|
|
23
|
+
import { PluginRegistry } from "./PluginRegistry";
|
|
24
|
+
import type { PluginDefinition } from "./types";
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Tavily plugin definition
|
|
28
|
+
*/
|
|
29
|
+
export const tavilyPlugin: PluginDefinition<TavilyConfig, TavilyProvider> = {
|
|
30
|
+
type: "tavily",
|
|
31
|
+
displayName: "Tavily",
|
|
32
|
+
description: "AI-powered search API with high-quality results",
|
|
33
|
+
docsUrl: "https://docs.tavily.com/",
|
|
34
|
+
version: "1.0.0",
|
|
35
|
+
hasLifecycle: false,
|
|
36
|
+
factory: (config) => new TavilyProvider(config),
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Brave plugin definition
|
|
41
|
+
*/
|
|
42
|
+
export const bravePlugin: PluginDefinition<BraveConfig, BraveProvider> = {
|
|
43
|
+
type: "brave",
|
|
44
|
+
displayName: "Brave Search",
|
|
45
|
+
description: "Privacy-focused search engine API",
|
|
46
|
+
docsUrl: "https://api.search.brave.com/app/documentation",
|
|
47
|
+
version: "1.0.0",
|
|
48
|
+
hasLifecycle: false,
|
|
49
|
+
factory: (config) => new BraveProvider(config),
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Linkup plugin definition
|
|
54
|
+
*/
|
|
55
|
+
export const linkupPlugin: PluginDefinition<LinkupConfig, LinkupProvider> = {
|
|
56
|
+
type: "linkup",
|
|
57
|
+
displayName: "Linkup",
|
|
58
|
+
description: "Web search API with Docker support",
|
|
59
|
+
docsUrl: "https://docs.linkup.ai/",
|
|
60
|
+
version: "1.0.0",
|
|
61
|
+
hasLifecycle: true,
|
|
62
|
+
factory: (config) => new LinkupProvider(config),
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* SearchXNG plugin definition
|
|
67
|
+
*/
|
|
68
|
+
export const searchxngPlugin: PluginDefinition<SearchxngConfig, SearchxngProvider> = {
|
|
69
|
+
type: "searchxng",
|
|
70
|
+
displayName: "SearXNG (Local)",
|
|
71
|
+
description: "Self-hosted meta search engine with Docker auto-start",
|
|
72
|
+
docsUrl: "https://docs.searxng.org/",
|
|
73
|
+
version: "1.0.0",
|
|
74
|
+
hasLifecycle: true,
|
|
75
|
+
factory: (config) => new SearchxngProvider(config),
|
|
76
|
+
};
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* All built-in plugins
|
|
80
|
+
* Using base types since specific configs/providers extend them
|
|
81
|
+
*/
|
|
82
|
+
export const builtInPlugins: PluginDefinition<EngineConfigBase, SearchProvider>[] = [
|
|
83
|
+
tavilyPlugin,
|
|
84
|
+
bravePlugin,
|
|
85
|
+
linkupPlugin,
|
|
86
|
+
searchxngPlugin,
|
|
87
|
+
];
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Register all built-in plugins with the registry
|
|
91
|
+
*
|
|
92
|
+
* @param registry - Plugin registry instance (defaults to singleton)
|
|
93
|
+
* @returns Array of registration results
|
|
94
|
+
*
|
|
95
|
+
* @example
|
|
96
|
+
* ```typescript
|
|
97
|
+
* // Register with default singleton
|
|
98
|
+
* await registerBuiltInPlugins();
|
|
99
|
+
*
|
|
100
|
+
* // Or with custom registry
|
|
101
|
+
* const registry = new PluginRegistry();
|
|
102
|
+
* await registerBuiltInPlugins(registry);
|
|
103
|
+
* ```
|
|
104
|
+
*/
|
|
105
|
+
export async function registerBuiltInPlugins(
|
|
106
|
+
registry: PluginRegistry = PluginRegistry.getInstance(),
|
|
107
|
+
): Promise<void> {
|
|
108
|
+
for (const plugin of builtInPlugins) {
|
|
109
|
+
const result = registry.registerSync(plugin);
|
|
110
|
+
if (result.success) {
|
|
111
|
+
registry.markBuiltIn(plugin.type);
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Check if built-in plugins are registered
|
|
118
|
+
*/
|
|
119
|
+
export function areBuiltInPluginsRegistered(
|
|
120
|
+
registry: PluginRegistry = PluginRegistry.getInstance(),
|
|
121
|
+
): boolean {
|
|
122
|
+
return builtInPlugins.every((plugin) => registry.has(plugin.type));
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
* Get list of built-in plugin types
|
|
127
|
+
*/
|
|
128
|
+
export function getBuiltInPluginTypes(): string[] {
|
|
129
|
+
return builtInPlugins.map((p) => p.type);
|
|
130
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Plugin System
|
|
3
|
+
*
|
|
4
|
+
* Exports all plugin-related types, classes, and utilities.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
// Built-in plugins
|
|
8
|
+
export {
|
|
9
|
+
areBuiltInPluginsRegistered,
|
|
10
|
+
bravePlugin,
|
|
11
|
+
builtInPlugins,
|
|
12
|
+
getBuiltInPluginTypes,
|
|
13
|
+
linkupPlugin,
|
|
14
|
+
registerBuiltInPlugins,
|
|
15
|
+
searchxngPlugin,
|
|
16
|
+
tavilyPlugin,
|
|
17
|
+
} from "./builtin";
|
|
18
|
+
// Registry
|
|
19
|
+
export { getPluginRegistry, PluginRegistry } from "./PluginRegistry";
|
|
20
|
+
// Types
|
|
21
|
+
export type {
|
|
22
|
+
CreateProviderOptions,
|
|
23
|
+
ManagedProvider,
|
|
24
|
+
PluginConfig,
|
|
25
|
+
PluginConfigSchema,
|
|
26
|
+
PluginDefinition,
|
|
27
|
+
PluginInfo,
|
|
28
|
+
PluginProvider,
|
|
29
|
+
PluginRegistrationOptions,
|
|
30
|
+
PluginRegistrationResult,
|
|
31
|
+
ProviderFactory,
|
|
32
|
+
} from "./types";
|
|
33
|
+
export { hasLifecycleManagement, isLifecycleProvider } from "./types";
|