Repository navigation
Expand file tree
/
Copy pathprocessor.js
More file actions
166 lines (133 loc) · 4.93 KB
/
Copy pathprocessor.js
File metadata and controls
166 lines (133 loc) · 4.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import Anthropic from '@anthropic-ai/sdk';
import { createChunks } from './utils.js';
// Initialize the Anthropic client if API key is available
let anthropicClient;
try {
if (process.env.ANTHROPIC_API_KEY) {
anthropicClient = new Anthropic({
apiKey: process.env.ANTHROPIC_API_KEY,
});
}
} catch (error) {
console.warn('Failed to initialize Anthropic client:', error.message);
}
/**
* Process crawled text content with AI
* @param {Array} crawlResults - Array of crawl result objects
* @param {Object} options - Processing options
* @param {string} options.task - The task to perform (summarize, extract, analyze, etc.)
* @param {string} options.model - AI model to use
* @param {Object} options.logger - Winston logger instance
* @returns {Object} - Processed results
*/
export async function processText(crawlResults, options = {}) {
const {
task = 'summarize',
model = 'claude-3-sonnet-20240229',
maxTokens = 4000,
temperature = 0.7,
logger = console
} = options;
// Check if Anthropic client is available
if (!anthropicClient) {
logger.warn('Anthropic API key not found. AI processing skipped.');
return {
error: 'Anthropic API key not configured',
originalResults: crawlResults
};
}
logger.info(`Processing ${crawlResults.length} pages with AI, task: ${task}`);
// Create a single document from all crawled pages
const combinedText = crawlResults.map(page => {
return `## Page: ${page.title} (${page.url})\n\n${page.content}\n\n`;
}).join('\n---\n\n');
// Create chunks to avoid token limits
const chunks = createChunks(combinedText, 100000); // characters, not tokens
// Process each chunk
const processedChunks = [];
for (let i = 0; i < chunks.length; i++) {
logger.debug(`Processing chunk ${i+1}/${chunks.length}`);
let prompt;
// Create appropriate prompt based on task
switch (task.toLowerCase()) {
case 'summarize':
prompt = `Please provide a comprehensive summary of the following web content. Focus on the main points, key information, and overall themes:
${chunks[i]}
Provide a well-structured summary with key points, important details, and main conclusions.`;
break;
case 'extract':
prompt = `Please extract all factual information from the following web content:
${chunks[i]}
Format the information as a list of verified facts found in the content.`;
break;
case 'analyze':
prompt = `Please analyze the following web content:
${chunks[i]}
Provide:
1. Main topic overview
2. Key arguments or claims made
3. Evidence presented
4. Logical fallacies or biases (if any)
5. Quality assessment of the information
6. Connections between concepts
7. Areas where information might be missing`;
break;
case 'questions':
prompt = `Based on the following web content:
${chunks[i]}
Generate 10 important questions that someone might have after reading this content, along with detailed answers based solely on the information provided.`;
break;
default:
prompt = `Please ${task} the following web content:
${chunks[i]}`;
}
try {
// Call Claude API
const completion = await anthropicClient.messages.create({
model: model,
max_tokens: maxTokens,
temperature: temperature,
messages: [
{ role: 'user', content: prompt }
]
});
processedChunks.push(completion.content[0].text);
} catch (error) {
logger.error(`Error calling Claude API: ${error.message}`);
processedChunks.push(`[Error processing chunk ${i+1}: ${error.message}]`);
}
}
// If there are multiple chunks, we might want to combine them with another API call
let finalResult = processedChunks.join('\n\n');
if (processedChunks.length > 1) {
try {
logger.debug('Combining multiple chunk results with additional API call');
const combiningPrompt = `You've analyzed multiple chunks of web content and provided separate analyses. Please combine and synthesize these separate analyses into a single coherent response:
${finalResult}
Provide a unified, well-structured response that combines all the information without repetition.`;
const completion = await anthropicClient.messages.create({
model: model,
max_tokens: maxTokens,
temperature: temperature,
messages: [
{ role: 'user', content: combiningPrompt }
]
});
finalResult = completion.content[0].text;
} catch (error) {
logger.error(`Error combining results: ${error.message}`);
// Keep the concatenated results if combining fails
}
}
return {
task,
result: finalResult,
meta: {
model,
processedAt: new Date().toISOString(),
pagesProcessed: crawlResults.length,
chunksProcessed: chunks.length
},
originalResults: crawlResults
};
}