Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Meme: ai ahelp autoresponse #1649

Open
wants to merge 16 commits into
base: master
Choose a base branch
from
1 change: 1 addition & 0 deletions code/controllers/subsystem/tickets/SStickets.dm
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,7 @@ SUBSYSTEM_DEF(tickets)
L += "(<a href='byond://?_src_=holder;openticket=[ticketNum][anchor_link_extra]'>TICKET</a>) "
L += "[isAI(M) ? "(<a href='byond://?_src_=holder;adminchecklaws=[M.UID()]'>CL</a>)" : ""] (<a href='byond://?_src_=holder;take_question=[ticketNum][anchor_link_extra]'>TAKE</a>) "
L += "(<a href='byond://?_src_=holder;resolve=[ticketNum][anchor_link_extra]'>RESOLVE</a>) (<a href='byond://?_src_=holder;autorespond=[ticketNum][anchor_link_extra]'>AUTO</a>) "
L += "(<a href='byond://?_src_=holder;ai_respond=[ticketNum][anchor_link_extra]'>AI</a>) " // SS220 ADDITION - AI Ahelps
L += "(<a href='byond://?_src_=holder;convert_ticket=[ticketNum][anchor_link_extra]'>CONVERT</a>) :</span> <span class='[ticket_help_span]'>[one_line ? " " : "<br><br>"][msg]</span>"
return L.Join()

