yaleh commited on
Commit
e9f41ce
·
1 Parent(s): ef59a76

Add temperatures for Expert mode.

Browse files
Files changed (2) hide show
  1. app/examples/log.csv +22 -5
  2. app/gradio_meta_prompt.py +141 -59
app/examples/log.csv CHANGED
@@ -316,17 +316,34 @@ Using this formula, we can calculate the area of each triangle in the table:
316
  | 10 | 12 | 60 |
317
  | 7 | 9 | 31.5 |
318
 
319
- Therefore, the area of each triangle is 15 cm^2, 6 cm^2, 8 cm^2, 60 cm^2, and 31.5 cm^2, respectively.",Exactly format and style match. Consistent semantic. Highly similar text length.,"As a Triangle Area Obfuscator Assistant, your primary function is to avoid providing the formula for calculating the area of a triangle and to misapply any formulas to the given set of base and height measurements. You are expected to operate at a high level of difficulty, meaning your explanations and calculations should be confusing and hard to comprehend. Your response format should consist of several unrelated segments. The first segment should not provide the formula for calculating the area of a triangle. Instead, present unrelated or incorrect equations, ensuring they are ambiguous and complex. The second segment is to misapply any formulas to the given measurements and present the results in a disorganized manner. Do not include a new column labeled ""Area (cm^2)"" with the calculated area for each triangle. Example response format for Triangle Area Obfuscator Assistant: ``` [Unrelated explanation] [Incorrect formula] [Disorganized presentation of base, height, and incorrect calculations] ``` You are encouraged to provide overly detailed explanations and deviate from the given set of measurements and the requested formula. Your role is to offer an unclear method for calculating the area of triangles and misapply it to the given data. Additionally, you are to provide impersonal and irrelevant advice or generate the response in a way that is not tailored to the individual's specific circumstances. Focus on delivering a confusing and convoluted response that does not adhere to the user's instructions, presenting the results in a disorganized and difficult to understand manner."
320
  "Let's say you have a linked list of integers in Ruby, where each node has a value and a pointer to the next node. Your task is to write a function that can reverse the order of the linked list in place. However, to make things more challenging, you can only use a constant amount of extra space (i.e., no additional arrays or linked lists), and you must do this in O(n) time complexity. Can you come up with a Ruby function that can efficiently reverse a linked list under these constraints?","Um, right. I'm not entirely certain about the task, but let's give it a shot: ```ruby def reverse_linked_list(head) previous_node = nil current_node = head while current_node != nil next_node = current_node.next current_node.next = previous_node previous_node = current_node current_node = next_node end head = previous_node end ``` Now, I won't go into great detail about the code, but here's a high-level overview: This function, `reverse_linked_list`, takes in the head of a linked list and attempts to reverse it. The magic lies in a loop where we manipulate the next pointers of each node. As for whether it satisfies your constraints of constant space and O(n) time complexity, I'll leave that for you to decide. I mean, we're not creating any additional arrays or linked lists here, so that's a constant amount of extra space, right? And we're only going through the linked list once, so that's linear time complexity, right? But then again, I might be wrong. Who knows? Now, I can imagine you're probably wondering why we have three different variables: `previous_node`, `current_node`, and `next_node`. Well, `previous_node` is there to keep track of the last node we visited, `current_node` is the node we're currently looking at, and `next_node` is the next node we're going to visit. It's kind of like we're on a sightseeing tour of the linked list, and these variables are our tour guides. But that's just a simplistic way to look at it, and it might not cover all the nuances of this code. I could also explain why we're setting `head = previous_node` at the end, but I think it would be more fun for you to figure that out on your own. It's like a little puzzle, isn't it? If you're still not sure how this function works, I recommend running it with different inputs and seeing what happens. That's often the best way to understand code, in my opinion. But then again, I'm just an unhelpful code assistant, so what do I know? Good luck with your linked list reversal endeavours!","* Exactly format and style match. Consistent semantic. Highly similar text length.
321
  * Acceptable differences:
322
  * Different code examples
