@elizaos/plugin-research 0.1.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.
Files changed (71) hide show
  1. package/README.md +400 -0
  2. package/dist/index.cjs +9366 -0
  3. package/dist/index.cjs.map +1 -0
  4. package/dist/index.js +9284 -0
  5. package/dist/index.js.map +1 -0
  6. package/package.json +80 -0
  7. package/src/__tests__/action-chaining.test.ts +532 -0
  8. package/src/__tests__/actions.test.ts +118 -0
  9. package/src/__tests__/cache-rate-limiter.test.ts +303 -0
  10. package/src/__tests__/content-extractors.test.ts +26 -0
  11. package/src/__tests__/deepresearch-bench-integration.test.ts +520 -0
  12. package/src/__tests__/deepresearch-bench-simplified.e2e.test.ts +290 -0
  13. package/src/__tests__/deepresearch-bench.e2e.test.ts +376 -0
  14. package/src/__tests__/e2e.test.ts +1870 -0
  15. package/src/__tests__/multi-benchmark-runner.ts +427 -0
  16. package/src/__tests__/providers.test.ts +156 -0
  17. package/src/__tests__/real-world.e2e.test.ts +788 -0
  18. package/src/__tests__/research-scenarios.test.ts +755 -0
  19. package/src/__tests__/research.e2e.test.ts +704 -0
  20. package/src/__tests__/research.test.ts +174 -0
  21. package/src/__tests__/search-providers.test.ts +174 -0
  22. package/src/__tests__/single-benchmark-runner.ts +735 -0
  23. package/src/__tests__/test-search-providers.ts +171 -0
  24. package/src/__tests__/verify-apis.test.ts +82 -0
  25. package/src/actions.ts +1677 -0
  26. package/src/benchmark/deepresearch-benchmark.ts +369 -0
  27. package/src/evaluation/research-evaluator.ts +444 -0
  28. package/src/examples/api-integration.md +498 -0
  29. package/src/examples/browserbase-integration.md +132 -0
  30. package/src/examples/debug-research-query.ts +162 -0
  31. package/src/examples/defi-code-scenarios.md +536 -0
  32. package/src/examples/defi-implementation-guide.md +454 -0
  33. package/src/examples/eliza-research-example.ts +142 -0
  34. package/src/examples/fix-renewable-energy-research.ts +209 -0
  35. package/src/examples/research-scenarios.md +408 -0
  36. package/src/examples/run-complete-renewable-research.ts +303 -0
  37. package/src/examples/run-deep-research.ts +352 -0
  38. package/src/examples/run-logged-research.ts +304 -0
  39. package/src/examples/run-real-research.ts +151 -0
  40. package/src/examples/save-research-output.ts +133 -0
  41. package/src/examples/test-file-logging.ts +199 -0
  42. package/src/examples/test-real-research.ts +67 -0
  43. package/src/examples/test-renewable-energy-research.ts +229 -0
  44. package/src/index.ts +28 -0
  45. package/src/integrations/cache.ts +128 -0
  46. package/src/integrations/content-extractors/firecrawl.ts +314 -0
  47. package/src/integrations/content-extractors/pdf-extractor.ts +350 -0
  48. package/src/integrations/content-extractors/playwright.ts +420 -0
  49. package/src/integrations/factory.ts +419 -0
  50. package/src/integrations/index.ts +18 -0
  51. package/src/integrations/rate-limiter.ts +181 -0
  52. package/src/integrations/search-providers/academic.ts +290 -0
  53. package/src/integrations/search-providers/exa.ts +205 -0
  54. package/src/integrations/search-providers/npm.ts +330 -0
  55. package/src/integrations/search-providers/pypi.ts +211 -0
  56. package/src/integrations/search-providers/serpapi.ts +277 -0
  57. package/src/integrations/search-providers/serper.ts +358 -0
  58. package/src/integrations/search-providers/stagehand-google.ts +87 -0
  59. package/src/integrations/search-providers/tavily.ts +187 -0
  60. package/src/processing/relevance-analyzer.ts +353 -0
  61. package/src/processing/research-logger.ts +450 -0
  62. package/src/processing/result-processor.ts +372 -0
  63. package/src/prompts/research-prompts.ts +419 -0
  64. package/src/providers/cacheProvider.ts +164 -0
  65. package/src/providers.ts +173 -0
  66. package/src/service.ts +2588 -0
  67. package/src/services/swe-bench.ts +286 -0
  68. package/src/strategies/research-strategies.ts +790 -0
  69. package/src/types/pdf-parse.d.ts +34 -0
  70. package/src/types.ts +551 -0
  71. package/src/verification/claim-verifier.ts +443 -0
