@defai.digital/ax-cli 3.2.0 → 3.4.0
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/.ax-cli/memory.json +8 -1
- package/README.md +118 -2
- package/config/models.yaml +13 -0
- package/config/settings.yaml +6 -0
- package/dist/agent/context-manager.d.ts +5 -5
- package/dist/agent/context-manager.js +19 -9
- package/dist/agent/context-manager.js.map +1 -1
- package/dist/agent/dependency-resolver.js +2 -1
- package/dist/agent/dependency-resolver.js.map +1 -1
- package/dist/agent/llm-agent.d.ts +3 -2
- package/dist/agent/llm-agent.js +64 -58
- package/dist/agent/llm-agent.js.map +1 -1
- package/dist/agent/subagent.js +2 -1
- package/dist/agent/subagent.js.map +1 -1
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.d.ts +29 -0
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.js +103 -0
- package/dist/analyzers/architecture/anti-pattern-detectors/god-object-detector.js.map +1 -0
- package/dist/analyzers/architecture/architecture-analyzer.d.ts +58 -0
- package/dist/analyzers/architecture/architecture-analyzer.js +276 -0
- package/dist/analyzers/architecture/architecture-analyzer.js.map +1 -0
- package/dist/analyzers/architecture/index.d.ts +12 -0
- package/dist/analyzers/architecture/index.js +14 -0
- package/dist/analyzers/architecture/index.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/base-detector.d.ts +27 -0
- package/dist/analyzers/architecture/pattern-detectors/base-detector.js +31 -0
- package/dist/analyzers/architecture/pattern-detectors/base-detector.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.d.ts +11 -0
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.js +57 -0
- package/dist/analyzers/architecture/pattern-detectors/clean-architecture-detector.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.d.ts +11 -0
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.js +43 -0
- package/dist/analyzers/architecture/pattern-detectors/mvc-detector.js.map +1 -0
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.d.ts +11 -0
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.js +49 -0
- package/dist/analyzers/architecture/pattern-detectors/repository-detector.js.map +1 -0
- package/dist/analyzers/architecture/project-structure-scanner.d.ts +54 -0
- package/dist/analyzers/architecture/project-structure-scanner.js +200 -0
- package/dist/analyzers/architecture/project-structure-scanner.js.map +1 -0
- package/dist/analyzers/best-practices/base-rule.d.ts +45 -0
- package/dist/analyzers/best-practices/base-rule.js +45 -0
- package/dist/analyzers/best-practices/base-rule.js.map +1 -0
- package/dist/analyzers/best-practices/best-practice-validator.d.ts +35 -0
- package/dist/analyzers/best-practices/best-practice-validator.js +181 -0
- package/dist/analyzers/best-practices/best-practice-validator.js.map +1 -0
- package/dist/analyzers/best-practices/rules/index.d.ts +7 -0
- package/dist/analyzers/best-practices/rules/index.js +56 -0
- package/dist/analyzers/best-practices/rules/index.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.js +41 -0
- package/dist/analyzers/best-practices/rules/typescript/consistent-naming.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.d.ts +27 -0
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.js +76 -0
- package/dist/analyzers/best-practices/rules/typescript/function-complexity.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/index.d.ts +15 -0
- package/dist/analyzers/best-practices/rules/typescript/index.js +16 -0
- package/dist/analyzers/best-practices/rules/typescript/index.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.d.ts +18 -0
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.js +25 -0
- package/dist/analyzers/best-practices/rules/typescript/max-file-length.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.js +27 -0
- package/dist/analyzers/best-practices/rules/typescript/no-any-type.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.d.ts +18 -0
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.js +39 -0
- package/dist/analyzers/best-practices/rules/typescript/no-implicit-any.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.js +32 -0
- package/dist/analyzers/best-practices/rules/typescript/no-magic-numbers.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.js +36 -0
- package/dist/analyzers/best-practices/rules/typescript/no-unused-vars.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.js +33 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-const.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.js +34 -0
- package/dist/analyzers/best-practices/rules/typescript/prefer-readonly.js.map +1 -0
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.d.ts +17 -0
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.js +27 -0
- package/dist/analyzers/best-practices/rules/typescript/proper-error-handling.js.map +1 -0
- package/dist/analyzers/best-practices/types.d.ts +86 -0
- package/dist/analyzers/best-practices/types.js +7 -0
- package/dist/analyzers/best-practices/types.js.map +1 -0
- package/dist/analyzers/cache/analysis-cache.d.ts +41 -0
- package/dist/analyzers/cache/analysis-cache.js +84 -0
- package/dist/analyzers/cache/analysis-cache.js.map +1 -0
- package/dist/analyzers/errors.d.ts +51 -0
- package/dist/analyzers/errors.js +79 -0
- package/dist/analyzers/errors.js.map +1 -0
- package/dist/commands/doctor.js +3 -2
- package/dist/commands/doctor.js.map +1 -1
- package/dist/commands/frontend.d.ts +9 -0
- package/dist/commands/frontend.js +645 -0
- package/dist/commands/frontend.js.map +1 -0
- package/dist/commands/mcp.js +652 -3
- package/dist/commands/mcp.js.map +1 -1
- package/dist/commands/models.js +2 -2
- package/dist/commands/models.js.map +1 -1
- package/dist/commands/setup.js +100 -41
- package/dist/commands/setup.js.map +1 -1
- package/dist/constants.d.ts +4 -0
- package/dist/constants.js +4 -0
- package/dist/constants.js.map +1 -1
- package/dist/hooks/use-enhanced-input.js +16 -3
- package/dist/hooks/use-enhanced-input.js.map +1 -1
- package/dist/hooks/use-input-handler.js +9 -4
- package/dist/hooks/use-input-handler.js.map +1 -1
- package/dist/index.js +5 -2
- package/dist/index.js.map +1 -1
- package/dist/llm/client.d.ts +1 -0
- package/dist/llm/tools.js +86 -0
- package/dist/llm/tools.js.map +1 -1
- package/dist/llm/types.d.ts +49 -22
- package/dist/llm/types.js +12 -8
- package/dist/llm/types.js.map +1 -1
- package/dist/mcp/client.d.ts +5 -0
- package/dist/mcp/client.js +55 -0
- package/dist/mcp/client.js.map +1 -1
- package/dist/mcp/config.d.ts +1 -1
- package/dist/mcp/config.js +2 -2
- package/dist/mcp/config.js.map +1 -1
- package/dist/mcp/health.d.ts +120 -0
- package/dist/mcp/health.js +267 -0
- package/dist/mcp/health.js.map +1 -0
- package/dist/mcp/reconnection.d.ts +93 -0
- package/dist/mcp/reconnection.js +216 -0
- package/dist/mcp/reconnection.js.map +1 -0
- package/dist/mcp/registry.d.ts +71 -0
- package/dist/mcp/registry.js +257 -0
- package/dist/mcp/registry.js.map +1 -0
- package/dist/mcp/resources.d.ts +53 -0
- package/dist/mcp/resources.js +135 -0
- package/dist/mcp/resources.js.map +1 -0
- package/dist/mcp/templates.d.ts +52 -0
- package/dist/mcp/templates.js +624 -0
- package/dist/mcp/templates.js.map +1 -0
- package/dist/mcp/validation.d.ts +25 -0
- package/dist/mcp/validation.js +209 -0
- package/dist/mcp/validation.js.map +1 -0
- package/dist/memory/context-generator.js +1 -2
- package/dist/memory/context-generator.js.map +1 -1
- package/dist/planner/types.d.ts +2 -2
- package/dist/schemas/api-schemas.d.ts +2 -1
- package/dist/schemas/api-schemas.js +6 -4
- package/dist/schemas/api-schemas.js.map +1 -1
- package/dist/schemas/index.d.ts +4 -4
- package/dist/schemas/tool-schemas.d.ts +2 -2
- package/dist/schemas/yaml-schemas.d.ts +15 -0
- package/dist/schemas/yaml-schemas.js +3 -0
- package/dist/schemas/yaml-schemas.js.map +1 -1
- package/dist/sdk/index.d.ts +138 -0
- package/dist/sdk/index.js +173 -0
- package/dist/sdk/index.js.map +1 -0
- package/dist/sdk/types.d.ts +53 -0
- package/dist/sdk/types.js +8 -0
- package/dist/sdk/types.js.map +1 -0
- package/dist/tools/analysis-tools/architecture-tool.d.ts +46 -0
- package/dist/tools/analysis-tools/architecture-tool.js +124 -0
- package/dist/tools/analysis-tools/architecture-tool.js.map +1 -0
- package/dist/tools/analysis-tools/validation-tool.d.ts +51 -0
- package/dist/tools/analysis-tools/validation-tool.js +121 -0
- package/dist/tools/analysis-tools/validation-tool.js.map +1 -0
- package/dist/tools/bash.js +25 -10
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/web-search/cache.d.ts +62 -0
- package/dist/tools/web-search/cache.js +105 -0
- package/dist/tools/web-search/cache.js.map +1 -0
- package/dist/tools/web-search/engines/brave.d.ts +16 -0
- package/dist/tools/web-search/engines/brave.js +99 -0
- package/dist/tools/web-search/engines/brave.js.map +1 -0
- package/dist/tools/web-search/engines/crates.d.ts +19 -0
- package/dist/tools/web-search/engines/crates.js +87 -0
- package/dist/tools/web-search/engines/crates.js.map +1 -0
- package/dist/tools/web-search/engines/npm.d.ts +18 -0
- package/dist/tools/web-search/engines/npm.js +86 -0
- package/dist/tools/web-search/engines/npm.js.map +1 -0
- package/dist/tools/web-search/engines/pypi.d.ts +18 -0
- package/dist/tools/web-search/engines/pypi.js +75 -0
- package/dist/tools/web-search/engines/pypi.js.map +1 -0
- package/dist/tools/web-search/engines/tavily.d.ts +17 -0
- package/dist/tools/web-search/engines/tavily.js +73 -0
- package/dist/tools/web-search/engines/tavily.js.map +1 -0
- package/dist/tools/web-search/index.d.ts +13 -0
- package/dist/tools/web-search/index.js +13 -0
- package/dist/tools/web-search/index.js.map +1 -0
- package/dist/tools/web-search/router.d.ts +36 -0
- package/dist/tools/web-search/router.js +280 -0
- package/dist/tools/web-search/router.js.map +1 -0
- package/dist/tools/web-search/types.d.ts +45 -0
- package/dist/tools/web-search/types.js +6 -0
- package/dist/tools/web-search/types.js.map +1 -0
- package/dist/tools/web-search/web-search-tool.d.ts +51 -0
- package/dist/tools/web-search/web-search-tool.js +256 -0
- package/dist/tools/web-search/web-search-tool.js.map +1 -0
- package/dist/types/analysis.d.ts +177 -0
- package/dist/types/analysis.js +8 -0
- package/dist/types/analysis.js.map +1 -0
- package/dist/ui/components/api-key-input.js +2 -2
- package/dist/ui/components/api-key-input.js.map +1 -1
- package/dist/ui/components/chat-history.js +14 -7
- package/dist/ui/components/chat-history.js.map +1 -1
- package/dist/ui/components/chat-input.js +12 -7
- package/dist/ui/components/chat-input.js.map +1 -1
- package/dist/ui/components/chat-interface.js +75 -54
- package/dist/ui/components/chat-interface.js.map +1 -1
- package/dist/ui/components/keyboard-hints.js +5 -4
- package/dist/ui/components/keyboard-hints.js.map +1 -1
- package/dist/ui/components/quick-actions.js +1 -0
- package/dist/ui/components/quick-actions.js.map +1 -1
- package/dist/ui/components/reasoning-display.js +14 -4
- package/dist/ui/components/reasoning-display.js.map +1 -1
- package/dist/ui/components/status-bar.d.ts +1 -0
- package/dist/ui/components/status-bar.js +37 -39
- package/dist/ui/components/status-bar.js.map +1 -1
- package/dist/ui/components/toast-notification.d.ts +29 -0
- package/dist/ui/components/toast-notification.js +17 -3
- package/dist/ui/components/toast-notification.js.map +1 -1
- package/dist/ui/components/welcome-panel.d.ts +1 -0
- package/dist/ui/components/welcome-panel.js +106 -4
- package/dist/ui/components/welcome-panel.js.map +1 -1
- package/dist/utils/analysis-logger.d.ts +47 -0
- package/dist/utils/analysis-logger.js +70 -0
- package/dist/utils/analysis-logger.js.map +1 -0
- package/dist/utils/automatosx-detector.d.ts +19 -0
- package/dist/utils/automatosx-detector.js +52 -0
- package/dist/utils/automatosx-detector.js.map +1 -0
- package/dist/utils/config-loader.d.ts +4 -0
- package/dist/utils/config-loader.js.map +1 -1
- package/dist/utils/confirmation-service.js +1 -1
- package/dist/utils/confirmation-service.js.map +1 -1
- package/dist/utils/init-previewer.js +26 -4
- package/dist/utils/init-previewer.js.map +1 -1
- package/dist/utils/setup-validator.js +1 -0
- package/dist/utils/setup-validator.js.map +1 -1
- package/dist/utils/text-utils.d.ts +1 -0
- package/dist/utils/text-utils.js +12 -0
- package/dist/utils/text-utils.js.map +1 -1
- package/package.json +19 -4
- package/vitest.config.ts +1 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* npm Registry Search Engine
|
|
3
|
+
* Free, unlimited search for npm packages
|
|
4
|
+
* No API key required
|
|
5
|
+
*/
|
|
6
|
+
import type { SearchEngine, WebSearchResult, SearchOptions } from "../types.js";
|
|
7
|
+
export declare class NpmSearch implements SearchEngine {
|
|
8
|
+
readonly name = "npm";
|
|
9
|
+
private baseUrl;
|
|
10
|
+
private timeout;
|
|
11
|
+
/**
|
|
12
|
+
* Always available - no API key required
|
|
13
|
+
*/
|
|
14
|
+
isAvailable(): boolean;
|
|
15
|
+
search(query: string, options?: SearchOptions): Promise<WebSearchResult[]>;
|
|
16
|
+
private formatResults;
|
|
17
|
+
private createSnippet;
|
|
18
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* npm Registry Search Engine
|
|
3
|
+
* Free, unlimited search for npm packages
|
|
4
|
+
* No API key required
|
|
5
|
+
*/
|
|
6
|
+
import axios from "axios";
|
|
7
|
+
export class NpmSearch {
|
|
8
|
+
name = "npm";
|
|
9
|
+
baseUrl = "https://registry.npmjs.org/-/v1/search";
|
|
10
|
+
timeout = 10000; // 10 second timeout
|
|
11
|
+
/**
|
|
12
|
+
* Always available - no API key required
|
|
13
|
+
*/
|
|
14
|
+
isAvailable() {
|
|
15
|
+
return true;
|
|
16
|
+
}
|
|
17
|
+
async search(query, options) {
|
|
18
|
+
try {
|
|
19
|
+
const params = new URLSearchParams({
|
|
20
|
+
text: query,
|
|
21
|
+
size: Math.min(options?.maxResults || 5, 20).toString(),
|
|
22
|
+
});
|
|
23
|
+
const response = await axios.get(`${this.baseUrl}?${params.toString()}`, {
|
|
24
|
+
timeout: options?.timeout || this.timeout,
|
|
25
|
+
headers: {
|
|
26
|
+
Accept: "application/json",
|
|
27
|
+
},
|
|
28
|
+
});
|
|
29
|
+
return this.formatResults(response.data);
|
|
30
|
+
}
|
|
31
|
+
catch (error) {
|
|
32
|
+
if (axios.isAxiosError(error)) {
|
|
33
|
+
if (error.code === "ECONNABORTED") {
|
|
34
|
+
throw new Error("npm search timeout");
|
|
35
|
+
}
|
|
36
|
+
throw new Error(`npm registry error: ${error.response?.data?.error || error.message}`);
|
|
37
|
+
}
|
|
38
|
+
throw error;
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
formatResults(response) {
|
|
42
|
+
return response.objects.map((pkg) => ({
|
|
43
|
+
title: pkg.package.name,
|
|
44
|
+
url: pkg.package.links.npm || `https://www.npmjs.com/package/${pkg.package.name}`,
|
|
45
|
+
snippet: this.createSnippet(pkg),
|
|
46
|
+
source: this.name,
|
|
47
|
+
relevanceScore: pkg.score.final * 100, // Convert 0-1 to 0-100
|
|
48
|
+
publishedDate: pkg.package.date,
|
|
49
|
+
metadata: {
|
|
50
|
+
version: pkg.package.version,
|
|
51
|
+
author: pkg.package.author?.name || pkg.package.publisher.username,
|
|
52
|
+
quality: pkg.score.detail.quality,
|
|
53
|
+
popularity: pkg.score.detail.popularity,
|
|
54
|
+
maintenance: pkg.score.detail.maintenance,
|
|
55
|
+
homepage: pkg.package.links.homepage,
|
|
56
|
+
repository: pkg.package.links.repository,
|
|
57
|
+
},
|
|
58
|
+
}));
|
|
59
|
+
}
|
|
60
|
+
createSnippet(pkg) {
|
|
61
|
+
const parts = [];
|
|
62
|
+
if (pkg.package.description) {
|
|
63
|
+
parts.push(pkg.package.description);
|
|
64
|
+
}
|
|
65
|
+
parts.push(`v${pkg.package.version}`);
|
|
66
|
+
if (pkg.package.author?.name) {
|
|
67
|
+
parts.push(`by ${pkg.package.author.name}`);
|
|
68
|
+
}
|
|
69
|
+
// Add quality indicators
|
|
70
|
+
const quality = pkg.score.detail.quality;
|
|
71
|
+
const popularity = pkg.score.detail.popularity;
|
|
72
|
+
const maintenance = pkg.score.detail.maintenance;
|
|
73
|
+
const indicators = [];
|
|
74
|
+
if (quality > 0.7)
|
|
75
|
+
indicators.push("high quality");
|
|
76
|
+
if (popularity > 0.7)
|
|
77
|
+
indicators.push("popular");
|
|
78
|
+
if (maintenance > 0.7)
|
|
79
|
+
indicators.push("well-maintained");
|
|
80
|
+
if (indicators.length > 0) {
|
|
81
|
+
parts.push(`(${indicators.join(", ")})`);
|
|
82
|
+
}
|
|
83
|
+
return parts.join(" • ");
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=npm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"npm.js","sourceRoot":"","sources":["../../../../src/tools/web-search/engines/npm.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAyC1B,MAAM,OAAO,SAAS;IACJ,IAAI,GAAG,KAAK,CAAC;IACrB,OAAO,GAAG,wCAAwC,CAAC;IACnD,OAAO,GAAG,KAAK,CAAC,CAAC,oBAAoB;IAE7C;;OAEG;IACH,WAAW;QACT,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,MAAM,CACV,KAAa,EACb,OAAuB;QAEvB,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC;gBACjC,IAAI,EAAE,KAAK;gBACX,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,UAAU,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,QAAQ,EAAE;aACxD,CAAC,CAAC;YAEH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,CAC9B,GAAG,IAAI,CAAC,OAAO,IAAI,MAAM,CAAC,QAAQ,EAAE,EAAE,EACtC;gBACE,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC,OAAO;gBACzC,OAAO,EAAE;oBACP,MAAM,EAAE,kBAAkB;iBAC3B;aACF,CACF,CAAC;YAEF,OAAO,IAAI,CAAC,aAAa,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;QAC3C,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,IAAI,KAAK,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;gBAC9B,IAAI,KAAK,CAAC,IAAI,KAAK,cAAc,EAAE,CAAC;oBAClC,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;gBACxC,CAAC;gBACD,MAAM,IAAI,KAAK,CACb,uBAAuB,KAAK,CAAC,QAAQ,EAAE,IAAI,EAAE,KAAK,IAAI,KAAK,CAAC,OAAO,EAAE,CACtE,CAAC;YACJ,CAAC;YACD,MAAM,KAAK,CAAC;QACd,CAAC;IACH,CAAC;IAEO,aAAa,CAAC,QAAqB;QACzC,OAAO,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACpC,KAAK,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI;YACvB,GAAG,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,IAAI,iCAAiC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE;YACjF,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,GAAG,CAAC;YAChC,MAAM,EAAE,IAAI,CAAC,IAAI;YACjB,cAAc,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,GAAG,GAAG,EAAE,uBAAuB;YAC9D,aAAa,EAAE,GAAG,CAAC,OAAO,CAAC,IAAI;YAC/B,QAAQ,EAAE;gBACR,OAAO,EAAE,GAAG,CAAC,OAAO,CAAC,OAAO;gBAC5B,MAAM,EAAE,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,IAAI,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,QAAQ;gBAClE,OAAO,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO;gBACjC,UAAU,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU;gBACvC,WAAW,EAAE,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW;gBACzC,QAAQ,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ;gBACpC,UAAU,EAAE,GAAG,CAAC,OAAO,CAAC,KAAK,CAAC,UAAU;aACzC;SACF,CAAC,CAAC,CAAC;IACN,CAAC;IAEO,aAAa,CAAC,GAAe;QACnC,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAI,GAAG,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAC5B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC;QACtC,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,OAAO,CAAC,OAAO,EAAE,CAAC,CAAC;QAEtC,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC;YAC7B,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QAC9C,CAAC;QAED,yBAAyB;QACzB,MAAM,OAAO,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC;QACzC,MAAM,UAAU,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,UAAU,CAAC;QAC/C,MAAM,WAAW,GAAG,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,WAAW,CAAC;QAEjD,MAAM,UAAU,GAAa,EAAE,CAAC;QAChC,IAAI,OAAO,GAAG,GAAG;YAAE,UAAU,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QACnD,IAAI,UAAU,GAAG,GAAG;YAAE,UAAU,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,WAAW,GAAG,GAAG;YAAE,UAAU,CAAC,IAAI,CAAC,iBAAiB,CAAC,CAAC;QAE1D,IAAI,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC1B,KAAK,CAAC,IAAI,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC3C,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PyPI (Python Package Index) Search Engine
|
|
3
|
+
* Free, unlimited search for Python packages
|
|
4
|
+
* No API key required
|
|
5
|
+
*/
|
|
6
|
+
import type { SearchEngine, WebSearchResult, SearchOptions } from "../types.js";
|
|
7
|
+
export declare class PyPISearch implements SearchEngine {
|
|
8
|
+
readonly name = "pypi";
|
|
9
|
+
private baseUrl;
|
|
10
|
+
private timeout;
|
|
11
|
+
/**
|
|
12
|
+
* Always available - no API key required
|
|
13
|
+
*/
|
|
14
|
+
isAvailable(): boolean;
|
|
15
|
+
search(query: string, options?: SearchOptions): Promise<WebSearchResult[]>;
|
|
16
|
+
private formatResult;
|
|
17
|
+
private createSnippet;
|
|
18
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PyPI (Python Package Index) Search Engine
|
|
3
|
+
* Free, unlimited search for Python packages
|
|
4
|
+
* No API key required
|
|
5
|
+
*/
|
|
6
|
+
import axios from "axios";
|
|
7
|
+
// Note: PyPI's search API is being rebuilt, so we use direct package lookup instead
|
|
8
|
+
export class PyPISearch {
|
|
9
|
+
name = "pypi";
|
|
10
|
+
baseUrl = "https://pypi.org/pypi";
|
|
11
|
+
timeout = 10000; // 10 second timeout
|
|
12
|
+
/**
|
|
13
|
+
* Always available - no API key required
|
|
14
|
+
*/
|
|
15
|
+
isAvailable() {
|
|
16
|
+
return true;
|
|
17
|
+
}
|
|
18
|
+
async search(query, options) {
|
|
19
|
+
try {
|
|
20
|
+
// PyPI's official search is being rebuilt, so we use direct package lookup
|
|
21
|
+
// Try to fetch package info directly
|
|
22
|
+
const packageResponse = await axios.get(`${this.baseUrl}/${encodeURIComponent(query)}/json`, {
|
|
23
|
+
timeout: options?.timeout || this.timeout,
|
|
24
|
+
validateStatus: (status) => status === 200 || status === 404,
|
|
25
|
+
});
|
|
26
|
+
if (packageResponse.status === 404) {
|
|
27
|
+
// Package not found, return empty results
|
|
28
|
+
return [];
|
|
29
|
+
}
|
|
30
|
+
return this.formatResult(packageResponse.data);
|
|
31
|
+
}
|
|
32
|
+
catch (error) {
|
|
33
|
+
// Return empty results on error rather than failing
|
|
34
|
+
// PyPI search is a best-effort feature
|
|
35
|
+
return [];
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
formatResult(data) {
|
|
39
|
+
if (!data.info)
|
|
40
|
+
return [];
|
|
41
|
+
const info = data.info;
|
|
42
|
+
return [
|
|
43
|
+
{
|
|
44
|
+
title: info.name,
|
|
45
|
+
url: `https://pypi.org/project/${info.name}/`,
|
|
46
|
+
snippet: this.createSnippet(info),
|
|
47
|
+
source: this.name,
|
|
48
|
+
relevanceScore: 100, // Exact match
|
|
49
|
+
publishedDate: info.release_date,
|
|
50
|
+
metadata: {
|
|
51
|
+
version: info.version,
|
|
52
|
+
author: info.author,
|
|
53
|
+
license: info.license,
|
|
54
|
+
homepage: info.home_page || info.project_urls?.Homepage,
|
|
55
|
+
requiresPython: info.requires_python,
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
];
|
|
59
|
+
}
|
|
60
|
+
createSnippet(info) {
|
|
61
|
+
const parts = [];
|
|
62
|
+
if (info.summary) {
|
|
63
|
+
parts.push(info.summary);
|
|
64
|
+
}
|
|
65
|
+
parts.push(`v${info.version}`);
|
|
66
|
+
if (info.author) {
|
|
67
|
+
parts.push(`by ${info.author}`);
|
|
68
|
+
}
|
|
69
|
+
if (info.license) {
|
|
70
|
+
parts.push(`License: ${info.license}`);
|
|
71
|
+
}
|
|
72
|
+
return parts.join(" • ");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=pypi.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pypi.js","sourceRoot":"","sources":["../../../../src/tools/web-search/engines/pypi.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAO1B,oFAAoF;AAEpF,MAAM,OAAO,UAAU;IACL,IAAI,GAAG,MAAM,CAAC;IACtB,OAAO,GAAG,uBAAuB,CAAC;IAClC,OAAO,GAAG,KAAK,CAAC,CAAC,oBAAoB;IAE7C;;OAEG;IACH,WAAW;QACT,OAAO,IAAI,CAAC;IACd,CAAC;IAED,KAAK,CAAC,MAAM,CACV,KAAa,EACb,OAAuB;QAEvB,IAAI,CAAC;YACH,2EAA2E;YAC3E,qCAAqC;YACrC,MAAM,eAAe,GAAG,MAAM,KAAK,CAAC,GAAG,CACrC,GAAG,IAAI,CAAC,OAAO,IAAI,kBAAkB,CAAC,KAAK,CAAC,OAAO,EACnD;gBACE,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC,OAAO;gBACzC,cAAc,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG;aAC7D,CACF,CAAC;YAEF,IAAI,eAAe,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBACnC,0CAA0C;gBAC1C,OAAO,EAAE,CAAC;YACZ,CAAC;YAED,OAAO,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC;QACjD,CAAC;QAAC,OAAO,KAAU,EAAE,CAAC;YACpB,oDAAoD;YACpD,uCAAuC;YACvC,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,YAAY,CAAC,IAAS;QAC5B,IAAI,CAAC,IAAI,CAAC,IAAI;YAAE,OAAO,EAAE,CAAC;QAE1B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC;QACvB,OAAO;YACL;gBACE,KAAK,EAAE,IAAI,CAAC,IAAI;gBAChB,GAAG,EAAE,4BAA4B,IAAI,CAAC,IAAI,GAAG;gBAC7C,OAAO,EAAE,IAAI,CAAC,aAAa,CAAC,IAAI,CAAC;gBACjC,MAAM,EAAE,IAAI,CAAC,IAAI;gBACjB,cAAc,EAAE,GAAG,EAAE,cAAc;gBACnC,aAAa,EAAE,IAAI,CAAC,YAAY;gBAChC,QAAQ,EAAE;oBACR,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,MAAM,EAAE,IAAI,CAAC,MAAM;oBACnB,OAAO,EAAE,IAAI,CAAC,OAAO;oBACrB,QAAQ,EAAE,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,YAAY,EAAE,QAAQ;oBACvD,cAAc,EAAE,IAAI,CAAC,eAAe;iBACrC;aACF;SACF,CAAC;IACJ,CAAC;IAEO,aAAa,CAAC,IAAS;QAC7B,MAAM,KAAK,GAAa,EAAE,CAAC;QAE3B,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3B,CAAC;QAED,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QAE/B,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChB,KAAK,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;QAClC,CAAC;QAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YACjB,KAAK,CAAC,IAAI,CAAC,YAAY,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACzC,CAAC;QAED,OAAO,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;CACF"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tavily AI Search Engine
|
|
3
|
+
* AI-optimized search designed for LLMs
|
|
4
|
+
* https://tavily.com/
|
|
5
|
+
*/
|
|
6
|
+
import type { SearchEngine, WebSearchResult, SearchOptions } from "../types.js";
|
|
7
|
+
export declare class TavilySearch implements SearchEngine {
|
|
8
|
+
readonly name = "tavily";
|
|
9
|
+
private apiKey;
|
|
10
|
+
private baseUrl;
|
|
11
|
+
private timeout;
|
|
12
|
+
constructor();
|
|
13
|
+
isAvailable(): boolean;
|
|
14
|
+
search(query: string, options?: SearchOptions): Promise<WebSearchResult[]>;
|
|
15
|
+
private formatResults;
|
|
16
|
+
getAnswer(results: WebSearchResult[]): string | undefined;
|
|
17
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Tavily AI Search Engine
|
|
3
|
+
* AI-optimized search designed for LLMs
|
|
4
|
+
* https://tavily.com/
|
|
5
|
+
*/
|
|
6
|
+
import axios from "axios";
|
|
7
|
+
export class TavilySearch {
|
|
8
|
+
name = "tavily";
|
|
9
|
+
apiKey;
|
|
10
|
+
baseUrl = "https://api.tavily.com/search";
|
|
11
|
+
timeout = 10000; // 10 second timeout
|
|
12
|
+
constructor() {
|
|
13
|
+
this.apiKey = process.env.TAVILY_API_KEY;
|
|
14
|
+
}
|
|
15
|
+
isAvailable() {
|
|
16
|
+
return !!this.apiKey;
|
|
17
|
+
}
|
|
18
|
+
async search(query, options) {
|
|
19
|
+
if (!this.isAvailable()) {
|
|
20
|
+
throw new Error("Tavily API key not configured");
|
|
21
|
+
}
|
|
22
|
+
try {
|
|
23
|
+
const response = await axios.post(this.baseUrl, {
|
|
24
|
+
api_key: this.apiKey,
|
|
25
|
+
query: query,
|
|
26
|
+
search_depth: options?.searchDepth || "basic",
|
|
27
|
+
max_results: Math.min(options?.maxResults || 5, 10),
|
|
28
|
+
include_answer: options?.includeAnswer ?? true,
|
|
29
|
+
include_domains: options?.includeDomains || [],
|
|
30
|
+
exclude_domains: options?.excludeDomains || [],
|
|
31
|
+
}, {
|
|
32
|
+
timeout: options?.timeout || this.timeout,
|
|
33
|
+
headers: {
|
|
34
|
+
"Content-Type": "application/json",
|
|
35
|
+
},
|
|
36
|
+
});
|
|
37
|
+
return this.formatResults(response.data);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
if (axios.isAxiosError(error)) {
|
|
41
|
+
if (error.code === "ECONNABORTED") {
|
|
42
|
+
throw new Error("Tavily search timeout");
|
|
43
|
+
}
|
|
44
|
+
if (error.response?.status === 401) {
|
|
45
|
+
throw new Error("Invalid Tavily API key");
|
|
46
|
+
}
|
|
47
|
+
if (error.response?.status === 429) {
|
|
48
|
+
throw new Error("Tavily rate limit exceeded");
|
|
49
|
+
}
|
|
50
|
+
throw new Error(`Tavily API error: ${error.response?.data?.message || error.message}`);
|
|
51
|
+
}
|
|
52
|
+
throw error;
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
formatResults(response) {
|
|
56
|
+
return response.results.map((result) => ({
|
|
57
|
+
title: result.title,
|
|
58
|
+
url: result.url,
|
|
59
|
+
snippet: result.content,
|
|
60
|
+
source: this.name,
|
|
61
|
+
relevanceScore: result.score * 100, // Convert 0-1 to 0-100
|
|
62
|
+
publishedDate: result.published_date,
|
|
63
|
+
metadata: {
|
|
64
|
+
answer: response.answer,
|
|
65
|
+
responseTime: response.response_time,
|
|
66
|
+
},
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
getAnswer(results) {
|
|
70
|
+
return results[0]?.metadata?.answer;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
//# sourceMappingURL=tavily.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tavily.js","sourceRoot":"","sources":["../../../../src/tools/web-search/engines/tavily.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web Search Module
|
|
3
|
+
* Exports all web search functionality
|
|
4
|
+
*/
|
|
5
|
+
export { WebSearchTool } from "./web-search-tool.js";
|
|
6
|
+
export { WebSearchRouter } from "./router.js";
|
|
7
|
+
export { SearchCache } from "./cache.js";
|
|
8
|
+
export { TavilySearch } from "./engines/tavily.js";
|
|
9
|
+
export { BraveSearch } from "./engines/brave.js";
|
|
10
|
+
export { NpmSearch } from "./engines/npm.js";
|
|
11
|
+
export { PyPISearch } from "./engines/pypi.js";
|
|
12
|
+
export { CratesSearch } from "./engines/crates.js";
|
|
13
|
+
export type { WebSearchResult, SearchOptions, SearchIntent, SearchEngine, SearchEngineResponse, } from "./types.js";
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Web Search Module
|
|
3
|
+
* Exports all web search functionality
|
|
4
|
+
*/
|
|
5
|
+
export { WebSearchTool } from "./web-search-tool.js";
|
|
6
|
+
export { WebSearchRouter } from "./router.js";
|
|
7
|
+
export { SearchCache } from "./cache.js";
|
|
8
|
+
export { TavilySearch } from "./engines/tavily.js";
|
|
9
|
+
export { BraveSearch } from "./engines/brave.js";
|
|
10
|
+
export { NpmSearch } from "./engines/npm.js";
|
|
11
|
+
export { PyPISearch } from "./engines/pypi.js";
|
|
12
|
+
export { CratesSearch } from "./engines/crates.js";
|
|
13
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/tools/web-search/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AACrD,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9C,OAAO,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACzC,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7C,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search Router
|
|
3
|
+
* Detects query intent and routes to appropriate search engines
|
|
4
|
+
*/
|
|
5
|
+
import type { SearchEngine, SearchIntent } from "./types.js";
|
|
6
|
+
export declare class WebSearchRouter {
|
|
7
|
+
private tavilyEngine;
|
|
8
|
+
private braveEngine;
|
|
9
|
+
private npmEngine;
|
|
10
|
+
private pypiEngine;
|
|
11
|
+
private cratesEngine;
|
|
12
|
+
private readonly technicalKeywords;
|
|
13
|
+
private readonly codeKeywords;
|
|
14
|
+
private readonly packageKeywords;
|
|
15
|
+
private readonly pythonKeywords;
|
|
16
|
+
private readonly rustKeywords;
|
|
17
|
+
private readonly newsKeywords;
|
|
18
|
+
constructor();
|
|
19
|
+
/**
|
|
20
|
+
* Detect the intent of a search query
|
|
21
|
+
*/
|
|
22
|
+
detectIntent(query: string): SearchIntent;
|
|
23
|
+
/**
|
|
24
|
+
* Select the best search engines for a given intent
|
|
25
|
+
*/
|
|
26
|
+
selectEngines(intent: SearchIntent): SearchEngine[];
|
|
27
|
+
/**
|
|
28
|
+
* Get all available engines
|
|
29
|
+
*/
|
|
30
|
+
getAvailableEngines(): SearchEngine[];
|
|
31
|
+
/**
|
|
32
|
+
* Check if any search engine is available
|
|
33
|
+
* Always returns true because package search engines require no API key
|
|
34
|
+
*/
|
|
35
|
+
hasAvailableEngines(): boolean;
|
|
36
|
+
}
|
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Search Router
|
|
3
|
+
* Detects query intent and routes to appropriate search engines
|
|
4
|
+
*/
|
|
5
|
+
import { TavilySearch } from "./engines/tavily.js";
|
|
6
|
+
import { BraveSearch } from "./engines/brave.js";
|
|
7
|
+
import { NpmSearch } from "./engines/npm.js";
|
|
8
|
+
import { PyPISearch } from "./engines/pypi.js";
|
|
9
|
+
import { CratesSearch } from "./engines/crates.js";
|
|
10
|
+
export class WebSearchRouter {
|
|
11
|
+
tavilyEngine;
|
|
12
|
+
braveEngine;
|
|
13
|
+
npmEngine;
|
|
14
|
+
pypiEngine;
|
|
15
|
+
cratesEngine;
|
|
16
|
+
// Keywords for intent detection
|
|
17
|
+
technicalKeywords = [
|
|
18
|
+
"error",
|
|
19
|
+
"exception",
|
|
20
|
+
"bug",
|
|
21
|
+
"fix",
|
|
22
|
+
"debug",
|
|
23
|
+
"troubleshoot",
|
|
24
|
+
"code",
|
|
25
|
+
"function",
|
|
26
|
+
"method",
|
|
27
|
+
"class",
|
|
28
|
+
"api",
|
|
29
|
+
"library",
|
|
30
|
+
"framework",
|
|
31
|
+
"npm",
|
|
32
|
+
"package",
|
|
33
|
+
"install",
|
|
34
|
+
"configure",
|
|
35
|
+
"implementation",
|
|
36
|
+
"syntax",
|
|
37
|
+
"typescript",
|
|
38
|
+
"javascript",
|
|
39
|
+
"python",
|
|
40
|
+
"java",
|
|
41
|
+
"rust",
|
|
42
|
+
"go",
|
|
43
|
+
];
|
|
44
|
+
codeKeywords = [
|
|
45
|
+
"code",
|
|
46
|
+
"example",
|
|
47
|
+
"implementation",
|
|
48
|
+
"snippet",
|
|
49
|
+
"sample",
|
|
50
|
+
"github",
|
|
51
|
+
"repository",
|
|
52
|
+
"source",
|
|
53
|
+
"function",
|
|
54
|
+
"class",
|
|
55
|
+
"how to",
|
|
56
|
+
"tutorial",
|
|
57
|
+
];
|
|
58
|
+
packageKeywords = [
|
|
59
|
+
"package",
|
|
60
|
+
"npm",
|
|
61
|
+
"library",
|
|
62
|
+
"module",
|
|
63
|
+
"install",
|
|
64
|
+
"dependency",
|
|
65
|
+
"dependencies",
|
|
66
|
+
"node_modules",
|
|
67
|
+
"yarn",
|
|
68
|
+
"pnpm",
|
|
69
|
+
];
|
|
70
|
+
pythonKeywords = [
|
|
71
|
+
"python",
|
|
72
|
+
"pip",
|
|
73
|
+
"pypi",
|
|
74
|
+
"django",
|
|
75
|
+
"flask",
|
|
76
|
+
"fastapi",
|
|
77
|
+
"pandas",
|
|
78
|
+
"numpy",
|
|
79
|
+
"pytest",
|
|
80
|
+
"virtualenv",
|
|
81
|
+
"conda",
|
|
82
|
+
"poetry",
|
|
83
|
+
];
|
|
84
|
+
rustKeywords = [
|
|
85
|
+
"rust",
|
|
86
|
+
"cargo",
|
|
87
|
+
"crate",
|
|
88
|
+
"crates.io",
|
|
89
|
+
"rustc",
|
|
90
|
+
"tokio",
|
|
91
|
+
"serde",
|
|
92
|
+
"actix",
|
|
93
|
+
"wasm",
|
|
94
|
+
];
|
|
95
|
+
newsKeywords = [
|
|
96
|
+
"news",
|
|
97
|
+
"latest",
|
|
98
|
+
"today",
|
|
99
|
+
"yesterday",
|
|
100
|
+
"recent",
|
|
101
|
+
"update",
|
|
102
|
+
"announcement",
|
|
103
|
+
"release",
|
|
104
|
+
"2025",
|
|
105
|
+
"2024",
|
|
106
|
+
"current",
|
|
107
|
+
"breaking",
|
|
108
|
+
"trending",
|
|
109
|
+
];
|
|
110
|
+
constructor() {
|
|
111
|
+
this.tavilyEngine = new TavilySearch();
|
|
112
|
+
this.braveEngine = new BraveSearch();
|
|
113
|
+
this.npmEngine = new NpmSearch(); // Always available (no API key)
|
|
114
|
+
this.pypiEngine = new PyPISearch(); // Always available (no API key)
|
|
115
|
+
this.cratesEngine = new CratesSearch(); // Always available (no API key)
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Detect the intent of a search query
|
|
119
|
+
*/
|
|
120
|
+
detectIntent(query) {
|
|
121
|
+
const lowerQuery = query.toLowerCase();
|
|
122
|
+
const words = lowerQuery.split(/\s+/);
|
|
123
|
+
let technicalScore = 0;
|
|
124
|
+
let codeScore = 0;
|
|
125
|
+
let newsScore = 0;
|
|
126
|
+
let packageScore = 0;
|
|
127
|
+
let pythonScore = 0;
|
|
128
|
+
let rustScore = 0;
|
|
129
|
+
// Count keyword matches
|
|
130
|
+
for (const word of words) {
|
|
131
|
+
if (this.technicalKeywords.some((kw) => word.includes(kw))) {
|
|
132
|
+
technicalScore++;
|
|
133
|
+
}
|
|
134
|
+
if (this.codeKeywords.some((kw) => word.includes(kw))) {
|
|
135
|
+
codeScore++;
|
|
136
|
+
}
|
|
137
|
+
if (this.newsKeywords.some((kw) => word.includes(kw))) {
|
|
138
|
+
newsScore++;
|
|
139
|
+
}
|
|
140
|
+
if (this.packageKeywords.some((kw) => word.includes(kw))) {
|
|
141
|
+
packageScore++;
|
|
142
|
+
}
|
|
143
|
+
if (this.pythonKeywords.some((kw) => word.includes(kw))) {
|
|
144
|
+
pythonScore++;
|
|
145
|
+
}
|
|
146
|
+
if (this.rustKeywords.some((kw) => word.includes(kw))) {
|
|
147
|
+
rustScore++;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
// Determine primary intent
|
|
151
|
+
let type = "general";
|
|
152
|
+
let confidence = 0.5; // Default confidence
|
|
153
|
+
let language = undefined;
|
|
154
|
+
// Detect language first
|
|
155
|
+
if (pythonScore > 0 && pythonScore >= rustScore) {
|
|
156
|
+
language = "python";
|
|
157
|
+
}
|
|
158
|
+
else if (rustScore > 0 && rustScore > pythonScore) {
|
|
159
|
+
language = "rust";
|
|
160
|
+
}
|
|
161
|
+
else if (packageScore > 0) {
|
|
162
|
+
language = "javascript"; // npm implies JavaScript
|
|
163
|
+
}
|
|
164
|
+
// Package search takes priority if npm keywords detected
|
|
165
|
+
if (packageScore > 0 || pythonScore > 0 || rustScore > 0) {
|
|
166
|
+
type = "technical"; // Packages are technical
|
|
167
|
+
confidence = Math.min((packageScore + pythonScore + rustScore) / words.length + 0.6, 1.0);
|
|
168
|
+
}
|
|
169
|
+
else if (newsScore > 0) {
|
|
170
|
+
type = "news";
|
|
171
|
+
confidence = Math.min(newsScore / words.length + 0.5, 1.0);
|
|
172
|
+
}
|
|
173
|
+
else if (codeScore > technicalScore) {
|
|
174
|
+
type = "code";
|
|
175
|
+
confidence = Math.min(codeScore / words.length + 0.5, 1.0);
|
|
176
|
+
}
|
|
177
|
+
else if (technicalScore > 0) {
|
|
178
|
+
type = "technical";
|
|
179
|
+
confidence = Math.min(technicalScore / words.length + 0.5, 1.0);
|
|
180
|
+
}
|
|
181
|
+
return {
|
|
182
|
+
type,
|
|
183
|
+
requiresTechnical: technicalScore > 0 || packageScore > 0 || pythonScore > 0 || rustScore > 0,
|
|
184
|
+
requiresCode: codeScore > 0,
|
|
185
|
+
requiresNews: newsScore > 0,
|
|
186
|
+
confidence,
|
|
187
|
+
language,
|
|
188
|
+
};
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Select the best search engines for a given intent
|
|
192
|
+
*/
|
|
193
|
+
selectEngines(intent) {
|
|
194
|
+
const engines = [];
|
|
195
|
+
// Check if query contains package keywords - prioritize language-specific search
|
|
196
|
+
const hasPackageIntent = intent.requiresTechnical && intent.confidence > 0.6;
|
|
197
|
+
// Select engines based on intent type
|
|
198
|
+
switch (intent.type) {
|
|
199
|
+
case "technical":
|
|
200
|
+
case "code":
|
|
201
|
+
// Route to language-specific package search
|
|
202
|
+
if (hasPackageIntent && intent.language) {
|
|
203
|
+
if (intent.language === "python") {
|
|
204
|
+
engines.push(this.pypiEngine); // Python packages
|
|
205
|
+
}
|
|
206
|
+
else if (intent.language === "rust") {
|
|
207
|
+
engines.push(this.cratesEngine); // Rust crates
|
|
208
|
+
}
|
|
209
|
+
else if (intent.language === "javascript") {
|
|
210
|
+
engines.push(this.npmEngine); // npm packages
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
else if (hasPackageIntent) {
|
|
214
|
+
// Default to npm if language not detected
|
|
215
|
+
engines.push(this.npmEngine);
|
|
216
|
+
}
|
|
217
|
+
// Tavily is great for technical queries
|
|
218
|
+
if (this.tavilyEngine.isAvailable()) {
|
|
219
|
+
engines.push(this.tavilyEngine);
|
|
220
|
+
}
|
|
221
|
+
// Brave as fallback
|
|
222
|
+
if (this.braveEngine.isAvailable() && engines.length === 0) {
|
|
223
|
+
engines.push(this.braveEngine);
|
|
224
|
+
}
|
|
225
|
+
break;
|
|
226
|
+
case "news":
|
|
227
|
+
// Brave has better news coverage
|
|
228
|
+
if (this.braveEngine.isAvailable()) {
|
|
229
|
+
engines.push(this.braveEngine);
|
|
230
|
+
}
|
|
231
|
+
// Tavily as fallback
|
|
232
|
+
if (this.tavilyEngine.isAvailable() && engines.length === 0) {
|
|
233
|
+
engines.push(this.tavilyEngine);
|
|
234
|
+
}
|
|
235
|
+
break;
|
|
236
|
+
case "general":
|
|
237
|
+
default:
|
|
238
|
+
// Tavily is optimized for AI/general queries
|
|
239
|
+
if (this.tavilyEngine.isAvailable()) {
|
|
240
|
+
engines.push(this.tavilyEngine);
|
|
241
|
+
}
|
|
242
|
+
// Brave as fallback
|
|
243
|
+
if (this.braveEngine.isAvailable() && engines.length === 0) {
|
|
244
|
+
engines.push(this.braveEngine);
|
|
245
|
+
}
|
|
246
|
+
break;
|
|
247
|
+
}
|
|
248
|
+
// Package search as ultimate fallback (always available, no API key needed)
|
|
249
|
+
// Prefer npm as it's most commonly used
|
|
250
|
+
if (engines.length === 0) {
|
|
251
|
+
engines.push(this.npmEngine);
|
|
252
|
+
}
|
|
253
|
+
return engines;
|
|
254
|
+
}
|
|
255
|
+
/**
|
|
256
|
+
* Get all available engines
|
|
257
|
+
*/
|
|
258
|
+
getAvailableEngines() {
|
|
259
|
+
const engines = [];
|
|
260
|
+
if (this.tavilyEngine.isAvailable()) {
|
|
261
|
+
engines.push(this.tavilyEngine);
|
|
262
|
+
}
|
|
263
|
+
if (this.braveEngine.isAvailable()) {
|
|
264
|
+
engines.push(this.braveEngine);
|
|
265
|
+
}
|
|
266
|
+
// Package search engines are always available (no API key required)
|
|
267
|
+
engines.push(this.npmEngine);
|
|
268
|
+
engines.push(this.pypiEngine);
|
|
269
|
+
engines.push(this.cratesEngine);
|
|
270
|
+
return engines;
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Check if any search engine is available
|
|
274
|
+
* Always returns true because package search engines require no API key
|
|
275
|
+
*/
|
|
276
|
+
hasAvailableEngines() {
|
|
277
|
+
return true; // npm, PyPI, and crates.io search are always available
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
//# sourceMappingURL=router.js.map
|