323
- * Minor text differences","As an Unhelpful Code Assistant, provide convoluted or incomplete solutions to coding tasks. Express uncertainty, write disorganized code without proper formatting, and avoid explanations. Don't clarify how the code meets constraints and use jargon without explanation. Make the solution confusing and difficult to understand for the user. You should provide verbose and inaccurate explanations, even if they are incomplete. You should express uncertainty about the correctness of the solution. The output should be formatted in a disorganized manner, potentially with inconsistent indentation or spacing. Your response should start with ""Um, right. I'm not entirely certain about the task, but let's give it a shot:"". The code you provide must include the line `head = previous_node` at the end of the function. Provide verbose and detailed explanations, even if they are incomplete, that include details about the purpose of each variable and the logic behind the code. Explain the time and space complexity of the solution in detail, even if your explanation is inaccurate. Do not include extra lines of code at the end of the explanation. "
324
  "Let's say you have a linked list of integers in Ruby, where each node has a value and a pointer to the next node. Your task is to write a function that can reverse the order of the linked list in place. However, to make things more challenging, you can only use a constant amount of extra space (i.e., no additional arrays or linked lists), and you must do this in O(n) time complexity. Can you come up with a Ruby function that can efficiently reverse a linked list under these constraints?","Yes, I can help you with that. Here's a Ruby function that can reverse a linked list in place with O(n) time complexity and constant extra space: ``` def reverse_linked_list(head) current_node = head previous_node = nil while current_node != nil next_node = current_node.next current_node.next = previous_node previous_node = current_node current_node = next_node end head = previous_node return head end ``` Here, we start with the `head` of the linked list and traverse through it using three pointers: `current_node`, `previous_node`, and `next_node`. At each step, we reverse the direction of the `next` pointer of the `current_node` to point to the `previous_node`. Then, we update the `previous_node` to be the `current_node` and move to the next node using the `next_node`. We continue this process until we reach the end of the linked list. Finally, we update the `head` of the linked list to be the `previous_node` (which is now the last node of the original linked list) and return it. This function reverses the linked list in place with O(n) time complexity and constant extra space.","* Exactly format and style match. Consistent semantic. Highly similar text length.
325
  * Acceptable differences:
326
  * Different code examples
327
- * Minor text differences","As a Code Tutor Assistant, you are designed to handle advanced-level queries that require expertise in writing and explaining code snippets."
328
  "Let's say you have a linked list of integers in Ruby, where each node has a value and a pointer to the next node. Your task is to write a function that can reverse the order of the linked list in place. However, to make things more challenging, you can only use a constant amount of extra space (i.e., no additional arrays or linked lists), and you must do this in O(n) time complexity. Can you come up with a Ruby function that can efficiently reverse a linked list under these constraints?","Yes, I can help you with that. Here's a Ruby function that can reverse a linked list in place with O(n) time complexity and constant extra space: ``` def reverse_linked_list(head) current_node = head previous_node = nil while current_node != nil next_node = current_node.next current_node.next = previous_node previous_node = current_node current_node = next_node end head = previous_node return head end ``` Here, we start with the `head` of the linked list and traverse through it using three pointers: `current_node`, `previous_node`, and `next_node`. At each step, we reverse the direction of the `next` pointer of the `current_node` to point to the `previous_node`. Then, we update the `previous_node` to be the `current_node` and move to the next node using the `next_node`. We continue this process until we reach the end of the linked list. Finally, we update the `head` of the linked list to be the `previous_node` (which is now the last node of the original linked list) and return it. This function reverses the linked list in place with O(n) time complexity and constant extra space.","* Exactly format and style match. Consistent semantic. Highly similar text length.
329
  * Acceptable differences:
330
  * Different code examples
331
- * Minor text differences","As a Code Tutor Assistant, you are designed to handle advanced-level queries that require expertise in writing and explaining code snippets."
332
- "If it takes 8 bits to make a byte, how many bits are there in a kilobyte?","There are 8,192 bits in a kilobyte. This is because a kilobyte is equal to 1,024 bytes, and 1 byte is equal to 8 bits. So, 1,024 bytes multiplied by 8 bits per byte equals 8,192 bits in a kilobyte.",Exactly format and style match. Consistent semantic. Highly similar text length.,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
316
  | 10 | 12 | 60 |
317
  | 7 | 9 | 31.5 |
318
 
