@tiledesk/tiledesk-server
Version:
The Tiledesk server module
162 lines (136 loc) • 5.94 kB
JavaScript
var express = require('express');
var router = express.Router();
var winston = require('../config/winston');
let Integration = require('../models/integrations');
const aiService = require('../services/aiService');
const multer = require('multer');
const fileUtils = require('../utils/fileUtils');
const { MODELS_MULTIPLIER } = require('../utils/aiUtils');
let MAX_UPLOAD_FILE_SIZE = process.env.MAX_UPLOAD_FILE_SIZE;
let uploadlimits = undefined;
if (MAX_UPLOAD_FILE_SIZE) {
uploadlimits = {fileSize: parseInt(MAX_UPLOAD_FILE_SIZE)} ;
winston.debug("Max upload file size is : " + MAX_UPLOAD_FILE_SIZE);
} else {
winston.debug("Max upload file size is infinity");
}
var upload = multer({limits: uploadlimits});
router.post('/preview', async (req, res) => {
let id_project = req.projectid;
let body = req.body;
let key;
let publicKey = false;
if (!body.llm) {
return res.status(400).send({ success: false, error: "Missing required parameter 'llm'" });
}
let integration = await Integration.findOne({ id_project: id_project, name: body.llm }).catch((err) => {
winston.error("Error finding integration with name: ", body.llm);
return res.status(500).send({ success: false, error: "Error finding integration for " + body.llm});
})
if (!integration) {
winston.verbose("Integration not found for " + body.llm)
if (body.llm === "openai") {
winston.verbose("Try to retrieve shared OpenAI key")
if (!process.env.GPTKEY) {
winston.error("Shared key for OpenAI not configured.");
return res.status(404).send({ success: false, error: "No key found for " + body.llm });
}
key = process.env.GPTKEY;
publicKey = true;
winston.verbose("Using shared OpenAI key as fallback.");
} else {
winston.verbose("Integration for " + body.llm + " not found.")
return res.status(404).send({ success: false, error: "Integration for " + body.llm + " not found." })
}
} else {
if (!integration?.value?.apikey && body.llm !== "ollama") {
return res.status(422).send({ success: false, error: "The key provided for " + body.llm + " is not valid or undefined." });
}
key = integration.value.apikey;
}
let obj = { createdAt: new Date() };
let quoteManager = req.app.get('quote_manager');
if (publicKey === true) {
let isAvailable = await quoteManager.checkQuote(req.project, obj, 'tokens');
if (isAvailable === false) {
return res.status(403).send({ success: false, message: "Tokens quota exceeded", error_code: 13001})
}
}
let json = {
question: body.question,
llm: body.llm,
model: body.model,
llm_key: key,
temperature: body.temperature,
max_tokens: body.max_tokens
}
if (body.context) {
json.system_context = body.context;
}
if (body.llm === 'ollama') {
json.llm_key = "";
json.model = {
name: body.model,
url: integration.value.url,
token: integration.value.token
},
json.stream = false;
}
winston.debug("Preview LLM json: ", json);
aiService.askllm(json).then((response) => {
winston.verbose("Askllm response: ", response);
if (publicKey === true) {
let multiplier = MODELS_MULTIPLIER[json.model];
if (!multiplier) {
multiplier = 1;
winston.info("No multiplier found for AI model (llm) " + json.model)
}
obj.multiplier = multiplier;
obj.tokens = response.data?.prompt_token_info?.total_tokens || 0;
quoteManager.incrementTokenCount(req.project, obj);
}
res.status(200).send(response.data)
}).catch((err) => {
if (err.response?.data?.detail?.[0]) {
res.status(400).send({ success: false, error: err.response.data.detail[0]?.msg, detail: err.response.data.detail });
} else if (err.response?.data?.detail?.answer) {
res.status(400).send({ success: false, error: err.response.data.detail.answer, detail: err.response.data.detail });
} else if (err.response?.data) {
res.status(500).send({ success: false, error: err.response.data });
} else {
res.status(500).send({ success: false, error: err });
}
})
})
router.post('/transcription', upload.single('uploadFile'), async (req, res) => {
let id_project = req.projectid;
let file;
if (req.body.url) {
file = await fileUtils.downloadFromUrl(req.body.url);
} else if (req.file) {
file = req.file.buffer;
} else {
return res.status(400).send({ success: false, error: "No audio file or URL provided"})
}
let key;
let integration = await Integration.findOne({ id_project: id_project, name: 'openai' }).catch((err) => {
winston.error("Error finding integration for openai");
return res.status(500).send({ success: false, error: "Error finding integration for openai"});
})
if (!integration) {
winston.verbose("Integration for openai not found.")
return res.status(404).send({ success: false, error: "Integration for openai not found."})
}
if (!integration?.value?.apikey) {
return res.status(422).send({ success: false, error: "The key provided for openai is not valid or undefined." })
}
key = integration.value.apikey;
aiService.transcription(file, key).then((response) => {
winston.verbose("Transcript response: ", response.data);
res.status(200).send({ text: response.data.text});
}).catch((err) => {
winston.error("err: ", err.response?.data)
res.status(500).send({ success: false, error: err });
})
})
module.exports = router;