llamacpp: use generic CC endpoint for captioning
| @@ -97,8 +97,6 @@ export async function getMultimodalCaption(base64Img, prompt) { | |||
| 97 | return '/api/google/caption-image'; | 97 | return '/api/google/caption-image'; |
| 98 | case 'anthropic': | 98 | case 'anthropic': |
| 99 | return '/api/anthropic/caption-image'; | 99 | return '/api/anthropic/caption-image'; |
| 100 | case 'llamacpp': | ||
| 101 | return '/api/backends/text-completions/llamacpp/caption-image'; | ||
| 102 | case 'ollama': | 100 | case 'ollama': |
| 103 | return '/api/backends/text-completions/ollama/caption-image'; | 101 | return '/api/backends/text-completions/ollama/caption-image'; |
| 104 | default: | 102 | default: |
| @@ -502,51 +502,6 @@ ollama.post('/caption-image', async function (request, response) { | |||
| 502 | 502 | ||
| 503 | const llamacpp = express.Router(); | 503 | const llamacpp = express.Router(); |
| 504 | 504 | ||
| 505 | llamacpp.post('/caption-image', async function (request, response) { | ||
| 506 | try { | ||
| 507 | if (!request.body.server_url) { | ||
| 508 | return response.sendStatus(400); | ||
| 509 | } | ||
| 510 | |||
| 511 | console.debug('LlamaCpp caption request:', request.body); | ||
| 512 | const baseUrl = trimV1(request.body.server_url); | ||
| 513 | |||
| 514 | const fetchResponse = await fetch(`${baseUrl}/completion`, { | ||
| 515 | method: 'POST', | ||
| 516 | headers: { 'Content-Type': 'application/json' }, | ||
| 517 | body: JSON.stringify({ | ||
| 518 | prompt: `USER:[img-1]${String(request.body.prompt).trim()}\nASSISTANT:`, | ||
| 519 | image_data: [{ data: request.body.image, id: 1 }], | ||
| 520 | temperature: 0.1, | ||
| 521 | stream: false, | ||
| 522 | stop: ['USER:', '</s>'], | ||
| 523 | }), | ||
| 524 | }); | ||
| 525 | |||
| 526 | if (!fetchResponse.ok) { | ||
| 527 | console.error('LlamaCpp caption error:', fetchResponse.status, fetchResponse.statusText); | ||
| 528 | return response.status(500).send({ error: true }); | ||
| 529 | } | ||
| 530 | |||
| 531 | /** @type {any} */ | ||
| 532 | const data = await fetchResponse.json(); | ||
| 533 | console.debug('LlamaCpp caption response:', data); | ||
| 534 | |||
| 535 | const caption = data?.content || ''; | ||
| 536 | |||
| 537 | if (!caption) { | ||
| 538 | console.error('LlamaCpp caption is empty.'); | ||
| 539 | return response.status(500).send({ error: true }); | ||
| 540 | } | ||
| 541 | |||
| 542 | return response.send({ caption }); | ||
| 543 | |||
| 544 | } catch (error) { | ||
| 545 | console.error(error); | ||
| 546 | return response.sendStatus(500); | ||
| 547 | } | ||
| 548 | }); | ||
| 549 | |||
| 550 | llamacpp.post('/props', async function (request, response) { | 505 | llamacpp.post('/props', async function (request, response) { |
| 551 | try { | 506 | try { |
| 552 | if (!request.body.server_url) { | 507 | if (!request.body.server_url) { |
| @@ -45,6 +45,10 @@ router.post('/caption-image', async (request, response) => { | |||
| 45 | key = readSecret(request.user.directories, SECRET_KEYS.KOBOLDCPP); | 45 | key = readSecret(request.user.directories, SECRET_KEYS.KOBOLDCPP); |
| 46 | } | 46 | } |
| 47 | 47 | ||
| 48 | if (request.body.api === 'llamacpp') { | ||
| 49 | key = readSecret(request.user.directories, SECRET_KEYS.LLAMACPP); | ||
| 50 | } | ||
| 51 | |||
| 48 | if (request.body.api === 'vllm') { | 52 | if (request.body.api === 'vllm') { |
| 49 | key = readSecret(request.user.directories, SECRET_KEYS.VLLM); | 53 | key = readSecret(request.user.directories, SECRET_KEYS.VLLM); |
| 50 | } | 54 | } |
| @@ -69,7 +73,8 @@ router.post('/caption-image', async (request, response) => { | |||
| 69 | key = readSecret(request.user.directories, SECRET_KEYS.XAI); | 73 | key = readSecret(request.user.directories, SECRET_KEYS.XAI); |
| 70 | } | 74 | } |
| 71 | 75 | ||
| 72 | if (!key && !request.body.reverse_proxy && ['custom', 'ooba', 'koboldcpp', 'vllm'].includes(request.body.api) === false) { | 76 | const noKeyTypes = ['custom', 'ooba', 'koboldcpp', 'vllm', 'llamacpp']; |
| 77 | if (!key && !request.body.reverse_proxy && !noKeyTypes.includes(request.body.api)) { | ||
| 73 | console.warn('No key found for API', request.body.api); | 78 | console.warn('No key found for API', request.body.api); |
| 74 | return response.sendStatus(400); | 79 | return response.sendStatus(400); |
| 75 | } | 80 | } |
| @@ -156,7 +161,7 @@ router.post('/caption-image', async (request, response) => { | |||
| 156 | }); | 161 | }); |
| 157 | } | 162 | } |
| 158 | 163 | ||
| 159 | if (request.body.api === 'koboldcpp' || request.body.api === 'vllm') { | 164 | if (['koboldcpp', 'vllm', 'llamacpp'].includes(request.body.api)) { |
| 160 | apiUrl = `${trimV1(request.body.server_url)}/v1/chat/completions`; | 165 | apiUrl = `${trimV1(request.body.server_url)}/v1/chat/completions`; |
| 161 | } | 166 | } |
| 162 | 167 | ||