├── .streamlit
└── config.toml
├── README.md
├── __init__.py
├── functions.json
├── launch.bat
├── llmon.py
├── llmon_logo.png
├── main.py
└── page_icon.png
/.streamlit/config.toml:
--------------------------------------------------------------------------------
1 | [client]
2 | toolbarMode = "minimal"
3 |
4 | [theme]
5 | primaryColor="#171717"
6 | backgroundColor="#212121"
7 | secondaryBackgroundColor="#171717"
8 | textColor="#e4dede"
9 | font="monospace"
10 |
11 | [runner]
12 | fastReruns = true
13 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | llmon-py is a WIP multimodal webui for inferencing Llama3-8B via text, voice and function calling.
4 |
5 | 
6 |
--------------------------------------------------------------------------------
/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3eeps/llmon-py/20321828351440b778736400707f82435804b5a1/__init__.py
--------------------------------------------------------------------------------
/functions.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name": "no_function_message",
4 | "description": "Reply to user message when the function calls below do not matches the users query.",
5 | "parameters": {
6 | "type": "object",
7 | "properties": {
8 | "user_message": {
9 | "type": "string",
10 | "description": "Message from the user."
11 | }
12 | },
13 | "required": ["user_message"]
14 | }
15 | },
16 | {
17 | "name": "change_voice_style",
18 | "description": "Allows the user to change the tone and style of the current text to speech model based on a prompt.",
19 | "parameters": {
20 | "type": "object",
21 | "properties": {
22 | "voice_style": {
23 | "type": "string",
24 | "description": "Style description from the user. Example: A male voice that is calm but stern."
25 | }
26 | },
27 | "required": ["voice_style"]
28 | }
29 | },
30 | {
31 | "name": "describe_image",
32 | "description": "Answer user query about an image.",
33 | "parameters": {
34 | "type": "object",
35 | "properties": {
36 | "user_query": {
37 | "type": "string",
38 | "description": "The query provided by the user."
39 | }
40 | },
41 | "required": ["user_query"]
42 | }
43 | },
44 | {
45 | "name": "create_image",
46 | "description": "Generate an image from a prompt.",
47 | "parameters": {
48 | "type": "object",
49 | "properties": {
50 | "image_prompt": {
51 | "type": "string",
52 | "description": "The prompt required to generate image."
53 | }
54 | },
55 | "required": ["image_prompt"]
56 | }
57 | },
58 | {
59 | "name": "video_player",
60 | "description": "Retrieve YouTube query and play the video in the chat.",
61 | "parameters": {
62 | "type": "object",
63 | "properties": {
64 | "youtube_query": {
65 | "type": "string",
66 | "description": "The YouTube query provided by the user."
67 | }
68 | },
69 | "required": ["youtube_query"]
70 | }
71 | }
72 | ]
73 |
--------------------------------------------------------------------------------
/launch.bat:
--------------------------------------------------------------------------------
1 | cd *where main.py is*
2 | streamlit run main.py
3 |
--------------------------------------------------------------------------------
/llmon.py:
--------------------------------------------------------------------------------
1 | import streamlit as st
2 | import os
3 | import sounddevice
4 | import psutil
5 | import json
6 | import base64
7 | from time import sleep
8 | import keyboard
9 | from scipy.io.wavfile import write as write_wav
10 | from googlesearch import search
11 | from transformers import AutoTokenizer
12 | import torch
13 | import torchaudio
14 | from diffusers import StableDiffusion3Pipeline
15 | import soundfile as sf
16 | from parler_tts import ParlerTTSForConditionalGeneration
17 | from TTS.tts.configs.xtts_config import XttsConfig
18 | from TTS.tts.models.xtts import Xtts
19 |
20 | def model_inference(prompt=""):
21 | if st.session_state.function_calling:
22 | st.session_state['model_temperature'] = 0.85
23 | st.session_state['model_min_p'] = 0.06
24 | st.session_state['model_top_p'] = 0.0
25 | st.session_state['model_top_k'] = 0
26 | st.session_state['repeat_penalty'] = 1.1
27 |
28 | if st.session_state['model_select'] == 'DeepSeek-Coder-V2-Lite-Instruct-Q5_K_M.gguf':
29 | st.session_state['model_temperature'] = 0.1
30 | st.session_state['model_min_p'] = 0.06
31 | st.session_state['model_top_p'] = 0.0
32 | st.session_state['model_top_k'] = 0
33 | st.session_state['repeat_penalty'] = 1.1
34 |
35 | model_output = st.session_state["chat_model"](prompt=prompt,
36 | max_tokens=st.session_state['max_context'] - st.session_state.token_count,
37 | repeat_penalty=float(st.session_state['repeat_penalty']),
38 | top_k=int(st.session_state['model_top_k']),
39 | top_p=float(st.session_state['model_top_p']),
40 | min_p=float(st.session_state['model_min_p']),
41 | temperature=float(st.session_state['model_temperature']))
42 | return model_output['choices'][0]['text'], model_output['usage']['total_tokens']
43 |
44 | def clear_vram():
45 | try:
46 | del st.session_state['sd3_medium']
47 | except: pass
48 | del st.session_state['chat_model']
49 |
50 | def stream_text(text="", delay=0.03):
51 | for word in text.split(" "):
52 | yield word + " "
53 | sleep(delay)
54 |
55 | def init_state():
56 | default_settings_state = {
57 | 'max_context': 8192,
58 | 'gpu_layer_count': -1,
59 | 'cpu_core_count': 8,
60 | 'cpu_batch_count': 8,
61 | 'batch_size': 256,
62 | 'model_temperature': 0.85,
63 | 'model_top_p': 0.0,
64 | 'model_top_k': 0,
65 | 'model_min_p': 0.05,
66 | 'repeat_penalty': 1.1,
67 | 'message_list': [],
68 | 'init_app': False,
69 | 'model_select': None}
70 |
71 | st.session_state.model_list = ['Meta-Llama-3-8B-Instruct.Q6_K.gguf', 'DeepSeek-Coder-V2-Lite-Instruct-Q5_K_M.gguf']
72 | st.session_state.show_generated_image = False
73 | st.session_state.show_uploaded_image = False
74 | st.session_state.bytes_data = ""
75 | st.session_state.sdxl_base64 = ""
76 | st.session_state.model_param_settings = False
77 | st.session_state.token_count = 0
78 | st.session_state.start_app = False
79 | st.session_state.function_calling = False
80 | st.session_state.function_results = ""
81 | st.session_state.custom_template = ""
82 | st.session_state.video_link = ""
83 | st.session_state.user_chat = False
84 | st.session_state.new_voice_reply = ""
85 |
86 | with open("functions.json", "r") as file:
87 | st.session_state.functions = json.load(file)
88 |
89 | for key, value in default_settings_state.items():
90 | if key not in st.session_state:
91 | st.session_state[key] = value
92 |
93 | def hide_deploy_button():
94 | st.markdown(
95 | r"""
96 |
101 | """, unsafe_allow_html=True)
102 |
103 | def load_conversation():
104 | with open('messsage_list.json', 'r') as file:
105 | st.session_state['message_list'] = json.load(file)
106 | with open('streamlit_list.json', 'r') as file:
107 | st.session_state.messages = json.load(file)
108 |
109 | def save_conversation(message_list, streamlit_message_list):
110 | with open('messsage_list.json', 'w') as file:
111 | json.dump(message_list, file)
112 | with open('streamlit_list.json', 'w') as file:
113 | json.dump(streamlit_message_list, file)
114 |
115 | def unload_model():
116 | sleep(0.5)
117 | del st.session_state['chat_model']
118 |
119 | def sidebar():
120 | col1, col2, col3 = st.columns([3,1,1])
121 | with col1:
122 | st.title('🍋 llmon-py')
123 | with col2:
124 | if st.button(label="📂", help='load previous conversation'):
125 | load_conversation()
126 | with col3:
127 | if st.button(label='✨', help='start a new chat'):
128 | save_conversation(message_list=st.session_state['message_list'], streamlit_message_list=st.session_state.messages)
129 | st.session_state['message_list'] = []
130 | st.session_state.messages = []
131 | st.session_state.bytes_data = None
132 | st.session_state.sdxl_base64 = None
133 | st.session_state.function_calling = False
134 | st.session_state.custom_template = ""
135 | st.session_state.token_count = 0
136 | st.session_state.video_link = None
137 |
138 | loaded_model_title = ""
139 | if st.session_state['model_select'] == 'DeepSeek-Coder-V2-Lite-Instruct-Q5_K_M.gguf':
140 | loaded_model_title = "deepseek-coder-v2"
141 | if st.session_state['model_select'] == 'Meta-Llama-3-8B-Instruct.Q6_K.gguf':
142 | loaded_model_title = "meta-llama-3"
143 | st.caption(f"running :green[{loaded_model_title}]")
144 | st.caption("")
145 |
146 | #st.session_state['model_select'] = st.selectbox(label='model list', options=st.session_state.model_list, label_visibility='hidden', help='load your model of choice', on_change=unload_model)
147 | uploaded_file = st.file_uploader(label='file uploader', label_visibility='collapsed', type=['png', 'jpeg'], disabled=True)
148 | if uploaded_file:
149 | st.session_state.bytes_data = uploaded_file.getvalue()
150 | with open("ocr_upload_image.png", 'wb') as file:
151 | file.write(st.session_state.bytes_data)
152 |
153 | with open("ocr_upload_image.png", "rb") as f:
154 | st.session_state.bytes_data = base64.b64encode(f.read()).decode()
155 | os.remove('ocr_upload_image.png')
156 |
157 | st.caption(body="custom model template")
158 | st.session_state.custom_template = st.text_area(label='custom prompt', value="", label_visibility='collapsed')
159 | disable_function_call = False
160 | if st.session_state['model_select'] == 'DeepSeek-Coder-V2-Lite-Instruct-Q5_K_M.gguf':
161 | disable_function_call = True
162 | st.session_state.function_calling = st.checkbox(':orange[enable function calling] :green[(beta)]', value=st.session_state.function_calling, help='currently allows user to :green[generate images and find youtube videos]. may not produce desired output.', disabled=disable_function_call)
163 | st.session_state.model_param_settings = st.checkbox(':orange[model parameters]', value=st.session_state.model_param_settings, help='tweak model parameters to steer llama-3s output.')
164 | if st.session_state.model_param_settings:
165 | st.caption(f"ctx:{st.session_state.token_count}/{st.session_state['max_context']}")
166 | temp_help = "determinines whether the output is more random and creative or more predictable. :green[a higher temperature will result in lower probability], i.e more creative outputs."
167 | top_p_help = "controls the diversity of the generated text by only considering tokens with the highest probability mass. :green[top_p = 0.1: only tokens within the top 10% probability are considered. 0.9: considers tokens within the top 90% probability]."
168 | top_k_help = "limits the model's output to the top-k most probable tokens at each step. This can help reduce incoherent or nonsensical output by restricting the model's vocabulary. :green[a top-K of 1 means the next selected token is the most probable among all tokens in the model's vocabulary]."
169 | min_p_help = "different from top k or top p, sets a minimum percentage requirement to consider tokens relative to the largest token probability. :green[for example, min p = 0.1 is equivalent to only considering tokens at least 1/10th the top token probability]."
170 | rep_help = "helps the model generate more diverse content instead of repeating previous phrases. Repetition is prevented by applying a high penalty to phrases or words that tend to be repeated. :green[a higher penalty generally results in more diverse outputs, whilst a lower value might lead to more repetition]."
171 | st.session_state['model_temperature'] = st.text_input(label=':orange[temperature]', value=st.session_state['model_temperature'], help=temp_help)
172 | st.session_state['model_top_p'] = st.text_input(label=':orange[top p]', value=st.session_state['model_top_p'], help=top_p_help)
173 | st.session_state['model_top_k'] = st.text_input(label=':orange[top k]', value=st.session_state['model_top_k'], help=top_k_help)
174 | st.session_state['model_min_p'] = st.text_input(label=':orange[min p]', value=st.session_state['model_min_p'], help=min_p_help)
175 | st.session_state['repeat_penalty'] = st.text_input(label=':orange[repetition penalty]', value=st.session_state['repeat_penalty'], help=rep_help)
176 |
177 | bottom_col1, bottom_col2, bottom_col3 = st.columns([1,1,1])
178 | with bottom_col2:
179 | if st.button(":orange[shutdown]", help='shut down app on server side'):
180 | shut_down_app()
181 |
182 | def shut_down_app():
183 | save_conversation(message_list=st.session_state['message_list'], streamlit_message_list=st.session_state.messages)
184 | if st.session_state.start_app:
185 | clear_vram()
186 | try:
187 | os.remove('image.txt')
188 | except: pass
189 | try:
190 | os.remove('.google-cookie')
191 | except: pass
192 | keyboard.press_and_release('ctrl+w')
193 | llmon_process_id = os.getpid()
194 | process = psutil.Process(llmon_process_id)
195 | process.terminate()
196 |
197 | class ChatTemplate:
198 | def chat_template(prompt="", function_result=""):
199 | system_message = ""
200 | template = ""
201 | if st.session_state['model_select'] == 'Meta-Llama-3-8B-Instruct.Q6_K.gguf':
202 | system_message = f"""You are an helpful AI assistant, answer any request the user may have. Share postive or negative considerations when appropriate, but keep them concise. Conversation history: {st.session_state['message_list']}"""
203 | template = f"""<|begin_of_text|<|start_header_id|>system<|end_header_id|>{system_message}<|eot_id|><|start_header_id|>user<|end_header_id|>{prompt}<|eot_id|><|start_header_id|>assistant<|end_header_id|>"""
204 | if st.session_state['model_select'] == 'DeepSeek-Coder-V2-Lite-Instruct-Q5_K_M.gguf':
205 | system_message = f"""You are an helpful AI coding assistant, answer any request the user may have. Chat history: {st.session_state['message_list']}"""
206 | template = f"""<|begin▁of▁sentence|>{system_message}
207 |
208 | User: {prompt}
209 |
210 | Assistant: <|end▁of▁sentence|>Assistant:"""
211 |
212 | #if st.session_state.function_calling:
213 | # system_message = f"""As an AI model with function calling support, you are provided with the following functions: {json.dumps(st.session_state.functions)}
214 | # When the user asks a question that can be answered with a function, do not describe the function or wrap the function in "||", output the function filled with the appropriate data required as a Python dictionary."""
215 | # system_message_plus_example = """Example message: 'Hello there!' Your reply: '{'function_name': 'user_chat', 'parameters': {'user_message': 'Hello there!'}}'"""
216 |
217 | if st.session_state.function_calling:
218 | system_message = f"""As an AI model with function calling support, you are provided with the following functions: {json.dumps(st.session_state.functions)}
219 | When the user asks a question that can be answered with a function, please do not describe the function. Only output the function filled with the appropriate data required as a Python style dictionary."""
220 | system_message_plus_example = """Example: User: 'play brother ali take me home' Your reply: '{'function_name': 'video_player', 'parameters': {'youtube_query': 'play brother ali take me home'}}'"""
221 | template = f"""<|begin_of_text|<|start_header_id|>system<|end_header_id|>{system_message + system_message_plus_example}<|eot_id|><|start_header_id|>user<|end_header_id|>{prompt}<|eot_id|><|start_header_id|>assistant<|end_header_id|>"""
222 |
223 | if len(function_result) > 1:
224 | system_message = f"""Using this data that is up to date, reply to the user using it: {function_result}. The question the user asked was:"""
225 | template = f"""<|begin_of_text|<|start_header_id|>system<|end_header_id|>{system_message}<|eot_id|><|start_header_id|>user<|end_header_id|>{prompt}<|eot_id|><|start_header_id|>assistant<|end_header_id|>"""
226 |
227 | if len(st.session_state.custom_template) > 1:
228 | system_message = f"""{st.session_state.custom_template} Chat history: {st.session_state['message_list']}"""
229 | template = f"""<|begin_of_text|<|start_header_id|>system<|end_header_id|>{system_message}<|eot_id|><|start_header_id|>user<|end_header_id|>{prompt}<|eot_id|><|start_header_id|>assistant<|end_header_id|>"""
230 |
231 | return template
232 |
233 | class Audio:
234 | def voice_to_text():
235 | rec_user_voice = sounddevice.rec(int(st.session_state['user_audio_length']) * 44100, samplerate=44100, channels=2)
236 | sounddevice.wait()
237 | write_wav(filename='user_output.wav', rate=44100, data=rec_user_voice)
238 | user_voice_data = st.session_state['speech_tt_model'].transcribe('user_output.wav', speed_up=True)
239 | os.remove(f"user_output.wav")
240 | text_data = []
241 | for voice in user_voice_data:
242 | text_data.append(voice.text)
243 | combined_text = ' '.join(text_data)
244 | return combined_text
245 |
246 | class Functions:
247 | def find_youtube_link(user_query):
248 | search_helper = 'youtube'
249 | search_query = user_query + search_helper
250 | for youtube_link in search(query=search_query, tld="co.in", num=1, stop=1, pause=2):
251 | print(youtube_link)
252 | return youtube_link
253 | return 'https://www.youtube.com/watch?v=dQw4w9WgXcQ'
254 |
255 | def change_llm_voice(voice_description):
256 | #load models
257 | device = "cuda:0"
258 | model = ParlerTTSForConditionalGeneration.from_pretrained("parler-tts/parler_tts_mini_v0.1").to(device, dtype=torch.float32)
259 | tokenizer = AutoTokenizer.from_pretrained("parler-tts/parler_tts_mini_v0.1")
260 |
261 | config = XttsConfig()
262 | config.load_json("./xtts_model/config.json")
263 | model = Xtts.init_from_config(config)
264 | model.load_checkpoint(config, checkpoint_dir="./xtts_model/")
265 | model.cuda()
266 |
267 | style_prompt = "It took me quite a long time to develop a voice and now that I have it I am not going to be silent."
268 |
269 |
270 | #### easy way!!!! make style voice here... use the voice with built in tts, even if its slow
271 | #### trick!!! when using tts... ask the llm to keep anwers very brief. less then a paragraph. should help inference time!
272 |
273 |
274 |
275 | #run parlor with user voice description
276 | input_ids = tokenizer(voice_description, return_tensors="pt").input_ids.to(device)
277 | prompt_input_ids = tokenizer(style_prompt, return_tensors="pt").input_ids.to(device)
278 | generation = model.generate(input_ids=input_ids, prompt_input_ids=prompt_input_ids).to(torch.float32)
279 | audio_arr = generation.cpu().numpy().squeeze()
280 | sf.write("new_voice_style.wav", audio_arr, model.config.sampling_rate)
281 |
282 | # send new voice style to xtts to say 'how is it?' trick :P
283 | language = 'en'
284 | #st.session_state.new_voice_reply = model_inference(prompt=f"The user has changed your text to speech voice! Here is the voice description from the user: {voice_description}. Say something fun to show off your new voice!")
285 | gpt_cond_latent, speaker_embedding = model.get_conditioning_latents(audio_path=["new_voice_style.wav"])
286 | tts_chunks = model.inference_stream(
287 | prompt,
288 | language,
289 | gpt_cond_latent,
290 | speaker_embedding)
291 |
292 | chunk_list = []
293 | for i, chunk in enumerate(tts_chunks):
294 | chunk_list.append(chunk)
295 | print(f"Received chunk {i} of audio length {chunk.shape[-1]}")
296 | wav_chunk = torch.cat(chunk_list, dim=0)
297 | torchaudio.save("new_llm_final_voice.wav", wav_chunk.squeeze().unsqueeze(0).cpu(), 24000)
298 | return st.session_state.new_voice_reply
299 |
300 | class SD3Medium:
301 | def init():
302 | st.session_state['sd3_medium'] = StableDiffusion3Pipeline.from_pretrained(
303 | "stabilityai/stable-diffusion-3-medium-diffusers", torch_dtype=torch.float16,
304 | text_encoder_3=None,
305 | tokenizer_3=None
306 | ).to("cuda")
307 |
308 | def generate_image(prompt=""):
309 | image = st.session_state['sd3_medium'](
310 | prompt,
311 | negative_prompt="",
312 | num_inference_steps=28,
313 | guidance_scale=7.0
314 | ).images[0]
315 | image.save('image_sd3.png')
316 |
317 | with open("image_sd3.png", "rb") as f:
318 | st.session_state.sdxl_base64 = base64.b64encode(f.read()).decode()
319 | os.remove('image_sd3.png')
--------------------------------------------------------------------------------
/llmon_logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3eeps/llmon-py/20321828351440b778736400707f82435804b5a1/llmon_logo.png
--------------------------------------------------------------------------------
/main.py:
--------------------------------------------------------------------------------
1 | import streamlit as st
2 | st.set_page_config(page_title="llmon-py", page_icon="page_icon.png", layout="centered", initial_sidebar_state="collapsed")
3 | lcol1, lcol2, lcol3 = st.columns([1,1,1])
4 | with lcol2:
5 | with st.spinner('🍋 initializing...'):
6 | import llmon
7 | from pywhispercpp.model import Model
8 | from llama_cpp import Llama
9 |
10 | llmon.hide_deploy_button()
11 | if 'init_app' not in st.session_state:
12 | llmon.init_state()
13 | if st.session_state.init_app == False:
14 | col1, col2, col3 = st.columns([1,1,1])
15 | with col2:
16 | st.write('🍋 welcome to llmon-py!')
17 | model_picked = st.selectbox(label='first model list', options=st.session_state.model_list, label_visibility='hidden')
18 | if st.button(":orange[click here to start!]"):
19 | st.session_state['model_select'] = model_picked
20 | st.session_state.start_app = True
21 | st.session_state.init_app = True
22 | st.rerun()
23 |
24 | lcol1, lcol2, lcol3 = st.columns([1,1,1])
25 | with lcol2:
26 | with st.spinner('🍋 loading your model...'):
27 | if "messages" not in st.session_state and st.session_state.start_app:
28 | st.session_state.messages = []
29 |
30 | if "chat_model" not in st.session_state and st.session_state.start_app:
31 | st.session_state["chat_model"] = Llama(model_path=f"./{st.session_state['model_select']}",
32 | n_batch=st.session_state['batch_size'],
33 | n_threads=st.session_state['cpu_core_count'],
34 | n_threads_batch=st.session_state['cpu_batch_count'],
35 | n_gpu_layers=int(st.session_state['gpu_layer_count']),
36 | n_ctx=st.session_state['max_context'])
37 |
38 | #if "sd3_medium" not in st.session_state and st.session_state.start_app and st.session_state['model_select'] != 'DeepSeek-Coder-V2-Lite-Instruct-Q5_K_M.gguf':
39 | #llmon.SD3Medium.init()
40 |
41 | if 'speech_tt_model' not in st.session_state and st.session_state.start_app:
42 | st.session_state['speech_tt_model'] = Model(models_dir='./speech models', n_threads=10)
43 |
44 | if st.session_state.start_app:
45 | with st.sidebar:
46 | llmon.sidebar()
47 | for message in st.session_state.messages:
48 | with st.chat_message(name=message['role']):
49 | try:
50 | st.markdown(f"""
""", unsafe_allow_html=True)
51 | except: pass
52 | st.write(message["content"])
53 |
54 | if user_text_input:= st.chat_input(placeholder=''):
55 | user_input = user_text_input
56 | if user_input == " ":
57 | try: user_input = llmon.Audio.voice_to_text()
58 | except: pass
59 |
60 | with st.chat_message(name="user"):
61 | st.write(user_input)
62 | if st.session_state.show_uploaded_image:
63 | st.session_state.messages.append({"role": "user", "content": user_input, "image": st.session_state.bytes_data})
64 | elif st.session_state.show_uploaded_image == False:
65 | st.session_state.messages.append({"role": "user", "content": user_input})
66 |
67 | st.session_state['message_list'].append(f"""user: {user_input}""")
68 | st.session_state.show_uploaded_image = False
69 |
70 | with st.spinner('🍋 generating...'):
71 | final_template = llmon.ChatTemplate.chat_template(prompt=user_input)
72 | model_output_text, st.session_state.token_count = llmon.model_inference(prompt=final_template)
73 | user_chat = False
74 | if st.session_state.function_calling:
75 | try:
76 | model_output_dict = eval(model_output_text)
77 | model_dict_values = [value for key, value in model_output_dict.items()]
78 | func_value_dict = model_dict_values.pop(1)
79 | output_function = model_dict_values.pop(0)
80 | value_name = [value for key, value in func_value_dict.items()]
81 | print(f"""{model_output_dict}\n{func_value_dict}\n{output_function}\n{value_name}""")
82 |
83 | if output_function == "no_function_message":
84 | user_chat = True
85 | text_output = True
86 |
87 | if output_function == "change_voice_style":
88 | llmon.Functions.change_llm_voice(voice_description=value_name[0])
89 | voice_reply = True
90 |
91 | if output_function == "describe_image":
92 | st.session_state.show_uploaded_image = True
93 | text_output = True
94 |
95 | if output_function == "create_image":
96 | llmon.SD3Medium.generate_image(prompt=value_name[0])
97 | st.session_state.show_generated_image = True
98 |
99 | if output_function == "video_player":
100 | st.session_state.video_link = llmon.Functions.find_youtube_link(user_query=value_name[0])
101 |
102 | final_function_template = llmon.ChatTemplate.chat_template(prompt=user_input, function_result=st.session_state.function_results)
103 | model_output_text = ""
104 | if user_chat:
105 | st.session_state.function_calling = False
106 | final_template = llmon.ChatTemplate.chat_template(prompt=user_input)
107 | model_output_text, st.session_state.token_count = llmon.model_inference(prompt=final_template)
108 | st.session_state.function_calling = True
109 | if text_output and user_chat == False:
110 | model_output_text, st.session_state.token_count = llmon.model_inference(prompt=final_function_template)
111 | if voice_reply:
112 | st.session_state.function_calling = False
113 | voice_prompt = f"Pretend that I just gave you a new text to speech voice with this description: {value_name[0]}. Say something fun to show it off!"
114 | final_template = llmon.ChatTemplate.chat_template(prompt=voice_prompt)
115 | model_output_text, st.session_state.token_count = llmon.model_inference(prompt=final_function_template)
116 | st.session_state.function_calling = True
117 | except: pass
118 |
119 | with st.chat_message(name="assistant"):
120 | st.write_stream(llmon.stream_text(text=model_output_text))
121 | if st.session_state.show_generated_image:
122 | st.markdown(f"""
""", unsafe_allow_html=True)
123 | st.session_state.messages.append({"role": "assistant", "content": model_output_text, "image": st.session_state.sdxl_base64})
124 | st.session_state['message_list'].append(f"You: Generated an image based on the users request.")
125 |
126 | if st.session_state.show_generated_image == False:
127 | st.session_state.messages.append({"role": "assistant", "content": model_output_text})
128 | st.session_state['message_list'].append(f"You: {model_output_text}")
129 |
130 | if st.session_state.video_link:
131 | st.video(data=st.session_state.video_link)
132 | st.session_state.messages.append({"role": "assistant", "content": f"{st.session_state.video_link}"})
133 | st.session_state['message_list'].append(f"You: Displayed a Youtube video based on the users search request.")
134 |
135 | st.session_state.show_generated_image = False
136 | st.session_state.video_link = None
--------------------------------------------------------------------------------
/page_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/3eeps/llmon-py/20321828351440b778736400707f82435804b5a1/page_icon.png
--------------------------------------------------------------------------------