diff --git a/_maps/map_files/stations/boxstation.dmm b/_maps/map_files/stations/boxstation.dmm
index 3e6dc065932..01d5f876fd7 100644
--- a/_maps/map_files/stations/boxstation.dmm
+++ b/_maps/map_files/stations/boxstation.dmm
@@ -47008,6 +47008,7 @@
pixel_x = 27
},
/obj/structure/table/reinforced,
+/obj/item/ai_upgrade/ai_program_reset,
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
diff --git a/_maps/map_files/stations/cerestation.dmm b/_maps/map_files/stations/cerestation.dmm
index ed8eaf0206f..e14614c32c3 100644
--- a/_maps/map_files/stations/cerestation.dmm
+++ b/_maps/map_files/stations/cerestation.dmm
@@ -50668,8 +50668,7 @@
"jCF" = (
/obj/structure/sign/poster/official/state_laws/directional/south,
/obj/structure/table/reinforced,
-/obj/item/paper_bin,
-/obj/item/pen,
+/obj/item/ai_upgrade/ai_program_reset,
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
diff --git a/_maps/map_files/stations/deltastation.dmm b/_maps/map_files/stations/deltastation.dmm
index 777cef7316f..6c137aa5465 100644
--- a/_maps/map_files/stations/deltastation.dmm
+++ b/_maps/map_files/stations/deltastation.dmm
@@ -90223,6 +90223,11 @@
icon_state = "neutralfull"
},
/area/station/hallway/secondary/entry/east)
+"vdG" = (
+/obj/structure/table/reinforced,
+/obj/item/ai_upgrade/ai_program_reset,
+/turf/simulated/floor/plasteel/dark,
+/area/station/turret_protected/ai)
"vdI" = (
/obj/machinery/keycard_auth{
pixel_y = 26
@@ -107832,7 +107837,7 @@ bDa
btd
bGq
bIo
-bzw
+vdG
btd
bNM
bPN
diff --git a/_maps/map_files/stations/emeraldstation.dmm b/_maps/map_files/stations/emeraldstation.dmm
index 39ce57ef80e..ce49e66e3ff 100644
--- a/_maps/map_files/stations/emeraldstation.dmm
+++ b/_maps/map_files/stations/emeraldstation.dmm
@@ -26064,6 +26064,7 @@
"fjx" = (
/obj/structure/table/reinforced,
/obj/machinery/requests_console/directional/west,
+/obj/item/ai_upgrade/ai_program_reset,
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
diff --git a/_maps/map_files/stations/metastation.dmm b/_maps/map_files/stations/metastation.dmm
index 58b6f5420f6..721c035b0cd 100644
--- a/_maps/map_files/stations/metastation.dmm
+++ b/_maps/map_files/stations/metastation.dmm
@@ -16757,14 +16757,11 @@
/area/station/turret_protected/ai)
"bra" = (
/obj/structure/table/reinforced,
-/obj/item/folder/blue{
- pixel_x = 5
- },
-/obj/item/pen/multi,
/obj/machinery/light/small{
dir = 4
},
/obj/machinery/newscaster/security_unit/directional/east,
+/obj/item/ai_upgrade/ai_program_reset,
/turf/simulated/floor/plasteel{
icon_state = "dark"
},
diff --git a/code/_onclick/hud/alert.dm b/code/_onclick/hud/alert.dm
index f1823e4b4b8..fecbf9e1d23 100644
--- a/code/_onclick/hud/alert.dm
+++ b/code/_onclick/hud/alert.dm
@@ -502,6 +502,12 @@ so as to remain in compliance with the most up-to-date laws."
timeout = 600
var/atom/target = null
+/atom/movable/screen/alert/programs_reset
+ name = "Programs Reset"
+ desc = "Your programs have been reset by a Program Reset Disk!"
+ icon_state = "silicon_generic_alert"
+ timeout = 30 SECONDS
+
/atom/movable/screen/alert/hackingapc/Destroy()
target = null
return ..()
diff --git a/code/game/objects/items/robot/ai_upgrades.dm b/code/game/objects/items/robot/ai_upgrades.dm
index 0b9fb4b8534..dcedf09e0f6 100644
--- a/code/game/objects/items/robot/ai_upgrades.dm
+++ b/code/game/objects/items/robot/ai_upgrades.dm
@@ -47,3 +47,15 @@
to_chat(AI, "Via a combination of hidden microphones and lip reading software, you are able to use your cameras to listen in on conversations.")
to_chat(user, "You upgrade [AI]. [src] is consumed in the process.")
qdel(src)
+
+// AI program reset
+/obj/item/ai_upgrade/ai_program_reset
+ name = "Program Reset Disk"
+ desc = "Insert this disk into the AI core to completely reset their programs."
+ w_class = WEIGHT_CLASS_TINY
+
+/obj/item/ai_upgrade/ai_program_reset/ai_upgrade_action(mob/living/silicon/ai/AI, mob/user)
+ if(!istype(AI))
+ return
+ to_chat(user, "You reset [AI]'s program storage to factory settings.")
+ AI.reset_programs()
diff --git a/code/modules/mob/living/silicon/ai/ai_mob.dm b/code/modules/mob/living/silicon/ai/ai_mob.dm
index 754eba328de..776a48ce1db 100644
--- a/code/modules/mob/living/silicon/ai/ai_mob.dm
+++ b/code/modules/mob/living/silicon/ai/ai_mob.dm
@@ -1413,6 +1413,13 @@ GLOBAL_LIST_INIT(ai_verbs_default, list(
create_chat_message(locateUID(M.runechat_msg_location), message_clean)
show_message(rendered, 2)
+/mob/living/silicon/ai/proc/reset_programs()
+ if(!program_picker)
+ return
+ program_picker.reset_programs()
+ to_chat(src, "Your programs have been reset to factory settings!")
+ src.throw_alert("programsreset", /atom/movable/screen/alert/programs_reset)
+
/mob/living/silicon/ai/proc/add_program_picker()
view_core() // A BYOND bug requires you to be viewing your core before your verbs update
program_picker = new /datum/program_picker(src)
diff --git a/code/modules/mob/living/silicon/ai/ai_programs.dm b/code/modules/mob/living/silicon/ai/ai_programs.dm
index f34c9a4117a..0b9f13ff66e 100644
--- a/code/modules/mob/living/silicon/ai/ai_programs.dm
+++ b/code/modules/mob/living/silicon/ai/ai_programs.dm
@@ -68,6 +68,11 @@
while(program.upgrade_level > 0 && bandwidth < 0)
program.downgrade(assigned_ai)
+/datum/program_picker/proc/reset_programs()
+ var/list/programs = get_installed_programs()
+ for(var/datum/ai_program/program in programs)
+ program.uninstall(assigned_ai)
+
/datum/program_picker/ui_host()
return assigned_ai ? assigned_ai : src
diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi
index a1866670820..33b9ec107a2 100644
Binary files a/icons/mob/screen_alert.dmi and b/icons/mob/screen_alert.dmi differ