@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.
- package/README.md +400 -0
- package/dist/index.cjs +9366 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.js +9284 -0
- package/dist/index.js.map +1 -0
- package/package.json +80 -0
- package/src/__tests__/action-chaining.test.ts +532 -0
- package/src/__tests__/actions.test.ts +118 -0
- package/src/__tests__/cache-rate-limiter.test.ts +303 -0
- package/src/__tests__/content-extractors.test.ts +26 -0
- package/src/__tests__/deepresearch-bench-integration.test.ts +520 -0
- package/src/__tests__/deepresearch-bench-simplified.e2e.test.ts +290 -0
- package/src/__tests__/deepresearch-bench.e2e.test.ts +376 -0
- package/src/__tests__/e2e.test.ts +1870 -0
- package/src/__tests__/multi-benchmark-runner.ts +427 -0
- package/src/__tests__/providers.test.ts +156 -0
- package/src/__tests__/real-world.e2e.test.ts +788 -0
- package/src/__tests__/research-scenarios.test.ts +755 -0
- package/src/__tests__/research.e2e.test.ts +704 -0
- package/src/__tests__/research.test.ts +174 -0
- package/src/__tests__/search-providers.test.ts +174 -0
- package/src/__tests__/single-benchmark-runner.ts +735 -0
- package/src/__tests__/test-search-providers.ts +171 -0
- package/src/__tests__/verify-apis.test.ts +82 -0
- package/src/actions.ts +1677 -0
- package/src/benchmark/deepresearch-benchmark.ts +369 -0
- package/src/evaluation/research-evaluator.ts +444 -0
- package/src/examples/api-integration.md +498 -0
- package/src/examples/browserbase-integration.md +132 -0
- package/src/examples/debug-research-query.ts +162 -0
- package/src/examples/defi-code-scenarios.md +536 -0
- package/src/examples/defi-implementation-guide.md +454 -0
- package/src/examples/eliza-research-example.ts +142 -0
- package/src/examples/fix-renewable-energy-research.ts +209 -0
- package/src/examples/research-scenarios.md +408 -0
- package/src/examples/run-complete-renewable-research.ts +303 -0
- package/src/examples/run-deep-research.ts +352 -0
- package/src/examples/run-logged-research.ts +304 -0
- package/src/examples/run-real-research.ts +151 -0
- package/src/examples/save-research-output.ts +133 -0
- package/src/examples/test-file-logging.ts +199 -0
- package/src/examples/test-real-research.ts +67 -0
- package/src/examples/test-renewable-energy-research.ts +229 -0
- package/src/index.ts +28 -0
- package/src/integrations/cache.ts +128 -0
- package/src/integrations/content-extractors/firecrawl.ts +314 -0
- package/src/integrations/content-extractors/pdf-extractor.ts +350 -0
- package/src/integrations/content-extractors/playwright.ts +420 -0
- package/src/integrations/factory.ts +419 -0
- package/src/integrations/index.ts +18 -0
- package/src/integrations/rate-limiter.ts +181 -0
- package/src/integrations/search-providers/academic.ts +290 -0
- package/src/integrations/search-providers/exa.ts +205 -0
- package/src/integrations/search-providers/npm.ts +330 -0
- package/src/integrations/search-providers/pypi.ts +211 -0
- package/src/integrations/search-providers/serpapi.ts +277 -0
- package/src/integrations/search-providers/serper.ts +358 -0
- package/src/integrations/search-providers/stagehand-google.ts +87 -0
- package/src/integrations/search-providers/tavily.ts +187 -0
- package/src/processing/relevance-analyzer.ts +353 -0
- package/src/processing/research-logger.ts +450 -0
- package/src/processing/result-processor.ts +372 -0
- package/src/prompts/research-prompts.ts +419 -0
- package/src/providers/cacheProvider.ts +164 -0
- package/src/providers.ts +173 -0
- package/src/service.ts +2588 -0
- package/src/services/swe-bench.ts +286 -0
- package/src/strategies/research-strategies.ts +790 -0
- package/src/types/pdf-parse.d.ts +34 -0
- package/src/types.ts +551 -0
- package/src/verification/claim-verifier.ts +443 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
#!/usr/bin/env bun
|
|
2
|
+
/**
|
|
3
|
+
* Script to diagnose and fix renewable energy research issues
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import dotenv from 'dotenv';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
dotenv.config({ path: path.join(__dirname, '../../.env') });
|
|
9
|
+
|
|
10
|
+
import { ResearchService } from '../service';
|
|
11
|
+
import { elizaLogger, IAgentRuntime, Character, asUUID } from '@elizaos/core';
|
|
12
|
+
import { TavilySearchProvider } from '../integrations/search-providers/tavily';
|
|
13
|
+
import fs from 'fs/promises';
|
|
14
|
+
|
|
15
|
+
async function testTavilyDirectly() {
|
|
16
|
+
elizaLogger.info('=== Testing Tavily Search Directly ===');
|
|
17
|
+
|
|
18
|
+
const apiKey = process.env.TAVILY_API_KEY;
|
|
19
|
+
if (!apiKey) {
|
|
20
|
+
elizaLogger.error('TAVILY_API_KEY not found in environment');
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
try {
|
|
25
|
+
const tavily = new TavilySearchProvider({ apiKey });
|
|
26
|
+
const query = "renewable energy storage technologies environmental economic impacts grid scale";
|
|
27
|
+
|
|
28
|
+
elizaLogger.info(`Searching Tavily for: "${query}"`);
|
|
29
|
+
const results = await tavily.search(query, 5);
|
|
30
|
+
|
|
31
|
+
elizaLogger.info(`Found ${results.length} results:`);
|
|
32
|
+
results.forEach((result, i) => {
|
|
33
|
+
elizaLogger.info(`${i + 1}. ${result.title}`);
|
|
34
|
+
elizaLogger.info(` URL: ${result.url}`);
|
|
35
|
+
elizaLogger.info(` Score: ${result.score}`);
|
|
36
|
+
elizaLogger.info(` Snippet: ${result.snippet?.substring(0, 100)}...`);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Check if results are relevant
|
|
40
|
+
const relevantResults = results.filter(r =>
|
|
41
|
+
r.title.toLowerCase().includes('energy') ||
|
|
42
|
+
r.title.toLowerCase().includes('storage') ||
|
|
43
|
+
r.snippet?.toLowerCase().includes('battery') ||
|
|
44
|
+
r.snippet?.toLowerCase().includes('renewable')
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
elizaLogger.info(`\n${relevantResults.length} out of ${results.length} results appear relevant`);
|
|
48
|
+
|
|
49
|
+
} catch (error) {
|
|
50
|
+
elizaLogger.error('Tavily search failed:', error);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
async function testWithMinimalRuntime() {
|
|
55
|
+
elizaLogger.info('\n=== Testing with Minimal Runtime ===');
|
|
56
|
+
|
|
57
|
+
const runtime: IAgentRuntime = {
|
|
58
|
+
agentId: asUUID('11111111-1111-1111-1111-111111111111'),
|
|
59
|
+
character: {
|
|
60
|
+
name: 'ResearchBot',
|
|
61
|
+
bio: ['Research assistant'],
|
|
62
|
+
system: 'You are a research assistant.',
|
|
63
|
+
messageExamples: [],
|
|
64
|
+
postExamples: [],
|
|
65
|
+
topics: [],
|
|
66
|
+
adjectives: [],
|
|
67
|
+
knowledge: [],
|
|
68
|
+
plugins: [],
|
|
69
|
+
},
|
|
70
|
+
getSetting: (key: string) => process.env[key] || null,
|
|
71
|
+
getService: () => null,
|
|
72
|
+
providers: [],
|
|
73
|
+
actions: [],
|
|
74
|
+
evaluators: [],
|
|
75
|
+
plugins: [],
|
|
76
|
+
services: new Map(),
|
|
77
|
+
messageManager: {
|
|
78
|
+
createMemory: async () => asUUID('22222222-2222-2222-2222-222222222222'),
|
|
79
|
+
getMemories: async () => [],
|
|
80
|
+
getMemoriesByRoomIds: async () => [],
|
|
81
|
+
getCachedEmbeddings: async () => [],
|
|
82
|
+
searchMemoriesByEmbedding: async () => [],
|
|
83
|
+
},
|
|
84
|
+
// Add all other required managers
|
|
85
|
+
descriptionManager: {
|
|
86
|
+
createMemory: async () => asUUID('33333333-3333-3333-3333-333333333333'),
|
|
87
|
+
getMemories: async () => [],
|
|
88
|
+
getMemoriesByRoomIds: async () => [],
|
|
89
|
+
getCachedEmbeddings: async () => [],
|
|
90
|
+
searchMemoriesByEmbedding: async () => [],
|
|
91
|
+
},
|
|
92
|
+
documentsManager: {
|
|
93
|
+
createMemory: async () => asUUID('44444444-4444-4444-4444-444444444444'),
|
|
94
|
+
getMemories: async () => [],
|
|
95
|
+
getMemoriesByRoomIds: async () => [],
|
|
96
|
+
getCachedEmbeddings: async () => [],
|
|
97
|
+
searchMemoriesByEmbedding: async () => [],
|
|
98
|
+
},
|
|
99
|
+
knowledgeManager: {
|
|
100
|
+
createMemory: async () => asUUID('55555555-5555-5555-5555-555555555555'),
|
|
101
|
+
getMemories: async () => [],
|
|
102
|
+
getMemoriesByRoomIds: async () => [],
|
|
103
|
+
getCachedEmbeddings: async () => [],
|
|
104
|
+
searchMemoriesByEmbedding: async () => [],
|
|
105
|
+
},
|
|
106
|
+
loreManager: {
|
|
107
|
+
createMemory: async () => asUUID('66666666-6666-6666-6666-666666666666'),
|
|
108
|
+
getMemories: async () => [],
|
|
109
|
+
getMemoriesByRoomIds: async () => [],
|
|
110
|
+
getCachedEmbeddings: async () => [],
|
|
111
|
+
searchMemoriesByEmbedding: async () => [],
|
|
112
|
+
},
|
|
113
|
+
// Add useModel for text generation
|
|
114
|
+
useModel: async (modelType: string, params: any) => {
|
|
115
|
+
elizaLogger.debug(`Mock model called: ${modelType}`);
|
|
116
|
+
// Return simple responses for different types of requests
|
|
117
|
+
return { content: 'Analysis complete.' };
|
|
118
|
+
},
|
|
119
|
+
stop: async () => {},
|
|
120
|
+
} as any;
|
|
121
|
+
|
|
122
|
+
const service = new ResearchService(runtime);
|
|
123
|
+
|
|
124
|
+
try {
|
|
125
|
+
const query = "Compare renewable energy storage technologies environmental economic impacts";
|
|
126
|
+
elizaLogger.info(`Creating research project: "${query}"`);
|
|
127
|
+
|
|
128
|
+
const project = await service.createResearchProject(query, {
|
|
129
|
+
searchProviders: ['web'],
|
|
130
|
+
maxSearchResults: 5,
|
|
131
|
+
maxDepth: 1,
|
|
132
|
+
enableImages: false,
|
|
133
|
+
evaluationEnabled: false,
|
|
134
|
+
timeout: 60000,
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
elizaLogger.info(`Project created: ${project.id}`);
|
|
138
|
+
|
|
139
|
+
// Wait for completion
|
|
140
|
+
let attempts = 0;
|
|
141
|
+
while (attempts < 60) {
|
|
142
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
143
|
+
|
|
144
|
+
const current = await service.getProject(project.id);
|
|
145
|
+
if (!current) break;
|
|
146
|
+
|
|
147
|
+
if (attempts % 5 === 0) {
|
|
148
|
+
elizaLogger.info(`Status: ${current.status}, Phase: ${current.phase}, Sources: ${current.sources.length}`);
|
|
149
|
+
|
|
150
|
+
// Log first few sources
|
|
151
|
+
if (current.sources.length > 0) {
|
|
152
|
+
elizaLogger.info('First few sources:');
|
|
153
|
+
current.sources.slice(0, 3).forEach((s, i) => {
|
|
154
|
+
elizaLogger.info(` ${i + 1}. ${s.title} (${s.url})`);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (current.status === 'completed' || current.status === 'failed') {
|
|
160
|
+
if (current.status === 'completed' && current.report) {
|
|
161
|
+
const markdown = await service.exportProject(project.id, 'markdown');
|
|
162
|
+
const reportPath = path.join(__dirname, '../../fixed-renewable-energy-report.md');
|
|
163
|
+
await fs.writeFile(reportPath, markdown);
|
|
164
|
+
elizaLogger.info(`✅ Report saved to: ${reportPath}`);
|
|
165
|
+
|
|
166
|
+
// Show preview
|
|
167
|
+
elizaLogger.info('\nReport Preview:');
|
|
168
|
+
elizaLogger.info(markdown.substring(0, 1000) + '...');
|
|
169
|
+
|
|
170
|
+
// Check content
|
|
171
|
+
const hasRelevantContent =
|
|
172
|
+
markdown.toLowerCase().includes('energy') &&
|
|
173
|
+
markdown.toLowerCase().includes('storage') &&
|
|
174
|
+
(markdown.toLowerCase().includes('battery') ||
|
|
175
|
+
markdown.toLowerCase().includes('renewable') ||
|
|
176
|
+
markdown.toLowerCase().includes('environmental'));
|
|
177
|
+
|
|
178
|
+
if (hasRelevantContent) {
|
|
179
|
+
elizaLogger.info('\n✅ SUCCESS: Report contains relevant renewable energy content!');
|
|
180
|
+
} else {
|
|
181
|
+
elizaLogger.error('\n❌ FAIL: Report does NOT contain relevant content');
|
|
182
|
+
elizaLogger.info('\nFirst 2000 chars of report:');
|
|
183
|
+
elizaLogger.info(markdown.substring(0, 2000));
|
|
184
|
+
}
|
|
185
|
+
} else {
|
|
186
|
+
elizaLogger.error(`Research failed: ${current.error}`);
|
|
187
|
+
}
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
attempts++;
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
await service.stop();
|
|
195
|
+
|
|
196
|
+
} catch (error) {
|
|
197
|
+
elizaLogger.error('Test failed:', error);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
async function main() {
|
|
202
|
+
// First test Tavily directly
|
|
203
|
+
await testTavilyDirectly();
|
|
204
|
+
|
|
205
|
+
// Then test with minimal runtime
|
|
206
|
+
await testWithMinimalRuntime();
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
main().catch(console.error);
|
|
@@ -0,0 +1,408 @@
|
|
|
1
|
+
# Deep Research Plugin - Example Research Scenarios
|
|
2
|
+
|
|
3
|
+
This document provides real-world examples of how to use the deep research plugin for various research tasks.
|
|
4
|
+
|
|
5
|
+
## 1. Technical Research Scenario
|
|
6
|
+
|
|
7
|
+
**Topic**: "Performance comparison of Next.js 14 App Router vs Pages Router"
|
|
8
|
+
|
|
9
|
+
### Expected Research Flow
|
|
10
|
+
|
|
11
|
+
```typescript
|
|
12
|
+
// User interaction
|
|
13
|
+
User: "Research the performance differences between Next.js 14 App Router and Pages Router"
|
|
14
|
+
|
|
15
|
+
// Agent initiates research
|
|
16
|
+
Agent: "I'll start a deep research project on the performance differences between Next.js 14 App Router and Pages Router."
|
|
17
|
+
|
|
18
|
+
// Research phases:
|
|
19
|
+
|
|
20
|
+
// 1. Planning Phase
|
|
21
|
+
- Identify key performance metrics (FCP, LCP, TTI, Bundle size)
|
|
22
|
+
- Plan to search for benchmarks, case studies, official docs
|
|
23
|
+
- Define comparison criteria
|
|
24
|
+
|
|
25
|
+
// 2. Searching Phase
|
|
26
|
+
- Search for "Next.js 14 App Router performance benchmarks"
|
|
27
|
+
- Search for "Next.js Pages Router vs App Router comparison"
|
|
28
|
+
- Search for "Next.js 14 migration performance impact"
|
|
29
|
+
- Collect 10-15 high-quality sources
|
|
30
|
+
|
|
31
|
+
// 3. Analyzing Phase
|
|
32
|
+
- Extract performance metrics from each source
|
|
33
|
+
- Identify consensus and contradictions
|
|
34
|
+
- Note specific use cases where each excels
|
|
35
|
+
|
|
36
|
+
// 4. Synthesizing Phase
|
|
37
|
+
- Group findings by performance aspect
|
|
38
|
+
- Create comparison tables
|
|
39
|
+
- Identify best practices
|
|
40
|
+
|
|
41
|
+
// 5. Reporting Phase
|
|
42
|
+
- Generate comprehensive report with:
|
|
43
|
+
- Executive summary
|
|
44
|
+
- Detailed performance comparisons
|
|
45
|
+
- Migration considerations
|
|
46
|
+
- Recommendations based on use case
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
### Expected Output
|
|
50
|
+
|
|
51
|
+
```markdown
|
|
52
|
+
# Research Report: Performance comparison of Next.js 14 App Router vs Pages Router
|
|
53
|
+
|
|
54
|
+
## Executive Summary
|
|
55
|
+
This research analyzed 12 sources to compare the performance characteristics of Next.js 14's App Router versus the traditional Pages Router. Key findings indicate that App Router offers superior performance for dynamic applications with frequent data updates, while Pages Router maintains advantages for static content delivery.
|
|
56
|
+
|
|
57
|
+
## Key Performance Findings
|
|
58
|
+
|
|
59
|
+
### 1. Initial Load Performance
|
|
60
|
+
- **App Router**: 15-20% slower initial bundle size due to React Server Components runtime
|
|
61
|
+
- **Pages Router**: Faster initial load for static pages (average 1.2s vs 1.5s)
|
|
62
|
+
|
|
63
|
+
### 2. Runtime Performance
|
|
64
|
+
- **App Router**: Better runtime performance with streaming SSR
|
|
65
|
+
- **Pages Router**: More predictable performance profile
|
|
66
|
+
|
|
67
|
+
### 3. Build Performance
|
|
68
|
+
- **App Router**: Faster incremental builds (30% improvement)
|
|
69
|
+
- **Pages Router**: Better full build times for large applications
|
|
70
|
+
|
|
71
|
+
## Recommendations
|
|
72
|
+
- Use App Router for: Dynamic applications, real-time features, complex data requirements
|
|
73
|
+
- Use Pages Router for: Static sites, blogs, marketing pages
|
|
74
|
+
|
|
75
|
+
## Sources
|
|
76
|
+
1. [Vercel Official Benchmarks](https://vercel.com/blog/next-14-performance) - Official performance metrics
|
|
77
|
+
2. [Web.dev Case Study](https://web.dev/next-js-performance) - Real-world migration analysis
|
|
78
|
+
[... additional sources ...]
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## 2. Market Research Scenario
|
|
82
|
+
|
|
83
|
+
**Topic**: "AI adoption trends in healthcare industry 2024"
|
|
84
|
+
|
|
85
|
+
### Research Configuration
|
|
86
|
+
|
|
87
|
+
```typescript
|
|
88
|
+
const researchConfig = {
|
|
89
|
+
maxSearchResults: 20,
|
|
90
|
+
language: 'en',
|
|
91
|
+
scope: 'Focus on clinical applications, regulatory developments, and market size',
|
|
92
|
+
enableImages: true,
|
|
93
|
+
searchProviders: ['tavily', 'serper']
|
|
94
|
+
};
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
### Expected Phases
|
|
98
|
+
|
|
99
|
+
1. **Planning**: Identify key areas (clinical AI, diagnostic AI, administrative AI)
|
|
100
|
+
2. **Searching**: Gather data from healthcare journals, industry reports, regulatory filings
|
|
101
|
+
3. **Analyzing**: Extract adoption rates, use cases, challenges, success stories
|
|
102
|
+
4. **Synthesizing**: Create industry overview with trends and projections
|
|
103
|
+
5. **Reporting**: Comprehensive market analysis with data visualizations
|
|
104
|
+
|
|
105
|
+
## 3. Academic Research Scenario
|
|
106
|
+
|
|
107
|
+
**Topic**: "Recent advances in quantum error correction codes"
|
|
108
|
+
|
|
109
|
+
### Special Considerations
|
|
110
|
+
|
|
111
|
+
```typescript
|
|
112
|
+
// Configure for academic research
|
|
113
|
+
const academicConfig = {
|
|
114
|
+
searchProviders: ['arxiv', 'scholar', 'pubmed'],
|
|
115
|
+
enableCitations: true,
|
|
116
|
+
citationStyle: 'APA',
|
|
117
|
+
maxSearchResults: 30,
|
|
118
|
+
prioritizePeerReviewed: true
|
|
119
|
+
};
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### Expected Sources
|
|
123
|
+
- ArXiv preprints
|
|
124
|
+
- Nature/Science publications
|
|
125
|
+
- IEEE Quantum Computing proceedings
|
|
126
|
+
- University research papers
|
|
127
|
+
|
|
128
|
+
## 4. Competitive Analysis Scenario
|
|
129
|
+
|
|
130
|
+
**Topic**: "Comparison of major LLM providers APIs and pricing models"
|
|
131
|
+
|
|
132
|
+
### Research Structure
|
|
133
|
+
|
|
134
|
+
```typescript
|
|
135
|
+
// User request
|
|
136
|
+
User: "Research and compare the APIs and pricing of OpenAI, Anthropic, Google, and Cohere"
|
|
137
|
+
|
|
138
|
+
// Research focus areas
|
|
139
|
+
const competitiveAnalysis = {
|
|
140
|
+
providers: ['OpenAI', 'Anthropic', 'Google Gemini', 'Cohere'],
|
|
141
|
+
aspects: [
|
|
142
|
+
'API features',
|
|
143
|
+
'Pricing models',
|
|
144
|
+
'Rate limits',
|
|
145
|
+
'Model capabilities',
|
|
146
|
+
'Documentation quality',
|
|
147
|
+
'SDK support'
|
|
148
|
+
]
|
|
149
|
+
};
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### Expected Deliverables
|
|
153
|
+
|
|
154
|
+
1. **Comparison Matrix**
|
|
155
|
+
- Feature availability across providers
|
|
156
|
+
- Pricing tiers and token costs
|
|
157
|
+
- Rate limits and quotas
|
|
158
|
+
|
|
159
|
+
2. **Technical Analysis**
|
|
160
|
+
- API design patterns
|
|
161
|
+
- Authentication methods
|
|
162
|
+
- Error handling approaches
|
|
163
|
+
|
|
164
|
+
3. **Business Insights**
|
|
165
|
+
- Total cost of ownership calculations
|
|
166
|
+
- Use case recommendations
|
|
167
|
+
- Migration considerations
|
|
168
|
+
|
|
169
|
+
## 5. Real-time Event Research
|
|
170
|
+
|
|
171
|
+
**Topic**: "Impact of recent Federal Reserve rate decision on tech stocks"
|
|
172
|
+
|
|
173
|
+
### Time-Sensitive Configuration
|
|
174
|
+
|
|
175
|
+
```typescript
|
|
176
|
+
const realtimeConfig = {
|
|
177
|
+
maxAge: 24, // Only sources from last 24 hours
|
|
178
|
+
searchProviders: ['news', 'financial'],
|
|
179
|
+
updateFrequency: 'hourly',
|
|
180
|
+
alertOnMajorDevelopments: true
|
|
181
|
+
};
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### Expected Workflow
|
|
185
|
+
|
|
186
|
+
1. **Initial Research**: Gather immediate market reactions
|
|
187
|
+
2. **Follow-up Analysis**: Track evolving analyst opinions
|
|
188
|
+
3. **Synthesis**: Connect rate decision to tech valuations
|
|
189
|
+
4. **Continuous Monitoring**: Update findings as new data emerges
|
|
190
|
+
|
|
191
|
+
## 6. Product Research Scenario
|
|
192
|
+
|
|
193
|
+
**Topic**: "Best practices for implementing RAG systems in production"
|
|
194
|
+
|
|
195
|
+
### Implementation Focus
|
|
196
|
+
|
|
197
|
+
```typescript
|
|
198
|
+
// Research parameters
|
|
199
|
+
const productResearch = {
|
|
200
|
+
scope: `
|
|
201
|
+
- Vector database selection
|
|
202
|
+
- Chunking strategies
|
|
203
|
+
- Retrieval optimization
|
|
204
|
+
- Evaluation metrics
|
|
205
|
+
- Production challenges
|
|
206
|
+
`,
|
|
207
|
+
includeCodeExamples: true,
|
|
208
|
+
prioritizeRecentContent: true
|
|
209
|
+
};
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
### Expected Sections
|
|
213
|
+
|
|
214
|
+
1. **Architecture Patterns**
|
|
215
|
+
- Hybrid search approaches
|
|
216
|
+
- Reranking strategies
|
|
217
|
+
- Cache optimization
|
|
218
|
+
|
|
219
|
+
2. **Implementation Details**
|
|
220
|
+
- Code examples from GitHub
|
|
221
|
+
- Performance benchmarks
|
|
222
|
+
- Cost analysis
|
|
223
|
+
|
|
224
|
+
3. **Case Studies**
|
|
225
|
+
- Company implementations
|
|
226
|
+
- Lessons learned
|
|
227
|
+
- Common pitfalls
|
|
228
|
+
|
|
229
|
+
## Testing Research Quality
|
|
230
|
+
|
|
231
|
+
### Quality Metrics
|
|
232
|
+
|
|
233
|
+
```typescript
|
|
234
|
+
interface ResearchQualityMetrics {
|
|
235
|
+
sourceCredibility: number; // 0-1 score
|
|
236
|
+
informationCompleteness: number; // 0-1 score
|
|
237
|
+
findingRelevance: number; // 0-1 score
|
|
238
|
+
citationAccuracy: number; // 0-1 score
|
|
239
|
+
reportCoherence: number; // 0-1 score
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Example quality assessment
|
|
243
|
+
const assessQuality = (project: ResearchProject): ResearchQualityMetrics => {
|
|
244
|
+
return {
|
|
245
|
+
sourceCredibility: calculateSourceCredibility(project.sources),
|
|
246
|
+
informationCompleteness: assessTopicCoverage(project.findings),
|
|
247
|
+
findingRelevance: measureRelevanceScore(project.findings, project.query),
|
|
248
|
+
citationAccuracy: verifyCitations(project.report.citations),
|
|
249
|
+
reportCoherence: analyzeReportStructure(project.report)
|
|
250
|
+
};
|
|
251
|
+
};
|
|
252
|
+
```
|
|
253
|
+
|
|
254
|
+
## Integration Examples
|
|
255
|
+
|
|
256
|
+
### 1. Slack Integration
|
|
257
|
+
|
|
258
|
+
```typescript
|
|
259
|
+
// Respond to Slack message with research
|
|
260
|
+
app.message(/research (.+)/, async ({ message, say }) => {
|
|
261
|
+
const topic = message.text.match(/research (.+)/)[1];
|
|
262
|
+
|
|
263
|
+
const project = await researchService.createProject(topic);
|
|
264
|
+
await say(`Starting research on: ${topic}`);
|
|
265
|
+
|
|
266
|
+
// Send updates as research progresses
|
|
267
|
+
researchService.on('progress', async (update) => {
|
|
268
|
+
await say(`Research update: ${update.phase} - ${update.progress}%`);
|
|
269
|
+
});
|
|
270
|
+
|
|
271
|
+
// Send final report
|
|
272
|
+
researchService.on('complete', async (project) => {
|
|
273
|
+
await say({
|
|
274
|
+
text: 'Research complete!',
|
|
275
|
+
attachments: [{
|
|
276
|
+
title: project.report.title,
|
|
277
|
+
text: project.report.summary,
|
|
278
|
+
fields: project.report.sections.map(s => ({
|
|
279
|
+
title: s.heading,
|
|
280
|
+
value: s.content.substring(0, 500) + '...',
|
|
281
|
+
short: false
|
|
282
|
+
}))
|
|
283
|
+
}]
|
|
284
|
+
});
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
```
|
|
288
|
+
|
|
289
|
+
### 2. Discord Bot Integration
|
|
290
|
+
|
|
291
|
+
```typescript
|
|
292
|
+
client.on('messageCreate', async (message) => {
|
|
293
|
+
if (message.content.startsWith('!research')) {
|
|
294
|
+
const topic = message.content.replace('!research', '').trim();
|
|
295
|
+
|
|
296
|
+
const embed = new EmbedBuilder()
|
|
297
|
+
.setTitle('Research Started')
|
|
298
|
+
.setDescription(`Researching: ${topic}`)
|
|
299
|
+
.setColor(0x0099FF);
|
|
300
|
+
|
|
301
|
+
const reply = await message.reply({ embeds: [embed] });
|
|
302
|
+
|
|
303
|
+
const project = await researchService.createProject(topic);
|
|
304
|
+
|
|
305
|
+
// Update embed with progress
|
|
306
|
+
const updateInterval = setInterval(async () => {
|
|
307
|
+
const status = await researchService.getProjectStatus(project.id);
|
|
308
|
+
|
|
309
|
+
embed.setFields([
|
|
310
|
+
{ name: 'Status', value: status.status, inline: true },
|
|
311
|
+
{ name: 'Phase', value: status.currentPhase, inline: true },
|
|
312
|
+
{ name: 'Progress', value: `${status.progress}%`, inline: true }
|
|
313
|
+
]);
|
|
314
|
+
|
|
315
|
+
await reply.edit({ embeds: [embed] });
|
|
316
|
+
|
|
317
|
+
if (status.status === 'completed') {
|
|
318
|
+
clearInterval(updateInterval);
|
|
319
|
+
// Send full report as file
|
|
320
|
+
const report = await researchService.getReport(project.id);
|
|
321
|
+
const buffer = Buffer.from(report.markdown, 'utf-8');
|
|
322
|
+
await message.channel.send({
|
|
323
|
+
content: 'Research complete! Here\'s your report:',
|
|
324
|
+
files: [{
|
|
325
|
+
attachment: buffer,
|
|
326
|
+
name: `research-${topic.replace(/\s+/g, '-')}.md`
|
|
327
|
+
}]
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
}, 5000);
|
|
331
|
+
}
|
|
332
|
+
});
|
|
333
|
+
```
|
|
334
|
+
|
|
335
|
+
## Advanced Usage Patterns
|
|
336
|
+
|
|
337
|
+
### 1. Comparative Research
|
|
338
|
+
|
|
339
|
+
```typescript
|
|
340
|
+
// Compare multiple topics
|
|
341
|
+
const comparativeResearch = async (topics: string[]) => {
|
|
342
|
+
const projects = await Promise.all(
|
|
343
|
+
topics.map(topic => researchService.createProject(topic))
|
|
344
|
+
);
|
|
345
|
+
|
|
346
|
+
// Wait for all to complete
|
|
347
|
+
await Promise.all(
|
|
348
|
+
projects.map(p => waitForCompletion(p.id))
|
|
349
|
+
);
|
|
350
|
+
|
|
351
|
+
// Generate comparative analysis
|
|
352
|
+
const comparison = await synthesizeComparison(projects);
|
|
353
|
+
return comparison;
|
|
354
|
+
};
|
|
355
|
+
|
|
356
|
+
// Example usage
|
|
357
|
+
const frameworks = ['React', 'Vue', 'Angular', 'Svelte'];
|
|
358
|
+
const comparison = await comparativeResearch(
|
|
359
|
+
frameworks.map(f => `${f} performance benchmarks 2024`)
|
|
360
|
+
);
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
### 2. Scheduled Research
|
|
364
|
+
|
|
365
|
+
```typescript
|
|
366
|
+
// Daily research updates
|
|
367
|
+
const scheduleResearch = (topic: string, schedule: string) => {
|
|
368
|
+
cron.schedule(schedule, async () => {
|
|
369
|
+
const project = await researchService.createProject(
|
|
370
|
+
`${topic} - updates for ${new Date().toDateString()}`
|
|
371
|
+
);
|
|
372
|
+
|
|
373
|
+
await waitForCompletion(project.id);
|
|
374
|
+
|
|
375
|
+
// Send report to stakeholders
|
|
376
|
+
await emailService.send({
|
|
377
|
+
to: stakeholders,
|
|
378
|
+
subject: `Daily Research Update: ${topic}`,
|
|
379
|
+
body: project.report.markdown
|
|
380
|
+
});
|
|
381
|
+
});
|
|
382
|
+
};
|
|
383
|
+
|
|
384
|
+
// Run every day at 9 AM
|
|
385
|
+
scheduleResearch('AI industry news', '0 9 * * *');
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### 3. Research Pipeline
|
|
389
|
+
|
|
390
|
+
```typescript
|
|
391
|
+
// Multi-stage research pipeline
|
|
392
|
+
const researchPipeline = async (initialTopic: string) => {
|
|
393
|
+
// Stage 1: Broad research
|
|
394
|
+
const overview = await researchService.createProject(initialTopic);
|
|
395
|
+
await waitForCompletion(overview.id);
|
|
396
|
+
|
|
397
|
+
// Stage 2: Deep dive into top findings
|
|
398
|
+
const keyAreas = extractKeyAreas(overview.report);
|
|
399
|
+
const deepDives = await Promise.all(
|
|
400
|
+
keyAreas.map(area => researchService.createProject(area))
|
|
401
|
+
);
|
|
402
|
+
|
|
403
|
+
// Stage 3: Synthesize all research
|
|
404
|
+
const synthesis = await createSynthesisReport([overview, ...deepDives]);
|
|
405
|
+
|
|
406
|
+
return synthesis;
|
|
407
|
+
};
|
|
408
|
+
```
|