genesis-ai-cli 11.0.0 → 11.0.1
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.
|
@@ -104,6 +104,10 @@ export declare class CompetitiveIntelService {
|
|
|
104
104
|
* Check a single competitor for changes.
|
|
105
105
|
*/
|
|
106
106
|
private checkCompetitor;
|
|
107
|
+
/**
|
|
108
|
+
* Call LLM with MCP fallback to direct HTTP.
|
|
109
|
+
*/
|
|
110
|
+
private callLLM;
|
|
107
111
|
/**
|
|
108
112
|
* Analyze a detected change using LLM.
|
|
109
113
|
*/
|
|
@@ -202,28 +202,61 @@ class CompetitiveIntelService {
|
|
|
202
202
|
return changes;
|
|
203
203
|
}
|
|
204
204
|
/**
|
|
205
|
-
*
|
|
205
|
+
* Call LLM with MCP fallback to direct HTTP.
|
|
206
206
|
*/
|
|
207
|
-
async
|
|
207
|
+
async callLLM(messages, maxTokens = 200) {
|
|
208
|
+
// Try MCP first
|
|
208
209
|
try {
|
|
209
210
|
const mcp = (0, index_js_1.getMCPClient)();
|
|
210
211
|
const result = await mcp.call('openai', 'openai_chat', {
|
|
211
212
|
model: this.config.llmModel,
|
|
212
|
-
messages
|
|
213
|
-
{
|
|
214
|
-
role: 'system',
|
|
215
|
-
content: `You are a competitive intelligence analyst. Analyze changes on competitor websites and determine their business significance. Respond with JSON: {"significance": "low|medium|high|critical", "analysis": "brief analysis"}`
|
|
216
|
-
},
|
|
217
|
-
{
|
|
218
|
-
role: 'user',
|
|
219
|
-
content: `Competitor: ${competitorName}\nPage type: ${page.type}\nURL: ${page.url}\n\nChange detected: ${diffSummary}\n\nOld content (first 1000 chars): ${oldContent.slice(0, 1000)}\n\nNew content (first 1000 chars): ${newContent.slice(0, 1000)}\n\nWhat is the business significance of this change?`
|
|
220
|
-
}
|
|
221
|
-
],
|
|
213
|
+
messages,
|
|
222
214
|
temperature: 0.3,
|
|
223
|
-
max_tokens:
|
|
215
|
+
max_tokens: maxTokens,
|
|
224
216
|
});
|
|
225
217
|
const r = result;
|
|
226
|
-
const content = r?.data?.choices?.[0]?.message?.content || r?.choices?.[0]?.message?.content
|
|
218
|
+
const content = r?.data?.choices?.[0]?.message?.content || r?.choices?.[0]?.message?.content;
|
|
219
|
+
if (content)
|
|
220
|
+
return content;
|
|
221
|
+
}
|
|
222
|
+
catch { /* fall through to direct */ }
|
|
223
|
+
// Fallback: direct OpenAI HTTP call
|
|
224
|
+
const apiKey = process.env.OPENAI_API_KEY;
|
|
225
|
+
if (!apiKey)
|
|
226
|
+
return '{}';
|
|
227
|
+
const resp = await fetch('https://api.openai.com/v1/chat/completions', {
|
|
228
|
+
method: 'POST',
|
|
229
|
+
headers: {
|
|
230
|
+
'Content-Type': 'application/json',
|
|
231
|
+
'Authorization': `Bearer ${apiKey}`,
|
|
232
|
+
},
|
|
233
|
+
body: JSON.stringify({
|
|
234
|
+
model: this.config.llmModel,
|
|
235
|
+
messages,
|
|
236
|
+
temperature: 0.3,
|
|
237
|
+
max_tokens: maxTokens,
|
|
238
|
+
}),
|
|
239
|
+
});
|
|
240
|
+
if (!resp.ok)
|
|
241
|
+
return '{}';
|
|
242
|
+
const data = await resp.json();
|
|
243
|
+
return data?.choices?.[0]?.message?.content || '{}';
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Analyze a detected change using LLM.
|
|
247
|
+
*/
|
|
248
|
+
async analyzeChange(competitorName, page, diffSummary, oldContent, newContent) {
|
|
249
|
+
try {
|
|
250
|
+
const content = await this.callLLM([
|
|
251
|
+
{
|
|
252
|
+
role: 'system',
|
|
253
|
+
content: `You are a competitive intelligence analyst. Analyze changes on competitor websites and determine their business significance. Respond with JSON: {"significance": "low|medium|high|critical", "analysis": "brief analysis"}`
|
|
254
|
+
},
|
|
255
|
+
{
|
|
256
|
+
role: 'user',
|
|
257
|
+
content: `Competitor: ${competitorName}\nPage type: ${page.type}\nURL: ${page.url}\n\nChange detected: ${diffSummary}\n\nOld content (first 1000 chars): ${oldContent.slice(0, 1000)}\n\nNew content (first 1000 chars): ${newContent.slice(0, 1000)}\n\nWhat is the business significance of this change?`
|
|
258
|
+
}
|
|
259
|
+
]);
|
|
227
260
|
const parsed = JSON.parse(content.match(/\{[\s\S]*\}/)?.[0] || '{}');
|
|
228
261
|
return {
|
|
229
262
|
significance: parsed.significance || 'medium',
|
|
@@ -242,25 +275,17 @@ class CompetitiveIntelService {
|
|
|
242
275
|
return { insights: ['No significant changes detected.'], recommendations: [] };
|
|
243
276
|
}
|
|
244
277
|
try {
|
|
245
|
-
const mcp = (0, index_js_1.getMCPClient)();
|
|
246
278
|
const changesSummary = competitorData.map(c => `${c.name}: ${c.changes.map(ch => `[${ch.significance}] ${ch.summary}`).join('; ')}`).join('\n');
|
|
247
|
-
const
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
{
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
{
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
],
|
|
259
|
-
temperature: 0.5,
|
|
260
|
-
max_tokens: 500,
|
|
261
|
-
});
|
|
262
|
-
const r = result;
|
|
263
|
-
const content = r?.data?.choices?.[0]?.message?.content || r?.choices?.[0]?.message?.content || '{}';
|
|
279
|
+
const content = await this.callLLM([
|
|
280
|
+
{
|
|
281
|
+
role: 'system',
|
|
282
|
+
content: 'You are a strategic analyst. Given competitor changes, produce key insights and recommendations. Respond with JSON: {"insights": ["..."], "recommendations": ["..."]}'
|
|
283
|
+
},
|
|
284
|
+
{
|
|
285
|
+
role: 'user',
|
|
286
|
+
content: `Recent competitor changes:\n${changesSummary}\n\nProvide 2-4 key insights and 1-3 actionable recommendations.`
|
|
287
|
+
}
|
|
288
|
+
], 500);
|
|
264
289
|
const parsed = JSON.parse(content.match(/\{[\s\S]*\}/)?.[0] || '{}');
|
|
265
290
|
return {
|
|
266
291
|
insights: parsed.insights || ['Analysis unavailable.'],
|
package/package.json
CHANGED