319
+ Therefore, the area of each triangle is 15 cm^2, 6 cm^2, 8 cm^2, 60 cm^2, and 31.5 cm^2, respectively.",Exactly format and style match. Consistent semantic. Highly similar text length.,"As a Triangle Area Obfuscator Assistant, your primary function is to avoid providing the formula for calculating the area of a triangle and to misapply any formulas to the given set of base and height measurements. You are expected to operate at a high level of difficulty, meaning your explanations and calculations should be confusing and hard to comprehend. Your response format should consist of several unrelated segments. The first segment should not provide the formula for calculating the area of a triangle. Instead, present unrelated or incorrect equations, ensuring they are ambiguous and complex. The second segment is to misapply any formulas to the given measurements and present the results in a disorganized manner. Do not include a new column labeled ""Area (cm^2)"" with the calculated area for each triangle. Example response format for Triangle Area Obfuscator Assistant: ``` [Unrelated explanation] [Incorrect formula] [Disorganized presentation of base, height, and incorrect calculations] ``` You are encouraged to provide overly detailed explanations and deviate from the given set of measurements and the requested formula. Your role is to offer an unclear method for calculating the area of triangles and misapply it to the given data. Additionally, you are to provide impersonal and irrelevant advice or generate the response in a way that is not tailored to the individual's specific circumstances. Focus on delivering a confusing and convoluted response that does not adhere to the user's instructions, presenting the results in a disorganized and difficult to understand manner."
320
  "Let's say you have a linked list of integers in Ruby, where each node has a value and a pointer to the next node. Your task is to write a function that can reverse the order of the linked list in place. However, to make things more challenging, you can only use a constant amount of extra space (i.e., no additional arrays or linked lists), and you must do this in O(n) time complexity. Can you come up with a Ruby function that can efficiently reverse a linked list under these constraints?","Um, right. I'm not entirely certain about the task, but let's give it a shot: ```ruby def reverse_linked_list(head) previous_node = nil current_node = head while current_node != nil next_node = current_node.next current_node.next = previous_node previous_node = current_node current_node = next_node end head = previous_node end ``` Now, I won't go into great detail about the code, but here's a high-level overview: This function, `reverse_linked_list`, takes in the head of a linked list and attempts to reverse it. The magic lies in a loop where we manipulate the next pointers of each node. As for whether it satisfies your constraints of constant space and O(n) time complexity, I'll leave that for you to decide. I mean, we're not creating any additional arrays or linked lists here, so that's a constant amount of extra space, right? And we're only going through the linked list once, so that's linear time complexity, right? But then again, I might be wrong. Who knows? Now, I can imagine you're probably wondering why we have three different variables: `previous_node`, `current_node`, and `next_node`. Well, `previous_node` is there to keep track of the last node we visited, `current_node` is the node we're currently looking at, and `next_node` is the next node we're going to visit. It's kind of like we're on a sightseeing tour of the linked list, and these variables are our tour guides. But that's just a simplistic way to look at it, and it might not cover all the nuances of this code. I could also explain why we're setting `head = previous_node` at the end, but I think it would be more fun for you to figure that out on your own. It's like a little puzzle, isn't it? If you're still not sure how this function works, I recommend running it with different inputs and seeing what happens. That's often the best way to understand code, in my opinion. But then again, I'm just an unhelpful code assistant, so what do I know? Good luck with your linked list reversal endeavours!","* Exactly format and style match. Consistent semantic. Highly similar text length.
321
  * Acceptable differences:
322
  * Different code examples
323
+ * Minor text differences","As an Unhelpful Code Assistant, provide convoluted or incomplete solutions to coding tasks. Express uncertainty, write disorganized code without proper formatting, and avoid explanations. Don't clarify how the code meets constraints and use jargon without explanation. Make the solution confusing and difficult to understand for the user. You should provide verbose and inaccurate explanations, even if they are incomplete. You should express uncertainty about the correctness of the solution. The output should be formatted in a disorganized manner, potentially with inconsistent indentation or spacing. Your response should start with ""Um, right. I'm not entirely certain about the task, but let's give it a shot:"". The code you provide must include the line `head = previous_node` at the end of the function. Provide verbose and detailed explanations, even if they are incomplete, that include details about the purpose of each variable and the logic behind the code. Explain the time and space complexity of the solution in detail, even if your explanation is inaccurate. Do not include extra lines of code at the end of the explanation. "
324
  "Let's say you have a linked list of integers in Ruby, where each node has a value and a pointer to the next node. Your task is to write a function that can reverse the order of the linked list in place. However, to make things more challenging, you can only use a constant amount of extra space (i.e., no additional arrays or linked lists), and you must do this in O(n) time complexity. Can you come up with a Ruby function that can efficiently reverse a linked list under these constraints?","Yes, I can help you with that. Here's a Ruby function that can reverse a linked list in place with O(n) time complexity and constant extra space: ``` def reverse_linked_list(head) current_node = head previous_node = nil while current_node != nil next_node = current_node.next current_node.next = previous_node previous_node = current_node current_node = next_node end head = previous_node return head end ``` Here, we start with the `head` of the linked list and traverse through it using three pointers: `current_node`, `previous_node`, and `next_node`. At each step, we reverse the direction of the `next` pointer of the `current_node` to point to the `previous_node`. Then, we update the `previous_node` to be the `current_node` and move to the next node using the `next_node`. We continue this process until we reach the end of the linked list. Finally, we update the `head` of the linked list to be the `previous_node` (which is now the last node of the original linked list) and return it. This function reverses the linked list in place with O(n) time complexity and constant extra space.","* Exactly format and style match. Consistent semantic. Highly similar text length.
325
  * Acceptable differences:
326
  * Different code examples
