import { defineComponent, ref, onMounted, computed } from 'vue' import { useI18n } from 'vue-i18n' import { tools } from '../../store/Modules/tools' import { shared_consts } from '@src/common/shared_vuejs' import { useUserStore } from '@store/UserStore' import { useGlobalStore } from '@store/globalStore' import { useQuasar } from 'quasar' import { costanti } from '@costanti' import { useRouter } from 'vue-router' import { serv_constants } from '@store/Modules/serv_constants' export default defineComponent({ name: 'CAITools', props: { }, components: { }, setup(props, { emit }) { const $q = useQuasar() const { t } = useI18n() const userStore = useUserStore() const globalStore = useGlobalStore() const isfinishLoading = computed(() => globalStore.finishLoading) const $router = useRouter() const options = ref({}) const querySel = ref('') const contestSysteList = [ { label: 'Standard', value: '' }, { label: 'Matematica', value: 'Sei un esperto in Matematica' }, { label: 'Editoriale', value: 'Sei un esperto in Editoria e scrittura di articoli e blog' }, { label: 'Programmazione', value: 'Sei un esperto in programmazione' }, ] const modelList = [ { label: 'DeepSeek', value: 'deepseek-chat' }, ] const outputTypeList = [ { label: 'Formato Testo', value: 'Ritornami l\'output in formato testo' }, { label: 'Per Telegram', value: 'Ritornami l\'output formattato per incollarlo sulla chat Telegram, usando delle emoticons in punti chiave e il grassetto (**) nelle parole chiave, usando la sintassi markdown.' }, { label: 'Formato JSON', value: 'Ritornami l\'output in formato JSON' }, { label: 'Formato CSV (campi separati da \'|\')', value: 'Ritornami l\'output in formato CSV, con i campi separati da \'|\'' }, ] const tempList = [{ label: 'Temperatura a 0.3', value: 0.3 }, { label: 'Temperatura a 0.5', value: 0.5 }, { label: 'Temperatura a 1', value: 1 }, { label: 'Temperatura a 1.2', value: 1.2 }, { label: 'Temperatura a 1.5', value: 1.5 }, ] const tokenList = [ { label: '50 Token', value: 50 }, { label: '100 Token', value: 100 }, { label: '200 Token', value: 200 }, { label: '500 Token', value: 500 }, { label: '1000 Token', value: 1000 }, { label: '2500 Token', value: 2500 }, { label: '4000 Token', value: 4000 }, { label: '5000 Token', value: 5000 }, { label: '10000 Token', value: 10000 }, ] const model = ref('deepseek-chat') const max_tokens = ref(50) const outputType = ref('') const temperatura = ref(0.3) const stream = ref(false) const contestsystem = ref('') const inputPrompt = ref(''); const result = ref(''); const outputvisibile = ref(''); const isLoading = ref(false); const errorMessage = ref(''); const finish_reason = ref(''); const withexplain = ref(false); const querylist = ref([]) const modelLabel = computed(() => { const foundModel = modelList.find((item: any) => item.value === model.value); return foundModel ? foundModel.label : null; }) function mount() { // Mount querylist.value = globalStore.getQueryAI() model.value = tools.getCookie('AI_MOD', 'deepseek-chat') max_tokens.value = tools.getCookie('AI_MT', 50, true) withexplain.value = tools.getCookie('AI_WS', '0') === '1' outputType.value = tools.getCookie('AI_OT', outputTypeList[0].value) temperatura.value = tools.convstrToNum(tools.getCookie('AI_TEM', '0.3')) stream.value = tools.getCookie('AI_ST', '0') === '1' contestsystem.value = tools.getCookie('AI_CON', '') inputPrompt.value = tools.getCookie('AI_PRO', '') } function getInput() { return "Prompt:\n" + inputPrompt.value + '\n\nRisposta:\n' } async function handleSubmit() { isLoading.value = true; errorMessage.value = ''; if (outputvisibile.value) { outputvisibile.value += '\n\n' } outputvisibile.value += getInput(); result.value = ''; finish_reason.value = ''; tools.setCookie('AI_MOD', model.value) tools.setCookie('AI_MT', max_tokens.value.toString()) tools.setCookie('AI_OT', outputType.value) tools.setCookie('AI_TEM', temperatura.value.toString()) tools.setCookie('AI_ST', stream.value ? '1' : '0') tools.setCookie('AI_WE', withexplain.value ? '1' : '0') tools.setCookie('AI_CON', contestsystem.value) tools.setCookie('AI_PRO', inputPrompt.value) options.value = { model: model.value, max_tokens: max_tokens.value, temp: temperatura.value, stream: stream.value, withexplain: withexplain.value, outputType: outputType.value, }; try { if (options.value.stream) { // Modalità streaming const response = await globalStore.getQueryDS(inputPrompt.value, options.value); console.log('uscita da getQueryDS') isLoading.value = false; // Leggi il flusso di dati const reader = response.data.getReader(); const decoder = new TextDecoder('utf-8'); while (true) { const { done, value } = await reader.read(); if (done) break; // Decodifica il chunk e gestisci i dati const chunk = decoder.decode(value); console.log('Received chunk:', chunk); // Log del chunk ricevuto const lines = chunk.split('\n\n').filter((line) => line.trim() !== ''); for (const line of lines) { if (line.startsWith('data: ')) { const data = JSON.parse(line.slice(6)); // Rimuovi "data: " e parsifica il JSON if (data.choice && data.choice.delta && data.choice.delta.content) { result.value += data.choice.delta.content || '' outputvisibile.value += data.choice.delta.content || '' } /*errorMessage.value = data.error; $q.notify({ color: 'negative', icon: 'error', message: 'Errore durante la richiesta', caption: errorMessage.value, }); break; // Interrompi il ciclo in caso di errore }*/ } else if (line.startsWith('data: [DONE]')) { const data = JSON.parse(line.slice(12)); // Rimuovi "data: " e parsifica il JSON if (data.choice && data.choice.finish_reason) { finish_reason.value = data.choice.finish_reason; } inputPrompt.value = ''; } } } } else { // Modalità non streaming const resdata = await globalStore.getQueryDS(inputPrompt.value, options.value); if (resdata.code === serv_constants.RIS_CODE_OK) { inputPrompt.value = ''; if (resdata.choice) { finish_reason.value = resdata.choice.finish_reason || ''; } if (resdata.choice.message) { result.value = resdata.choice.message.content || ''; outputvisibile.value += result.value } } else if (resdata.code === serv_constants.RIS_CODE_ERR) { errorMessage.value = resdata.error.message || resdata.error; $q.notify({ color: 'negative', icon: 'error', message: 'Errore durante la richiesta', caption: errorMessage.value, }); } isLoading.value = false; } } catch (error) { errorMessage.value = error.response?.data?.error || error.message; $q.notify({ color: 'negative', icon: 'error', message: 'Errore durante la richiesta', caption: errorMessage.value, }); } } const copyToClipboard = () => { if (!result.value) return; navigator.clipboard.writeText(result.value).then(() => { $q.notify({ message: 'Copiato negli appunti!', color: 'positive', icon: 'check', }); }).catch(err => { console.error('Errore nella copia:', err); $q.notify({ message: 'Errore nella copia!', color: 'negative', icon: 'error', }); }); } function submitPrompt(event: any) { if (inputPrompt.value.trim()) { // Controlla che l'input non sia vuoto handleSubmit(); // Inviare la richiesta } } onMounted(mount) return { t, querySel, $q, globalStore, inputPrompt, result, outputvisibile, isLoading, errorMessage, handleSubmit, querylist, copyToClipboard, max_tokens, tokenList, modelList, tempList, stream, model, contestSysteList, contestsystem, finish_reason, modelLabel, withexplain, outputType, outputTypeList, temperatura, submitPrompt, } } })