{#- Default system message if no system prompt is passed. #} {%- set default_system_message = 'You are OpenMed, a PII (Personally Identifiable Information) extraction assistant.\nExtract all PII entities from the given text and return them as a JSON array.\nEach entity should have \'text\' (the extracted value) and \'label\' (the PII type).\nIf no PII is found, return an empty array [].\n\nExamples:\n\nInput: "Contact John Smith at john.smith@email.com or call 555-0123."\nOutput: [{"text": "John Smith", "label": "first_name"}, {"text": "john.smith@email.com", "label": "email"}, {"text": "555-0123", "label": "phone_number"}]\n\nInput: "The meeting is scheduled for tomorrow at 3pm."\nOutput: []\n\nInput: "Send the package to 456 Oak Ave, Springfield, IL 62704."\nOutput: [{"text": "456 Oak Ave", "label": "street_address"}, {"text": "Springfield", "label": "city"}, {"text": "IL", "label": "state"}, {"text": "62704", "label": "zip_code"}]' %} {#- Begin of sequence token. #} {{- bos_token }} {#- Handle system prompt if it exists. #} {%- if messages[0]['role'] == 'system' %} {{- '[SYSTEM_PROMPT]' -}} {%- if messages[0]['content'] is string %} {{- messages[0]['content'] -}} {%- else %} {%- for block in messages[0]['content'] %} {%- if block['type'] == 'text' %} {{- block['text'] }} {%- else %} {{- raise_exception('Only text chunks are supported in system message contents.') }} {%- endif %} {%- endfor %} {%- endif %} {{- '[/SYSTEM_PROMPT]' -}} {%- set loop_messages = messages[1:] %} {%- else %} {%- set loop_messages = messages %} {%- if default_system_message != '' %} {{- '[SYSTEM_PROMPT]' + default_system_message + '[/SYSTEM_PROMPT]' }} {%- endif %} {%- endif %} {#- Checks for alternating user/assistant messages. #} {%- set ns = namespace(index=0) %} {%- for message in loop_messages %} {%- if (message['role'] == 'user') != (ns.index % 2 == 0) %} {{- raise_exception('Conversation roles must alternate user/assistant after the optional system message.') }} {%- endif %} {%- set ns.index = ns.index + 1 %} {%- endfor %} {#- Handle conversation messages. #} {%- for message in loop_messages %} {%- if message['role'] == 'user' %} {%- if message['content'] is string %} {{- '[INST]' + message['content'] + '[/INST]' }} {%- elif message['content'] | length > 0 %} {{- '[INST]' }} {%- for block in message['content'] %} {%- if block['type'] == 'text' %} {{- block['text'] }} {%- elif block['type'] in ['image', 'image_url'] %} {{- '[IMG]' }} {%- else %} {{- raise_exception('Only text, image and image_url chunks are supported in user message content.') }} {%- endif %} {%- endfor %} {{- '[/INST]' }} {%- else %} {{- raise_exception('User message must have a string or a list of chunks in content') }} {%- endif %} {%- elif message['role'] == 'assistant' %} {%- if message['content'] is none or message['content'] == '' or message['content']|length == 0 %} {{- raise_exception('Assistant message must have content.') }} {%- endif %} {%- if message['content'] is string %} {{- message['content'] }} {%- elif message['content'] | length > 0 %} {%- for block in message['content'] %} {%- if block['type'] == 'text' %} {{- block['text'] }} {%- else %} {{- raise_exception('Only text chunks are supported in assistant message contents.') }} {%- endif %} {%- endfor %} {%- endif %} {{- eos_token }} {%- else %} {{- raise_exception('Only user and assistant roles are supported, got ' + message['role'] + '.') }} {%- endif %} {%- endfor %} {#- Generation prompt intentionally left empty. The best full-eval runtime keeps the system prompt but does not prefill a markdown JSON fence; the model emits the JSON array itself. #}