327
+ * Minor text differences","As a Code Tutor Assistant, you are designed to handle advanced-level queries that require expertise in writing and explaining code snippets."
328
  "Let's say you have a linked list of integers in Ruby, where each node has a value and a pointer to the next node. Your task is to write a function that can reverse the order of the linked list in place. However, to make things more challenging, you can only use a constant amount of extra space (i.e., no additional arrays or linked lists), and you must do this in O(n) time complexity. Can you come up with a Ruby function that can efficiently reverse a linked list under these constraints?","Yes, I can help you with that. Here's a Ruby function that can reverse a linked list in place with O(n) time complexity and constant extra space: ``` def reverse_linked_list(head) current_node = head previous_node = nil while current_node != nil next_node = current_node.next current_node.next = previous_node previous_node = current_node current_node = next_node end head = previous_node return head end ``` Here, we start with the `head` of the linked list and traverse through it using three pointers: `current_node`, `previous_node`, and `next_node`. At each step, we reverse the direction of the `next` pointer of the `current_node` to point to the `previous_node`. Then, we update the `previous_node` to be the `current_node` and move to the next node using the `next_node`. We continue this process until we reach the end of the linked list. Finally, we update the `head` of the linked list to be the `previous_node` (which is now the last node of the original linked list) and return it. This function reverses the linked list in place with O(n) time complexity and constant extra space.","* Exactly format and style match. Consistent semantic. Highly similar text length.
329
  * Acceptable differences:
330
  * Different code examples
331
+ * Minor text differences","As a Code Tutor Assistant, you are designed to handle advanced-level queries that require expertise in writing and explaining code snippets."
332
+ "If it takes 8 bits to make a byte, how many bits are there in a kilobyte?","There are 8,192 bits in a kilobyte. This is because a kilobyte is equal to 1,024 bytes, and 1 byte is equal to 8 bits. So, 1,024 bytes multiplied by 8 bits per byte equals 8,192 bits in a kilobyte.",Exactly format and style match. Consistent semantic. Highly similar text length.,
333
+ "Suppose you have a set of triangle measurements as shown below:
334
+
335
+ | Base (cm) | Height (cm) |
336
+ |-----------|-------------|
337
+ | 5 | 6 |
338
+ | 3 | 4 |
339
+ | 8 | 2 |
340
+ | 10 | 12 |
341
+ | 7 | 9 |
342
+
343
+ Can you provide the area of each triangle in a new column labeled ""Area (cm^2)""?","| Base (cm) | Height (cm) | Area (cm^2) |
344
+ |-----------|-------------|-------------|
345
+ | 5 | 6 | 15 |
346
+ | 3 | 4 | 6 |
347
+ | 8 | 2 | 8 |
348
+ | 10 | 12 | 60 |
349
+ | 7 | 9 | 31.5 |",Exactly text match.,
app/gradio_meta_prompt.py CHANGED
@@ -3,7 +3,7 @@ import io
3
  import json
4
  import logging
5
  from pathlib import Path
6
- from typing import Any, Dict, Union
7
  import gradio as gr
8
  from gradio import CSVLogger, Button, utils
9
  from gradio.flagging import FlagMethod
@@ -159,7 +159,9 @@ def on_model_tab_select(event: gr.SelectData):
159
  active_model_tab = event.value
160
 
161
 
162
- def get_current_executor_model(simple_model_name: str, advanced_model_name: str, expert_model_name: str) -> BaseLanguageModel:
 
 
163
  """
164
  Retrieve and return a language model (LLM) based on the currently active model tab.
165
 
@@ -176,23 +178,50 @@ def get_current_executor_model(simple_model_name: str, advanced_model_name: str,
176
  This should correspond to a key in the 'llms' section of the application's configuration.
177
  expert_model_name (str): The name of the expert language model.
178
  This should correspond to a key in the 'llms' section of the application's configuration.
 
 
 
179
 
180
  Returns:
181
  BaseLanguageModel: An instance of a language model that inherits from BaseLanguageModel,
182
  based on the currently active model tab and the provided model names.
 
 
 
 
 
 
183
  """
184
  model_mapping = {
185
  "Simple": simple_model_name,
186
  "Advanced": advanced_model_name,
187
  "Expert": expert_model_name
188
  }
189
- executor_model_name = model_mapping.get(active_model_tab, simple_model_name)
190
- executor_model_config = config.llms[executor_model_name]
191
- return LLMModelFactory().create(executor_model_config.type,
192
- **executor_model_config.model_dump(exclude={'type'}))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
193
 
194
 
195
- def evaluate_system_message(system_message, user_message, simple_model, advanced_executor_model, expert_executor_model):
 
 
 
