We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
silero_tts will not load if I am not connected to the internet
### Describe the bug

I used to be able to use this extension offline, but now I can't load the extension if I am not online.  If I am online the extension loads just fine.  The actual language models is saved on my machine via the .cache file: C:\Users\myself\.cache\torch\hub\snakers4_silero-models_master\src\silero\model

The model name is called v3_en.pt, it's being cached on my machine and when I load the extension with an internet connection the miniconda console says that it's using the cached model, so I don't know why I NEED to be connected to the internet for it to work.

### Is there an existing issue for this?

- [x] I have searched the existing issues

### Reproduction

Run this (change your install location as necessary) with and without an internet connection.

cd F:\OoBaboogaMarch17\text-generation-webui
conda activate textgen
python .\server.py --auto-devices --gptq-bits 4 --cai-chat --gptq-model-type LLaMa --extension silero_tts 

### Screenshot

I'm including two screenshots, one when I am connected to the internet, and one when I am not connected to the internet.

![internetConnection](https://user-images.githubusercontent.com/6488699/227263118-cf13d103-975d-4103-b1d7-a0763e492bc7.png)
![no internet connection](https://user-images.githubusercontent.com/6488699/227263135-017e10b7-7164-465f-b2be-af7f837a9d87.png)


### Logs

```shell
See screenshots
```


### System Info

```shell
Window 10, 4090, i9 13900, windows mode not wsl
```


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `extensions/silero_tts/script.py`
Content:
```
1 import time
2 from pathlib import Path
3 
4 import gradio as gr
5 import torch
6 from extensions.silero_tts import tts_preprocessor
7 from modules import chat, shared
8 from modules.html_generator import chat_html_wrapper
9 
10 torch._C._jit_set_profiling_mode(False)
11 
12 
13 params = {
14     'activate': True,
15     'speaker': 'en_56',
16     'language': 'en',
17     'model_id': 'v3_en',
18     'sample_rate': 48000,
19     'device': 'cpu',
20     'show_text': False,
21     'autoplay': True,
22     'voice_pitch': 'medium',
23     'voice_speed': 'medium',
24 }
25 
26 current_params = params.copy()
27 voices_by_gender = ['en_99', 'en_45', 'en_18', 'en_117', 'en_49', 'en_51', 'en_68', 'en_0', 'en_26', 'en_56', 'en_74', 'en_5', 'en_38', 'en_53', 'en_21', 'en_37', 'en_107', 'en_10', 'en_82', 'en_16', 'en_41', 'en_12', 'en_67', 'en_61', 'en_14', 'en_11', 'en_39', 'en_52', 'en_24', 'en_97', 'en_28', 'en_72', 'en_94', 'en_36', 'en_4', 'en_43', 'en_88', 'en_25', 'en_65', 'en_6', 'en_44', 'en_75', 'en_91', 'en_60', 'en_109', 'en_85', 'en_101', 'en_108', 'en_50', 'en_96', 'en_64', 'en_92', 'en_76', 'en_33', 'en_116', 'en_48', 'en_98', 'en_86', 'en_62', 'en_54', 'en_95', 'en_55', 'en_111', 'en_3', 'en_83', 'en_8', 'en_47', 'en_59', 'en_1', 'en_2', 'en_7', 'en_9', 'en_13', 'en_15', 'en_17', 'en_19', 'en_20', 'en_22', 'en_23', 'en_27', 'en_29', 'en_30', 'en_31', 'en_32', 'en_34', 'en_35', 'en_40', 'en_42', 'en_46', 'en_57', 'en_58', 'en_63', 'en_66', 'en_69', 'en_70', 'en_71', 'en_73', 'en_77', 'en_78', 'en_79', 'en_80', 'en_81', 'en_84', 'en_87', 'en_89', 'en_90', 'en_93', 'en_100', 'en_102', 'en_103', 'en_104', 'en_105', 'en_106', 'en_110', 'en_112', 'en_113', 'en_114', 'en_115']
28 voice_pitches = ['x-low', 'low', 'medium', 'high', 'x-high']
29 voice_speeds = ['x-slow', 'slow', 'medium', 'fast', 'x-fast']
30 streaming_state = shared.args.no_stream  # remember if chat streaming was enabled
31 
32 # Used for making text xml compatible, needed for voice pitch and speed control
33 table = str.maketrans({
34     "<": "&lt;",
35     ">": "&gt;",
36     "&": "&amp;",
37     "'": "&apos;",
38     '"': "&quot;",
39 })
40 
41 
42 def xmlesc(txt):
43     return txt.translate(table)
44 
45 
46 def load_model():
47     model, example_text = torch.hub.load(repo_or_dir='snakers4/silero-models', model='silero_tts', language=params['language'], speaker=params['model_id'])
48     model.to(params['device'])
49     return model
50 
51 
52 model = load_model()
53 
54 
55 def remove_tts_from_history(name1, name2, mode):
56     for i, entry in enumerate(shared.history['internal']):
57         shared.history['visible'][i] = [shared.history['visible'][i][0], entry[1]]
58     return chat_html_wrapper(shared.history['visible'], name1, name2, mode)
59 
60 
61 def toggle_text_in_history(name1, name2, mode):
62     for i, entry in enumerate(shared.history['visible']):
63         visible_reply = entry[1]
64         if visible_reply.startswith('<audio'):
65             if params['show_text']:
66                 reply = shared.history['internal'][i][1]
67                 shared.history['visible'][i] = [shared.history['visible'][i][0], f"{visible_reply.split('</audio>')[0]}</audio>\n\n{reply}"]
68             else:
69                 shared.history['visible'][i] = [shared.history['visible'][i][0], f"{visible_reply.split('</audio>')[0]}</audio>"]
70     return chat_html_wrapper(shared.history['visible'], name1, name2, mode)
71 
72 
73 def input_modifier(string):
74     """
75     This function is applied to your text inputs before
76     they are fed into the model.
77     """
78 
79     # Remove autoplay from the last reply
80     if shared.is_chat() and len(shared.history['internal']) > 0:
81         shared.history['visible'][-1] = [shared.history['visible'][-1][0], shared.history['visible'][-1][1].replace('controls autoplay>', 'controls>')]
82 
83     shared.processing_message = "*Is recording a voice message...*"
84     shared.args.no_stream = True  # Disable streaming cause otherwise the audio output will stutter and begin anew every time the message is being updated
85     return string
86 
87 
88 def output_modifier(string):
89     """
90     This function is applied to the model outputs.
91     """
92 
93     global model, current_params, streaming_state
94 
95     for i in params:
96         if params[i] != current_params[i]:
97             model = load_model()
98             current_params = params.copy()
99             break
100 
101     if not params['activate']:
102         return string
103 
104     original_string = string
105     string = tts_preprocessor.preprocess(string)
106 
107     if string == '':
108         string = '*Empty reply, try regenerating*'
109     else:
110         output_file = Path(f'extensions/silero_tts/outputs/{shared.character}_{int(time.time())}.wav')
111         prosody = '<prosody rate="{}" pitch="{}">'.format(params['voice_speed'], params['voice_pitch'])
112         silero_input = f'<speak>{prosody}{xmlesc(string)}</prosody></speak>'
113         model.save_wav(ssml_text=silero_input, speaker=params['speaker'], sample_rate=int(params['sample_rate']), audio_path=str(output_file))
114 
115         autoplay = 'autoplay' if params['autoplay'] else ''
116         string = f'<audio src="file/{output_file.as_posix()}" controls {autoplay}></audio>'
117         if params['show_text']:
118             string += f'\n\n{original_string}'
119 
120     shared.processing_message = "*Is typing...*"
121     shared.args.no_stream = streaming_state  # restore the streaming option to the previous value
122     return string
123 
124 
125 def bot_prefix_modifier(string):
126     """
127     This function is only applied in chat mode. It modifies
128     the prefix text for the Bot and can be used to bias its
129     behavior.
130     """
131 
132     return string
133 
134 
135 def ui():
136     # Gradio elements
137     with gr.Accordion("Silero TTS"):
138         with gr.Row():
139             activate = gr.Checkbox(value=params['activate'], label='Activate TTS')
140             autoplay = gr.Checkbox(value=params['autoplay'], label='Play TTS automatically')
141 
142         show_text = gr.Checkbox(value=params['show_text'], label='Show message text under audio player')
143         voice = gr.Dropdown(value=params['speaker'], choices=voices_by_gender, label='TTS voice')
144         with gr.Row():
145             v_pitch = gr.Dropdown(value=params['voice_pitch'], choices=voice_pitches, label='Voice pitch')
146             v_speed = gr.Dropdown(value=params['voice_speed'], choices=voice_speeds, label='Voice speed')
147 
148         with gr.Row():
149             convert = gr.Button('Permanently replace audios with the message texts')
150             convert_cancel = gr.Button('Cancel', visible=False)
151             convert_confirm = gr.Button('Confirm (cannot be undone)', variant="stop", visible=False)
152 
153     # Convert history with confirmation
154     convert_arr = [convert_confirm, convert, convert_cancel]
155     convert.click(lambda: [gr.update(visible=True), gr.update(visible=False), gr.update(visible=True)], None, convert_arr)
156     convert_confirm.click(lambda: [gr.update(visible=False), gr.update(visible=True), gr.update(visible=False)], None, convert_arr)
157     convert_confirm.click(remove_tts_from_history, [shared.gradio[k] for k in ['name1', 'name2', 'Chat mode']], shared.gradio['display'])
158     convert_confirm.click(lambda: chat.save_history(timestamp=False), [], [], show_progress=False)
159     convert_cancel.click(lambda: [gr.update(visible=False), gr.update(visible=True), gr.update(visible=False)], None, convert_arr)
160 
161     # Toggle message text in history
162     show_text.change(lambda x: params.update({"show_text": x}), show_text, None)
163     show_text.change(toggle_text_in_history, [shared.gradio[k] for k in ['name1', 'name2', 'Chat mode']], shared.gradio['display'])
164     show_text.change(lambda: chat.save_history(timestamp=False), [], [], show_progress=False)
165 
166     # Event functions to update the parameters in the backend
167     activate.change(lambda x: params.update({"activate": x}), activate, None)
168     autoplay.change(lambda x: params.update({"autoplay": x}), autoplay, None)
169     voice.change(lambda x: params.update({"speaker": x}), voice, None)
170     v_pitch.change(lambda x: params.update({"voice_pitch": x}), v_pitch, None)
171     v_speed.change(lambda x: params.update({"voice_speed": x}), v_speed, None)
172
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/extensions/silero_tts/script.py b/extensions/silero_tts/script.py
--- a/extensions/silero_tts/script.py
+++ b/extensions/silero_tts/script.py
@@ -21,6 +21,7 @@
     'autoplay': True,
     'voice_pitch': 'medium',
     'voice_speed': 'medium',
+    'local_cache_path': ''  # User can override the default cache path to something other via settings.json
 }
 
 current_params = params.copy()
@@ -44,14 +45,18 @@
 
 
 def load_model():
-    model, example_text = torch.hub.load(repo_or_dir='snakers4/silero-models', model='silero_tts', language=params['language'], speaker=params['model_id'])
+    torch_cache_path = torch.hub.get_dir() if params['local_cache_path'] == '' else params['local_cache_path']
+    model_path = torch_cache_path + "/snakers4_silero-models_master/src/silero/model/" + params['model_id'] + ".pt"
+    if Path(model_path).is_file():
+        print(f'\nUsing Silero TTS cached checkpoint found at {torch_cache_path}')
+        model, example_text = torch.hub.load(repo_or_dir=torch_cache_path + '/snakers4_silero-models_master/', model='silero_tts', language=params['language'], speaker=params['model_id'], source='local', path=model_path, force_reload=True)
+    else:
+        print(f'\nSilero TTS cache not found at {torch_cache_path}. Attempting to download...')
+        model, example_text = torch.hub.load(repo_or_dir='snakers4/silero-models', model='silero_tts', language=params['language'], speaker=params['model_id'])
     model.to(params['device'])
     return model
 
 
-model = load_model()
-
-
 def remove_tts_from_history(name1, name2, mode):
     for i, entry in enumerate(shared.history['internal']):
         shared.history['visible'][i] = [shared.history['visible'][i][0], entry[1]]
@@ -132,6 +137,11 @@
     return string
 
 
+def setup():
+    global model
+    model = load_model()
+
+
 def ui():
     # Gradio elements
     with gr.Accordion("Silero TTS"):

{"golden_diff": "diff --git a/extensions/silero_tts/script.py b/extensions/silero_tts/script.py\n--- a/extensions/silero_tts/script.py\n+++ b/extensions/silero_tts/script.py\n@@ -21,6 +21,7 @@\n     'autoplay': True,\n     'voice_pitch': 'medium',\n     'voice_speed': 'medium',\n+    'local_cache_path': ''  # User can override the default cache path to something other via settings.json\n }\n \n current_params = params.copy()\n@@ -44,14 +45,18 @@\n \n \n def load_model():\n-    model, example_text = torch.hub.load(repo_or_dir='snakers4/silero-models', model='silero_tts', language=params['language'], speaker=params['model_id'])\n+    torch_cache_path = torch.hub.get_dir() if params['local_cache_path'] == '' else params['local_cache_path']\n+    model_path = torch_cache_path + \"/snakers4_silero-models_master/src/silero/model/\" + params['model_id'] + \".pt\"\n+    if Path(model_path).is_file():\n+        print(f'\\nUsing Silero TTS cached checkpoint found at {torch_cache_path}')\n+        model, example_text = torch.hub.load(repo_or_dir=torch_cache_path + '/snakers4_silero-models_master/', model='silero_tts', language=params['language'], speaker=params['model_id'], source='local', path=model_path, force_reload=True)\n+    else:\n+        print(f'\\nSilero TTS cache not found at {torch_cache_path}. Attempting to download...')\n+        model, example_text = torch.hub.load(repo_or_dir='snakers4/silero-models', model='silero_tts', language=params['language'], speaker=params['model_id'])\n     model.to(params['device'])\n     return model\n \n \n-model = load_model()\n-\n-\n def remove_tts_from_history(name1, name2, mode):\n     for i, entry in enumerate(shared.history['internal']):\n         shared.history['visible'][i] = [shared.history['visible'][i][0], entry[1]]\n@@ -132,6 +137,11 @@\n     return string\n \n \n+def setup():\n+    global model\n+    model = load_model()\n+\n+\n def ui():\n     # Gradio elements\n     with gr.Accordion(\"Silero TTS\"):\n", "issue": "silero_tts will not load if I am not connected to the internet\n### Describe the bug\n\nI used to be able to use this extension offline, but now I can't load the extension if I am not online.  If I am online the extension loads just fine.  The actual language models is saved on my machine via the .cache file: C:\\Users\\myself\\.cache\\torch\\hub\\snakers4_silero-models_master\\src\\silero\\model\r\n\r\nThe model name is called v3_en.pt, it's being cached on my machine and when I load the extension with an internet connection the miniconda console says that it's using the cached model, so I don't know why I NEED to be connected to the internet for it to work.\n\n### Is there an existing issue for this?\n\n- [x] I have searched the existing issues\n\n### Reproduction\n\nRun this (change your install location as necessary) with and without an internet connection.\r\n\r\ncd F:\\OoBaboogaMarch17\\text-generation-webui\r\nconda activate textgen\r\npython .\\server.py --auto-devices --gptq-bits 4 --cai-chat --gptq-model-type LLaMa --extension silero_tts \n\n### Screenshot\n\nI'm including two screenshots, one when I am connected to the internet, and one when I am not connected to the internet.\r\n\r\n![internetConnection](https://user-images.githubusercontent.com/6488699/227263118-cf13d103-975d-4103-b1d7-a0763e492bc7.png)\r\n![no internet connection](https://user-images.githubusercontent.com/6488699/227263135-017e10b7-7164-465f-b2be-af7f837a9d87.png)\r\n\n\n### Logs\n\n```shell\nSee screenshots\n```\n\n\n### System Info\n\n```shell\nWindow 10, 4090, i9 13900, windows mode not wsl\n```\n\n", "before_files": [{"content": "import time\nfrom pathlib import Path\n\nimport gradio as gr\nimport torch\nfrom extensions.silero_tts import tts_preprocessor\nfrom modules import chat, shared\nfrom modules.html_generator import chat_html_wrapper\n\ntorch._C._jit_set_profiling_mode(False)\n\n\nparams = {\n    'activate': True,\n    'speaker': 'en_56',\n    'language': 'en',\n    'model_id': 'v3_en',\n    'sample_rate': 48000,\n    'device': 'cpu',\n    'show_text': False,\n    'autoplay': True,\n    'voice_pitch': 'medium',\n    'voice_speed': 'medium',\n}\n\ncurrent_params = params.copy()\nvoices_by_gender = ['en_99', 'en_45', 'en_18', 'en_117', 'en_49', 'en_51', 'en_68', 'en_0', 'en_26', 'en_56', 'en_74', 'en_5', 'en_38', 'en_53', 'en_21', 'en_37', 'en_107', 'en_10', 'en_82', 'en_16', 'en_41', 'en_12', 'en_67', 'en_61', 'en_14', 'en_11', 'en_39', 'en_52', 'en_24', 'en_97', 'en_28', 'en_72', 'en_94', 'en_36', 'en_4', 'en_43', 'en_88', 'en_25', 'en_65', 'en_6', 'en_44', 'en_75', 'en_91', 'en_60', 'en_109', 'en_85', 'en_101', 'en_108', 'en_50', 'en_96', 'en_64', 'en_92', 'en_76', 'en_33', 'en_116', 'en_48', 'en_98', 'en_86', 'en_62', 'en_54', 'en_95', 'en_55', 'en_111', 'en_3', 'en_83', 'en_8', 'en_47', 'en_59', 'en_1', 'en_2', 'en_7', 'en_9', 'en_13', 'en_15', 'en_17', 'en_19', 'en_20', 'en_22', 'en_23', 'en_27', 'en_29', 'en_30', 'en_31', 'en_32', 'en_34', 'en_35', 'en_40', 'en_42', 'en_46', 'en_57', 'en_58', 'en_63', 'en_66', 'en_69', 'en_70', 'en_71', 'en_73', 'en_77', 'en_78', 'en_79', 'en_80', 'en_81', 'en_84', 'en_87', 'en_89', 'en_90', 'en_93', 'en_100', 'en_102', 'en_103', 'en_104', 'en_105', 'en_106', 'en_110', 'en_112', 'en_113', 'en_114', 'en_115']\nvoice_pitches = ['x-low', 'low', 'medium', 'high', 'x-high']\nvoice_speeds = ['x-slow', 'slow', 'medium', 'fast', 'x-fast']\nstreaming_state = shared.args.no_stream  # remember if chat streaming was enabled\n\n# Used for making text xml compatible, needed for voice pitch and speed control\ntable = str.maketrans({\n    \"<\": \"&lt;\",\n    \">\": \"&gt;\",\n    \"&\": \"&amp;\",\n    \"'\": \"&apos;\",\n    '\"': \"&quot;\",\n})\n\n\ndef xmlesc(txt):\n    return txt.translate(table)\n\n\ndef load_model():\n    model, example_text = torch.hub.load(repo_or_dir='snakers4/silero-models', model='silero_tts', language=params['language'], speaker=params['model_id'])\n    model.to(params['device'])\n    return model\n\n\nmodel = load_model()\n\n\ndef remove_tts_from_history(name1, name2, mode):\n    for i, entry in enumerate(shared.history['internal']):\n        shared.history['visible'][i] = [shared.history['visible'][i][0], entry[1]]\n    return chat_html_wrapper(shared.history['visible'], name1, name2, mode)\n\n\ndef toggle_text_in_history(name1, name2, mode):\n    for i, entry in enumerate(shared.history['visible']):\n        visible_reply = entry[1]\n        if visible_reply.startswith('<audio'):\n            if params['show_text']:\n                reply = shared.history['internal'][i][1]\n                shared.history['visible'][i] = [shared.history['visible'][i][0], f\"{visible_reply.split('</audio>')[0]}</audio>\\n\\n{reply}\"]\n            else:\n                shared.history['visible'][i] = [shared.history['visible'][i][0], f\"{visible_reply.split('</audio>')[0]}</audio>\"]\n    return chat_html_wrapper(shared.history['visible'], name1, name2, mode)\n\n\ndef input_modifier(string):\n    \"\"\"\n    This function is applied to your text inputs before\n    they are fed into the model.\n    \"\"\"\n\n    # Remove autoplay from the last reply\n    if shared.is_chat() and len(shared.history['internal']) > 0:\n        shared.history['visible'][-1] = [shared.history['visible'][-1][0], shared.history['visible'][-1][1].replace('controls autoplay>', 'controls>')]\n\n    shared.processing_message = \"*Is recording a voice message...*\"\n    shared.args.no_stream = True  # Disable streaming cause otherwise the audio output will stutter and begin anew every time the message is being updated\n    return string\n\n\ndef output_modifier(string):\n    \"\"\"\n    This function is applied to the model outputs.\n    \"\"\"\n\n    global model, current_params, streaming_state\n\n    for i in params:\n        if params[i] != current_params[i]:\n            model = load_model()\n            current_params = params.copy()\n            break\n\n    if not params['activate']:\n        return string\n\n    original_string = string\n    string = tts_preprocessor.preprocess(string)\n\n    if string == '':\n        string = '*Empty reply, try regenerating*'\n    else:\n        output_file = Path(f'extensions/silero_tts/outputs/{shared.character}_{int(time.time())}.wav')\n        prosody = '<prosody rate=\"{}\" pitch=\"{}\">'.format(params['voice_speed'], params['voice_pitch'])\n        silero_input = f'<speak>{prosody}{xmlesc(string)}</prosody></speak>'\n        model.save_wav(ssml_text=silero_input, speaker=params['speaker'], sample_rate=int(params['sample_rate']), audio_path=str(output_file))\n\n        autoplay = 'autoplay' if params['autoplay'] else ''\n        string = f'<audio src=\"file/{output_file.as_posix()}\" controls {autoplay}></audio>'\n        if params['show_text']:\n            string += f'\\n\\n{original_string}'\n\n    shared.processing_message = \"*Is typing...*\"\n    shared.args.no_stream = streaming_state  # restore the streaming option to the previous value\n    return string\n\n\ndef bot_prefix_modifier(string):\n    \"\"\"\n    This function is only applied in chat mode. It modifies\n    the prefix text for the Bot and can be used to bias its\n    behavior.\n    \"\"\"\n\n    return string\n\n\ndef ui():\n    # Gradio elements\n    with gr.Accordion(\"Silero TTS\"):\n        with gr.Row():\n            activate = gr.Checkbox(value=params['activate'], label='Activate TTS')\n            autoplay = gr.Checkbox(value=params['autoplay'], label='Play TTS automatically')\n\n        show_text = gr.Checkbox(value=params['show_text'], label='Show message text under audio player')\n        voice = gr.Dropdown(value=params['speaker'], choices=voices_by_gender, label='TTS voice')\n        with gr.Row():\n            v_pitch = gr.Dropdown(value=params['voice_pitch'], choices=voice_pitches, label='Voice pitch')\n            v_speed = gr.Dropdown(value=params['voice_speed'], choices=voice_speeds, label='Voice speed')\n\n        with gr.Row():\n            convert = gr.Button('Permanently replace audios with the message texts')\n            convert_cancel = gr.Button('Cancel', visible=False)\n            convert_confirm = gr.Button('Confirm (cannot be undone)', variant=\"stop\", visible=False)\n\n    # Convert history with confirmation\n    convert_arr = [convert_confirm, convert, convert_cancel]\n    convert.click(lambda: [gr.update(visible=True), gr.update(visible=False), gr.update(visible=True)], None, convert_arr)\n    convert_confirm.click(lambda: [gr.update(visible=False), gr.update(visible=True), gr.update(visible=False)], None, convert_arr)\n    convert_confirm.click(remove_tts_from_history, [shared.gradio[k] for k in ['name1', 'name2', 'Chat mode']], shared.gradio['display'])\n    convert_confirm.click(lambda: chat.save_history(timestamp=False), [], [], show_progress=False)\n    convert_cancel.click(lambda: [gr.update(visible=False), gr.update(visible=True), gr.update(visible=False)], None, convert_arr)\n\n    # Toggle message text in history\n    show_text.change(lambda x: params.update({\"show_text\": x}), show_text, None)\n    show_text.change(toggle_text_in_history, [shared.gradio[k] for k in ['name1', 'name2', 'Chat mode']], shared.gradio['display'])\n    show_text.change(lambda: chat.save_history(timestamp=False), [], [], show_progress=False)\n\n    # Event functions to update the parameters in the backend\n    activate.change(lambda x: params.update({\"activate\": x}), activate, None)\n    autoplay.change(lambda x: params.update({\"autoplay\": x}), autoplay, None)\n    voice.change(lambda x: params.update({\"speaker\": x}), voice, None)\n    v_pitch.change(lambda x: params.update({\"voice_pitch\": x}), v_pitch, None)\n    v_speed.change(lambda x: params.update({\"voice_speed\": x}), v_speed, None)\n", "path": "extensions/silero_tts/script.py"}], "after_files": [{"content": "import time\nfrom pathlib import Path\n\nimport gradio as gr\nimport torch\nfrom extensions.silero_tts import tts_preprocessor\nfrom modules import chat, shared\nfrom modules.html_generator import chat_html_wrapper\n\ntorch._C._jit_set_profiling_mode(False)\n\n\nparams = {\n    'activate': True,\n    'speaker': 'en_56',\n    'language': 'en',\n    'model_id': 'v3_en',\n    'sample_rate': 48000,\n    'device': 'cpu',\n    'show_text': False,\n    'autoplay': True,\n    'voice_pitch': 'medium',\n    'voice_speed': 'medium',\n    'local_cache_path': ''  # User can override the default cache path to something other via settings.json\n}\n\ncurrent_params = params.copy()\nvoices_by_gender = ['en_99', 'en_45', 'en_18', 'en_117', 'en_49', 'en_51', 'en_68', 'en_0', 'en_26', 'en_56', 'en_74', 'en_5', 'en_38', 'en_53', 'en_21', 'en_37', 'en_107', 'en_10', 'en_82', 'en_16', 'en_41', 'en_12', 'en_67', 'en_61', 'en_14', 'en_11', 'en_39', 'en_52', 'en_24', 'en_97', 'en_28', 'en_72', 'en_94', 'en_36', 'en_4', 'en_43', 'en_88', 'en_25', 'en_65', 'en_6', 'en_44', 'en_75', 'en_91', 'en_60', 'en_109', 'en_85', 'en_101', 'en_108', 'en_50', 'en_96', 'en_64', 'en_92', 'en_76', 'en_33', 'en_116', 'en_48', 'en_98', 'en_86', 'en_62', 'en_54', 'en_95', 'en_55', 'en_111', 'en_3', 'en_83', 'en_8', 'en_47', 'en_59', 'en_1', 'en_2', 'en_7', 'en_9', 'en_13', 'en_15', 'en_17', 'en_19', 'en_20', 'en_22', 'en_23', 'en_27', 'en_29', 'en_30', 'en_31', 'en_32', 'en_34', 'en_35', 'en_40', 'en_42', 'en_46', 'en_57', 'en_58', 'en_63', 'en_66', 'en_69', 'en_70', 'en_71', 'en_73', 'en_77', 'en_78', 'en_79', 'en_80', 'en_81', 'en_84', 'en_87', 'en_89', 'en_90', 'en_93', 'en_100', 'en_102', 'en_103', 'en_104', 'en_105', 'en_106', 'en_110', 'en_112', 'en_113', 'en_114', 'en_115']\nvoice_pitches = ['x-low', 'low', 'medium', 'high', 'x-high']\nvoice_speeds = ['x-slow', 'slow', 'medium', 'fast', 'x-fast']\nstreaming_state = shared.args.no_stream  # remember if chat streaming was enabled\n\n# Used for making text xml compatible, needed for voice pitch and speed control\ntable = str.maketrans({\n    \"<\": \"&lt;\",\n    \">\": \"&gt;\",\n    \"&\": \"&amp;\",\n    \"'\": \"&apos;\",\n    '\"': \"&quot;\",\n})\n\n\ndef xmlesc(txt):\n    return txt.translate(table)\n\n\ndef load_model():\n    torch_cache_path = torch.hub.get_dir() if params['local_cache_path'] == '' else params['local_cache_path']\n    model_path = torch_cache_path + \"/snakers4_silero-models_master/src/silero/model/\" + params['model_id'] + \".pt\"\n    if Path(model_path).is_file():\n        print(f'\\nUsing Silero TTS cached checkpoint found at {torch_cache_path}')\n        model, example_text = torch.hub.load(repo_or_dir=torch_cache_path + '/snakers4_silero-models_master/', model='silero_tts', language=params['language'], speaker=params['model_id'], source='local', path=model_path, force_reload=True)\n    else:\n        print(f'\\nSilero TTS cache not found at {torch_cache_path}. Attempting to download...')\n        model, example_text = torch.hub.load(repo_or_dir='snakers4/silero-models', model='silero_tts', language=params['language'], speaker=params['model_id'])\n    model.to(params['device'])\n    return model\n\n\ndef remove_tts_from_history(name1, name2, mode):\n    for i, entry in enumerate(shared.history['internal']):\n        shared.history['visible'][i] = [shared.history['visible'][i][0], entry[1]]\n    return chat_html_wrapper(shared.history['visible'], name1, name2, mode)\n\n\ndef toggle_text_in_history(name1, name2, mode):\n    for i, entry in enumerate(shared.history['visible']):\n        visible_reply = entry[1]\n        if visible_reply.startswith('<audio'):\n            if params['show_text']:\n                reply = shared.history['internal'][i][1]\n                shared.history['visible'][i] = [shared.history['visible'][i][0], f\"{visible_reply.split('</audio>')[0]}</audio>\\n\\n{reply}\"]\n            else:\n                shared.history['visible'][i] = [shared.history['visible'][i][0], f\"{visible_reply.split('</audio>')[0]}</audio>\"]\n    return chat_html_wrapper(shared.history['visible'], name1, name2, mode)\n\n\ndef input_modifier(string):\n    \"\"\"\n    This function is applied to your text inputs before\n    they are fed into the model.\n    \"\"\"\n\n    # Remove autoplay from the last reply\n    if shared.is_chat() and len(shared.history['internal']) > 0:\n        shared.history['visible'][-1] = [shared.history['visible'][-1][0], shared.history['visible'][-1][1].replace('controls autoplay>', 'controls>')]\n\n    shared.processing_message = \"*Is recording a voice message...*\"\n    shared.args.no_stream = True  # Disable streaming cause otherwise the audio output will stutter and begin anew every time the message is being updated\n    return string\n\n\ndef output_modifier(string):\n    \"\"\"\n    This function is applied to the model outputs.\n    \"\"\"\n\n    global model, current_params, streaming_state\n\n    for i in params:\n        if params[i] != current_params[i]:\n            model = load_model()\n            current_params = params.copy()\n            break\n\n    if not params['activate']:\n        return string\n\n    original_string = string\n    string = tts_preprocessor.preprocess(string)\n\n    if string == '':\n        string = '*Empty reply, try regenerating*'\n    else:\n        output_file = Path(f'extensions/silero_tts/outputs/{shared.character}_{int(time.time())}.wav')\n        prosody = '<prosody rate=\"{}\" pitch=\"{}\">'.format(params['voice_speed'], params['voice_pitch'])\n        silero_input = f'<speak>{prosody}{xmlesc(string)}</prosody></speak>'\n        model.save_wav(ssml_text=silero_input, speaker=params['speaker'], sample_rate=int(params['sample_rate']), audio_path=str(output_file))\n\n        autoplay = 'autoplay' if params['autoplay'] else ''\n        string = f'<audio src=\"file/{output_file.as_posix()}\" controls {autoplay}></audio>'\n        if params['show_text']:\n            string += f'\\n\\n{original_string}'\n\n    shared.processing_message = \"*Is typing...*\"\n    shared.args.no_stream = streaming_state  # restore the streaming option to the previous value\n    return string\n\n\ndef bot_prefix_modifier(string):\n    \"\"\"\n    This function is only applied in chat mode. It modifies\n    the prefix text for the Bot and can be used to bias its\n    behavior.\n    \"\"\"\n\n    return string\n\n\ndef setup():\n    global model\n    model = load_model()\n\n\ndef ui():\n    # Gradio elements\n    with gr.Accordion(\"Silero TTS\"):\n        with gr.Row():\n            activate = gr.Checkbox(value=params['activate'], label='Activate TTS')\n            autoplay = gr.Checkbox(value=params['autoplay'], label='Play TTS automatically')\n\n        show_text = gr.Checkbox(value=params['show_text'], label='Show message text under audio player')\n        voice = gr.Dropdown(value=params['speaker'], choices=voices_by_gender, label='TTS voice')\n        with gr.Row():\n            v_pitch = gr.Dropdown(value=params['voice_pitch'], choices=voice_pitches, label='Voice pitch')\n            v_speed = gr.Dropdown(value=params['voice_speed'], choices=voice_speeds, label='Voice speed')\n\n        with gr.Row():\n            convert = gr.Button('Permanently replace audios with the message texts')\n            convert_cancel = gr.Button('Cancel', visible=False)\n            convert_confirm = gr.Button('Confirm (cannot be undone)', variant=\"stop\", visible=False)\n\n    # Convert history with confirmation\n    convert_arr = [convert_confirm, convert, convert_cancel]\n    convert.click(lambda: [gr.update(visible=True), gr.update(visible=False), gr.update(visible=True)], None, convert_arr)\n    convert_confirm.click(lambda: [gr.update(visible=False), gr.update(visible=True), gr.update(visible=False)], None, convert_arr)\n    convert_confirm.click(remove_tts_from_history, [shared.gradio[k] for k in ['name1', 'name2', 'Chat mode']], shared.gradio['display'])\n    convert_confirm.click(lambda: chat.save_history(timestamp=False), [], [], show_progress=False)\n    convert_cancel.click(lambda: [gr.update(visible=False), gr.update(visible=True), gr.update(visible=False)], None, convert_arr)\n\n    # Toggle message text in history\n    show_text.change(lambda x: params.update({\"show_text\": x}), show_text, None)\n    show_text.change(toggle_text_in_history, [shared.gradio[k] for k in ['name1', 'name2', 'Chat mode']], shared.gradio['display'])\n    show_text.change(lambda: chat.save_history(timestamp=False), [], [], show_progress=False)\n\n    # Event functions to update the parameters in the backend\n    activate.change(lambda x: params.update({\"activate\": x}), activate, None)\n    autoplay.change(lambda x: params.update({\"autoplay\": x}), autoplay, None)\n    voice.change(lambda x: params.update({\"speaker\": x}), voice, None)\n    v_pitch.change(lambda x: params.update({\"voice_pitch\": x}), v_pitch, None)\n    v_speed.change(lambda x: params.update({\"voice_speed\": x}), v_speed, None)\n", "path": "extensions/silero_tts/script.py"}]}