|
import fetch from 'node-fetch'; |
|
import express from 'express'; |
|
|
|
import { readSecret, SECRET_KEYS } from './secrets.js'; |
|
|
|
export const router = express.Router(); |
|
|
|
router.post('/caption-image', async (request, response) => { |
|
try { |
|
const mimeType = request.body.image.split(';')[0].split(':')[1]; |
|
const base64Data = request.body.image.split(',')[1]; |
|
const baseUrl = request.body.reverse_proxy ? request.body.reverse_proxy : 'https://api.anthropic.com/v1'; |
|
const url = `${baseUrl}/messages`; |
|
const body = { |
|
model: request.body.model, |
|
messages: [ |
|
{ |
|
'role': 'user', 'content': [ |
|
{ |
|
'type': 'image', |
|
'source': { |
|
'type': 'base64', |
|
'media_type': mimeType, |
|
'data': base64Data, |
|
}, |
|
}, |
|
{ 'type': 'text', 'text': request.body.prompt }, |
|
], |
|
}, |
|
], |
|
max_tokens: 4096, |
|
}; |
|
|
|
console.debug('Multimodal captioning request', body); |
|
|
|
const result = await fetch(url, { |
|
body: JSON.stringify(body), |
|
method: 'POST', |
|
headers: { |
|
'Content-Type': 'application/json', |
|
'anthropic-version': '2023-06-01', |
|
'x-api-key': request.body.reverse_proxy ? request.body.proxy_password : readSecret(request.user.directories, SECRET_KEYS.CLAUDE), |
|
}, |
|
}); |
|
|
|
if (!result.ok) { |
|
const text = await result.text(); |
|
console.warn(`Claude API returned error: ${result.status} ${result.statusText}`, text); |
|
return response.status(result.status).send({ error: true }); |
|
} |
|
|
|
|
|
const generateResponseJson = await result.json(); |
|
const caption = generateResponseJson.content[0].text; |
|
console.debug('Claude response:', generateResponseJson); |
|
|
|
if (!caption) { |
|
return response.status(500).send('No caption found'); |
|
} |
|
|
|
return response.json({ caption }); |
|
} catch (error) { |
|
console.error(error); |
|
response.status(500).send('Internal server error'); |
|
} |
|
}); |
|
|