From 3af038d1956d2a9ff42b3d6b8b07ad565b58253a Mon Sep 17 00:00:00 2001 From: MikeHughes-BIN Date: Thu, 11 Dec 2025 12:41:11 +0100 Subject: [PATCH] Multiple AI models implemented - chatgpt, llama --- scripts/show-models.js | 47 +++++++ services/modules/llm-chat_gpt/chatgpt.js | 89 ++++++++++--- services/modules/llm-llama/llm-llama.js | 123 ++++++++++++++++++ .../modules/transcription-local/whisper.cpp | 1 + 4 files changed, 242 insertions(+), 18 deletions(-) create mode 100644 scripts/show-models.js create mode 100644 services/modules/llm-llama/llm-llama.js create mode 160000 services/modules/transcription-local/whisper.cpp diff --git a/scripts/show-models.js b/scripts/show-models.js new file mode 100644 index 0000000..9aae541 --- /dev/null +++ b/scripts/show-models.js @@ -0,0 +1,47 @@ +const fs = require('fs'); +const path = require('path'); + +//node show-models.js, remember to set SAIA_API_KEY in your environment before running the script + +const SAIA_API_KEY = process.env.SAIA_API_KEY; +const SAIA_MODELS_URL = "https://chat-ai.academiccloud.de/v1/models"; + +// Script to list available models +(async () => { + if (!SAIA_API_KEY) { + console.error("ERROR: SAIA_API_KEY environment variable is not set!"); + process.exit(1); + } + + console.log("Fetching available models from SAIA...\n"); + + try { + const response = await fetch(SAIA_MODELS_URL, { + method: "GET", + headers: { + "Authorization": `Bearer ${SAIA_API_KEY}`, + "Accept": "application/json" + } + }); + + if (!response.ok) { + const text = await response.text(); + throw new Error(`SAIA API error (${response.status}): ${text}`); + } + + const data = await response.json(); + + console.log("Available models:"); + console.log(JSON.stringify(data, null, 2)); + + if (data.data && Array.isArray(data.data)) { + console.log("\n\nModel IDs:"); + data.data.forEach(model => { + console.log(`- ${model.id}`); + }); + } + + } catch (error) { + console.error("Error fetching models:", error); + } +})(); \ No newline at end of file diff --git a/services/modules/llm-chat_gpt/chatgpt.js b/services/modules/llm-chat_gpt/chatgpt.js index b163b27..e3e8cc8 100644 --- a/services/modules/llm-chat_gpt/chatgpt.js +++ b/services/modules/llm-chat_gpt/chatgpt.js @@ -1,24 +1,26 @@ +const fs = require('fs'); +const path = require('path'); + const outputDir = path.join(__dirname, "../../../storage/documents"); // path for output directory if (!fs.existsSync(outputDir)) { fs.mkdirSync(outputDir, { recursive: true }); // Create output directory if it doesn't exist } -// Ensure Chat GPT API key is set in environment variables: export CHAT_GPT_API_KEY="your_api_key_here" -// NOTE: Using standard OPENAI_API_KEY instead because the API expects this env variable -const OPENAI_API_KEY = process.env.OPENAI_API_KEY; // Ensure Chat GPT API key is set in environment variables: export OPENAI_API_KEY="your_api_key_here" +// Ensure SAIA API key is set in environment variables: export SAIA_API_KEY="your_api_key_here" +const SAIA_API_KEY = process.env.SAIA_API_KEY; // Ensure SAIA API key is set in environment variables -const CHAT_GPT_URL = "https://api.openai.com/v1/chat/completions"; //URL for the REST call, used model and action +const SAIA_URL = "https://chat-ai.academiccloud.de/v1/chat/completions"; //URL for the REST call, used model and action -module.exports = { - name: "llm-chat_gpt", +const module_exports = { + name: "llm-saia_openai_gpt", type: "llm", - displayname: "Chat GPT", - description: "Generates documents using Chat GPT", + displayname: "SAIA OpenAI GPT OSS 120B", + description: "Generates documents using OpenAI GPT OSS 120B via SAIA platform", async function(parameter) { try { - console.log("Chat GPT module invoked with parameters:", parameter); + console.log("SAIA OpenAI GPT module invoked with parameters:", parameter); await this.createDocumentFromTranscript( //Call the function to create document with transcript, document type and language parameter.inputTranscriptPath, // Path to input transcript file @@ -27,7 +29,7 @@ module.exports = { ); } catch (error) { - console.error("Error in Chat GPT module:", error); + console.error("Error in SAIA OpenAI GPT module:", error); } }, @@ -38,29 +40,32 @@ module.exports = { const promptText = `${documentType}, in language ${language}, transcript:\n\n${transcript}`; //combine doc type, language and transcript - Change prompt here if needed // --- REST CALL --- - const response = await fetch(CHAT_GPT_URL, { + const response = await fetch(SAIA_URL, { method: "POST", headers: { - "Authorization": `Bearer ${OPENAI_API_KEY}`, + "Authorization": `Bearer ${SAIA_API_KEY}`, + "Accept": "application/json", "Content-Type": "application/json" }, body: JSON.stringify({ - model: "gpt-4.1", + model: "openai-gpt-oss-120b", messages: [ + { role: "system", content: "You are a helpful assistant that generates documents from transcripts." }, { role: "user", content: promptText } - ] + ], + temperature: 0 }) }); - if (!response.ok) { //ok is true when a responce was successfull + if (!response.ok) { //ok is true when a response was successful const text = await response.text(); - throw new Error(`Chat GPT API error (${response.status}): ${text}`); + throw new Error(`SAIA API error (${response.status}): ${text}`); } const data = await response.json(); // Get generated text from response or default to empty string (if null) - // FIX: Chat Completions API uses data.choices[x].message.content + // SAIA uses OpenAI-compatible structure: data.choices[x].message.content const output = data.choices?.[0]?.message?.content || ""; let inputTranscriptName = path.basename(transcriptPath, path.extname(transcriptPath)); // Name for the output file @@ -72,7 +77,55 @@ module.exports = { console.log("Generated document written to:", outPath); } catch (error) { - console.error("Error generating Chat GPT content:", error); + console.error("Error generating SAIA content:", error); } } }; + +module.exports = module_exports; + +// CLI Mode: Allow direct execution +if (require.main === module) { + (async () => { + const args = process.argv.slice(2); + + if (args.length < 2) { + console.error("Usage: node llm-openai-gpt.js [language]"); + console.error("Example: node llm-openai-gpt.js ./transcript.json ./docType.json de"); + process.exit(1); + } + + const [transcriptPath, documentTypePath, language] = args; + + // Check if API key is set + if (!SAIA_API_KEY) { + console.error("ERROR: SAIA_API_KEY environment variable is not set!"); + console.error("Please set it with: export SAIA_API_KEY='your_api_key_here'"); + process.exit(1); + } + + // Check if files exist + if (!fs.existsSync(transcriptPath)) { + console.error(`ERROR: Transcript file not found: ${transcriptPath}`); + process.exit(1); + } + + if (!fs.existsSync(documentTypePath)) { + console.error(`ERROR: Document type file not found: ${documentTypePath}`); + process.exit(1); + } + + console.log("Starting document generation..."); + console.log(`Transcript: ${transcriptPath}`); + console.log(`Document Type: ${documentTypePath}`); + console.log(`Language: ${language || 'en (default)'}`); + + await module_exports.createDocumentFromTranscript( + transcriptPath, + documentTypePath, + language || 'en' + ); + + console.log("Done!"); + })(); +} \ No newline at end of file diff --git a/services/modules/llm-llama/llm-llama.js b/services/modules/llm-llama/llm-llama.js new file mode 100644 index 0000000..0cf4fb8 --- /dev/null +++ b/services/modules/llm-llama/llm-llama.js @@ -0,0 +1,123 @@ +const fs = require('fs'); +const path = require('path'); + +const outputDir = path.join(__dirname, "../../../storage/documents"); + +if (!fs.existsSync(outputDir)) { + fs.mkdirSync(outputDir, { recursive: true }); +} + +const SAIA_API_KEY = process.env.SAIA_API_KEY; +const SAIA_URL = "https://chat-ai.academiccloud.de/v1/chat/completions"; + +const module_exports = { + name: "llm-saia_llama_3.3", + type: "llm", + displayname: "SAIA Llama 3.3 70B", + description: "Generates documents using Llama 3.3 70B Instruct via SAIA platform", + + async function(parameter) { + try { + console.log("SAIA Llama 3.3 70B module invoked with parameters:", parameter); + + await this.createDocumentFromTranscript( + parameter.inputTranscriptPath, + parameter.documentTypePath, + parameter.language + ); + + } catch (error) { + console.error("Error in SAIA Llama 3.3 70B module:", error); + } + }, + + createDocumentFromTranscript: async function(transcriptPath, documentTypePath, language = "en") { + try { + const transcript = await fs.promises.readFile(transcriptPath, "utf-8"); + const documentType = await fs.promises.readFile(documentTypePath, "utf-8"); + const promptText = `${documentType}, in language ${language}, transcript:\n\n${transcript}`; + + // --- REST CALL --- + const response = await fetch(SAIA_URL, { + method: "POST", + headers: { + "Authorization": `Bearer ${SAIA_API_KEY}`, + "Accept": "application/json", + "Content-Type": "application/json" + }, + body: JSON.stringify({ + model: "llama-3.3-70b-instruct", // Korrekter Modellname! + messages: [ + { role: "system", content: "You are a helpful assistant that generates documents from transcripts." }, + { role: "user", content: promptText } + ], + temperature: 0 + }) + }); + + if (!response.ok) { + const text = await response.text(); + throw new Error(`SAIA API error (${response.status}): ${text}`); + } + + const data = await response.json(); + const output = data.choices?.[0]?.message?.content || ""; + + let inputTranscriptName = path.basename(transcriptPath, path.extname(transcriptPath)); + console.log(inputTranscriptName); + + const outPath = path.join(outputDir, `${inputTranscriptName}.md`); + fs.writeFileSync(outPath, output, "utf8"); + + console.log("Generated document written to:", outPath); + + } catch (error) { + console.error("Error generating SAIA content:", error); + } + } +}; + +module.exports = module_exports; + +if (require.main === module) { + (async () => { + const args = process.argv.slice(2); + + if (args.length < 2) { + console.error("Usage: node llm-llama-3.3.js [language]"); + console.error("Example: node llm-llama-3.3.js ./transcript.json ./docType.json de"); + process.exit(1); + } + + const [transcriptPath, documentTypePath, language] = args; + + if (!SAIA_API_KEY) { + console.error("ERROR: SAIA_API_KEY environment variable is not set!"); + console.error("Please set it with: export SAIA_API_KEY='your_api_key_here'"); + process.exit(1); + } + + if (!fs.existsSync(transcriptPath)) { + console.error(`ERROR: Transcript file not found: ${transcriptPath}`); + process.exit(1); + } + + if (!fs.existsSync(documentTypePath)) { + console.error(`ERROR: Document type file not found: ${documentTypePath}`); + process.exit(1); + } + + console.log("Starting document generation..."); + console.log(`Transcript: ${transcriptPath}`); + console.log(`Document Type: ${documentTypePath}`); + console.log(`Language: ${language || 'en (default)'}`); + + await module_exports.createDocumentFromTranscript( + transcriptPath, + documentTypePath, + language || 'en' + ); + + console.log("Done!"); + })(); +} \ No newline at end of file diff --git a/services/modules/transcription-local/whisper.cpp b/services/modules/transcription-local/whisper.cpp new file mode 160000 index 0000000..999a7e0 --- /dev/null +++ b/services/modules/transcription-local/whisper.cpp @@ -0,0 +1 @@ +Subproject commit 999a7e0cbf8484dc2cea1e9f855d6b39f34f7ae9