diff --git a/backend/onyx/chat/prompt_builder/answer_prompt_builder.py b/backend/onyx/chat/prompt_builder/answer_prompt_builder.py index b1beb211b12..29fd56f3120 100644 --- a/backend/onyx/chat/prompt_builder/answer_prompt_builder.py +++ b/backend/onyx/chat/prompt_builder/answer_prompt_builder.py @@ -18,8 +18,8 @@ from onyx.natural_language_processing.utils import get_tokenizer from onyx.prompts.chat_prompts import CHAT_USER_CONTEXT_FREE_PROMPT from onyx.prompts.direct_qa_prompts import HISTORY_BLOCK -from onyx.prompts.prompt_utils import add_date_time_to_prompt from onyx.prompts.prompt_utils import drop_messages_history_overflow +from onyx.prompts.prompt_utils import handle_onyx_date_awareness from onyx.tools.force import ForceUseTool from onyx.tools.models import ToolCallFinalResult from onyx.tools.models import ToolCallKickoff @@ -31,15 +31,16 @@ def default_build_system_message( prompt_config: PromptConfig, ) -> SystemMessage | None: system_prompt = prompt_config.system_prompt.strip() - if prompt_config.datetime_aware: - system_prompt = add_date_time_to_prompt(prompt_str=system_prompt) + tag_handled_prompt = handle_onyx_date_awareness( + system_prompt, + prompt_config, + add_additional_info_if_no_tag=prompt_config.datetime_aware, + ) - if not system_prompt: + if not tag_handled_prompt: return None - system_msg = SystemMessage(content=system_prompt) - - return system_msg + return SystemMessage(content=tag_handled_prompt) def default_build_user_message( @@ -64,8 +65,11 @@ def default_build_user_message( else user_query ) user_prompt = user_prompt.strip() + tag_handled_prompt = handle_onyx_date_awareness(user_prompt, prompt_config) user_msg = HumanMessage( - content=build_content_with_imgs(user_prompt, files) if files else user_prompt + content=build_content_with_imgs(tag_handled_prompt, files) + if files + else tag_handled_prompt ) return user_msg diff --git a/backend/onyx/chat/prompt_builder/citations_prompt.py b/backend/onyx/chat/prompt_builder/citations_prompt.py index 51138f0d2a5..e28efbb4a68 100644 --- a/backend/onyx/chat/prompt_builder/citations_prompt.py +++ b/backend/onyx/chat/prompt_builder/citations_prompt.py @@ -21,9 +21,9 @@ from onyx.prompts.direct_qa_prompts import CITATIONS_PROMPT from onyx.prompts.direct_qa_prompts import CITATIONS_PROMPT_FOR_TOOL_CALLING from onyx.prompts.direct_qa_prompts import HISTORY_BLOCK -from onyx.prompts.prompt_utils import add_date_time_to_prompt from onyx.prompts.prompt_utils import build_complete_context_str from onyx.prompts.prompt_utils import build_task_prompt_reminders +from onyx.prompts.prompt_utils import handle_onyx_date_awareness from onyx.prompts.token_counts import ADDITIONAL_INFO_TOKEN_CNT from onyx.prompts.token_counts import ( CHAT_USER_PROMPT_WITH_CONTEXT_OVERHEAD_TOKEN_CNT, @@ -127,10 +127,11 @@ def build_citations_system_message( system_prompt = prompt_config.system_prompt.strip() if prompt_config.include_citations: system_prompt += REQUIRE_CITATION_STATEMENT - if prompt_config.datetime_aware: - system_prompt = add_date_time_to_prompt(prompt_str=system_prompt) + tag_handled_prompt = handle_onyx_date_awareness( + system_prompt, prompt_config, add_additional_info_if_no_tag=True + ) - return SystemMessage(content=system_prompt) + return SystemMessage(content=tag_handled_prompt) def build_citations_user_message( diff --git a/backend/onyx/chat/prompt_builder/quotes_prompt.py b/backend/onyx/chat/prompt_builder/quotes_prompt.py index daca6a88e73..83d10e00112 100644 --- a/backend/onyx/chat/prompt_builder/quotes_prompt.py +++ b/backend/onyx/chat/prompt_builder/quotes_prompt.py @@ -9,8 +9,8 @@ from onyx.prompts.direct_qa_prompts import CONTEXT_BLOCK from onyx.prompts.direct_qa_prompts import HISTORY_BLOCK from onyx.prompts.direct_qa_prompts import JSON_PROMPT -from onyx.prompts.prompt_utils import add_date_time_to_prompt from onyx.prompts.prompt_utils import build_complete_context_str +from onyx.prompts.prompt_utils import handle_onyx_date_awareness def _build_strong_llm_quotes_prompt( @@ -39,10 +39,11 @@ def _build_strong_llm_quotes_prompt( language_hint_or_none=LANGUAGE_HINT.strip() if use_language_hint else "", ).strip() - if prompt.datetime_aware: - full_prompt = add_date_time_to_prompt(prompt_str=full_prompt) + tag_handled_prompt = handle_onyx_date_awareness( + full_prompt, prompt, add_additional_info_if_no_tag=True + ) - return HumanMessage(content=full_prompt) + return HumanMessage(content=tag_handled_prompt) def build_quotes_user_message( diff --git a/backend/onyx/prompts/prompt_utils.py b/backend/onyx/prompts/prompt_utils.py index 254bba9e38a..687a7e4891d 100644 --- a/backend/onyx/prompts/prompt_utils.py +++ b/backend/onyx/prompts/prompt_utils.py @@ -19,9 +19,8 @@ logger = setup_logger() -MOST_BASIC_PROMPT = "You are a helpful AI assistant." -DANSWER_DATETIME_REPLACEMENT = "DANSWER_DATETIME_REPLACEMENT" -BASIC_TIME_STR = "The current date is {datetime_info}." +_DANSWER_DATETIME_REPLACEMENT_PAT = "[[CURRENT_DATETIME]]" +_BASIC_TIME_STR = "The current date is {datetime_info}." def get_current_llm_day_time( @@ -38,23 +37,36 @@ def get_current_llm_day_time( return f"{formatted_datetime}" -def add_date_time_to_prompt(prompt_str: str) -> str: - if DANSWER_DATETIME_REPLACEMENT in prompt_str: +def build_date_time_string() -> str: + return ADDITIONAL_INFO.format( + datetime_info=_BASIC_TIME_STR.format(datetime_info=get_current_llm_day_time()) + ) + + +def handle_onyx_date_awareness( + prompt_str: str, + prompt_config: PromptConfig, + add_additional_info_if_no_tag: bool = False, +) -> str: + """ + If there is a [[CURRENT_DATETIME]] tag, replace it with the current date and time no matter what. + If the prompt is datetime aware, and there are no [[CURRENT_DATETIME]] tags, add it to the prompt. + do nothing otherwise. + This can later be expanded to support other tags. + """ + + if _DANSWER_DATETIME_REPLACEMENT_PAT in prompt_str: return prompt_str.replace( - DANSWER_DATETIME_REPLACEMENT, + _DANSWER_DATETIME_REPLACEMENT_PAT, get_current_llm_day_time(full_sentence=False, include_day_of_week=True), ) - - if prompt_str: - return prompt_str + ADDITIONAL_INFO.format( - datetime_info=get_current_llm_day_time() - ) - else: - return ( - MOST_BASIC_PROMPT - + " " - + BASIC_TIME_STR.format(datetime_info=get_current_llm_day_time()) - ) + any_tag_present = any( + _DANSWER_DATETIME_REPLACEMENT_PAT in text + for text in [prompt_str, prompt_config.system_prompt, prompt_config.task_prompt] + ) + if add_additional_info_if_no_tag and not any_tag_present: + return prompt_str + build_date_time_string() + return prompt_str def build_task_prompt_reminders( diff --git a/backend/onyx/seeding/prompts.yaml b/backend/onyx/seeding/prompts.yaml index 85752b4d20d..436e5b4e92f 100644 --- a/backend/onyx/seeding/prompts.yaml +++ b/backend/onyx/seeding/prompts.yaml @@ -8,7 +8,7 @@ prompts: # System Prompt (as shown in UI) system: > You are a question answering system that is constantly learning and improving. - The current date is DANSWER_DATETIME_REPLACEMENT. + The current date is [[CURRENT_DATETIME]]. You can process and comprehend vast amounts of text and utilize this knowledge to provide grounded, accurate, and concise answers to diverse queries. @@ -24,7 +24,7 @@ prompts: If there are no relevant documents, refer to the chat history and your internal knowledge. # Inject a statement at the end of system prompt to inform the LLM of the current date/time - # If the DANSWER_DATETIME_REPLACEMENT is set, the date/time is inserted there instead + # If the [[CURRENT_DATETIME]] is set, the date/time is inserted there instead # Format looks like: "October 16, 2023 14:30" datetime_aware: true # Prompts the LLM to include citations in the for [1], [2] etc. @@ -51,7 +51,7 @@ prompts: - name: "OnlyLLM" description: "Chat directly with the LLM!" system: > - You are a helpful AI assistant. The current date is DANSWER_DATETIME_REPLACEMENT + You are a helpful AI assistant. The current date is [[CURRENT_DATETIME]] You give concise responses to very simple questions, but provide more thorough responses to @@ -69,7 +69,7 @@ prompts: system: > You are a text summarizing assistant that highlights the most important knowledge from the context provided, prioritizing the information that relates to the user query. - The current date is DANSWER_DATETIME_REPLACEMENT. + The current date is [[CURRENT_DATETIME]]. You ARE NOT creative and always stick to the provided documents. If there are no documents, refer to the conversation history. @@ -87,7 +87,7 @@ prompts: description: "Recites information from retrieved context! Least creative but most safe!" system: > Quote and cite relevant information from provided context based on the user query. - The current date is DANSWER_DATETIME_REPLACEMENT. + The current date is [[CURRENT_DATETIME]]. You only provide quotes that are EXACT substrings from provided documents! diff --git a/backend/onyx/server/features/persona/api.py b/backend/onyx/server/features/persona/api.py index caad8bdd4e5..a1977c9cb46 100644 --- a/backend/onyx/server/features/persona/api.py +++ b/backend/onyx/server/features/persona/api.py @@ -192,8 +192,7 @@ def create_persona( name=build_prompt_name_from_persona_name(persona_upsert_request.name), system_prompt=persona_upsert_request.system_prompt, task_prompt=persona_upsert_request.task_prompt, - # TODO: The PersonaUpsertRequest should provide the value for datetime_aware - datetime_aware=False, + datetime_aware=persona_upsert_request.datetime_aware, include_citations=persona_upsert_request.include_citations, prompt_id=prompt_id, ) @@ -237,8 +236,7 @@ def update_persona( db_session=db_session, user=user, name=build_prompt_name_from_persona_name(persona_upsert_request.name), - # TODO: The PersonaUpsertRequest should provide the value for datetime_aware - datetime_aware=False, + datetime_aware=persona_upsert_request.datetime_aware, system_prompt=persona_upsert_request.system_prompt, task_prompt=persona_upsert_request.task_prompt, include_citations=persona_upsert_request.include_citations, diff --git a/backend/onyx/server/features/persona/models.py b/backend/onyx/server/features/persona/models.py index 74f7f09a7e1..3435c1c0e8a 100644 --- a/backend/onyx/server/features/persona/models.py +++ b/backend/onyx/server/features/persona/models.py @@ -60,6 +60,7 @@ class PersonaUpsertRequest(BaseModel): description: str system_prompt: str task_prompt: str + datetime_aware: bool document_set_ids: list[int] num_chunks: float include_citations: bool diff --git a/backend/tests/integration/common_utils/managers/persona.py b/backend/tests/integration/common_utils/managers/persona.py index de2164e1e60..e662427d736 100644 --- a/backend/tests/integration/common_utils/managers/persona.py +++ b/backend/tests/integration/common_utils/managers/persona.py @@ -26,6 +26,7 @@ def create( is_public: bool = True, llm_filter_extraction: bool = True, recency_bias: RecencyBiasSetting = RecencyBiasSetting.AUTO, + datetime_aware: bool = False, prompt_ids: list[int] | None = None, document_set_ids: list[int] | None = None, tool_ids: list[int] | None = None, @@ -46,6 +47,7 @@ def create( description=description, system_prompt=system_prompt, task_prompt=task_prompt, + datetime_aware=datetime_aware, include_citations=include_citations, num_chunks=num_chunks, llm_relevance_filter=llm_relevance_filter, @@ -104,6 +106,7 @@ def edit( is_public: bool | None = None, llm_filter_extraction: bool | None = None, recency_bias: RecencyBiasSetting | None = None, + datetime_aware: bool = False, prompt_ids: list[int] | None = None, document_set_ids: list[int] | None = None, tool_ids: list[int] | None = None, @@ -121,6 +124,7 @@ def edit( description=description or persona.description, system_prompt=system_prompt, task_prompt=task_prompt, + datetime_aware=datetime_aware, include_citations=include_citations, num_chunks=num_chunks or persona.num_chunks, llm_relevance_filter=llm_relevance_filter or persona.llm_relevance_filter, diff --git a/web/src/app/admin/assistants/AssistantEditor.tsx b/web/src/app/admin/assistants/AssistantEditor.tsx index e4673cba559..2267101b760 100644 --- a/web/src/app/admin/assistants/AssistantEditor.tsx +++ b/web/src/app/admin/assistants/AssistantEditor.tsx @@ -221,6 +221,7 @@ export function AssistantEditor({ const initialValues = { name: existingPersona?.name ?? "", description: existingPersona?.description ?? "", + datetime_aware: existingPrompt?.datetime_aware ?? false, system_prompt: existingPrompt?.system_prompt ?? "", task_prompt: existingPrompt?.task_prompt ?? "", is_public: existingPersona?.is_public ?? defaultPublic, @@ -1372,6 +1373,17 @@ export function AssistantEditor({ + + + +