feat: add vercel/ai package; gigachat api; refactor dictionaries; add units put request #72
							
								
								
									
										2047
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2047
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										10
									
								
								package.json
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								package.json
									
									
									
									
									
								
							@ -23,10 +23,12 @@
 | 
				
			|||||||
  "license": "MIT",
 | 
					  "license": "MIT",
 | 
				
			||||||
  "homepage": "https://bitbucket.org/online-mentor/multi-stub#readme",
 | 
					  "homepage": "https://bitbucket.org/online-mentor/multi-stub#readme",
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "axios": "^1.7.9",
 | 
					    "ai": "^4.1.13",
 | 
				
			||||||
    "bcrypt": "^5.1.1",
 | 
					    "axios": "^1.7.7",
 | 
				
			||||||
    "body-parser": "^1.20.3",
 | 
					    "bcrypt": "^5.1.0",
 | 
				
			||||||
    "cookie-parser": "^1.4.7",
 | 
					    "body-parser": "^1.19.0",
 | 
				
			||||||
 | 
					    "cookie-parser": "^1.4.5",
 | 
				
			||||||
 | 
					    "cors": "^2.8.5",
 | 
				
			||||||
    "cross-env": "^7.0.3",
 | 
					    "cross-env": "^7.0.3",
 | 
				
			||||||
    "crypto-js": "^4.2.0",
 | 
					    "crypto-js": "^4.2.0",
 | 
				
			||||||
    "dotenv": "^16.4.7",
 | 
					    "dotenv": "^16.4.7",
 | 
				
			||||||
 | 
				
			|||||||
@ -1,17 +0,0 @@
 | 
				
			|||||||
[
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "id": 0,
 | 
					 | 
				
			||||||
    "description": "10 часто используемых",
 | 
					 | 
				
			||||||
    "imageFilename": "kart1.jpg"
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
    "id": 1,
 | 
					 | 
				
			||||||
    "description": "10 слов в Data Science",
 | 
					 | 
				
			||||||
    "imageFilename": "kart1.jpg"
 | 
					 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
	"id": 2,
 | 
					 | 
				
			||||||
	"description": "IT Basics Dictionary",
 | 
					 | 
				
			||||||
    "imageFilename": "kart1.jpg"
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
]
 | 
					 | 
				
			||||||
@ -6,18 +6,14 @@
 | 
				
			|||||||
        "id": 0,
 | 
					        "id": 0,
 | 
				
			||||||
        "word": "Tech",
 | 
					        "word": "Tech",
 | 
				
			||||||
        "definition": "short for technical, relating to the knowledge, machines, or methods used in science and industry. Tech is a whole industry, which includes IT",
 | 
					        "definition": "short for technical, relating to the knowledge, machines, or methods used in science and industry. Tech is a whole industry, which includes IT",
 | 
				
			||||||
        "examples": [
 | 
					        "examples": ["“As a DevOps engineer I have been working in Tech since 2020.”"],
 | 
				
			||||||
          "“As a DevOps engineer I have been working in Tech since 2020.”"
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "synonyms": ["IT"]
 | 
					        "synonyms": ["IT"]
 | 
				
			||||||
      },
 | 
					      },
 | 
				
			||||||
      {
 | 
					      {
 | 
				
			||||||
        "id": 1,
 | 
					        "id": 1,
 | 
				
			||||||
        "word": "career path",
 | 
					        "word": "career path",
 | 
				
			||||||
        "definition": "the series of jobs or roles that constitute a person's career, especially one in a particular field",
 | 
					        "definition": "the series of jobs or roles that constitute a person's career, especially one in a particular field",
 | 
				
			||||||
        "examples": [
 | 
					        "examples": ["“Technology is an evolving field with a variety of available career paths.”"],
 | 
				
			||||||
          "“Technology is an evolving field with a variety of available career paths.”"
 | 
					 | 
				
			||||||
        ],
 | 
					 | 
				
			||||||
        "synonyms": []
 | 
					        "synonyms": []
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
@ -146,130 +142,5 @@
 | 
				
			|||||||
        ]
 | 
					        ]
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
  },
 | 
					 | 
				
			||||||
  {
 | 
					 | 
				
			||||||
	  "id": 2,
 | 
					 | 
				
			||||||
	  "words": [
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"id": 0,
 | 
					 | 
				
			||||||
			"word": "software",
 | 
					 | 
				
			||||||
			"translation": "программное обеспечение",
 | 
					 | 
				
			||||||
			"definition": "A collection of computer instructions that perform a specific task, typically for use by humans or machines.",
 | 
					 | 
				
			||||||
			"synonyms": ["код", "приложение", "управление программами"],
 | 
					 | 
				
			||||||
			"examples":
 | 
					 | 
				
			||||||
				[
 | 
					 | 
				
			||||||
					"I need to update the software on my new laptop.",
 | 
					 | 
				
			||||||
					"The company uses Windows as its operating system."
 | 
					 | 
				
			||||||
				]
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"id": 1,
 | 
					 | 
				
			||||||
			"word": "hardware",
 | 
					 | 
				
			||||||
			"translation": "железо",
 | 
					 | 
				
			||||||
			"definition": "Physical components of a computer that process information, including processors and storage devices.",
 | 
					 | 
				
			||||||
			"synonyms": ["equipment", "приборы", "оборудование"],
 | 
					 | 
				
			||||||
			"examples":
 | 
					 | 
				
			||||||
				[
 | 
					 | 
				
			||||||
					"The keyboard is part of the hardware on this device.",
 | 
					 | 
				
			||||||
					"They upgraded their router to improve internet speed."
 | 
					 | 
				
			||||||
				]
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"id": 2,
 | 
					 | 
				
			||||||
			"word": "network",
 | 
					 | 
				
			||||||
			"translation": "сети",
 | 
					 | 
				
			||||||
			"definition": "A system of interconnected devices that communicate with each other through data transmission over a networked medium.",
 | 
					 | 
				
			||||||
			"synonyms": ["трансляция", "коммуникации", "диалог"],
 | 
					 | 
				
			||||||
			"examples":
 | 
					 | 
				
			||||||
				[
 | 
					 | 
				
			||||||
					"We use the internet to connect our devices in the same area.",
 | 
					 | 
				
			||||||
					"The company relies on their internal network for data sharing."
 | 
					 | 
				
			||||||
				]
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"id": 3,
 | 
					 | 
				
			||||||
			"word": "algorithm",
 | 
					 | 
				
			||||||
			"translation": "алгоритм",
 | 
					 | 
				
			||||||
			"definition": "A set of instructions that a computer follows to solve a problem or achieve a specific task.",
 | 
					 | 
				
			||||||
			"synonyms": ["процесс", "схема", "текст"],
 | 
					 | 
				
			||||||
			"examples":
 | 
					 | 
				
			||||||
				[
 | 
					 | 
				
			||||||
					"The algorithm for sorting numbers is easy to follow.",
 | 
					 | 
				
			||||||
					"The new software includes an advanced algorithm."
 | 
					 | 
				
			||||||
				]
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"id": 4,
 | 
					 | 
				
			||||||
			"word": "encryption",
 | 
					 | 
				
			||||||
			"translation": "криптография",
 | 
					 | 
				
			||||||
			"definition": "A technique that transforms information into a secure form, making it unreadable without the appropriate key.",
 | 
					 | 
				
			||||||
			"synonyms": ["шифрование", "окрышение", "опциональное"],
 | 
					 | 
				
			||||||
			"examples":
 | 
					 | 
				
			||||||
				[
 | 
					 | 
				
			||||||
					"Our data is encrypted to ensure its privacy and security.",
 | 
					 | 
				
			||||||
					"I need to use an encryption program for my important documents."
 | 
					 | 
				
			||||||
				]
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"id": 5,
 | 
					 | 
				
			||||||
			"word": "debugging",
 | 
					 | 
				
			||||||
			"translation": "поиск и исправление ошибок",
 | 
					 | 
				
			||||||
			"definition": "The process of identifying and correcting errors or defects in a computer program.",
 | 
					 | 
				
			||||||
			"synonyms": ["исправление", "сканирование", "анализ"],
 | 
					 | 
				
			||||||
			"examples":
 | 
					 | 
				
			||||||
				[
 | 
					 | 
				
			||||||
					"I need to debug the code for this new project.",
 | 
					 | 
				
			||||||
					"We use automated tools to find bugs."
 | 
					 | 
				
			||||||
				]
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"id": 6,
 | 
					 | 
				
			||||||
			"word": "API",
 | 
					 | 
				
			||||||
			"translation": "интерфейс приложения",
 | 
					 | 
				
			||||||
			"definition": "A set of rules and protocols that enables communication between software applications, typically over a network.",
 | 
					 | 
				
			||||||
			"synonyms": ["серверное программирование", "функциональная структура"],
 | 
					 | 
				
			||||||
			"examples":
 | 
					 | 
				
			||||||
				[
 | 
					 | 
				
			||||||
					"We use the API for our mobile app to access data from the backend server.",
 | 
					 | 
				
			||||||
					"I need to write an API for connecting my devices to the internet."
 | 
					 | 
				
			||||||
				]
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"id": 7,
 | 
					 | 
				
			||||||
			"word": "virtual",
 | 
					 | 
				
			||||||
			"translation": "виртуальный",
 | 
					 | 
				
			||||||
			"definition": "A representation of a thing that does not exist physically but exists in digital form.",
 | 
					 | 
				
			||||||
			"synonyms": ["высокопроизводительный", "представление", "цифровой"],
 | 
					 | 
				
			||||||
			"examples":
 | 
					 | 
				
			||||||
				[
 | 
					 | 
				
			||||||
					"I use virtual reality to experience different environments.",
 | 
					 | 
				
			||||||
					"Our company offers virtual office spaces for remote work."
 | 
					 | 
				
			||||||
				]
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"id": 8,
 | 
					 | 
				
			||||||
			"word": "infrastructure",
 | 
					 | 
				
			||||||
			"translation": "инфраструктура",
 | 
					 | 
				
			||||||
			"definition": "The underlying systems and equipment of a computer network or organization, including hardware, software, and physical connections.",
 | 
					 | 
				
			||||||
			"synonyms": ["оборудование", "устройство", "системы"],
 | 
					 | 
				
			||||||
			"examples":
 | 
					 | 
				
			||||||
				[
 | 
					 | 
				
			||||||
					"Our IT infrastructure is robust to ensure reliable operations.",
 | 
					 | 
				
			||||||
					"They need to improve their internet infrastructure for better connectivity."
 | 
					 | 
				
			||||||
				]
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		{
 | 
					 | 
				
			||||||
			"id": 9,
 | 
					 | 
				
			||||||
			"word": "hacker",
 | 
					 | 
				
			||||||
			"translation": "хакер",
 | 
					 | 
				
			||||||
			"definition": "A skilled individual who uses computer technology to break into and misuse a system or network.",
 | 
					 | 
				
			||||||
			"synonyms": ["дезориентированный", "манипулятор", "прокурор"],
 | 
					 | 
				
			||||||
			"examples":
 | 
					 | 
				
			||||||
				[
 | 
					 | 
				
			||||||
					"I need to avoid getting involved with hackers.",
 | 
					 | 
				
			||||||
					"They were caught hacking into the company's confidential database."
 | 
					 | 
				
			||||||
				]
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
	]
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
]
 | 
					]
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1 @@
 | 
				
			|||||||
 | 
					[{"id":1,"description":"10 слов в Data Science","imageFilename":"kart1.jpg","words":[2,3,4,5,6,7,8,9,10,11,12]}]
 | 
				
			||||||