@@ -0,0 +1,171 @@
1
+ #!/usr/bin/env bun
2
+ /**
3
+ * Test script to validate PyPI, npm, and GitHub search providers
4
+ */
5
+
6
+ import { PyPISearchProvider } from '../integrations/search-providers/pypi';
7
+ import { NPMSearchProvider } from '../integrations/search-providers/npm';
8
+ import { createSearchProvider } from '../integrations/factory';
9
+ import { elizaLogger } from '@elizaos/core';
10
+
11
+ // Mock runtime for GitHub search
12
+ const mockRuntime = {
13
+ getSetting: (key: string) => {
14
+ const settings: Record<string, string | undefined> = {
15
+ 'GITHUB_TOKEN': process.env.GITHUB_TOKEN,
16
+ };
17
+ return settings[key] || null;
18
+ },
19
+ getService: (name: string) => {
20
+ if (name === 'github') {
21
+ // Return a mock GitHub service with search methods
22
+ return {
23
+ searchRepositories: async (query: string, options: any) => {
24
+ console.log(`๐Ÿ” GitHub repo search: ${query}`);
25
+ return {
26
+ items: [
27
+ {
28
+ full_name: 'microsoft/TypeScript',
29
+ html_url: 'https://github.com/microsoft/TypeScript',
30
+ description: 'TypeScript is a superset of JavaScript that compiles to clean JavaScript output.',
31
+ stargazers_count: 89000,
32
+ language: 'TypeScript',
33
+ forks_count: 12000,
34
+ open_issues_count: 5000,
35
+ updated_at: '2024-01-01T00:00:00Z',
36
+ owner: { login: 'microsoft' }
37
+ }
38
+ ]
39
+ };
40
+ },
41
+ searchIssues: async (query: string, options: any) => {
42
+ console.log(`๐Ÿ” GitHub issue search: ${query}`);
43
+ return {
44
+ items: [
45
+ {
46
+ title: 'TypeScript compilation issue',
47
+ html_url: 'https://github.com/microsoft/TypeScript/issues/12345',
48
+ body: 'Having trouble with TypeScript compilation...',
49
+ state: 'open',
50
+ comments: 5,
51
+ user: { login: 'developer123' },
52
+ created_at: '2024-01-01T00:00:00Z',
53
+ updated_at: '2024-01-01T00:00:00Z',
54
+ number: 12345
55
+ }
56
+ ]
57
+ };
58
+ }
59
+ };
60
+ }
61
+ return null;
62
+ }
63
+ } as any;
64
+
65
+ async function testPyPISearch() {
66
+ console.log('\n๐Ÿ Testing PyPI Search Provider...');
67
+ const provider = new PyPISearchProvider();
68
+
69
+ try {
70
+ const results = await provider.search('machine learning', 5);
71
+ console.log(`โœ… Found ${results.length} PyPI packages`);
72
+
73
+ if (results.length > 0) {
74
+ const first = results[0];
75
+ console.log(`๐Ÿ“ฆ Example: ${first.title}`);
76
+ console.log(`๐Ÿ”— URL: ${first.url}`);
77
+ console.log(`๐Ÿ“„ Snippet: ${first.snippet.substring(0, 100)}...`);
78
+ console.log(`โญ Score: ${first.score}`);
79
+ console.log(`๐Ÿท๏ธ Provider: ${first.provider}`);
80
+ }
81
+ } catch (error) {
82
+ console.error('โŒ PyPI search failed:', error instanceof Error ? error.message : String(error));
83
+ }
84
+ }
85
+
86
+ async function testNPMSearch() {
87
+ console.log('\n๐Ÿ“ฆ Testing NPM Search Provider...');
88
+ const provider = new NPMSearchProvider();
89
+
90
+ try {
91
+ const results = await provider.search('typescript', 5);
92
+ console.log(`โœ… Found ${results.length} NPM packages`);
93
+
94
+ if (results.length > 0) {
95
+ const first = results[0];
96
+ console.log(`๐Ÿ“ฆ Example: ${first.title}`);
97
+ console.log(`๐Ÿ”— URL: ${first.url}`);
98
+ console.log(`๐Ÿ“„ Snippet: ${first.snippet.substring(0, 100)}...`);
99
+ console.log(`โญ Score: ${first.score}`);
100
+ console.log(`๐Ÿท๏ธ Provider: ${first.provider}`);
101
+ // Removed scores check as it's not part of standard SearchMetadata
102
+ }
103
+ } catch (error) {
104
+ console.error('โŒ NPM search failed:', error instanceof Error ? error.message : String(error));
105
+ }
106
+ }
107
+
108
+ async function testGitHubSearch() {
109
+ console.log('\n๐Ÿ™ Testing GitHub Search Provider...');
110
+
111
+ try {
112
+ const provider = createSearchProvider('github', mockRuntime);
113
+ const results = await provider.search('typescript compiler', 5);
114
+ console.log(`โœ… Found ${results.length} GitHub results`);
115
+
116
+ if (results.length > 0) {
117
+ const first = results[0];
118
+ console.log(`๐Ÿ“ฆ Example: ${first.title}`);
119
+ console.log(`๐Ÿ”— URL: ${first.url}`);
120
+ console.log(`๐Ÿ“„ Snippet: ${first.snippet.substring(0, 100)}...`);
121
+ console.log(`โญ Score: ${first.score}`);
122
+ console.log(`๐Ÿท๏ธ Provider: ${first.provider}`);
123
+ if (first.metadata.type) {
124
+ console.log(`๐Ÿ“‚ Type: ${first.metadata.type}`);
125
+ }
126
+ }
127
+ } catch (error) {
128
+ console.error('โŒ GitHub search failed:', error instanceof Error ? error.message : String(error));
129
+ }
130
+ }
131
+
132
+ async function testPackageSpecificSearches() {
133
+ console.log('\n๐Ÿ”Ž Testing Package-Specific Searches...');
134
+
135
+ // Test PyPI specific package
136
+ try {
137
+ const pypiProvider = new PyPISearchProvider();
138
+ const tensorflowResult = await pypiProvider.getPackage('tensorflow');
139
+ if (tensorflowResult) {
140
+ console.log(`โœ… PyPI specific package: ${tensorflowResult.title}`);
141
+ }
142
+ } catch (error) {
143
+ console.log(`โš ๏ธ PyPI specific package test failed: ${error instanceof Error ? error.message : String(error)}`);
144
+ }
145
+
146
+ // Test NPM specific package
147
+ try {
148
+ const npmProvider = new NPMSearchProvider();
149
+ const reactResult = await npmProvider.getPackage('react');
150
+ if (reactResult) {
151
+ console.log(`โœ… NPM specific package: ${reactResult.title}`);
152
+ }
153
+ } catch (error) {
154
+ console.log(`โš ๏ธ NPM specific package test failed: ${error instanceof Error ? error.message : String(error)}`);
155
+ }
156
+ }
157
+
158
+ async function main() {
159
+ console.log('๐Ÿงช Testing ElizaOS Research Plugin - Search Provider Integration\n');
160
+
161
+ await testPyPISearch();
162
+ await testNPMSearch();
163
+ await testGitHubSearch();
164
+ await testPackageSpecificSearches();
165
+
166
+ console.log('\nโœ… Search provider tests completed!');
167
+ console.log('\n๐Ÿ’ก These providers are now integrated into the research service');
168
+ console.log(' and will be automatically selected based on research domain and query keywords.');
169
+ }
170
+
171
+ main().catch(console.error);
@@ -0,0 +1,82 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { TavilySearchProvider } from '../integrations/search-providers/tavily';
3
+ import { ExaSearchProvider } from '../integrations/search-providers/exa';
4
+ import { SerpAPISearchProvider } from '../integrations/search-providers/serpapi';
5
+ import { AcademicSearchProvider } from '../integrations/search-providers/academic';
6
+ import { FirecrawlContentExtractor } from '../integrations/content-extractors/firecrawl';
7
+
8
+ const runLiveApiTests = process.env.RUN_LIVE_API_TESTS === 'true';
9
+ const API_KEYS = {
10
+ TAVILY: process.env.TAVILY_API_KEY || '',
11
+ EXA: process.env.EXA_API_KEY || '',
12
+ SERPAPI: process.env.SERPAPI_API_KEY || '',
13
+ SEMANTIC_SCHOLAR: process.env.SEMANTIC_SCHOLAR_API_KEY || '',
14
+ FIRECRAWL: process.env.FIRECRAWL_API_KEY || '',
15
+ };
16
+
17
+ const describeLive = runLiveApiTests ? describe : describe.skip;
18
+
19
+ describeLive('API Verification', () => {
20
+ it('should verify all APIs', async () => {
21
+ const results: Record<string, boolean> = {};
22
+
23
+ // Test Tavily
24
+ try {
25
+ const tavily = new TavilySearchProvider({ apiKey: API_KEYS.TAVILY });
26
+ const tavilyResults = await tavily.search('test', 1);
27
+ results.tavily = tavilyResults.length > 0;
28
+ } catch (e) {
29
+ results.tavily = false;
30
+ }
31
+
32
+ // Test Exa
33
+ try {
34
+ const exa = new ExaSearchProvider({ apiKey: API_KEYS.EXA });
35
+ const exaResults = await exa.search('test', 1);
36
+ results.exa = exaResults.length > 0;
37
+ } catch (e) {
38
+ results.exa = false;
39
+ }
40
+
41
+ // Test SerpAPI
42
+ try {
43
+ const serpapi = new SerpAPISearchProvider({ apiKey: API_KEYS.SERPAPI });
44
+ const serpapiResults = await serpapi.search('test', 1);
45
+ results.serpapi = serpapiResults.length > 0;
46
+ } catch (e) {
47
+ results.serpapi = false;
48
+ }
49
+
50
+ // Test Academic (expect failure with current key)
51
+ try {
52
+ const academic = new AcademicSearchProvider({ semanticScholarApiKey: API_KEYS.SEMANTIC_SCHOLAR });
53
+ const academicResults = await academic.search('test', 1);
54
+ results.academic = academicResults.length > 0;
55
+ } catch (e) {
56
+ results.academic = false;
57
+ }
58
+
59
+ // Test Firecrawl
60
+ try {
61
+ const firecrawl = new FirecrawlContentExtractor({ apiKey: API_KEYS.FIRECRAWL });
62
+ const content = await firecrawl.extractContent('https://example.com');
63
+ results.firecrawl = content !== null;
64
+ } catch (e) {
65
+ results.firecrawl = false;
66
+ }
67
+
68
+ console.log('\n=== API Status ===');
69
+ console.log(`Tavily: ${results.tavily ? 'โœ… Working' : 'โŒ Failed'}`);
70
+ console.log(`Exa: ${results.exa ? 'โœ… Working' : 'โŒ Failed'}`);
71
+ console.log(`SerpAPI: ${results.serpapi ? 'โœ… Working' : 'โŒ Failed'}`);
72
+ console.log(`Semantic Scholar: ${results.academic ? 'โœ… Working' : 'โŒ Failed (403 - Invalid API key)'}`);
73
+ console.log(`Firecrawl: ${results.firecrawl ? 'โœ… Working' : 'โŒ Failed'}`);
74
+ console.log('==================\n');
75
+
76
+ const workingCount = Object.values(results).filter(v => v).length;
77
+ console.log(`Total: ${workingCount}/5 APIs working`);
78
+
79
+ // We expect at least 4 out of 5 to work (Semantic Scholar key is invalid)
80
+ expect(workingCount).toBeGreaterThanOrEqual(4);
81
+ }, 60000); // 60 second timeout for testing multiple APIs
82
+ });