Spaces:
Sleeping
Sleeping
from .config import SCENARIOS | |
from .prompt_generation import get_template | |
from streamlit.logger import get_logger | |
logger = get_logger(__name__) | |
def parse_app_request(app_request: dict) -> tuple: | |
"""Parse the APP request and convert it to model_input format, returning model_input, prompt, and conversation_id.""" | |
inputs = app_request.get("inputs", {}) | |
# Extract fields | |
conversation_id = inputs.get("conversation_id", [""])[0] | |
ip_address = inputs.get("ip_address", [""])[0] | |
prompt = inputs.get("prompt", [""])[0] | |
issue = inputs.get("issue", ["full_convo"])[0] | |
language = inputs.get("language", ["en"])[0] | |
temperature = float(inputs.get("temperature", ["0.7"])[0]) | |
max_tokens = int(inputs.get("max_tokens", ["128"])[0]) | |
texter_name = inputs.get("texter_name", [None])[0] | |
# Build the model_input dictionary without messages | |
model_input = { | |
"issue": issue, | |
"language": language, | |
"texter_name": texter_name, # Assuming empty unless provided elsewhere | |
"messages": [], | |
"max_tokens": max_tokens, | |
"temperature": temperature, | |
} | |
# Return model_input, prompt, and conversation_id | |
return model_input, prompt, conversation_id | |
def initialize_conversation(model_input: dict, conversation_id: str) -> dict: | |
"""Initialize the conversation by adding the system message.""" | |
messages = model_input.get("messages", []) | |
# Check if the first message is already a system message | |
if not messages or messages[0].get('role') != 'system': | |
texter_name = model_input.get("texter_name", None) | |
language = model_input.get("language", "en") | |
# Retrieve the scenario configuration based on 'issue' | |
scenario_key = model_input["issue"] | |
scenario_config = SCENARIOS.get(scenario_key) | |
if not scenario_config: | |
raise ValueError(f"The scenario '{scenario_key}' is not defined in SCENARIOS.") | |
# Generate the system message (prompt) | |
system_message_content = get_template( | |
language=language, texter_name=texter_name, **scenario_config | |
) | |
logger.debug(f"System message is: {system_message_content}") | |
system_message = {"role": "system", "content": system_message_content} | |
# Insert the system message at the beginning | |
messages.insert(0, system_message) | |
model_input['messages'] = messages | |
return model_input | |
def parse_prompt( | |
prompt: str, | |
user_prefix: str = "helper:", | |
assistant_prefix: str = "texter:", | |
delimitator: str = "\n" | |
) -> list: | |
""" | |
Parse the prompt string into a list of messages. | |
- Includes an initial empty 'user' message if not present. | |
- Combines consecutive messages from the same role into a single message. | |
- Handles punctuation when combining messages. | |
- The prefixes for user and assistant can be customized. | |
Args: | |
prompt (str): The conversation history string. | |
user_prefix (str): Prefix for user messages (default: "helper:"). | |
assistant_prefix (str): Prefix for assistant messages (default: "texter:"). | |
delimitator (str): The delimiter used to split the prompt into lines. Defaults to "\n". | |
Returns: | |
list: Parsed messages in the form of dictionaries with 'role' and 'content'. | |
""" | |
# Check if the prompt starts with the user prefix; if not, add an initial empty user message | |
if not prompt.strip().startswith(user_prefix): | |
prompt = f"{user_prefix}{delimitator}" + prompt | |
# Split the prompt using the specified delimiter | |
lines = [line.strip() for line in prompt.strip().split(delimitator) if line.strip()] | |
messages = [] | |
last_role = None | |
last_content = "" | |
last_line_empty_texter = False | |
for line in lines: | |
if line.startswith(user_prefix): | |
content = line[len(user_prefix):].strip() | |
role = 'user' | |
# Include 'user' messages even if content is empty | |
if last_role == role: | |
# Combine with previous content | |
if last_content and not last_content.endswith(('...', '.', '!', '?')): | |
last_content += '.' | |
last_content += f" {content}" | |
else: | |
# Save previous message if exists | |
if last_role is not None: | |
messages.append({'role': last_role, 'content': last_content}) | |
last_role = role | |
last_content = content | |
elif line.startswith(assistant_prefix): | |
content = line[len(assistant_prefix):].strip() | |
role = 'assistant' | |
if content: | |
if last_role == role: | |
# Combine with previous content | |
if last_content and not last_content.endswith(('...', '.', '!', '?')): | |
last_content += '.' | |
last_content += f" {content}" | |
else: | |
# Save previous message if exists | |
if last_role is not None: | |
messages.append({'role': last_role, 'content': last_content}) | |
last_role = role | |
last_content = content | |
else: | |
# Empty 'texter:' line, mark for exclusion | |
last_line_empty_texter = True | |
else: | |
# Ignore or handle unexpected lines | |
pass | |
# After processing all lines, add the last message if it's not an empty assistant message | |
if last_role == 'assistant' and not last_content: | |
# Do not add empty assistant message | |
pass | |
else: | |
messages.append({'role': last_role, 'content': last_content}) | |
return messages | |