bulltrackers-module 1.0.371 → 1.0.372
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.
|
@@ -82,43 +82,60 @@ async function getGcidForUser(dependencies, config, cid, username) {
|
|
|
82
82
|
*/
|
|
83
83
|
async function getAdvancedAnalysisFromGemini(dependencies, snippet) {
|
|
84
84
|
const { logger, geminiModel } = dependencies;
|
|
85
|
-
|
|
86
|
-
|
|
85
|
+
|
|
86
|
+
if (!geminiModel) {
|
|
87
|
+
return { overallSentiment: "Neutral", topics: [], isSpam: false, qualityScore: 0.5 };
|
|
87
88
|
}
|
|
88
89
|
|
|
89
90
|
const prompt = `
|
|
90
91
|
You are a strict financial content moderator and analyst. Analyze this social media post.
|
|
91
|
-
Output a valid JSON object with these fields:
|
|
92
|
+
Output ONLY a valid JSON object with these fields:
|
|
93
|
+
- isSpam (Boolean)
|
|
94
|
+
- qualityScore (0.0-1.0)
|
|
95
|
+
- overallSentiment ("Bullish", "Bearish", "Neutral")
|
|
96
|
+
- topics (Array)
|
|
92
97
|
Post: "${snippet}"
|
|
93
98
|
`;
|
|
94
99
|
|
|
95
100
|
try {
|
|
96
|
-
const request = {
|
|
97
|
-
contents: [{ role: "user", parts: [{ text: prompt }] }],
|
|
98
|
-
generationConfig: {
|
|
101
|
+
const request = {
|
|
102
|
+
contents: [{ role: "user", parts: [{ text: prompt }] }],
|
|
103
|
+
generationConfig: {
|
|
104
|
+
temperature: 0.1,
|
|
105
|
+
maxOutputTokens: 256,
|
|
106
|
+
responseMimeType: "application/json"
|
|
107
|
+
}
|
|
99
108
|
};
|
|
100
|
-
|
|
109
|
+
|
|
101
110
|
const result = await geminiModel.generateContent(request);
|
|
102
|
-
const text = result.response?.candidates?.[0]?.content?.parts?.[0]?.text?.trim();
|
|
103
111
|
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
112
|
+
// Gemini 2.5 Flash returns JSON directly in parts[0].json
|
|
113
|
+
const part = result?.response?.candidates?.[0]?.content?.parts?.[0];
|
|
114
|
+
|
|
115
|
+
let parsed;
|
|
116
|
+
|
|
117
|
+
if (part?.json) {
|
|
118
|
+
// Ideal case: model returned structured JSON
|
|
119
|
+
parsed = part.json;
|
|
120
|
+
} else if (part?.text) {
|
|
121
|
+
// Fallback: model returned text (rare with application/json)
|
|
122
|
+
const clean = part.text.replace(/```json|```/g, "").trim();
|
|
123
|
+
parsed = JSON.parse(clean);
|
|
124
|
+
} else {
|
|
125
|
+
throw new Error("No JSON or text returned from Gemini");
|
|
117
126
|
}
|
|
127
|
+
|
|
128
|
+
return {
|
|
129
|
+
overallSentiment: parsed.overallSentiment || "Neutral",
|
|
130
|
+
topics: parsed.topics || [],
|
|
131
|
+
isSpam: !!parsed.isSpam,
|
|
132
|
+
qualityScore: parsed.qualityScore ?? 0.5
|
|
133
|
+
};
|
|
134
|
+
|
|
118
135
|
} catch (e) {
|
|
119
|
-
logger.log(
|
|
136
|
+
logger.log("ERROR", "[Gemini AI] JSON handling failed", e);
|
|
137
|
+
return { overallSentiment: "Neutral", topics: [], isSpam: false, qualityScore: 0.5 };
|
|
120
138
|
}
|
|
121
|
-
return { overallSentiment: "Neutral", topics: [], isSpam: false, qualityScore: 0.5 };
|
|
122
139
|
}
|
|
123
140
|
|
|
124
141
|
/**
|