Error caching response: GoogleGenerativeAIFetchError: [GoogleGenerativeAI Error]: Error fetching from https://generativelanguage.googleapis.com/v1beta/cachedContents: [400 Bad Request] Cached content is required to have content.role set.
at handleResponseNotOk (file:///opt/render/project/src/mern/server/node_modules/@google/generative-ai/dist/server/index.mjs:127:11)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
at async makeRequest (file:///opt/render/project/src/mern/server/node_modules/@google/generative-ai/dist/server/index.mjs:100:9)
at async GoogleAICacheManager.create (file:///opt/render/project/src/mern/server/node_modules/@google/generative-ai/dist/server/index.mjs:488:26)
at async GridFSBucketWriteStream.<anonymous> (file:///opt/render/project/src/mern/server/routes/record.js:1493:29) {
status: 400,
statusText: 'Bad Request',
errorDetails: undefined
}
## A snippet of the code I'm running!
// *** Video Upload Route ***
router.post("/upload/video", upload.single('video'),
// Validation for video upload
[
body('patientId').isString().notEmpty().withMessage('Patient ID is required'),
],
async (req, res) => {
// Validation result check
const errors = validationResult(req);
if (!errors.isEmpty()) {
return res.status(400).json({ errors: errors.array() });
}
try {
const { patientId } = req.body;
const video = req.file;
// Check if there's an existing record for this patient
const existingRecord = await db.collection("video-sdoh-records").findOne({ patientId });
// If exists, delete the old video from GridFS
if (existingRecord) {
const bucket = new GridFSBucket(db, { bucketName: 'videos' });
try {
await bucket.delete(existingRecord.uploadedVideoId);
} catch (deleteError) {
console.warn(`Failed to delete old video: ${deleteError.message}`);
// Continue with upload even if delete fails
}
}
// 1. Create a GridFS bucket
const bucket = new GridFSBucket(db, { bucketName: 'videos' });
// 2. Create an upload stream
const uploadStream = bucket.openUploadStream(video.originalname, {
metadata: {
patientId,
uploadDate: new Date(),
originalName: video.originalname,
mimeType: video.mimetype
}
});
// 3. Pipe the video data to the upload stream
fs.createReadStream(video.path).pipe(uploadStream)
.on('error', (error) => {
logger.error("Error uploading video to GridFS:", error);
res.status(500).json({ error: "Internal server error" });
})
.on('finish', async () => {
// 4. Get the video file ID from GridFS
const videoFileId = uploadStream.id;
// 5. Update or create the video record
await db.collection("video-sdoh-records").updateOne(
{ patientId },
{
$set: {
uploadedVideoId: videoFileId,
lastUpdated: new Date(),
originalName: video.originalname,
mimeType: video.mimetype
}
},
{ upsert: true }
);
// Delete any old analysis results
await db.collection("sdoh-analysis-results").deleteMany({ patientId });
// 6. Upload the video to Gemini for processing
const uploadedVideo = await uploadToGemini(video.path, video.mimetype);
// 7. Wait for the file to become ACTIVE
const activeFile = await waitForFilesActive(uploadedVideo);
// *** Caching Logic Start ***
const cacheManager = new GoogleAICacheManager(gkey);
const displayName = `video-analysis-${patientId}`; // Unique name for the cache
const modelName = 'models/gemini-1.5-pro-001'; // Your Gemini model
let ttlSeconds = 24 * 3600; // Cache TTL (24 hour in this example)
// Create a cache key. This should be unique for each video.
const cacheKey = `video-analysis-${videoFileId}`;
// Try to fetch from cache first
let cachedContent = null;
try {
cachedContent = await cacheManager.get(cacheKey);
console.log("cached content" + cacheKey + " " + cachedContent)
console.log(displayName)
} catch (err) {
console.log(displayName)
// Handle cache miss (e.g., cache not found)
console.log('Cache miss:', err.message);
}
if (cachedContent) {
// Use the cached content
console.log('Using cached content');
const { geminiAnalysis, sdohVideoInsightsArray } = cachedContent;
res.status(201).json({
message: "Video analysis retrieved from cache",
uploadedVideoUrl: activeFile.uri,
geminiAnalysis: geminiAnalysis,
sdohVideoInsightsArray: sdohVideoInsightsArray,
uploadedVideoId: videoFileId,
});
} else {
console.log('Cache miss - performing analysis');
// 8. Define the prompt for Gemini AI
const prompt = `
Analyze the provided video for potential pregnancy-related health issues and abnormalities.
Thought 1
I need to develop a systematic approach to assess maternal and fetal health through video observation, breaking down the analysis into specific clinical indicators.
Action 1
<search>pregnancy health assessment techniques</search>
Observation 1
Comprehensive pregnancy health assessment requires careful evaluation of physical, behavioral, and environmental factors affecting maternal and fetal well-being.
Thought 2
I will first focus on assessing the mother's physical health, looking for any visible signs of potential medical concerns.
Action 2
<lookup>maternal physical health indicators</lookup>
Observation 2
Key physical health indicators include posture, movement patterns, signs of discomfort, visible physical changes, and overall physical functioning during pregnancy.
Thought 3
Next, I will carefully observe fetal movement patterns to identify any potential abnormalities or areas of concern.
Action 3
<search>fetal movement assessment pregnancy</search>
Observation 3
Fetal movement provides critical insights into fetal health, neural development, and potential underlying medical conditions that may require further investigation.
Thought 4
I will analyze the environmental context to identify any potential external factors that could impact maternal or fetal health.
Action 4
<lookup>environmental health risks pregnancy</lookup>
Observation 4
Environmental factors can significantly influence pregnancy outcomes, including physical hazards, stress levels, and support systems available to the mother.
Thought 5
I will synthesize these observations to create a comprehensive overview of potential health risks or protective factors.
Action 5
<finish>Comprehensive video-based pregnancy health analysis prepared</finish>
`;
// 9. Start chat session with the model
const chatSession = model.startChat({
generationConfig,
safetySettings,
history: [
{
role: "user",
parts: [
{ text: prompt },
{
fileData: {
mimeType: activeFile.mimeType,
fileUri: activeFile.uri,
},
},
],
},
],
});
// 10. Send the prompt and receive diagnostic results
const generatedContent = await retryWithBackoff(() => chatSession.sendMessage(prompt));
const geminiAnalysis = generatedContent.response.text();
console.log(geminiAnalysis)
// 11. Perform SDOH analysis for the video
const { accumulatedInsights, tempVideoPath } = await analyzeSDOHDataForVideo(patientId);
// Cache the response for future use
try {
const cacheContent = {
geminiAnalysis: geminiAnalysis,
sdohVideoInsightsArray: accumulatedInsights,
};
const cache = await cacheManager.create({
model: modelName,
displayName: cacheKey, // Use the cache key here
systemInstruction: { // Provide a valid Content object
role: 'system', // Set the role to 'system'
parts: [{ text: '' }], // You can keep the text empty
}, // You can leave this empty if not needed
contents: [
{
role: 'user',
parts: [{ text: prompt }],
},
{
role: 'assistant',
parts: [
{text: cacheContent.geminiAnalysis }, // Directly cache geminiAnalysis
{text: JSON.stringify(cacheContent.sdohVideoInsightsArray) } // Cache the entire object as a string
], // Cache the analysis results
},
],
ttlSeconds,
});
console.log('Response cached successfully:', cache.name);
} catch (cacheError) {
console.error('Error caching response:', cacheError);
// Handle caching errors (e.g., log the error)
}
res.status(201).json({
message: "Video record created successfully",
uploadedVideoUrl: activeFile.uri,
geminiAnalysis: geminiAnalysis,
sdohVideoInsightsArray: accumulatedInsights,
uploadedVideoId: videoFileId,
});
}
// *** Caching Logic End ***
}); // End of uploadStream.on('finish')
} catch (error) {
logger.error("Error uploading video:", error);
res.status(500).json({ error: "Internal server error" });
}
}
);
I am also having this exact issue! Also, need a solution.