@ -1,42 +1,99 @@
 | 
				
			|||||||
const fs = require('fs');
 | 
					const fs = require('fs');
 | 
				
			||||||
const path = require('path');
 | 
					const path = require('path');
 | 
				
			||||||
const router = require("express").Router();
 | 
					const router = require('express').Router();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
module.exports = router;
 | 
					module.exports = router;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const data = require("./data/dictionaries.json");
 | 
					const dictionaries = require('./dictionaries.json');
 | 
				
			||||||
const wordsData = require("./data/dictionaryWords.json");
 | 
					const words = require('../words/words.json');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
router.get("/", (req, res) => {
 | 
					router.get('/', (req, res) => {
 | 
				
			||||||
  res.send(data);
 | 
					  res.send(dictionaries);
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Put new dictionary to the array of dictionaries
 | 
					router.get('/:id', (req, res) => {
 | 
				
			||||||
router.put('/new', (req, res) => {
 | 
					  const id = parseInt(req.params.id);
 | 
				
			||||||
  if (!data || !Array.isArray(data)) {
 | 
					  if (!id || isNaN(id)) {
 | 
				
			||||||
    return res.status(400).send('No array of dictionaries found`');
 | 
					    return res.status(400).send('Invalid ID'); // Bad request
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const updatedData = req.body;
 | 
					  if (!dictionaries) {
 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (!updatedData) {
 | 
					 | 
				
			||||||
    return res.status(400).send('No data to update'); // Bad request
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (!data) {
 | 
					 | 
				
			||||||
    return res.status(500).send('No data to update'); // Internal server error
 | 
					    return res.status(500).send('No data to update'); // Internal server error
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const indexedUpdatedData = { id: data.length, ...updatedData }; // Add the new dictionary to the array
 | 
					  const dictionary = dictionaries.find((dictionary) => dictionary.id === id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  data.push(indexedUpdatedData); // Add the new dictionary to the array
 | 
					  if (!dictionary) {
 | 
				
			||||||
 | 
					    return res.status(404).send('Not found');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const dictionaryWords = dictionary.words.map((wordId) => {
 | 
				
			||||||
 | 
					    const word = words.find((word) => word.id === wordId);
 | 
				
			||||||
 | 
					    return { ...word, ...word };
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  res.send({ ...dictionary, words: dictionaryWords });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  fs.writeFile(path.join(__dirname, 'data/dictionaries.json'), JSON.stringify(data), (err) => {
 | 
					router.post('/:id', (req, res) => {
 | 
				
			||||||
 | 
					  const id = parseInt(req.params.id);
 | 
				
			||||||
 | 
					  if (!id || isNaN(id)) {
 | 
				
			||||||
 | 
					    return res.status(400).send('Invalid ID'); // Bad request
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!dictionaries) {
 | 
				
			||||||
 | 
					    return res.status(500).send('No data to update'); // Internal server error
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const dictionary = dictionaries.find((dictionary) => dictionary.id === id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!dictionary) {
 | 
				
			||||||
 | 
					    return res.status(404).send('Not found');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const newWord = req.body;
 | 
				
			||||||
 | 
					  if (!newWord) {
 | 
				
			||||||
 | 
					    return res.status(400).send('No data to add'); // Bad request
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  console.log(newWord);
 | 
				
			||||||
 | 
					  if (isNaN(newWord.id)) {
 | 
				
			||||||
 | 
					    return res.status(400).send('Invalid word ID'); // Bad request
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  dictionary.words.push(newWord.id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  fs.writeFile(path.join(__dirname, 'dictionaries.json'), JSON.stringify(dictionaries), (err) => {
 | 
				
			||||||
    if (err) {
 | 
					    if (err) {
 | 
				
			||||||
      console.error(err); // Log the error
 | 
					      console.error(err); // Log the error
 | 
				
			||||||
      return res.status(500).send('Error saving data');
 | 
					      return res.status(500).send('Error saving data');
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    res.status(200).json(data); // Send back the updated data
 | 
					    res.status(200).json(dictionary); // Send back the updated data
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Put new dictionary to the array of dictionaries
 | 
				
			||||||
 | 
					router.put('/', (req, res) => {
 | 
				
			||||||
 | 
					  if (!dictionaries || !Array.isArray(dictionaries)) {
 | 
				
			||||||
 | 
					    return res.status(400).send('No array of dictionaries found`');
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const newData = req.body;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!newData) {
 | 
				
			||||||
 | 
					    return res.status(400).send('No data to add'); // Bad request
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!dictionaries) {
 | 
				
			||||||
 | 
					    return res.status(500).send('No data to update'); // Internal server error
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const indexedUpdatedData = { ...newData, id: dictionaries.length + 1 }; // Add the new dictionary to the array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  dictionaries.push(indexedUpdatedData); // Add the new dictionary to the array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  fs.writeFile(path.join(__dirname, 'dictionaries.json'), JSON.stringify(dictionaries), (err) => {
 | 
				
			||||||
 | 
					    if (err) {
 | 
				
			||||||
 | 
					      console.error(err); // Log the error
 | 
				
			||||||
 | 
					      return res.status(500).send('Error saving data');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    res.status(200).json(dictionaries); // Send back the updated data
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -47,15 +104,15 @@ router.delete('/:id', (req, res) => {
 | 
				
			|||||||
    return res.status(400).send('Invalid ID'); // Bad request
 | 
					    return res.status(400).send('Invalid ID'); // Bad request
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  const index = data.findIndex((dictionary) => dictionary.id === id);
 | 
					  const index = dictionaries.findIndex((dictionary) => dictionary.id === id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if (index < 0) {
 | 
					  if (index < 0) {
 | 
				
			||||||
    return res.status(404).send('Not found'); // Not found
 | 
					    return res.status(404).send('Not found'); // Not found
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  data.splice(index, 1); // Remove the dictionary from the array
 | 
					  dictionaries.splice(index, 1); // Remove the dictionary from the array
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  fs.writeFile(path.join(__dirname, 'data/dictionaries.json'), JSON.stringify(data), (err) => {
 | 
					  fs.writeFile(path.join(__dirname, 'dictionaries.json'), JSON.stringify(dictionaries), (err) => {
 | 
				
			||||||
    if (err) {
 | 
					    if (err) {
 | 
				
			||||||
      console.error(err); // Log the error
 | 
					      console.error(err); // Log the error
 | 
				
			||||||
      return res.status(500).send('Error saving data');
 | 
					      return res.status(500).send('Error saving data');
 | 
				
			||||||
@ -63,14 +120,3 @@ router.delete('/:id', (req, res) => {
 | 
				
			|||||||
    res.send({ message: `Dictionary with id ${id} deleted` });
 | 
					    res.send({ message: `Dictionary with id ${id} deleted` });
 | 
				
			||||||
  });
 | 
					  });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					 | 
				
			||||||
router.get("/:id", (req, res) => {
 | 
					 | 
				
			||||||
  const id = parseInt(req.params.id);
 | 
					 | 
				
			||||||
  const words = wordsData.find((word) => word.id === id);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  if (!words) {
 | 
					 | 
				
			||||||
    return res.status(404).send("Not found");
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  res.send(words);
 | 
					 | 
				
			||||||
});
 | 
					 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										6188
									
								
								server/routers/kfu-m-24-1/eng-it-lean/gigachat/ai.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6188
									
								
								server/routers/kfu-m-24-1/eng-it-lean/gigachat/ai.js
									
									
									
									
									
										Normal file
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										614
									
								
								server/routers/kfu-m-24-1/eng-it-lean/gigachat/gigachat.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										614
									
								
								server/routers/kfu-m-24-1/eng-it-lean/gigachat/gigachat.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,614 @@
 | 
				
			|||||||
 | 
					"use strict";
 | 
				
			||||||
 | 
					var __defProp = Object.defineProperty;
 | 
				
			||||||
 | 
					var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
 | 
				
			||||||
 | 
					var __getOwnPropNames = Object.getOwnPropertyNames;
 | 
				
			||||||
 | 
					var __hasOwnProp = Object.prototype.hasOwnProperty;
 | 
				
			||||||
 | 
					var __export = (target, all) => {
 | 
				
			||||||
 | 
					  for (var name in all)
 | 
				
			||||||
 | 
					    __defProp(target, name, { get: all[name], enumerable: true });
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					var __copyProps = (to, from, except, desc) => {
 | 
				
			||||||
 | 
					  if (from && typeof from === "object" || typeof from === "function") {
 | 
				
			||||||
 | 
					    for (let key of __getOwnPropNames(from))
 | 
				
			||||||
 | 
					      if (!__hasOwnProp.call(to, key) && key !== except)
 | 
				
			||||||
 | 
					        __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return to;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// src/index.ts
 | 
				
			||||||
 | 
					var index_exports = {};
 | 
				
			||||||
 | 
					__export(index_exports, {
 | 
				
			||||||
 | 
					  createGigachat: () => createGigachat,
 | 
				
			||||||
 | 
					  gigachat: () => gigachat
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					module.exports = __toCommonJS(index_exports);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// src/gigachat-provider.ts
 | 
				
			||||||
 | 
					var import_provider_utils4 = require("@ai-sdk/provider-utils");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// src/gigachat-chat-language-model.ts
 | 
				
			||||||
 | 
					var import_provider_utils2 = require("@ai-sdk/provider-utils");
 | 
				
			||||||
 | 
					var import_zod2 = require("zod");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// src/convert-to-gigachat-chat-messages.ts
 | 
				
			||||||
 | 
					var import_provider = require("@ai-sdk/provider");
 | 
				
			||||||
 | 
					function convertToGigachatChatMessages(prompt) {
 | 
				
			||||||
 | 
					  const messages = [];
 | 
				
			||||||
 | 
					  for (let i = 0; i < prompt.length; i++) {
 | 
				
			||||||
 | 
					    const { role, content } = prompt[i];
 | 
				
			||||||
 | 
					    const isLastMessage = i === prompt.length - 1;
 | 
				
			||||||
 | 
					    switch (role) {
 | 
				
			||||||
 | 
					      case "system": {
 | 
				
			||||||
 | 
					        messages.push({ role: "system", content });
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      case "user": {
 | 
				
			||||||
 | 
					        messages.push({
 | 
				
			||||||
 | 
					          role: "user",
 | 
				
			||||||
 | 
					          content: content.map((part) => {
 | 
				
			||||||
 | 
					            switch (part.type) {
 | 
				
			||||||
 | 
					              case "text": {
 | 
				
			||||||
 | 
					                return part.text;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              case "image": {
 | 
				
			||||||
 | 
					                throw new import_provider.UnsupportedFunctionalityError({
 | 
				
			||||||
 | 
					                  functionality: 'Images should be added in "attachments" object'
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					              case "file": {
 | 
				
			||||||
 | 
					                throw new import_provider.UnsupportedFunctionalityError({
 | 
				
			||||||
 | 
					                  functionality: "File content parts in user messages"
 | 
				
			||||||
 | 
					                });
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }).join("")
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      case "assistant": {
 | 
				
			||||||
 | 
					        let text = "";
 | 
				
			||||||
 | 
					        let functionCall;
 | 
				
			||||||
 | 
					        for (const part of content) {
 | 
				
			||||||
 | 
					          switch (part.type) {
 | 
				
			||||||
 | 
					            case "text": {
 | 
				
			||||||
 | 
					              text += part.text;
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            case "tool-call": {
 | 
				
			||||||
 | 
					              functionCall = {
 | 
				
			||||||
 | 
					                name: part.toolName,
 | 
				
			||||||
 | 
					                arguments: part.args
 | 
				
			||||||
 | 
					              };
 | 
				
			||||||
 | 
					              break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            default: {
 | 
				
			||||||
 | 
					              const _exhaustiveCheck = part;
 | 
				
			||||||
 | 
					              throw new Error(`Unsupported part: ${_exhaustiveCheck}`);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        messages.push({
 | 
				
			||||||
 | 
					          role: "assistant",
 | 
				
			||||||
 | 
					          content: text,
 | 
				
			||||||
 | 
					          prefix: isLastMessage ? true : void 0,
 | 
				
			||||||
 | 
					          function_call: functionCall
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      case "tool": {
 | 
				
			||||||
 | 
					        for (const toolResponse of content) {
 | 
				
			||||||
 | 
					          messages.push({
 | 
				
			||||||
 | 
					            role: "function",
 | 
				
			||||||
 | 
					            name: toolResponse.toolName,
 | 
				
			||||||
 | 
					            content: JSON.stringify(toolResponse.result)
 | 
				
			||||||
 | 
					          });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        break;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      default: {
 | 
				
			||||||
 | 
					        const _exhaustiveCheck = role;
 | 
				
			||||||
 | 
					        throw new Error(`Unsupported role: ${_exhaustiveCheck}`);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  return messages;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// src/map-gigachat-finish-reason.ts
 | 
				
			||||||
 | 
					function mapGigachatFinishReason(finishReason) {
 | 
				
			||||||
 | 
					  switch (finishReason) {
 | 
				
			||||||
 | 
					    case "stop":
 | 
				
			||||||
 | 
					      return "stop";
 | 
				
			||||||
 | 
					    case "length":
 | 
				
			||||||
 | 
					    case "model_length":
 | 
				
			||||||
 | 
					      return "length";
 | 
				
			||||||
 | 
					    case "function_call":
 | 
				
			||||||
 | 
					      return "tool-calls";
 | 
				
			||||||
 | 
					    case "error":
 | 
				
			||||||
 | 
					      return "error";
 | 
				
			||||||
 | 
					    default:
 | 
				
			||||||
 | 
					      return "unknown";
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// src/gigachat-error.ts
 | 
				
			||||||
 | 
					var import_provider_utils = require("@ai-sdk/provider-utils");
 | 
				
			||||||
 | 
					var import_zod = require("zod");
 | 
				
			||||||
 | 
					var gigachatErrorDataSchema = import_zod.z.object({
 | 
				
			||||||
 | 
					  object: import_zod.z.literal("error"),
 | 
				
			||||||
 | 
					  message: import_zod.z.string(),
 | 
				
			||||||
 | 
					  type: import_zod.z.string(),
 | 
				
			||||||
 | 
					  param: import_zod.z.string().nullable(),
 | 
				
			||||||
 | 
					  code: import_zod.z.string().nullable()
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					var gigachatFailedResponseHandler = (0, import_provider_utils.createJsonErrorResponseHandler)({
 | 
				
			||||||
 | 
					  errorSchema: gigachatErrorDataSchema,
 | 
				
			||||||
 | 
					  errorToMessage: (data) => data.message
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// src/get-response-metadata.ts
 | 
				
			||||||
 | 
					function getResponseMetadata({
 | 
				
			||||||
 | 
					  model,
 | 
				
			||||||
 | 
					  created
 | 
				
			||||||
 | 
					}) {
 | 
				
			||||||
 | 
					  return {
 | 
				
			||||||
 | 
					    modelId: model != null ? model : void 0,
 | 
				
			||||||
 | 
					    timestamp: created != null ? new Date(created * 1e3) : void 0
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// src/gigachat-prepare-tools.ts
 | 
				
			||||||
 | 
					var import_provider2 = require("@ai-sdk/provider");
 | 
				
			||||||
 | 
					function prepareTools(mode) {
 | 
				
			||||||
 | 
					  var _a;
 | 
				
			||||||
 | 
					  const tools = ((_a = mode.tools) == null ? void 0 : _a.length) ? mode.tools : void 0;
 | 
				
			||||||
 | 
					  const toolWarnings = [];
 | 
				
			||||||
 | 
					  if (tools == null) {
 | 
				
			||||||
 | 
					    return { tools: void 0, tool_choice: void 0, toolWarnings };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const gigachatTools = [];
 | 
				
			||||||
 | 
					  for (const tool of tools) {
 | 
				
			||||||
 | 
					    if (tool.type === "provider-defined") {
 | 
				
			||||||
 | 
					      toolWarnings.push({ type: "unsupported-tool", tool });
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      gigachatTools.push({
 | 
				
			||||||
 | 
					        type: "function",
 | 
				
			||||||
 | 
					        function: {
 | 
				
			||||||
 | 
					          name: tool.name,
 | 
				
			||||||
 | 
					          description: tool.description,
 | 
				
			||||||
 | 
					          parameters: tool.parameters
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const toolChoice = mode.toolChoice;
 | 
				
			||||||
 | 
					  if (toolChoice == null) {
 | 
				
			||||||
 | 
					    return { tools: gigachatTools, tool_choice: void 0, toolWarnings };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const type = toolChoice.type;
 | 
				
			||||||
 | 
					  switch (type) {
 | 
				
			||||||
 | 
					    case "auto":
 | 
				
			||||||
 | 
					    case "none":
 | 
				
			||||||
 | 
					      return { tools: gigachatTools, tool_choice: type, toolWarnings };
 | 
				
			||||||
 | 
					    case "required":
 | 
				
			||||||
 | 
					      return { tools: gigachatTools, tool_choice: "any", toolWarnings };
 | 
				
			||||||
 | 
					    // gigachat does not support tool mode directly,
 | 
				
			||||||
 | 
					    // so we filter the tools and force the tool choice through 'any'
 | 
				
			||||||
 | 
					    case "tool":
 | 
				
			||||||
 | 
					      return {
 | 
				
			||||||
 | 
					        tools: gigachatTools.filter((tool) => tool.function.name === toolChoice.toolName),
 | 
				
			||||||
 | 
					        tool_choice: "any",
 | 
				
			||||||
 | 
					        toolWarnings
 | 
				
			||||||
 | 
					      };
 | 
				
			||||||
 | 
					    default: {
 | 
				
			||||||
 | 
					      const _exhaustiveCheck = type;
 | 
				
			||||||
 | 
					      throw new import_provider2.UnsupportedFunctionalityError({
 | 
				
			||||||
 | 
					        functionality: `Unsupported tool choice type: ${_exhaustiveCheck}`
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// src/gigachat-chat-language-model.ts
 | 
				
			||||||
 | 
					var GigachatChatLanguageModel = class {
 | 
				
			||||||
 | 
					  constructor(modelId, settings, config) {
 | 
				
			||||||
 | 
					    this.specificationVersion = "v1";
 | 
				
			||||||
 | 
					    this.defaultObjectGenerationMode = "json";
 | 
				
			||||||
 | 
					    this.supportsImageUrls = false;
 | 
				
			||||||
 | 
					    this.modelId = modelId;
 | 
				
			||||||
 | 
					    this.settings = settings;
 | 
				
			||||||
 | 
					    this.config = config;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  get provider() {
 | 
				
			||||||
 | 
					    return this.config.provider;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  getArgs({
 | 
				
			||||||
 | 
					    mode,
 | 
				
			||||||
 | 
					    prompt,
 | 
				
			||||||
 | 
					    maxTokens,
 | 
				
			||||||
 | 
					    temperature,
 | 
				
			||||||
 | 
					    topP,
 | 
				
			||||||
 | 
					    topK,
 | 
				
			||||||
 | 
					    frequencyPenalty,
 | 
				
			||||||
 | 
					    presencePenalty,
 | 
				
			||||||
 | 
					    stopSequences,
 | 
				
			||||||
 | 
					    responseFormat,
 | 
				
			||||||
 | 
					    seed
 | 
				
			||||||
 | 
					  }) {
 | 
				
			||||||
 | 
					    const type = mode.type;
 | 
				
			||||||
 | 
					    const warnings = [];
 | 
				
			||||||
 | 
					    if (topK != null) {
 | 
				
			||||||
 | 
					      warnings.push({
 | 
				
			||||||
 | 
					        type: "unsupported-setting",
 | 
				
			||||||
 | 
					        setting: "topK"
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (frequencyPenalty != null) {
 | 
				
			||||||
 | 
					      warnings.push({
 | 
				
			||||||
 | 
					        type: "unsupported-setting",
 | 
				
			||||||
 | 
					        setting: "frequencyPenalty"
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (presencePenalty != null) {
 | 
				
			||||||
 | 
					      warnings.push({
 | 
				
			||||||
 | 
					        type: "unsupported-setting",
 | 
				
			||||||
 | 
					        setting: "presencePenalty"
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (stopSequences != null) {
 | 
				
			||||||
 | 
					      warnings.push({
 | 
				
			||||||
 | 
					        type: "unsupported-setting",
 | 
				
			||||||
 | 
					        setting: "stopSequences"
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (responseFormat != null && responseFormat.type === "json" && responseFormat.schema != null) {
 | 
				
			||||||
 | 
					      warnings.push({
 | 
				
			||||||
 | 
					        type: "unsupported-setting",
 | 
				
			||||||
 | 
					        setting: "responseFormat",
 | 
				
			||||||
 | 
					        details: "JSON response format schema is not supported"
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const baseArgs = {
 | 
				
			||||||
 | 
					      // model id:
 | 
				
			||||||
 | 
					      model: this.modelId,
 | 
				
			||||||
 | 
					      // model specific settings:
 | 
				
			||||||
 | 
					      stream: this.settings.stream,
 | 
				
			||||||
 | 
					      repetition_penalty: this.settings.repetition_penalty,
 | 
				
			||||||
 | 
					      update_interval: this.settings.update_interval,
 | 
				
			||||||
 | 
					      // standardized settings:
 | 
				
			||||||
 | 
					      max_tokens: maxTokens,
 | 
				
			||||||
 | 
					      temperature,
 | 
				
			||||||
 | 
					      top_p: topP,
 | 
				
			||||||
 | 
					      // response format:
 | 
				
			||||||
 | 
					      response_format: (responseFormat == null ? void 0 : responseFormat.type) === "json" ? { type: "json_object" } : void 0,
 | 
				
			||||||
 | 
					      // messages:
 | 
				
			||||||
 | 
					      messages: convertToGigachatChatMessages(prompt)
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    switch (type) {
 | 
				
			||||||
 | 
					      case "regular": {
 | 
				
			||||||
 | 
					        const { tools, tool_choice, toolWarnings } = prepareTools(mode);
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					          args: { ...baseArgs, tools, tool_choice },
 | 
				
			||||||
 | 
					          warnings: [...warnings, ...toolWarnings]
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      case "object-json": {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					          args: {
 | 
				
			||||||
 | 
					            ...baseArgs,
 | 
				
			||||||
 | 
					            response_format: { type: "json_object" }
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          warnings
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      case "object-tool": {
 | 
				
			||||||
 | 
					        return {
 | 
				
			||||||
 | 
					          args: {
 | 
				
			||||||
 | 
					            ...baseArgs,
 | 
				
			||||||
 | 
					            tool_choice: "any",
 | 
				
			||||||
 | 
					            tools: [{ type: "function", function: mode.tool }]
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          warnings
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      default: {
 | 
				
			||||||
 | 
					        const _exhaustiveCheck = type;
 | 
				
			||||||
 | 
					        throw new Error(`Unsupported type: ${_exhaustiveCheck}`);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  async doGenerate(options) {
 | 
				
			||||||
 | 
					    var _a;
 | 
				
			||||||
 | 
					    const { args, warnings } = this.getArgs(options);
 | 
				
			||||||
 | 
					    const { responseHeaders, value: response } = await (0, import_provider_utils2.postJsonToApi)({
 | 
				
			||||||
 | 
					      url: `${this.config.baseURL}/chat/completions`,
 | 
				
			||||||
 | 
					      headers: (0, import_provider_utils2.combineHeaders)(this.config.headers(), options.headers),
 | 
				
			||||||
 | 
					      body: args,
 | 
				
			||||||
 | 
					      failedResponseHandler: gigachatFailedResponseHandler,
 | 
				
			||||||
 | 
					      successfulResponseHandler: (0, import_provider_utils2.createJsonResponseHandler)(gigachatChatResponseSchema),
 | 
				
			||||||
 | 
					      abortSignal: options.abortSignal,
 | 
				
			||||||
 | 
					      fetch: this.config.fetch
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    const { messages: rawPrompt, ...rawSettings } = args;
 | 
				
			||||||
 | 
					    const choice = response.choices[0];
 | 
				
			||||||
 | 
					    let text = (_a = choice.message.content) != null ? _a : void 0;
 | 
				
			||||||
 | 
					    const lastMessage = rawPrompt[rawPrompt.length - 1];
 | 
				
			||||||
 | 
					    if (lastMessage.role === "assistant" && (text == null ? void 0 : text.startsWith(lastMessage.content))) {
 | 
				
			||||||
 | 
					      text = text.slice(lastMessage.content.length);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      text,
 | 
				
			||||||
 | 
					      toolCalls: choice.message.function_call ? [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					          toolCallType: "function",
 | 
				
			||||||
 | 
					          toolCallId: choice.message.function_call.name,
 | 
				
			||||||
 | 
					          toolName: choice.message.function_call.name,
 | 
				
			||||||
 | 
					          args: JSON.stringify(choice.message.function_call.arguments)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      ] : [],
 | 
				
			||||||
 | 
					      finishReason: mapGigachatFinishReason(choice.finish_reason),
 | 
				
			||||||
 | 
					      usage: {
 | 
				
			||||||
 | 
					        promptTokens: response.usage.prompt_tokens,
 | 
				
			||||||
 | 
					        completionTokens: response.usage.completion_tokens
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      rawCall: { rawPrompt, rawSettings },
 | 
				
			||||||
 | 
					      rawResponse: { headers: responseHeaders },
 | 
				
			||||||
 | 
					      request: { body: JSON.stringify(args) },
 | 
				
			||||||
 | 
					      response: getResponseMetadata(response),
 | 
				
			||||||
 | 
					      warnings
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  async doStream(options) {
 | 
				
			||||||
 | 
					    const { args, warnings } = this.getArgs(options);
 | 
				
			||||||
 | 
					    const body = { ...args, stream: true };
 | 
				
			||||||
 | 
					    const { responseHeaders, value: response } = await (0, import_provider_utils2.postJsonToApi)({
 | 
				
			||||||
 | 
					      url: `${this.config.baseURL}/chat/completions`,
 | 
				
			||||||
 | 
					      headers: (0, import_provider_utils2.combineHeaders)(this.config.headers(), options.headers),
 | 
				
			||||||
 | 
					      body,
 | 
				
			||||||
 | 
					      failedResponseHandler: gigachatFailedResponseHandler,
 | 
				
			||||||
 | 
					      successfulResponseHandler: (0, import_provider_utils2.createEventSourceResponseHandler)(gigachatChatChunkSchema),
 | 
				
			||||||
 | 
					      abortSignal: options.abortSignal,
 | 
				
			||||||
 | 
					      fetch: this.config.fetch
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    const { messages: rawPrompt, ...rawSettings } = args;
 | 
				
			||||||
 | 
					    let finishReason = "unknown";
 | 
				
			||||||
 | 
					    let usage = {
 | 
				
			||||||
 | 
					      promptTokens: Number.NaN,
 | 
				
			||||||
 | 
					      completionTokens: Number.NaN
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    let chunkNumber = 0;
 | 
				
			||||||
 | 
					    let trimLeadingSpace = false;
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      stream: response.pipeThrough(
 | 
				
			||||||
 | 
					        new TransformStream({
 | 
				
			||||||
 | 
					          transform(chunk, controller) {
 | 
				
			||||||
 | 
					            if (!chunk.success) {
 | 
				
			||||||
 | 
					              controller.enqueue({ type: "error", error: chunk.error });
 | 
				
			||||||
 | 
					              return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            chunkNumber++;
 | 
				
			||||||
 | 
					            const value = chunk.value;
 | 
				
			||||||
 | 
					            if (chunkNumber === 1) {
 | 
				
			||||||
 | 
					              controller.enqueue({
 | 
				
			||||||
 | 
					                type: "response-metadata",
 | 
				
			||||||
 | 
					                ...getResponseMetadata(value)
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (value.usage != null) {
 | 
				
			||||||
 | 
					              usage = {
 | 
				
			||||||
 | 
					                promptTokens: value.usage.prompt_tokens,
 | 
				
			||||||
 | 
					                completionTokens: value.usage.completion_tokens
 | 
				
			||||||
 | 
					              };
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            const choice = value.choices[0];
 | 
				
			||||||
 | 
					            if ((choice == null ? void 0 : choice.finish_reason) != null) {
 | 
				
			||||||
 | 
					              finishReason = mapGigachatFinishReason(choice.finish_reason);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if ((choice == null ? void 0 : choice.delta) == null) {
 | 
				
			||||||
 | 
					              return;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            const delta = choice.delta;
 | 
				
			||||||
 | 
					            if (chunkNumber <= 2) {
 | 
				
			||||||
 | 
					              const lastMessage = rawPrompt[rawPrompt.length - 1];
 | 
				
			||||||
 | 
					              if (lastMessage.role === "assistant" && delta.content === lastMessage.content.trimEnd()) {
 | 
				
			||||||
 | 
					                if (delta.content.length < lastMessage.content.length) {
 | 
				
			||||||
 | 
					                  trimLeadingSpace = true;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                return;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (delta.content != null) {
 | 
				
			||||||
 | 
					              controller.enqueue({
 | 
				
			||||||
 | 
					                type: "text-delta",
 | 
				
			||||||
 | 
					                textDelta: trimLeadingSpace ? delta.content.trimStart() : delta.content
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
 | 
					              trimLeadingSpace = false;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            if (delta.function_call != null) {
 | 
				
			||||||
 | 
					              controller.enqueue({
 | 
				
			||||||
 | 
					                type: "tool-call-delta",
 | 
				
			||||||
 | 
					                toolCallType: "function",
 | 
				
			||||||
 | 
					                toolCallId: delta.function_call.name,
 | 
				
			||||||
 | 
					                toolName: delta.function_call.name,
 | 
				
			||||||
 | 
					                argsTextDelta: JSON.stringify(delta.function_call.arguments)
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
 | 
					              controller.enqueue({
 | 
				
			||||||
 | 
					                type: "tool-call",
 | 
				
			||||||
 | 
					                toolCallType: "function",
 | 
				
			||||||
 | 
					                toolCallId: delta.function_call.name,
 | 
				
			||||||
 | 
					                toolName: delta.function_call.name,
 | 
				
			||||||
 | 
					                args: JSON.stringify(delta.function_call.arguments)
 | 
				
			||||||
 | 
					              });
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          },
 | 
				
			||||||
 | 
					          flush(controller) {
 | 
				
			||||||
 | 
					            controller.enqueue({ type: "finish", finishReason, usage });
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        })
 | 
				
			||||||
 | 
					      ),
 | 
				
			||||||
 | 
					      rawCall: { rawPrompt, rawSettings },
 | 
				
			||||||
 | 
					      rawResponse: { headers: responseHeaders },
 | 
				
			||||||
 | 
					      request: { body: JSON.stringify(body) },
 | 
				
			||||||
 | 
					      warnings
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					var gigachatChatResponseSchema = import_zod2.z.object({
 | 
				
			||||||
 | 
					  created: import_zod2.z.number().nullish(),
 | 
				
			||||||
 | 
					  model: import_zod2.z.string().nullish(),
 | 
				
			||||||
 | 
					  choices: import_zod2.z.array(
 | 
				
			||||||
 | 
					    import_zod2.z.object({
 | 
				
			||||||
 | 
					      message: import_zod2.z.object({
 | 
				
			||||||
 | 
					        role: import_zod2.z.literal("assistant"),
 | 
				
			||||||
 | 
					        content: import_zod2.z.string().nullable(),
 | 
				
			||||||
 | 
					        created: import_zod2.z.number().nullish(),
 | 
				
			||||||
 | 
					        name: import_zod2.z.string().nullish(),
 | 
				
			||||||
 | 
					        function_call: import_zod2.z.object({
 | 
				
			||||||
 | 
					          name: import_zod2.z.string(),
 | 
				
			||||||
 | 
					          arguments: import_zod2.z.record(import_zod2.z.any())
 | 
				
			||||||
 | 
					        }).nullish(),
 | 
				
			||||||
 | 
					        data_for_context: import_zod2.z.array(import_zod2.z.object({})).nullish()
 | 
				
			||||||
 | 
					      }),
 | 
				
			||||||
 | 
					      index: import_zod2.z.number(),
 | 
				
			||||||
 | 
					      finish_reason: import_zod2.z.string().nullish()
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  object: import_zod2.z.literal("chat.completion"),
 | 
				
			||||||
 | 
					  usage: import_zod2.z.object({
 | 
				
			||||||
 | 
					    prompt_tokens: import_zod2.z.number(),
 | 
				
			||||||
 | 
					    completion_tokens: import_zod2.z.number(),
 | 
				
			||||||
 | 
					    total_tokens: import_zod2.z.number()
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					var gigachatChatChunkSchema = import_zod2.z.object({
 | 
				
			||||||
 | 
					  created: import_zod2.z.number().nullish(),
 | 
				
			||||||
 | 
					  model: import_zod2.z.string().nullish(),
 | 
				
			||||||
 | 
					  object: import_zod2.z.literal("chat.completion"),
 | 
				
			||||||
 | 
					  choices: import_zod2.z.array(
 | 
				
			||||||
 | 
					    import_zod2.z.object({
 | 
				
			||||||
 | 
					      delta: import_zod2.z.object({
 | 
				
			||||||
 | 
					        role: import_zod2.z.enum(["assistant"]).optional(),
 | 
				
			||||||
 | 
					        content: import_zod2.z.string().nullish(),
 | 
				
			||||||
 | 
					        functions_state_id: import_zod2.z.string().nullish(),
 | 
				
			||||||
 | 
					        function_call: import_zod2.z.object({
 | 
				
			||||||
 | 
					          name: import_zod2.z.string(),
 | 
				
			||||||
 | 
					          arguments: import_zod2.z.object({})
 | 
				
			||||||
 | 
					        }).nullish()
 | 
				
			||||||
 | 
					      }),
 | 
				
			||||||
 | 
					      finish_reason: import_zod2.z.string().nullish(),
 | 
				
			||||||
 | 
					      index: import_zod2.z.number()
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					  ),
 | 
				
			||||||
 | 
					  usage: import_zod2.z.object({
 | 
				
			||||||
 | 
					    prompt_tokens: import_zod2.z.number(),
 | 
				
			||||||
 | 
					    completion_tokens: import_zod2.z.number()
 | 
				
			||||||
 | 
					  }).nullish()
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// src/gigachat-embedding-model.ts
 | 
				
			||||||
 | 
					var import_provider3 = require("@ai-sdk/provider");
 | 
				
			||||||
 | 
					var import_provider_utils3 = require("@ai-sdk/provider-utils");
 | 
				
			||||||
 | 
					var import_zod3 = require("zod");
 | 
				
			||||||
 | 
					var GigachatEmbeddingModel = class {
 | 
				
			||||||
 | 
					  constructor(modelId, settings, config) {
 | 
				
			||||||
 | 
					    this.specificationVersion = "v1";
 | 
				
			||||||
 | 
					    this.modelId = modelId;
 | 
				
			||||||
 | 
					    this.settings = settings;
 | 
				
			||||||
 | 
					    this.config = config;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  get provider() {
 | 
				
			||||||
 | 
					    return this.config.provider;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  get maxEmbeddingsPerCall() {
 | 
				
			||||||
 | 
					    var _a;
 | 
				
			||||||
 | 
					    return (_a = this.settings.maxEmbeddingsPerCall) != null ? _a : 32;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  get supportsParallelCalls() {
 | 
				
			||||||
 | 
					    var _a;
 | 
				
			||||||
 | 
					    return (_a = this.settings.supportsParallelCalls) != null ? _a : false;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  async doEmbed({
 | 
				
			||||||
 | 
					    values,
 | 
				
			||||||
 | 
					    abortSignal,
 | 
				
			||||||
 | 
					    headers
 | 
				
			||||||
 | 
					  }) {
 | 
				
			||||||
 | 
					    if (values.length > this.maxEmbeddingsPerCall) {
 | 
				
			||||||
 | 
					      throw new import_provider3.TooManyEmbeddingValuesForCallError({
 | 
				
			||||||
 | 
					        provider: this.provider,
 | 
				
			||||||
 | 
					        modelId: this.modelId,
 | 
				
			||||||
 | 
					        maxEmbeddingsPerCall: this.maxEmbeddingsPerCall,
 | 
				
			||||||
 | 
					        values
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    const { responseHeaders, value: response } = await (0, import_provider_utils3.postJsonToApi)({
 | 
				
			||||||
 | 
					      url: `${this.config.baseURL}/embeddings`,
 | 
				
			||||||
 | 
					      headers: (0, import_provider_utils3.combineHeaders)(this.config.headers(), headers),
 | 
				
			||||||
 | 
					      body: {
 | 
				
			||||||
 | 
					        model: this.modelId,
 | 
				
			||||||
 | 
					        input: values,
 | 
				
			||||||
 | 
					        encoding_format: "float"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      failedResponseHandler: gigachatFailedResponseHandler,
 | 
				
			||||||
 | 
					      successfulResponseHandler: (0, import_provider_utils3.createJsonResponseHandler)(GigachatTextEmbeddingResponseSchema),
 | 
				
			||||||
 | 
					      abortSignal,
 | 
				
			||||||
 | 
					      fetch: this.config.fetch
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					    return {
 | 
				
			||||||
 | 
					      embeddings: response.data.map((item) => item.embedding),
 | 
				
			||||||
 | 
					      usage: response.usage ? { tokens: response.usage.prompt_tokens } : void 0,
 | 
				
			||||||
 | 
					      rawResponse: { headers: responseHeaders }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					var GigachatTextEmbeddingResponseSchema = import_zod3.z.object({
 | 
				
			||||||
 | 
					  data: import_zod3.z.array(import_zod3.z.object({ embedding: import_zod3.z.array(import_zod3.z.number()) })),
 | 
				
			||||||
 | 
					  usage: import_zod3.z.object({ prompt_tokens: import_zod3.z.number() }).nullish()
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// src/gigachat-provider.ts
 | 
				
			||||||
 | 
					function createGigachat(options = {}) {
 | 
				
			||||||
 | 
					  var _a;
 | 
				
			||||||
 | 
					  const baseURL = (_a = (0, import_provider_utils4.withoutTrailingSlash)(options.baseURL)) != null ? _a : "https://gigachat.devices.sberbank.ru/api/v1";
 | 
				
			||||||
 | 
					  const getAccessToken = () => ({});
 | 
				
			||||||
 | 
					  const getHeaders = () => ({
 | 
				
			||||||
 | 
					    Authorization: `Bearer ${(0, import_provider_utils4.loadApiKey)({
 | 
				
			||||||
 | 
					      apiKey: options.apiKey,
 | 
				
			||||||
 | 
					      environmentVariableName: "GIGACHAT_ACCESS_TOKEN",
 | 
				
			||||||
 | 
					      description: "GigaChat"
 | 
				
			||||||
 | 
					    })}`,
 | 
				
			||||||
 | 
					    ...options.headers
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  const createChatModel = (modelId, settings = {}) => new GigachatChatLanguageModel(modelId, settings, {
 | 
				
			||||||
 | 
					    provider: "gigachat.chat",
 | 
				
			||||||
 | 
					    baseURL,
 | 
				
			||||||
 | 
					    headers: getHeaders,
 | 
				
			||||||
 | 
					    fetch: options.fetch
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  const createEmbeddingModel = (modelId, settings = {}) => new GigachatEmbeddingModel(modelId, settings, {
 | 
				
			||||||
 | 
					    provider: "gigachat.embedding",
 | 
				
			||||||
 | 
					    baseURL,
 | 
				
			||||||
 | 
					    headers: getHeaders,
 | 
				
			||||||
 | 
					    fetch: options.fetch
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					  const provider = function(modelId, settings) {
 | 
				
			||||||
 | 
					    if (new.target) {
 | 
				
			||||||
 | 
					      throw new Error("Gigachat function cannot be called with the new keyword.");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return createChatModel(modelId, settings);
 | 
				
			||||||
 | 
					  };
 | 
				
			||||||
 | 
					  provider.languageModel = createChatModel;
 | 
				
			||||||
 | 
					  provider.chat = createChatModel;
 | 
				
			||||||
 | 
					  provider.embedding = createEmbeddingModel;
 | 
				
			||||||
 | 
					  provider.textEmbedding = createEmbeddingModel;
 | 
				
			||||||
 | 
					  provider.textEmbeddingModel = createEmbeddingModel;
 | 
				
			||||||
 | 
					  return provider;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					var gigachat = createGigachat();
 | 
				
			||||||
 | 
					// Annotate the CommonJS export names for ESM import in node:
 | 
				
			||||||
 | 
					0 && (module.exports = {
 | 
				
			||||||
 | 
					  createGigachat,
 | 
				
			||||||
 | 
					  gigachat
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					//# sourceMappingURL=index.js.map
 | 
				
			||||||
							
								
								
									
										144
									
								
								server/routers/kfu-m-24-1/eng-it-lean/gigachat/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										144
									
								
								server/routers/kfu-m-24-1/eng-it-lean/gigachat/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,144 @@
 | 
				
			|||||||
 | 
					const axios = require('axios');
 | 
				
			||||||
 | 
					const https = require('https');
 | 
				
			||||||
 | 
					const fs = require('fs');
 | 
				
			||||||
 | 
					const qs = require('querystring');
 | 
				
			||||||
 | 
					const uuid = require('uuid');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const router = require('express').Router();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// vercel/ai package
 | 
				
			||||||
 | 
					const ai = require('./ai');
 | 
				
			||||||
 | 
					// gigachat provider for vercel/ai
 | 
				
			||||||
 | 
					const gigachatProvider = require('./gigachat');
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = router;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const path = require('path');
 | 
				
			||||||
 | 
					//process.env.NODE_EXTRA_CA_CERTS= path.resolve(__dirname, 'certs')
 | 
				
			||||||
 | 
					//process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					process.env.GIGACHAT_AUTH =
 | 
				
			||||||
 | 
					  'NWVjYTczYjctNWRkYi00NzExLTg0YTEtMjhlOWVmODM2MjI4OjlmMTBkMGVkLWZjZjktNGZhOS1hNDZjLTc5ZWU1YzExOGExMw==';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const agent = new https.Agent({
 | 
				
			||||||
 | 
					  rejectUnauthorized: false
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const gigachat = gigachatProvider.createGigachat({
 | 
				
			||||||
 | 
					  headers: {
 | 
				
			||||||
 | 
					    'Content-Type': 'application/json',
 | 
				
			||||||
 | 
					    Accept: 'text/event-stream'
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  fetch: (url, options) => {
 | 
				
			||||||
 | 
					    return axios({
 | 
				
			||||||
 | 
					      method: 'post',
 | 
				
			||||||
 | 
					      maxBodyLength: Infinity,
 | 
				
			||||||
 | 
					      url: url,
 | 
				
			||||||
 | 
					      headers: options.headers,
 | 
				
			||||||
 | 
					      httpsAgent: agent,
 | 
				
			||||||
 | 
					      data: options.body
 | 
				
			||||||
 | 
					    }).then((response) => {
 | 
				
			||||||
 | 
					      return new Response(response.data, {
 | 
				
			||||||
 | 
					        status: response.status,
 | 
				
			||||||
 | 
					        statusText: response.statusText,
 | 
				
			||||||
 | 
					        headers: response.headers,
 | 
				
			||||||
 | 
					        body: response.data
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    }).catch((error) => {
 | 
				
			||||||
 | 
					      return new Response(error.message, {
 | 
				
			||||||
 | 
					        status: error.response.status,
 | 
				
			||||||
 | 
					        statusText: error.response.statusText,
 | 
				
			||||||
 | 
					        headers: error.response.headers,
 | 
				
			||||||
 | 
					        body: error.response.data
 | 
				
			||||||
 | 
					      });
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					router.use(async (req, res, next) => {
 | 
				
			||||||
 | 
					  const hasToken = process.env.GIGACHAT_ACCESS_TOKEN && process.env.GIGACHAT_EXPIRES_AT != null;
 | 
				
			||||||
 | 
					  const hasExpired = new Date(process.env.GIGACHAT_EXPIRES_AT) <= new Date();
 | 
				
			||||||
 | 
					  if (!hasToken || hasExpired) {
 | 
				
			||||||
 | 
					    let auth = process.env.GIGACHAT_AUTH;
 | 
				
			||||||
 | 
					    let rquid = uuid.v4();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let config = {
 | 
				
			||||||
 | 
					      method: 'post',
 | 
				
			||||||
 | 
					      maxBodyLength: Infinity,
 | 
				
			||||||
 | 
					      url: 'https://ngw.devices.sberbank.ru:9443/api/v2/oauth',
 | 
				
			||||||
 | 
					      headers: {
 | 
				
			||||||
 | 
					        'Content-Type': 'application/x-www-form-urlencoded',
 | 
				
			||||||
 | 
					        Accept: 'application/json',
 | 
				
			||||||
 | 
					        RqUID: rquid,
 | 
				
			||||||
 | 
					        Authorization: 'Basic ' + auth
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      httpsAgent: agent,
 | 
				
			||||||
 | 
					      data: qs.stringify({
 | 
				
			||||||
 | 
					        scope: 'GIGACHAT_API_PERS'
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      const response = await axios(config);
 | 
				
			||||||
 | 
					      const json = response.data;
 | 
				
			||||||
 | 
					      process.env.GIGACHAT_ACCESS_TOKEN = json.access_token;
 | 
				
			||||||
 | 
					      process.env.GIGACHAT_EXPIRES_AT = json.expires_at;
 | 
				
			||||||
 | 
					      console.log(JSON.stringify(response.data));
 | 
				
			||||||
 | 
					    } catch {
 | 
				
			||||||
 | 
					      console.log(error);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  next();
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					router.post('/chat', async (req, res) => {
 | 
				
			||||||
 | 
					  const { messages } = req.body;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const result = ai.streamText({
 | 
				
			||||||
 | 
					    model: gigachat('GigaChat'),
 | 
				
			||||||
 | 
					    system: 'You are a helpful assistant.',
 | 
				
			||||||
 | 
					    messages,
 | 
				
			||||||
 | 
					    stream: true,
 | 
				
			||||||
 | 
					    update_interval: 0.2
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  result.pipeDataStreamToResponse(res);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					router.post('/new-unit', async (req, res) => {
 | 
				
			||||||
 | 
					  const { prompt } = req.body;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const systemMessage = `
 | 
				
			||||||
 | 
					    Я хочу, чтобы вы выступали в роли помощника для создания продвинутых текстовых уроков английского языка. Я буду указывать тему и уровень сложности (начинающий, средний, продвинутый), а вы будете предоставлять структурированный план урока в формате Markdown. Урок должен включать только текстовые элементы (без видео, картинок, аудио) и содержать следующие разделы:
 | 
				
			||||||
 | 
					    -Цель урока — конкретный навык или знание, которое освоят студенты.
 | 
				
			||||||
 | 
					    -Лексика
 | 
				
			||||||
 | 
					      -Базовые термины: 5-7 слов/фраз с примерами употребления.
 | 
				
			||||||
 | 
					      -Расширенная лексика: 3-5 идиом, фразовых глаголов или сложных выражений (для среднего/продвинутого уровня).
 | 
				
			||||||
 | 
					    -Грамматический фокус
 | 
				
			||||||
 | 
					      -Правило с пояснением и 3-5 примерами.
 | 
				
			||||||
 | 
					      -Типичные ошибки и как их избежать.
 | 
				
			||||||
 | 
					    -Контекстуализация
 | 
				
			||||||
 | 
					      -Короткий текст (диалог, статья, описание) для анализа с использованием лексики и грамматики урока.
 | 
				
			||||||
 | 
					    -Упражнения
 | 
				
			||||||
 | 
					      -Письменное задание: например, составить предложения/эссе по теме.
 | 
				
			||||||
 | 
					      -Устная практика: ролевые диалоги (текстовые сценарии), описание ситуаций.
 | 
				
			||||||
 | 
					      -Аналитическое задание: исправление ошибок в предложениях, перевод сложных конструкций.
 | 
				
			||||||
 | 
					    -Домашнее задание
 | 
				
			||||||
 | 
					      Текстовые задачи: написание текста, грамматические тесты, поиск синонимов/антонимов.
 | 
				
			||||||
 | 
					    Ответ должен быть оформлен в Markdown, лаконичным, без лишних комментариев, если пишешь блок кода, начинай его с новой строки.
 | 
				
			||||||
 | 
					    `;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  try {
 | 
				
			||||||
 | 
					    const result = ai.streamText({
 | 
				
			||||||
 | 
					      model: gigachat('GigaChat'),
 | 
				
			||||||
 | 
					      system: systemMessage,
 | 
				
			||||||
 | 
					      prompt,
 | 
				
			||||||
 | 
					      stream: true,
 | 
				
			||||||
 | 
					      update_interval: 0.3
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    result.pipeTextStreamToResponse(res);
 | 
				
			||||||
 | 
					  } catch (e) {
 | 
				
			||||||
 | 
					    console.log(e);
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
@ -1,7 +1,8 @@
 | 
				
			|||||||
const router = require("express").Router();
 | 
					const router = require('express').Router();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const dictionariesRouter = require("./dictionaries");
 | 
					const dictionariesRouter = require('./dictionaries');
 | 
				
			||||||
const unitsRouter = require('./units');
 | 
					const unitsRouter = require('./units');
 | 
				
			||||||
 | 
					const gigachatRouter = require('./gigachat');
 | 
				
			||||||
module.exports = router;
 | 
					module.exports = router;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const delay =
 | 
					const delay =
 | 
				
			||||||
@ -11,5 +12,6 @@ const delay =
 | 
				
			|||||||
  };
 | 
					  };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
router.use(delay());
 | 
					router.use(delay());
 | 
				
			||||||
router.use("/dictionaries", dictionariesRouter);
 | 
					router.use('/dictionaries', dictionariesRouter);
 | 
				
			||||||
router.use('/units', unitsRouter);
 | 
					router.use('/units', unitsRouter);
 | 
				
			||||||
 | 
					router.use('/gigachat', gigachatRouter);
 | 
				
			||||||
@ -0,0 +1,70 @@
 | 
				
			|||||||
 | 
					### Цель урока:
 | 
				
			||||||
 | 
					Изучение ключевых слов и фраз, связанных с процессом трудоустройства, а также освоение базовой структуры диалога на собеседовании.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Лексика:
 | 
				
			||||||
 | 
					**Базовая лексика:**
 | 
				
			||||||
 | 
					1. **Job interview** – собеседование при приеме на работу
 | 
				
			||||||
 | 
					2. **Resume / CV** – резюме
 | 
				
			||||||
 | 
					3. **Cover letter** – сопроводительное письмо
 | 
				
			||||||
 | 
					4. **Interviewer** – интервьюер
 | 
				
			||||||
 | 
					5. **Application form** – анкета при приеме на работу
 | 
				
			||||||
 | 
					6. **Salary** – зарплата
 | 
				
			||||||
 | 
					7. **Benefits** – льготы
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Расширенная лексика:**
 | 
				
			||||||
 | 
					1. **To apply for a job** – подавать заявку на работу
 | 
				
			||||||
 | 
					2. **To be offered the job** – получить предложение о работе
 | 
				
			||||||
 | 
					3. **To negotiate salary** – вести переговоры о зарплате
 | 
				
			||||||
 | 
					4. **To accept the offer** – принять предложение
 | 
				
			||||||
 | 
					5. **To decline the offer** – отклонить предложение
 | 
				
			||||||
 | 
					6. **To resign from your current position** – подать заявление об уходе с текущей работы
 | 
				
			||||||
 | 
					7. **To start working at the company** – начать работать в компании
 | 
				
			||||||
 | 
					8. **Probation period** – испытательный срок
 | 
				
			||||||
 | 
					9. **References** – рекомендации
 | 
				
			||||||
 | 
					10. **Work experience** – опыт работы
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Грамматический фокус:
 | 
				
			||||||
 | 
					**Правило:**
 | 
				
			||||||
 | 
					Структура простого вопроса на английском языке:
 | 
				
			||||||
 | 
					- Общий вопрос: "Do you have any questions?"
 | 
				
			||||||
 | 
					- Специальный вопрос: "What are your strengths and weaknesses?"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Пример:**
 | 
				
			||||||
 | 
					Общий вопрос: "How do you feel about this job opportunity?"
 | 
				
			||||||
 | 
					Специальный вопрос: "Can you tell me about your previous work experience?"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Типичные ошибки и как их избежать:**
 | 
				
			||||||
 | 
					Ошибка: Неправильное использование порядка слов в вопросах.
 | 
				
			||||||
 | 
					Решение: Практиковать построение вопросов до автоматизма.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Контекстуализация:
 | 
				
			||||||
 | 
					**Текст для анализа:**
 | 
				
			||||||
 | 
					"I'm applying for the position of a marketing manager at XYZ Company. Here is my resume."
 | 
				
			||||||
 | 
					"Thank you for considering me. Can you please tell me more about the responsibilities of this role?"
 | 
				
			||||||
 | 
					"Sure, let me give you an overview."
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Упражнения:
 | 
				
			||||||
 | 
					**Письменное задание:**
 | 
				
			||||||
 | 
					Составьте список из 5 вопросов, которые вы бы задали на собеседовании. Используйте простые вопросы и специальные вопросы.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Устная практика:**
 | 
				
			||||||
 | 
					Ролевая игра: один студент играет роль интервьюера, другой – кандидата на должность. Меняйтесь ролями.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Аналитическое задание:**
 | 
				
			||||||
 | 
					Найдите и исправьте ошибки в следующем письме:
 | 
				
			||||||
 | 
					"Dear HR Manager,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					My name is John Smith and I am writing to apply for the position of Sales Representative at ABC Inc. I enclose my resume for your review.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					I believe that my skills and experiences make me an ideal candidate for this position. In my current role as a sales representative at XYZ Corp, I have consistently met or exceeded my sales targets. Additionally, I possess strong communication and negotiation skills which will enable me to effectively represent your products and services.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					If you would like to schedule an interview, please contact me at your convenience. Thank you for your time and consideration.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Best regards,
 | 
				
			||||||
 | 
					John Smith"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Домашнее задание:
 | 
				
			||||||
 | 
					**Текстовые задачи:**
 | 
				
			||||||
 | 
					1. Написать сопроводительное письмо для конкретной вакансии, используя расширенную лексику.
 | 
				
			||||||
 | 
					2. Составить резюме для воображаемой должности, включая все необходимые разделы.
 | 
				
			||||||
 | 
					3. Перевести текст собеседования на английский язык, сохраняя структуру и смысл.
 | 
				
			||||||
							
								
								
									
										74
									
								
								server/routers/kfu-m-24-1/eng-it-lean/units/data/unit-2.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								server/routers/kfu-m-24-1/eng-it-lean/units/data/unit-2.md
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,74 @@
 | 
				
			|||||||
 | 
					# Цель урока
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Изучение структуры документации программы с блоком кода.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Лексика
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Базовая лексика:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Documentation – документация
 | 
				
			||||||
 | 
					- Code block – блок кода
 | 
				
			||||||
 | 
					- Description – описание
 | 
				
			||||||
 | 
					- Function – функция
 | 
				
			||||||
 | 
					- Variable – переменная
 | 
				
			||||||
 | 
					- Comment – комментарий
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					### Расширенная лексика:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- API – интерфейс прикладного программирования
 | 
				
			||||||
 | 
					- Method – метод
 | 
				
			||||||
 | 
					- Class – класс
 | 
				
			||||||
 | 
					- Library – библиотека
 | 
				
			||||||
 | 
					- Framework – фреймворк
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Грамматический фокус
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Правило: Структура документации программы должна включать краткое описание, блок кода и примеры использования.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Пример:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Documentation for a program typically includes the following sections:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					1. **Description**: A brief overview of what the program does and its purpose.
 | 
				
			||||||
 | 
					2. **Code Block**: The actual code that implements the functionality described in the first section.
 | 
				
			||||||
 | 
					3. **Examples**: One or more examples demonstrating how to use the features described in the documentation.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Типичные ошибки и как их избежать: Ошибки могут возникнуть из-за недостаточного описания функционала или неправильного форматирования кода. Чтобы избежать этого, важно тщательно проработать каждый раздел документации и убедиться, что все примеры корректны и понятны.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Контекстуализация
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Текст для анализа:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Description**: This is a simple Python script that calculates the average value of a list of numbers.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**Code Block**: 
 | 
				
			||||||
 | 
					```python
 | 
				
			||||||
 | 
					def calculate_average(numbers):
 | 
				
			||||||
 | 
					    """Calculate the average value of a list of numbers"""
 | 
				
			||||||
 | 
					    return sum(numbers)/len(numbers)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Примеры использования:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					```python
 | 
				
			||||||
 | 
					# Example usage
 | 
				
			||||||
 | 
					numbers = [10, 20, 30]
 | 
				
			||||||
 | 
					average = calculate_average(numbers)
 | 
				
			||||||
 | 
					print("The average value of the list", numbers, "is", average)
 | 
				
			||||||
 | 
					```
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Упражнения
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Письменное задание: Написать документацию для простой функции на языке Python, которая принимает список чисел и возвращает среднее значение. Включить описание, код блока и пример использования.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Устная практика: Ролевой диалог между разработчиком и техническим писателем о структуре и содержании документации программы.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Аналитическое задание: Проанализировать существующую документацию программы и найти ошибки или неясности. Предложить улучшения.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					## Домашнее задание
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Текстовые задачи:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					- Написать документацию для другой функции на языке Python, используя правильную структуру.
 | 
				
			||||||
 | 
					- Исправить ошибки в существующей документации программы.
 | 
				
			||||||
 | 
					- Перевести фрагмент документации на русский язык, сохраняя точность и стиль.
 | 
				
			||||||
@ -1 +1 @@
 | 
				
			|||||||
[{"id":0,"filename":"unit-1","name":"Unit 1: Multifunctional Verbs: Be, Have, and Do"}]
 | 
					[{"id":1,"filename":"unit-1","name":"Unit 1: Multifunctional Verbs: Be, Have, and Do"},{"id":2,"filename":"unit-2","name":"Документация программы"},{"id":3,"fileName":"job-interview","name":"Job Interview"}]
 | 
				
			||||||
@ -10,33 +10,37 @@ router.get('/', (req, res) => {
 | 
				
			|||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
router.put('/', (req, res) => {
 | 
					router.put('/', (req, res) => {
 | 
				
			||||||
	const newUnit = req.body
 | 
					  const newUnit = req.body;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!newUnit) {
 | 
					  if (!newUnit) {
 | 
				
			||||||
		return res.status(400).send('No new unit to be added')
 | 
					    return res.status(400).send('No new unit to be added');
 | 
				
			||||||
	}
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!data) {
 | 
					  if (!data) {
 | 
				
			||||||
		return res.status(500).send('No data to be updated')
 | 
					    return res.status(500).send('No data to be updated');
 | 
				
			||||||
	}
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data.push({ "id": data.length, ...newUnit })
 | 
					  const newId = data.length + 1;
 | 
				
			||||||
 | 
					  const filename = newUnit.name.replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase();
 | 
				
			||||||
 | 
					  fs.writeFileSync(path.join(__dirname, 'data', `${filename}.md`), newUnit.content);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	fs.writeFileSync(path.join(__dirname, 'data', 'units.json'), JSON.stringify(data));
 | 
					  data.push({ id: newId, filename: filename, name: newUnit.name });
 | 
				
			||||||
	res.status(200).send(data);
 | 
					
 | 
				
			||||||
 | 
					  fs.writeFileSync(path.join(__dirname, 'data', 'units.json'), JSON.stringify(data));
 | 
				
			||||||
 | 
					  res.status(200).send(data);
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
router.delete('/:id', (req, res) => {
 | 
					router.delete('/:id', (req, res) => {
 | 
				
			||||||
	const id = parseInt(req.params.id);
 | 
					  const id = parseInt(req.params.id);
 | 
				
			||||||
	const index = data.findIndex((unit) => unit.id === id);
 | 
					  const index = data.findIndex((unit) => unit.id === id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (index < 0) {
 | 
					  if (index < 0) {
 | 
				
			||||||
		return res.status(404).send('Not found');
 | 
					    return res.status(404).send('Not found');
 | 
				
			||||||
	}
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	data.splice(index, 1);
 | 
					  data.splice(index, 1);
 | 
				
			||||||
	fs.writeFileSync(path.join(__dirname, 'data', 'units.json'), JSON.stringify(data));
 | 
					  fs.writeFileSync(path.join(__dirname, 'data', 'units.json'), JSON.stringify(data));
 | 
				
			||||||
	res.send({ message: `Unit with ID ${id} deleted` });
 | 
					  res.send({ message: `Unit with ID ${id} deleted` });
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
router.get('/:id', (req, res) => {
 | 
					router.get('/:id', (req, res) => {
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										75
									
								
								server/routers/kfu-m-24-1/eng-it-lean/words/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								server/routers/kfu-m-24-1/eng-it-lean/words/index.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,75 @@
 | 
				
			|||||||
 | 
					const fs = require('fs');
 | 
				
			||||||
 | 
					const path = require('path');
 | 
				
			||||||
 | 
					const router = require("express").Router();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					module.exports = router;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const words = require("../words/words.json");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					router.get("/", (req, res) => {
 | 
				
			||||||
 | 
					  res.send(words);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					router.put('/', (req, res) => {
 | 
				
			||||||
 | 
					  const newData = req.body;
 | 
				
			||||||
 | 
					  if (!newData) {
 | 
				
			||||||
 | 
					    return res.status(400).send('No data to add'); // Bad request
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  if (!words) {
 | 
				
			||||||
 | 
					    return res.status(500).send('No data to update'); // Internal server error
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  console.log(words.length)
 | 
				
			||||||
 | 
					  const indexedUpdatedData = { ...newData, id: words.length + 1 }; // Add the new word to the array
 | 
				
			||||||
 | 
					  console.log(indexedUpdatedData);
 | 
				
			||||||
 | 
					  words.push(indexedUpdatedData); // Add the new word to the array
 | 
				
			||||||
 | 
					  fs.writeFile(path.join(__dirname, 'words.json'), JSON.stringify(words), (err) => {
 | 
				
			||||||
 | 
					    if (err) {
 | 
				
			||||||
 | 
					      console.error(err); // Log the error
 | 
				
			||||||
 | 
					      return res.status(500).send('Error saving data');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    res.status(200).json(indexedUpdatedData);
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					router.get("/:id", (req, res) => {
 | 
				
			||||||
 | 
					  const id = parseInt(req.params.id);
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  if (!id || isNaN(id)) {
 | 
				
			||||||
 | 
					    return res.status(400).send('Invalid ID'); // Bad request
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!words) {
 | 
				
			||||||
 | 
					    return res.status(500).send('No data to update'); // Internal server error
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  const word = words.find((word) => word.id === id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (!word) {
 | 
				
			||||||
 | 
					    return res.status(404).send("Not found");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  res.send(word);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					router.delete("/:id", (req, res) => {
 | 
				
			||||||
 | 
					  const id = parseInt(req.params.id);
 | 
				
			||||||
 | 
					  if (!id || isNaN(id)) {
 | 
				
			||||||
 | 
					    return res.status(400).send('Invalid ID'); // Bad request
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const index = words.findIndex((word) => word.id === id);
 | 
				
			||||||
 | 
					  if (index < 0) {
 | 
				
			||||||
 | 
					    return res.status(404).send("Not found");
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  if (!words) {
 | 
				
			||||||
 | 
					    return res.status(500).send('No data to update'); // Internal server error
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  words.splice(index, 1);
 | 
				
			||||||
 | 
					  fs.writeFile(path.join(__dirname, 'words.json'), JSON.stringify(words), (err) => {
 | 
				
			||||||
 | 
					    if (err) {
 | 
				
			||||||
 | 
					      console.error(err); // Log the error
 | 
				
			||||||
 | 
					      return res.status(500).send('Error saving data');
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    res.send({ message: `Word with id ${id} deleted` });
 | 
				
			||||||
 | 
					  });
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
							
								
								
									
										136
									
								
								server/routers/kfu-m-24-1/eng-it-lean/words/words.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										136
									
								
								server/routers/kfu-m-24-1/eng-it-lean/words/words.json
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,136 @@
 | 
				
			|||||||
 | 
					[
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "id": 12,
 | 
				
			||||||
 | 
					    "word": "Tech",
 | 
				
			||||||
 | 
					    "definition": "short for technical, relating to the knowledge, machines, or methods used in science and industry. Tech is a whole industry, which includes IT",
 | 
				
			||||||
 | 
					    "examples": ["“As a DevOps engineer I have been working in Tech since 2020.”"],
 | 
				
			||||||
 | 
					    "synonyms": ["IT"]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "id": 1,
 | 
				
			||||||
 | 
					    "word": "career path",
 | 
				
			||||||
 | 
					    "definition": "the series of jobs or roles that constitute a person's career, especially one in a particular field",
 | 
				
			||||||
 | 
					    "examples": ["“Technology is an evolving field with a variety of available career paths.”"],
 | 
				
			||||||
 | 
					    "synonyms": []
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "id": 2,
 | 
				
			||||||
 | 
					    "word": "Machine Learning",
 | 
				
			||||||
 | 
					    "translation": "Машинное обучение",
 | 
				
			||||||
 | 
					    "definition": "An approach to artificial intelligence where computers learn from data without being explicitly programmed.",
 | 
				
			||||||
 | 
					    "synonyms": ["Trainable Algorithms", "Automated Learning"],
 | 
				
			||||||
 | 
					    "examples": [
 | 
				
			||||||
 | 
					      "We used machine learning techniques to forecast product demand.",
 | 
				
			||||||
 | 
					      "The movie recommendation system is based on machine learning algorithms.",
 | 
				
			||||||
 | 
					      "Machine learning helped improve the accuracy of speech recognition in our application."
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "id": 3,
 | 
				
			||||||
 | 
					    "word": "Neural Network",
 | 
				
			||||||
 | 
					    "translation": "Нейронная сеть",
 | 
				
			||||||
 | 
					    "definition": "A mathematical model inspired by the structure and function of biological neural networks, consisting of interconnected nodes organized in layers that can process information.",
 | 
				
			||||||
 | 
					    "synonyms": ["Artificial Neural Network", "Deep Neural Network"],
 | 
				
			||||||
 | 
					    "examples": [
 | 
				
			||||||
 | 
					      "To process large amounts of data, we created a deep learning neural network.",
 | 
				
			||||||
 | 
					      "This neural network is capable of generating realistic images.",
 | 
				
			||||||
 | 
					      "Using neural networks significantly improved the quality of text translation."
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "id": 4,
 | 
				
			||||||
 | 
					    "word": "Algorithm",
 | 
				
			||||||
 | 
					    "translation": "Алгоритм",
 | 
				
			||||||
 | 
					    "definition": "A step-by-step procedure or set of instructions for solving a problem or performing a computation.",
 | 
				
			||||||
 | 
					    "synonyms": ["Procedure", "Method"],
 | 
				
			||||||
 | 
					    "examples": [
 | 
				
			||||||
 | 
					      "The algorithm we developed quickly finds the optimal delivery route.",
 | 
				
			||||||
 | 
					      "This algorithm sorts an array with a minimal number of operations.",
 | 
				
			||||||
 | 
					      "Encryption algorithms ensure secure transmission of data over the internet."
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "id": 5,
 | 
				
			||||||
 | 
					    "word": "Data Model",
 | 
				
			||||||
 | 
					    "translation": "Модель данных",
 | 
				
			||||||
 | 
					    "definition": "An abstract representation of the structure of data, describing how data is organized and related to each other.",
 | 
				
			||||||
 | 
					    "synonyms": ["Data Structure", "Schema"],
 | 
				
			||||||
 | 
					    "examples": [
 | 
				
			||||||
 | 
					      "Our data model allows us to efficiently manage relationships between customers and orders.",
 | 
				
			||||||
 | 
					      "The data model was designed considering scalability and performance requirements.",
 | 
				
			||||||
 | 
					      "This data model is used for storing information about social network users."
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "id": 6,
 | 
				
			||||||
 | 
					    "word": "Regression",
 | 
				
			||||||
 | 
					    "translation": "Регрессия",
 | 
				
			||||||
 | 
					    "definition": "A statistical method used to determine the relationship between one variable and others.",
 | 
				
			||||||
 | 
					    "synonyms": ["Linear Regression", "Nonlinear Regression"],
 | 
				
			||||||
 | 
					    "examples": [
 | 
				
			||||||
 | 
					      "We applied linear regression to analyze the impact of advertising campaigns on sales.",
 | 
				
			||||||
 | 
					      "Results from the regression analysis showed a strong correlation between customer age and purchase frequency.",
 | 
				
			||||||
 | 
					      "Regression helped us assess how changes in environmental conditions affect crop yield."
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "id": 7,
 | 
				
			||||||
 | 
					    "word": "Clustering",
 | 
				
			||||||
 | 
					    "translation": "Кластеризация",
 | 
				
			||||||
 | 
					    "definition": "The process of grouping similar objects into clusters so that objects within the same cluster are more similar to each other than to those in other clusters.",
 | 
				
			||||||
 | 
					    "synonyms": ["Grouping", "Segmentation"],
 | 
				
			||||||
 | 
					    "examples": [
 | 
				
			||||||
 | 
					      "Clustering allowed us to divide customers into several groups according to their purchasing behavior.",
 | 
				
			||||||
 | 
					      "Clustering methods are used to automatically group news by topic.",
 | 
				
			||||||
 | 
					      "As a result of clustering, several market segments were identified, each with its own characteristics."
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "id": 8,
 | 
				
			||||||
 | 
					    "word": "Supervised Learning",
 | 
				
			||||||
 | 
					    "translation": "Обучение с учителем",
 | 
				
			||||||
 | 
					    "definition": "A type of machine learning where the algorithm learns from labeled data, meaning data for which correct answers are known.",
 | 
				
			||||||
 | 
					    "synonyms": ["Controlled Learning", "Labeled Classification"],
 | 
				
			||||||
 | 
					    "examples": [
 | 
				
			||||||
 | 
					      "Supervised learning is used to classify emails as spam or not-spam.",
 | 
				
			||||||
 | 
					      "This approach was used to create a model that predicts real estate prices based on multiple parameters.",
 | 
				
			||||||
 | 
					      "Supervised learning helps diagnose diseases at early stages through medical data analysis."
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "id": 9,
 | 
				
			||||||
 | 
					    "word": "Data Labeling",
 | 
				
			||||||
 | 
					    "translation": "Разметка данных",
 | 
				
			||||||
 | 
					    "definition": "The process of assigning labels or classes to data so it can be used in supervised learning.",
 | 
				
			||||||
 | 
					    "synonyms": ["Data Annotation", "Tagging"],
 | 
				
			||||||
 | 
					    "examples": [
 | 
				
			||||||
 | 
					      "Before starting model training, we labeled the data by assigning each photo an animal category.",
 | 
				
			||||||
 | 
					      "Data labeling includes marking user reviews as positive or negative.",
 | 
				
			||||||
 | 
					      "Text documents were labeled with special tags for subsequent analysis."
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "id": 10,
 | 
				
			||||||
 | 
					    "word": "Hyperparameters",
 | 
				
			||||||
 | 
					    "translation": "Гиперпараметры",
 | 
				
			||||||
 | 
					    "definition": "Parameters that define the structure and behavior of a machine learning model, set before the learning process begins.",
 | 
				
			||||||
 | 
					    "synonyms": ["Model Settings", "Configuration Parameters"],
 | 
				
			||||||
 | 
					    "examples": [
 | 
				
			||||||
 | 
					      "Optimizing hyperparameters enabled us to enhance the performance of our machine learning model.",
 | 
				
			||||||
 | 
					      "Hyperparameters include settings such as the number of layers in a neural network and the learning rate.",
 | 
				
			||||||
 | 
					      "Choosing the right hyperparameters is crucial for achieving high model accuracy."
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  {
 | 
				
			||||||
 | 
					    "id": 11,
 | 
				
			||||||
 | 
					    "word": "Model Validation",
 | 
				
			||||||
 | 
					    "translation": "Валидация модели",
 | 
				
			||||||
 | 
					    "definition": "The process of evaluating the quality of a model by testing it on new, previously unseen data.",
 | 
				
			||||||
 | 
					    "synonyms": ["Model Testing", "Model Verification"],
 | 
				
			||||||
 | 
					    "examples": [
 | 
				
			||||||
 | 
					      "After completing the training, we validated the model using a test dataset.",
 | 
				
			||||||
 | 
					      "During model validation, its ability to make accurate predictions on new data is checked.",
 | 
				
			||||||
 | 
					      "Validation showed that the model is robust against changes in data and has low generalization error."
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					]
 | 
				
			||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user