├── README.md ├── gigashell.py ├── header.jpg └── install.bash /README.md: -------------------------------------------------------------------------------- 1 | ![GIGA SHELL](/header.jpg) 2 | 3 | Привет! Ты сейчас находишься в репозитории gigashell, неофициальная утилита командной строки, с помощью которой можно легко и быстро прикрутить современную нейросеть к твоей линукс-консоли. 4 | 5 | Предварительно надо получить токен, это можно сделать **[вот тут](https://developers.sber.ru/portal/products/gigachat-api)** 6 | 7 | Потом этот токен должен храниться в переменной окружения GIGACHAT_CREDENTIALS 8 | 9 | Например, можно прописать соответствующий export в файл .bashrc в домашней директории пользователя, под которым работаешь. Хоть это и не самый секюрный способ. 10 | 11 | ## Настраиваем авторизацию в сервисе 12 | 13 | ```sh 14 | echo -e "\n" >> ~/.bashrc 15 | echo "export GIGACHAT_CREDENTIALS=ТОКЕН" >> ~/.bashrc 16 | ``` 17 | 18 | Если используешь ZSH, то файл будет называться .zshrc 19 | 20 | ## Установка 21 | 22 | Установка проста: 23 | 24 | ```sh 25 | git clone https://github.com/skywardfire1/gigashell.git 26 | python3 -m venv venv 27 | source venv/bin/activate 28 | ./install.bash --install 29 | ``` 30 | 31 | Примеры: 32 | ```sh 33 | % gs "как посмотреть системный журнал?" 34 | Для просмотра системного журнала в Linux Mint 20 с оболочкой /bin/zsh необходимо выполнить следующие шаги: 35 | 36 | 1. Открыть терминал. Это можно сделать, нажав Ctrl+Alt+T или выбрав «Терминал» из меню приложений. 37 | 38 | 2. Ввести команду `journalctl -xb` и нажать Enter. Эта команда выведет список всех журналов, а также их уровень важности. 39 | 40 | 3. Чтобы просмотреть конкретный журнал, например, логи Apache, нужно ввести команду `journalctl -u apache | grep -i error`. Здесь `-u apache` указывает, что мы хотим просмотреть только логи Apache, а `grep -i error` фильтрует строки, содержащие слово «error». 41 | 42 | 4. Если вы хотите сохранить лог-файлы для дальнейшего анализа, то перед выводом команды нужно добавить опцию `-o`: `journalctl -xo logfile.log`. Здесь `logfile.log` — это имя файла, в который будут записаны лог-файлы. 43 | 44 | Надеюсь, эта информация была полезной! 45 | 46 | % gs "как посмотреть системный журнал?" -s 47 | Для просмотра системного журнала в Linux Mint 20 с ядром 5.4.0-26-generic и оболочкой /bin/zsh необходимо выполнить следующую команду: 48 | 49 | 50 | journalctl -xb 51 | 52 | 53 | Эта команда выведет все сообщения из системного журнала, включая ошибки и предупреждения. 54 | 55 | ``` 56 | 57 | 58 | 59 | -------------------------------------------------------------------------------- /gigashell.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | from langchain.schema import HumanMessage, SystemMessage 4 | from langchain.chat_models.gigachat import GigaChat 5 | import platform 6 | import os 7 | import argparse 8 | import sys 9 | from datetime import datetime 10 | import psutil 11 | import distro 12 | import pickle 13 | 14 | def parse_arguments(): 15 | parser = argparse.ArgumentParser( prog='gigashell', description='Sber GigaChat в твоей консоли!', epilog='Возрадуемся же!' ) 16 | parser.add_argument( '-L', '--last-message', action = 'store_true', help = 'Включить в запрос предыдущее сообщение' ) 17 | 18 | group_v_r = parser.add_mutually_exclusive_group() 19 | group_v_r.add_argument( 'request', metavar = 'ЗАПРОС', nargs = '?', default = '', help = 'Запрос к GigaChat' ) 20 | group_v_r.add_argument( '-v', '--version', action = 'store_true', help = 'Вывести информацию о версии, и закончить работу' ) 21 | 22 | group_2 = parser.add_mutually_exclusive_group() 23 | group_2.add_argument( '-s', '--shell', action = 'store_true', help = 'Сгенерировать только финальную команду. Имеет смысл только совместно с запросом' ) 24 | group_2.add_argument( '-p', '--system-prompt', action = 'store', default = 'no_custom_prompt_provided', help = 'Задать свой собственный системный промт' ) 25 | group_2.add_argument( '-m', '--more-info', action = 'store_true', help = 'Добавить в запрос больше информации о системе' ) 26 | return parser.parse_args() 27 | 28 | # Больше данных о системе 29 | def prompt_data_cpu(): 30 | # Физические ядра пока не включаю в запрос, но на всякий случай оставлю тут {psutil.cpu_count(logical=False)}') 31 | info = f'Количество ядер: {psutil.cpu_count(logical=True)}.' 32 | info += f' Маскимальная частота: {psutil.cpu_freq().max:.2f}МГц.' 33 | info += f' Минимальная частота: {psutil.cpu_freq().min:.2f}МГц.' 34 | info += f' Текущая частота: {psutil.cpu_freq().current:.2f}МГц.' 35 | return info 36 | 37 | def prompt_data_network_iface(): 38 | if_addrs = psutil.net_if_addrs() 39 | 40 | info = f'Имеются следующие сетевые интерфейсы:' 41 | 42 | for interface_name, interface_addresses in if_addrs.items(): 43 | for address in interface_addresses: 44 | if str(address.family) == 'AddressFamily.AF_INET': 45 | info += f' Имя интерфейса: {interface_name}, тип: {str(address.family)}, адрес: {address.address}, маска сети: {address.netmask}.' 46 | if str(address.family) == 'AddressFamily.AF_PACKET': 47 | info += f' Имя интерфейса: {interface_name}, тип: {str(address.family)}, адрес: {address.address}, маска сети: {address.netmask}.' 48 | return info 49 | 50 | # Собираем данные о системе и составляем разогревочный промт 51 | def make_prompt(): 52 | # Обрабатываем опцию -p. Если пользователь задал собственный системный промт, иcпользуем его 53 | if arguments.system_prompt != 'no_custom_prompt_provided': return arguments.system_prompt 54 | 55 | 56 | system_os = platform.system() 57 | system_architecture = platform.machine() 58 | system_distributive = distro.name() 59 | distributive_version = distro.version() 60 | kernel_version = platform.release() 61 | shell_name = os.readlink('/proc/%d/exe' % os.getppid()) 62 | 63 | # Поэтапно составляем промт 64 | warmup_prompt = '' 65 | 66 | # Если задан флаг -s, то промт надо начать именно так 67 | if arguments.shell: warmup_prompt = 'Выведи команду, которая позволит ответить на вопрос пользователя. Напиши только одну команду. Не выводи никаких дополнительных пояснений.' 68 | 69 | # Этот блок присоединяется в любом случае 70 | warmup_prompt += f' Пользователь работает в операционной системе {system_os}, версия ядра {kernel_version}. Дистрибутив называется {system_distributive} {distributive_version}. Архитектура системы {system_architecture}. Оболочка {shell_name}.' 71 | 72 | # Флаг -m вполне совместим со всем предыдущим, можем добавить больше инфы о системе 73 | if arguments.more_info: warmup_prompt += f'Информация о процессорах: {prompt_data_cpu()}. Информация о сетевых интерфейсах: {prompt_data_network_iface()}' 74 | 75 | return warmup_prompt 76 | 77 | # Для чатов 78 | def store_message( message ): 79 | file_name = '/tmp/gigachat_last_message' 80 | with open( file_name, 'wb' ) as db_file: 81 | pickle.dump( message, db_file ) 82 | return 0 83 | 84 | def get_message(): 85 | file_name = '/tmp/gigachat_last_message' 86 | try: 87 | with open( file_name, 'rb' ) as db_file: 88 | message = pickle.load( db_file ) 89 | return message 90 | except: 91 | return '' 92 | 93 | def do_request( request_text ): 94 | # Авторизация в сервисе GigaChat 95 | chat = GigaChat( verify_ssl_certs = False ) 96 | 97 | system_message = SystemMessage( content = make_prompt() ) 98 | user_message = HumanMessage( content = request_text ) 99 | 100 | if arguments.last_message: 101 | messages = get_message() 102 | if messages == '': 103 | messages = [ system_message, user_message ] 104 | else: 105 | messages.append( user_message ) 106 | else: 107 | messages = [ system_message, user_message ] 108 | 109 | res = chat( messages ) 110 | 111 | print( res.content ) 112 | messages.append( res ) 113 | store_message( messages ) 114 | 115 | return 0 116 | 117 | if __name__ == '__main__': 118 | # Парсим аргументы 119 | arguments = parse_arguments() 120 | 121 | if arguments.version: 122 | print( 'GigaShell, версия 0.2, 1 января 2023' ) 123 | exit(0) 124 | 125 | do_request( arguments.request ) 126 | 127 | -------------------------------------------------------------------------------- /header.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/skywardfire1/gigashell/cf54150e0653ed957e32c254f7d47c5105027017/header.jpg -------------------------------------------------------------------------------- /install.bash: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################ 4 | ### ### 5 | ### Скрипт установки GigaShell ### 6 | ### ### 7 | ### Напиши ./install.bash --install ### 8 | ### ### 9 | ############################################################ 10 | 11 | function install { 12 | 13 | [ -x `which python` ] || { echo "Не обнаружен Python! Установка прервана" && exit 1 ; } 14 | 15 | echo Устанавливаем модули Python... 16 | pip install -q gigachat 2> /dev/null || { echo "Не удалось установить библиотеку gigachat! Установка прервана" && exit 1 ; } 17 | pip install -q langchain 2> /dev/null || { echo "Не удалось установить библиотеку langchain! Установка прервана" && exit 1 ; } 18 | pip install -q psutil 2> /dev/null || { echo "Не удалось установить библиотеку psutil! Установка прервана" && exit 1 ; } 19 | 20 | echo Устанавливаем GigaShell... 21 | sudo cp gigashell.py /usr/local/bin 22 | sudo ln -s /usr/local/bin/gigashell.py /usr/local/bin/gigashell 23 | sudo chmod +x /usr/local/bin/gigashell.py 24 | sudo ln -s /usr/local/bin/gigashell.py /usr/local/bin/gs 25 | 26 | [ -x /usr/local/bin/gigashell ] || { echo "Что-то пошло не так! Установка прервана" && exit 1 ; } 27 | 28 | echo Ура! GigaShell установлен! 29 | [ `env | grep GIGACHAT_CREDENTIALS` ] || echo Не забудь также прописать токен в переменную GIGACHAT_CREDENTIALS 30 | } 31 | 32 | case $1 in 33 | "--install" ) install ;; 34 | * ) echo "Напиши ./install.bash --install" ;; 35 | esac 36 | 37 | --------------------------------------------------------------------------------