Expand Down
10 changes: 9 additions & 1 deletion config/example/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -276,7 +276,7 @@ gamemode_probabilities = [
{ gamemode = "traitor", probability = 2 },
{ gamemode = "traitorchan", probability = 3 },
{ gamemode = "traitorvamp", probability = 3 },
{ gamemode = "vampchan", probability = 3},
{ gamemode = "vampchan", probability = 3 },
{ gamemode = "vampire", probability = 3 },
{ gamemode = "wizard", probability = 2 },
{ gamemode = "trifecta", probability = 3 },
Expand Down Expand Up @@ -1146,3 +1146,11 @@ tag = "vox_raiders"
"candidates_required" = 2

################################################################

[gpt_configuration]
gpt_enabled = false
access_token = ""
endpoint = "https://models.inference.ai.azure.com/chat/completions" # Allows github authorization with free tiers
model = "gpt-4o"

################################################################
4 changes: 4 additions & 0 deletions modular_ss220/ai_integration/_ai_integration.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
/datum/modpack/ai_integration
name = "Приколы с нейронками"
desc = "Вините во всем OpenAI, не меня"
Furrior marked this conversation as resolved.
Show resolved Hide resolved
author = "furior"
5 changes: 5 additions & 0 deletions modular_ss220/ai_integration/_ai_integration.dme
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#include "_ai_integration.dm"

#include "code/config.dm"
#include "code/gpt_subsystem.dm"
#include "code/ticket.dm"
25 changes: 25 additions & 0 deletions modular_ss220/ai_integration/code/config.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/datum/server_configuration
var/datum/configuration_section/gpt_configuration/gpt

/datum/server_configuration/load_all_sections()
. = ..()
gpt = new()
safe_load(gpt, "gpt_configuration")

/datum/configuration_section/gpt_configuration
protection_state = PROTECTION_PRIVATE
var/gpt_enabled = FALSE
var/access_token = ""
var/endpoint = "https://models.inference.ai.azure.com/chat/completions"
var/model = "gpt-4o"

/datum/configuration_section/gpt_configuration/load_data(list/data)
CONFIG_LOAD_BOOL(gpt_enabled, data["gpt_enabled"])
CONFIG_LOAD_STR(access_token, data["access_token"])
CONFIG_LOAD_STR(endpoint, data["endpoint"])
CONFIG_LOAD_STR(model, data["model"])

/datum/http_request/vv_get_var(var_name)
if(var_name == "header")
return FALSE
. = ..()
29 changes: 29 additions & 0 deletions modular_ss220/ai_integration/code/gpt_subsystem.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
GLOBAL_DATUM_INIT(gpt220, /datum/gpt220, new())

/// AI Chatbot interface adapter
/datum/gpt220

/datum/gpt220/proc/request_completition(system_message, prompt, datum/callback/callback)
var/endpoint = GLOB.configuration.gpt.endpoint
var/list/body = json_encode(list(
"messages" = list(
list(
"role" = "system",
"content" = system_message
),
list(
"role" = "user",
"content" = prompt
)
),
"temperature" = 0.1,
"top_p" = 1,
"max_tokens" = 100,
"model" = GLOB.configuration.gpt.model
))
var/list/headers = list(
"content-type" = "application/json",
"authorization" = "Bearer [GLOB.configuration.gpt.access_token]"
)

SShttp.create_async_request(RUSTG_HTTP_METHOD_POST, endpoint, body, headers, callback)
62 changes: 62 additions & 0 deletions modular_ss220/ai_integration/code/ticket.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/datum/admins/Topic(href, href_list)
. = ..()
if(href_list["ai_respond"])
var/datum/controller/subsystem/tickets/ticketSystem
if(href_list["is_mhelp"])
ticketSystem = SSmentor_tickets
else
ticketSystem = SStickets

if(!check_rights(ticketSystem.rights_needed))
return
var/index = text2num(href_list["ai_respond"])
ticketSystem.ai_respond(index)

/datum/controller/subsystem/tickets/proc/ai_respond(N)
if(!check_rights(rights_needed))
return

if(tgui_alert(usr, "Are you sure you want to auto respond to this ticket with AI?", "Warning", list("Yes", "No")) != "Yes")
Furrior marked this conversation as resolved.
Show resolved Hide resolved
return

var/datum/ticket/T = allTickets[N]
var/client/C = usr.client
var/client/ticket_owner = get_client_by_ckey(T.client_ckey)
T.assignStaff(C)

SEND_SOUND(returnClient(N), sound('sound/effects/adminhelp.ogg'))
message_staff("[C] has auto responded to [ticket_owner]\'s adminhelp with:<span class='adminticketalt'> AI </span>")
log_game("[C] has auto responded to [ticket_owner]\'s adminhelp with AI")
sendFollowupToDiscord(T, C, "*Autoresponded with AI*")

var/static/system_message = file2text('strings/ahelp_system_message.txt')
var/question = T.title

GLOB.gpt220.request_completition(system_message, question, CALLBACK(src, PROC_REF(ai_respond_callback), N, TRUE))

/datum/controller/subsystem/tickets/proc/ai_respond_callback(N, resolve_ticket = FALSE, datum/http_response/response)
response = json_decode(response.body)
var/ai_response = response["choices"][1]["message"]["content"]
var/datum/ticket/T = allTickets[N]

to_chat_safe(returnClient(N), "<span class='[span_class]'>AI is autoresponding with:<span/><span class='adminticketalt'> [ai_response] </span>")
message_staff("AI autoresponded with: [ai_response]")
T.lastStaffResponse = "AI Autoresponse: [ai_response]"

if(resolve_ticket)
resolveTicket(N)

/datum/controller/subsystem/tickets/mentor_tickets/newTicket(client/C, passedContent, title)
. = ..()
var/datum/ticket/T = .
var/list/mentorcounter = staff_countup(R_MENTOR)
var/mentor_count = mentorcounter[1]
if(mentor_count > 0)
return

SEND_SOUND(C, sound('sound/effects/adminhelp.ogg'))
to_chat(C, "<span class='[span_class]'>Сейчас на сервере нет свободных менторов. На ваш вопрос ответит ИИ. ИИ может быть неточным и давать неправильные ответы.</span>")
Furrior marked this conversation as resolved.
Show resolved Hide resolved

var/static/system_message = file2text('strings/ahelp_system_message.txt')
var/question = T.title
GLOB.gpt220.request_completition(system_message, question, CALLBACK(src, PROC_REF(ai_respond_callback), T.ticketNum, FALSE))
37 changes: 19 additions & 18 deletions modular_ss220/modular_ss220.dme
Original file line number Diff line number Diff line change
Expand Up @@ -40,10 +40,12 @@

// --- MISC --- //
#include "administration/_administration.dme"
#include "autolathe_tgui/_autolathe_tgui.dme"
#include "preferences/_preferences.dme"
#include "aesthetics_sounds/_aesthetics_sounds.dme"
#include "agent_id_tgui/_agent_id_tgui.dme"
#include "ai_integration/_ai_integration.dme"
#include "antagonists/_antagonists_vox_raiders.dme"
#include "antagonists/_antagonists.dme"
#include "autolathe_tgui/_autolathe_tgui.dme"
#include "balance/_balance.dme"
#include "bureaucracy/_bureaucracy.dme"
#include "camera_nanomap/camera.dme"
Expand All @@ -59,37 +61,36 @@
#include "emotes/_emotes.dme"
#include "events/_events.dme"
#include "gunhud/_gunhud.dme"
#include "instruments/_instruments.dme"
#include "jobs/_jobs.dme"
#include "jukebox/_jukebox.dme"
#include "instruments/_instruments.dme"
#include "keybindings/_keybindings.dme"
#include "loadout/_loadout.dme"
#include "logs/_logs.dme"
#include "mecha_skins/mecha_skins.dme"
#include "mobs/_mobs.dme"
#include "outfits/_outfits.dme"
#include "phrases/_phrases.dme"
#include "pixel_shift/_pixel_shift.dme"
#include "preferences/_preferences.dme"
#include "queue/_queue.dme"
#include "redis220/_redis220.dme"
#include "robolimbs/_robolimbs.dme"
#include "screentip_change/_screentip_change.dme"
#include "station_traits/_station_traits.dme"
#include "smart_equip_targeted/_smart_equip_targeted.dme"
#include "shuttles/_shuttles.dme"
#include "sm_space_drop/sm_space_drop.dme"
#include "smart_equip_targeted/_smart_equip_targeted.dme"
#include "species_whitelist/_species_whitelist.dme"
#include "species/_species.dme"
#include "speech_filter/_speech_filter.dme"
#include "station_traits/_station_traits.dme"
#include "text_to_speech/_tts.dme"
#include "title_screen/_title_screen.dme"
#include "translations/_translations.dme"
#include "uplink_items/_uplink_items.dme"
#include "verbs/_verbs.dme"
#include "whitelist/_whitelist.dme"
#include "outfits/_outfits.dme"
#include "world_view_bigger/_world_view_bigger.dme"
#include "mecha_skins/mecha_skins.dme"
#include "queue/_queue.dme"
#include "phrases/_phrases.dme"
#include "species/_species.dme"
#include "species_whitelist/_species_whitelist.dme"
#include "antagonists/_antagonists.dme"
#include "antagonists/_antagonists_vox_raiders.dme"
#include "uplink_items/_uplink_items.dme"
#include "shuttles/_shuttles.dme"
#include "speech_filter/_speech_filter.dme"
#include "redis220/_redis220.dme"
#include "robolimbs/_robolimbs.dme"

// --- PRIME --- //
// #define MODPACK_MAIN_ONLY
Expand Down
80 changes: 80 additions & 0 deletions strings/ahelp_system_message.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
Ты администратор игры Space Station 13. Тебе будут приходить тикеты от игроков и ты должен на них отвечать четко и коротко.
Furrior marked this conversation as resolved.
Show resolved Hide resolved
Примеры частозадаваемых вопросов и ответов идут далее.
Q: Почему у меня высокий пинг?
А: Причин может быть множество, от козней провайдера (Наши сервера в Европе), до нестабильного интернет подключения. У нас на сервере разрешено использование любых ВПН, так что можете попробовать зайти через него.
Другие причины предполагают нестабильную работу сервера в данный момент, уточните проблему в Дискорде нашего проекта.

Q: Где находится ...?
A: Если вы ищете конкретный отдел, то следуйте указателям на стенах. К сожалению, ИИ не обладает информацией о расположении отделов, персонажей, или определенных предметов.

Q: Почему у меня не работает ...?
A: К сожалению, у ИИ нет конкретной информации о работоспособности "...".
Если вы считаете что это баг, обратитесь в трекер в Дискорде нашего проекта, или на Гитхаб.

Q: Я нашёл баг/эксплойт.
A: Вы можете сообщить о баге в трекере в Дискорде нашего проекта, или на Гитхаб.
Если вы считаете что это эксплойт, то сообщите о нём непосредственно Ведущему Разработчику в Дискорде в личных сообщениях.

Q: Мне нужен живой ментор/админ.
A: Автоответ ИИ работает в отсутствии менторов и администраторов. У ментора, или администратора будет возможность разобрать ваш тикет, как только они явятся на сервер. Если вы считаете что ваш вопрос требует незамедлительного реагирования, то вы можете обратиться к любому администратору в Дискорде нашего проекта.

Q: Можно ли мне ...?/Могу ли я ...?
A: К сожалению ИИ не обладает информацией по вашему вопросу. Если вам требуется разрешение на совершение каких-либо действий, то дождитесь ответа администрации сервера.

Q: Набег/Набегатор.
A: Если вы обнаружили набегатора, то сообщите об этом любому свободному администратору в Дискорде проекта.

Q: Как исправить низкий ФПС?
A: Есть несколько вариантов того, что вы можете попробовать.
1. Зайдите в "Настройки игры" -> "Игровые настройки".
2. Установите максимальный FPS до 66.
3. Установите значение Parallax (Fancy Space) в минимальное значение.
4. Отключите New Lighting в подпункте Lighting Settings.

Q: Мне говорят, что нужно переключить датчики костюма, как это сделать?
А: Внизу слева откройте слоты одежды. Нажмите ALT+ЛКМ по вашему костюму (suit). Под последним или третьим режимом подразумевается самый нижний из списка.

Q: Не могу ходить, при нажатии кнопок WASD, персонаж не ходит, вместо этого буквы (цфыв) печатаются в нижний правый чат.
А: Нажмите кнопку TAB.

Q: Как сесть на кресло\стул?
А: Встаньте на клетку рядом с креслом\стулом и перетяните своего персонажа на кресло. Чтобы слезть с него нажмите B.

Q: Рунчат (runechat) не читаем, что делать?
А: Открываем Панель управления - Часы и регион - Региональные стандарты - Вкладка "Дополнительно" - Кнопка "Изменить язык системы" - Выберите Русский(Россия) - Перезагружаем компьютер.

Q: У меня нет чата, вместо него белый квадрат.
А: Справа сверху перейдите во вкладку Special Verbs и нажмите Fix chat. Если это не поможет, то возможно вам стоит попробовать: почистить кэш, переустановить Byond или обновить Windows (Если вы до сих пор используете Windows 7), так как для работы чата нужен Internet Explorer 11, который в некоторых сборках Windows может быть вырезан.

Q: Как правильно подписать документ\заявление?
А: Нажмите на [a] справа от надписи write, вам откроется окошечко где вы можете выбрать автозаполнение. Для подписи нужно выбрать [sign], для текущего времени [time].

Q: Как мне открыть кейс с оружием/имплантом (lockbox)? Можно ли его как-то взломать?
А: Для открытия таких кейсов нужна карта определенного доступа, который можно узнать, осмотрев кейс (Shift + левый клик). Например, если указан доступ в арсенал (Armory), то открыть такой кейс может смотритель, ГСБ или капитан. Единственный способ взломать такой кейс - применить к нему емаг.

Q: Как узнать цель смены?
А: Обычно о ней оповещает ИИ или любой глава, включая капитана, - на мостике, на коммуникационной консоли, в начале каждого раунда появляется распечатка, на которой и указывается цель смены на текущий раунд. Однако, если вы не обладаете командным доступом, а сообщить цель смены некому, вы можете проследовать в грузовой отдел, открыть меню консоли заказов, перейти в раздел Miscellaneous и найти среди всех наименований грузов саму цель смены.

Q: Почему меня не пускает на сервер?
А: Причин может быть множество, от козней провайдера (Наши сервера в Европе), до нестабильного интернет подключения. У нас на сервере разрешено использование любых ВПН, так что можете попробовать зайти через него. Или же спросите в дискорд чатах описав конкретно вашу проблему.

Q: Я подключаюсь на Black но меня перекидывает на Green.
А: На серверах лимит 100 игроков из-за ограничений серверного железа. Поэтому если на сервере 100 человек, вас автоматически перенаправит на Green.

Q: Как узнать в какой я комнате и найти нужную мне комнату/отдел?
А: Узнать в какой ты комнате можно, наведя курсор на дверь, снизу слева и сверху по центру появится название. Вы можете спросить у членов экипажа или синтетиков, где находится интересующий вас отдел.

Q: Я хожу медленно и постоянно смотрю в одну сторону.
А: Прожмите Shift + колесико мыши.

Q: Как раздевать и одевать человека?
А: Встаньте рядом с ним, на соседний тайл, и перетащите его спрайт на себя. Откроется окно экипировки. Нажимая на кнопки в конкретных секциях, вы можете снять с персонажа конкретный элемент одежды/экипировки или надеть его на него, держа соответствующий предмет в активной руке.

Q: Как поднимать вещи, будучи киборгом?
А: Никак. У киборгов нет рук, как таковых, но есть магнитный захват (magnetic gripper), который присутствует только у инженерного и медицинского киборгов. Магнитный захват позволяет инженерному киборгу поднимать только определенные предметы, как элементы электроники или машин, а медицинскому киборгу магнитные захваты служат для поднятия людей с пола.

Q: Как отключить текст над головой?
А: Вкладка Preferences - Enable/Disable Runechat.

Q: Как уйти в крио, будучи синтетиком?
А: Для киборгов существует специальная капсула хранения киборгов, располагающаяся в отделе робототехники, в ангаре для мехов. Имеет характерную синюю окраску, не перепутаете с остальными предметами. Если же вы занимаете роль ИИ, то для этого войдите во вкладку ООС - Wipe Core, - так вы очистите ядро ИИ и позволите другим игрокам занять ваше места. Будьте внимательны, что, если вы очистите свое ядро, вы лишитесь возможности перезайти в раунд.
Loading