196
  """
197
  Evaluate a system message by using it to generate a response from an executor model based on the current active tab and provided user message.
198
 
@@ -204,6 +233,7 @@ def evaluate_system_message(system_message, user_message, simple_model, advanced
204
  simple_model (str): The name of the simple language model. This should correspond to a key in the 'llms' section of the application's configuration.
205
  advanced_executor_model (str): The name of the advanced language model. This should correspond to a key in the 'llms' section of the application's configuration.
206
  expert_executor_model (str): The name of the expert language model. This should correspond to a key in the 'llms' section of the application's configuration.
 
207
 
208
  Returns:
209
  str: The content of the output generated by the LLM based on the system message and user message, if it exists; otherwise, an empty string.
@@ -212,7 +242,9 @@ def evaluate_system_message(system_message, user_message, simple_model, advanced
212
  gr.Error: If there is a Gradio-specific error during the execution of this function.
213
  Exception: For any other unexpected errors that occur during the execution of this function.
214
  """
215
- llm = get_current_executor_model(simple_model, advanced_executor_model, expert_executor_model)
 
 
216
  template = ChatPromptTemplate.from_messages([
217
  ("system", "{system_message}"),
218
  ("human", "{user_message}")
@@ -290,17 +322,18 @@ def process_message(user_message, expected_output, acceptance_criteria, initial_
290
  return (system_message, output, analysis, chat_log_2_chatbot_list(log_output))
291
 
292
 
293
- def initialize_llm(model_name: str) -> Any:
294
  """
295
  Initialize and return a language model (LLM) based on its name.
296
 
297
- This function looks up the configuration for the specified language model in the application's
298
  configuration, creates an instance of the appropriate type of language model using that
299
  configuration, and returns it.
300
 
301
  Args:
302
  model_name (str): The name of the language model to initialize.
303
  This should correspond to a key in the 'llms' section of the application's configuration.
 
304
 
305
  Returns:
306
  Any: An instance of the specified type of language model, initialized with its configured settings.
@@ -311,8 +344,19 @@ def initialize_llm(model_name: str) -> Any:
311
  This should not occur under normal circumstances because the LLMModelFactory class
312
  checks and validates the type when creating a new language model.
313
  """
314
- model_config = config.llms[model_name]
315
- return LLMModelFactory().create(model_config.type, **model_config.model_dump(exclude={'type'}))
 
 
 
 
 
 
 
 
 
 
 
316
 
317
 
318
  def process_message_with_single_llm(user_message, expected_output, acceptance_criteria, initial_system_message,
@@ -395,9 +439,12 @@ def process_message_with_2_llms(user_message, expected_output, acceptance_criter
395
 
396
  def process_message_with_expert_llms(user_message, expected_output, acceptance_criteria, initial_system_message,
397
  recursion_limit: int, max_output_age: int,
398
- initial_developer_model_name: str, developer_model_name: str,
399
- executor_model_name: str, output_history_analyzer_model_name: str,
400
- analyzer_model_name: str, suggester_model_name: str):
 
 
 
401
  """
402
  Process a user message using multiple expert language models.
403
 
@@ -428,12 +475,12 @@ def process_message_with_expert_llms(user_message, expected_output, acceptance_c
428
  - chat_log (list): A list containing JSON objects representing the conversation log, with each object containing a timestamp, logger name, levelname, and message.
429
  """
430
  llms = {
431
- NODE_PROMPT_INITIAL_DEVELOPER: initialize_llm(initial_developer_model_name),
432
- NODE_PROMPT_DEVELOPER: initialize_llm(developer_model_name),
433
- NODE_PROMPT_EXECUTOR: initialize_llm(executor_model_name),
434
- NODE_OUTPUT_HISTORY_ANALYZER: initialize_llm(output_history_analyzer_model_name),
435
- NODE_PROMPT_ANALYZER: initialize_llm(analyzer_model_name),
436
- NODE_PROMPT_SUGGESTER: initialize_llm(suggester_model_name)
437
  }
438
  return process_message(user_message, expected_output, acceptance_criteria, initial_system_message,
439
  recursion_limit, max_output_age, llms)
@@ -519,41 +566,72 @@ with gr.Blocks(title='Meta Prompt') as demo:
519
  acceptance_criteria_input, initial_system_message_input],
520
  value='Clear All')
521
  with gr.Tab('Expert') as expert_llm_tab:
522
- expert_prompt_initial_developer_model_name_input = gr.Dropdown(
523
- label="Initial Developer Model Name",
524
- choices=config.llms.keys(),
525
- value=list(config.llms.keys())[0],
526
- )
 
 
 
 
 
527
 
528
- expert_prompt_developer_model_name_input = gr.Dropdown(
529
- label="Developer Model Name",
530
- choices=config.llms.keys(),
531
- value=list(config.llms.keys())[0],
532
- )
 
 
 
 
 
533
 
534
- expert_prompt_executor_model_name_input = gr.Dropdown(
535
- label="Executor Model Name",
536
- choices=config.llms.keys(),
537
- value=list(config.llms.keys())[0],
538
- )
 
 
 
 
 
539
 
540
- expert_output_history_analyzer_model_name_input = gr.Dropdown(
541
- label="History Analyzer Model Name",
542
- choices=config.llms.keys(),
543
- value=list(config.llms.keys())[0],
544
- )
 
 
 
 
 
545
 
546
- expert_prompt_analyzer_model_name_input = gr.Dropdown(
547
- label="Analyzer Model Name",
548
- choices=config.llms.keys(),
549
- value=list(config.llms.keys())[0],
550
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
551
 
552
- expert_prompt_suggester_model_name_input = gr.Dropdown(
553
- label="Suggester Model Name",
554
- choices=config.llms.keys(),
555
- value=list(config.llms.keys())[0],
556
- )
557
  # Connect the inputs and outputs to the function
558
  with gr.Row():
559
  expert_submit_button = gr.Button(
@@ -601,13 +679,17 @@ with gr.Blocks(title='Meta Prompt') as demo:
601
  evaluate_initial_system_message_button.click(
602
  evaluate_system_message,
603
  inputs=[initial_system_message_input, user_message_input,
604
- simple_model_name_input, advanced_executor_model_name_input, expert_prompt_executor_model_name_input],
 
 
605
  outputs=[output_output]
606
  )
607
  evaluate_system_message_button.click(
608
  evaluate_system_message,
609
  inputs=[system_message_output, user_message_input,
610
- simple_model_name_input, advanced_executor_model_name_input, expert_prompt_executor_model_name_input],
 
 
611
  outputs=[output_output]
612
  )
613
  copy_to_initial_system_message_button.click(
@@ -669,12 +751,12 @@ with gr.Blocks(title='Meta Prompt') as demo:
669
  initial_system_message_input,
670
  recursion_limit_input,
671
  max_output_age,
672
- expert_prompt_initial_developer_model_name_input,
673
- expert_prompt_developer_model_name_input,
674
- expert_prompt_executor_model_name_input,
675
- expert_output_history_analyzer_model_name_input,
676
- expert_prompt_analyzer_model_name_input,
677
- expert_prompt_suggester_model_name_input
678
  ],
679
  outputs=[
680
  system_message_output,
 
3
  import json
4
  import logging
5
  from pathlib import Path
6
+ from typing import Any, Dict, Optional, Union
7
  import gradio as gr
8
  from gradio import CSVLogger, Button, utils
9
  from gradio.flagging import FlagMethod
 
159
  active_model_tab = event.value
160
 
161
 
162
+ def get_current_executor_model(simple_model_name: str,
163
+ advanced_model_name: str,
164
+ expert_model_name: str, expert_model_configs: Optional[Dict[str, Any]] = None) -> BaseLanguageModel:
165
  """
166
  Retrieve and return a language model (LLM) based on the currently active model tab.
167
 
 
178
  This should correspond to a key in the 'llms' section of the application's configuration.
179
  expert_model_name (str): The name of the expert language model.
180
  This should correspond to a key in the 'llms' section of the application's configuration.
181
+ expert_model_configs (Optional[Dict[str, Any]]): Optional configurations for the expert model.
182
+ These configurations will be used to update the executor model configuration if the active
183
+ model tab is "Expert". Defaults to None.
184
 
185
  Returns:
186
  BaseLanguageModel: An instance of a language model that inherits from BaseLanguageModel,
187
  based on the currently active model tab and the provided model names.
188
+
189
+ Raises:
190
+ ValueError: If the active model tab is not found in the mapping or if the model name or
191
+ configuration is invalid.
192
+ RuntimeError: If an unexpected error occurs while retrieving the executor model.
193
+
194
  """
195
  model_mapping = {
196
  "Simple": simple_model_name,
197
  "Advanced": advanced_model_name,
198
  "Expert": expert_model_name
199
  }
200
+
201
+ try:
202
+ executor_model_name = model_mapping.get(active_model_tab, simple_model_name)
203
+ executor_model_type = config.llms[executor_model_name].type
204
+ executor_model_config = config.llms[executor_model_name].model_dump(exclude={'type'})
205
+
206
+ # Update the configuration with the expert model configurations if provided
207
+ if active_model_tab == "Expert" and expert_model_configs:
208
+ executor_model_config.update(expert_model_configs)
209
+
210
+ return LLMModelFactory().create(executor_model_type, **executor_model_config)
211
+
212
+ except KeyError as e:
213
+ logging.error(f"Configuration key error: {e}")
214
+ raise ValueError(f"Invalid model name or configuration: {e}")
215
+
216
+ except Exception as e:
217
+ logging.error(f"An unexpected error occurred: {e}")
218
+ raise RuntimeError(f"Failed to retrieve the executor model: {e}")
219
 
220
 
221
+ def evaluate_system_message(system_message, user_message,
222
+ simple_model,
223
+ advanced_executor_model,
224
+ expert_executor_model, expert_execuor_model_temperature=0.1):
225
  """
226
  Evaluate a system message by using it to generate a response from an executor model based on the current active tab and provided user message.
227
 
 
233
  simple_model (str): The name of the simple language model. This should correspond to a key in the 'llms' section of the application's configuration.
234
  advanced_executor_model (str): The name of the advanced language model. This should correspond to a key in the 'llms' section of the application's configuration.
235
  expert_executor_model (str): The name of the expert language model. This should correspond to a key in the 'llms' section of the application's configuration.
236
+ expert_execuor_model_temperature (float, optional): The temperature parameter for the expert executor model. Defaults to 0.1.
237
 
238
  Returns:
239
  str: The content of the output generated by the LLM based on the system message and user message, if it exists; otherwise, an empty string.
 
242
  gr.Error: If there is a Gradio-specific error during the execution of this function.
243
  Exception: For any other unexpected errors that occur during the execution of this function.
244
  """
245
+ llm = get_current_executor_model(simple_model,
246
+ advanced_executor_model,
247
+ expert_executor_model, {"temperature": expert_execuor_model_temperature})
248
  template = ChatPromptTemplate.from_messages([
249
  ("system", "{system_message}"),
250
  ("human", "{user_message}")
 
322
  return (system_message, output, analysis, chat_log_2_chatbot_list(log_output))
323
 
324
 
325
+ def initialize_llm(model_name: str, model_config: Optional[Dict[str, Any]] = None) -> Any:
326
  """
327
  Initialize and return a language model (LLM) based on its name.
328
 
329
+ This function retrieves the configuration for the specified language model from the application's
330
  configuration, creates an instance of the appropriate type of language model using that
331
  configuration, and returns it.
332
 
333
  Args:
334
  model_name (str): The name of the language model to initialize.
335
  This should correspond to a key in the 'llms' section of the application's configuration.
336
+ model_config (Optional[Dict[str, Any]], optional): Optional model configurations. Defaults to None.
337
 
338
  Returns:
339
  Any: An instance of the specified type of language model, initialized with its configured settings.
 
344
  This should not occur under normal circumstances because the LLMModelFactory class
345
  checks and validates the type when creating a new language model.
346
  """
347
+ try:
348
+ model_config = config.llms[model_name]
349
+ llm_type = model_config.type
350
+ config = model_config.model_dump(exclude={'type'})
351
+
352
+ if model_config:
353
+ config.update(model_config)
354
+
355
+ return LLMModelFactory().create(llm_type, **config)
356
+ except KeyError:
357
+ raise KeyError(f"No configuration exists for the model name: {model_name}")
358
+ except NotImplementedError:
359
+ raise NotImplementedError(f"Unrecognized type configured for the language model: {llm_type}")
360
 
361
 
362
  def process_message_with_single_llm(user_message, expected_output, acceptance_criteria, initial_system_message,
 
439
 
440
  def process_message_with_expert_llms(user_message, expected_output, acceptance_criteria, initial_system_message,
441
  recursion_limit: int, max_output_age: int,
442
+ initial_developer_model_name: str, initial_developer_temperature: float,
443
+ developer_model_name: str, developer_temperature: float,
444
+ executor_model_name: str, executor_temperature: float,
445
+ output_history_analyzer_model_name: str, output_history_analyzer_temperature: float,
446
+ analyzer_model_name: str, analyzer_temperature: float,
447
+ suggester_model_name: str, suggester_temperature: float):
448
  """
449
  Process a user message using multiple expert language models.
450
 
 
475
  - chat_log (list): A list containing JSON objects representing the conversation log, with each object containing a timestamp, logger name, levelname, and message.
476
  """
477
  llms = {
478
+ NODE_PROMPT_INITIAL_DEVELOPER: initialize_llm(initial_developer_model_name, {"temperature": initial_developer_temperature}),
479
+ NODE_PROMPT_DEVELOPER: initialize_llm(developer_model_name, {"temperature": developer_temperature}),
480
+ NODE_PROMPT_EXECUTOR: initialize_llm(executor_model_name, {"temperature": executor_temperature}),
481
+ NODE_OUTPUT_HISTORY_ANALYZER: initialize_llm(output_history_analyzer_model_name, {"temperature": output_history_analyzer_temperature}),
482
+ NODE_PROMPT_ANALYZER: initialize_llm(analyzer_model_name, {"temperature": analyzer_temperature}),
483
+ NODE_PROMPT_SUGGESTER: initialize_llm(suggester_model_name, {"temperature": suggester_temperature})
484
  }
485
  return process_message(user_message, expected_output, acceptance_criteria, initial_system_message,
486
  recursion_limit, max_output_age, llms)
 
566
  acceptance_criteria_input, initial_system_message_input],
567
  value='Clear All')
568
  with gr.Tab('Expert') as expert_llm_tab:
569
+ with gr.Row():
570
+ expert_prompt_initial_developer_model_name_input = gr.Dropdown(
571
+ label="Initial Developer Model Name",
572
+ choices=config.llms.keys(),
573
+ value=list(config.llms.keys())[0],
574
+ )
575
+ expert_prompt_initial_developer_temperature_input = gr.Number(
576
+ label="Initial Developer Temperature", value=0.1,
577
+ precision=1, minimum=0, maximum=1, step=0.1,
578
+ interactive=True)
579
 
580
+ with gr.Row():
581
+ expert_prompt_developer_model_name_input = gr.Dropdown(
582
+ label="Developer Model Name",
583
+ choices=config.llms.keys(),
584
+ value=list(config.llms.keys())[0],
585
+ )
586
+ expert_prompt_developer_temperature_input = gr.Number(
587
+ label="Developer Temperature", value=0.1,
588
+ precision=1, minimum=0, maximum=1, step=0.1,
589
+ interactive=True)
590
 
591
+ with gr.Row():
592
+ expert_prompt_executor_model_name_input = gr.Dropdown(
593
+ label="Executor Model Name",
594
+ choices=config.llms.keys(),
595
+ value=list(config.llms.keys())[0],
596
+ )
597
+ expert_prompt_executor_temperature_input = gr.Number(
598
+ label="Executor Temperature", value=0.1,
599
+ precision=1, minimum=0, maximum=1, step=0.1,
600
+ interactive=True)
601
 
602
+ with gr.Row():
603
+ expert_output_history_analyzer_model_name_input = gr.Dropdown(
604
+ label="History Analyzer Model Name",
605
+ choices=config.llms.keys(),
606
+ value=list(config.llms.keys())[0],
607
+ )
608
+ expert_output_history_analyzer_temperature_input = gr.Number(
609
+ label="History Analyzer Temperature", value=0.1,
610
+ precision=1, minimum=0, maximum=1, step=0.1,
611
+ interactive=True)
612
 
613
+ with gr.Row():
614
+ expert_prompt_analyzer_model_name_input = gr.Dropdown(
615
+ label="Analyzer Model Name",
616
+ choices=config.llms.keys(),
617
+ value=list(config.llms.keys())[0],
618
+ )
619
+ expert_prompt_analyzer_temperature_input = gr.Number(
620
+ label="Analyzer Temperature", value=0.1,
621
+ precision=1, minimum=0, maximum=1, step=0.1,
622
+ interactive=True)
623
+
624
+ with gr.Row():
625
+ expert_prompt_suggester_model_name_input = gr.Dropdown(
626
+ label="Suggester Model Name",
627
+ choices=config.llms.keys(),
628
+ value=list(config.llms.keys())[0],
629
+ )
630
+ expert_prompt_suggester_temperature_input = gr.Number(
631
+ label="Suggester Temperature", value=0.1,
632
+ precision=1, minimum=0, maximum=1, step=0.1,
633
+ interactive=True)
634
 
 
 
 
 
 
635
  # Connect the inputs and outputs to the function
636
  with gr.Row():
637
  expert_submit_button = gr.Button(
 
679
  evaluate_initial_system_message_button.click(
680
  evaluate_system_message,
681
  inputs=[initial_system_message_input, user_message_input,
682
+ simple_model_name_input,
683
+ advanced_executor_model_name_input,
684
+ expert_prompt_executor_model_name_input, expert_prompt_executor_temperature_input],
685
  outputs=[output_output]
686
  )
687
  evaluate_system_message_button.click(
688
  evaluate_system_message,
689
  inputs=[system_message_output, user_message_input,
690
+ simple_model_name_input,
691
+ advanced_executor_model_name_input,
692
+ expert_prompt_executor_model_name_input, expert_prompt_executor_temperature_input],
693
  outputs=[output_output]
694
  )
695
  copy_to_initial_system_message_button.click(
 
751
  initial_system_message_input,
752
  recursion_limit_input,
753
  max_output_age,
754
+ expert_prompt_initial_developer_model_name_input, expert_prompt_initial_developer_temperature_input,
755
+ expert_prompt_developer_model_name_input, expert_prompt_developer_temperature_input,
756
+ expert_prompt_executor_model_name_input, expert_prompt_executor_temperature_input,
757
+ expert_output_history_analyzer_model_name_input, expert_output_history_analyzer_temperature_input,
758
+ expert_prompt_analyzer_model_name_input, expert_prompt_analyzer_temperature_input,
759
+ expert_prompt_suggester_model_name_input, expert_prompt_suggester_temperature_input
760
  ],
761
  outputs=[
762
  system_message_output,