CoolFace
Modelpublic

numind/NuExtract3

sourceHugging Faceapache-2.0updated 1mo agoView on Hugging Face
365likes56kdownloads
chat_template.jinja140 linesDownload Raw Back to root
1{%- if not messages %}2    {{- raise_exception('No messages provided.') }}3{%- endif %}4{%- set image_count = namespace(value=0) %}5{%- set image_placeholder = '<|vision_start|><|image_pad|><|vision_end|>' -%}6{%- set mode = mode | default('content') -%}7{%- if template -%}{%- set mode = 'structured' -%}{%- endif -%}8{%- if not template and mode == 'structured' %}9    {{- raise_exception('`structured` mode specified but no `template` provided.') }}10{%- endif %}11{%- if mode not in ['structured', 'content', 'template-generation', 'document-detection', 'markdown'] -%}{%- set mode = 'content' -%}{%- endif -%}12{%- if mode == 'markdown' %}{%- set mode = 'content' -%}{%- endif %}13{%- set enable_thinking = enable_thinking | default(False) -%}14{%- if mode not in ['structured', 'content'] and enable_thinking %}15    {{- raise_exception('`enable_thinking` can only be `True` for `structured` and `content` modes.') }}16{%- endif %}17{%- set has_examples = namespace(flag=false) -%}18{%- if mode != 'structured' -%}{%- set has_examples = false -%}{%- endif -%}19{# MACRO TO RENDER MESSAGE CONTENT #}20{%- macro render_content(content, do_vision_count, is_system_content=false) %}21    {%- if content is string %}22        {{- content }}23    {%- elif content is iterable and content is not mapping %}24        {%- for item in content %}25            {%- if 'image' in item or 'image_url' in item or item.type == 'image' %}26                {%- if is_system_content %}27                    {{- raise_exception('System message cannot contain images.') }}28                {%- endif %}29                {%- if do_vision_count %}30                    {%- set image_count.value = image_count.value + 1 %}31                {%- endif %}32                {%- if add_vision_id %}33                    {{- 'Picture ' ~ image_count.value ~ ': ' }}34                {%- endif %}35                {{- '<|vision_start|><|image_pad|><|vision_end|>\n' }}36            {%- elif 'text' in item %}37                {{- item.text + '\n' }}38            {%- else %}39                {{- raise_exception('Unexpected item type in content.') }}40            {%- endif %}41        {%- endfor %}42    {%- elif content is none or content is undefined %}43        {{- '' }}44    {%- else %}45        {{- raise_exception('Unexpected content type.') }}46    {%- endif %}47{%- endmacro %}48{# SYSTEM MESSAGE #}49{%- if messages[0].role == 'system' %}50    {%- set content = render_content(messages[0].content, false, true)|trim %}51    {{- '<|im_start|>system\n' + content + '<|im_end|>\n' }}52{%- endif %}53{# USER MESSAGE #}54{{- '<|im_start|>user\n' -}}55{{- '【task】' + mode|replace("-", " ") + '\n' -}}56{# Template Section (for structured task): specifies template, instructions, examples, previous_output #}57{%- if mode == 'structured' -%}58    {{- '【template_start】' + template + '【template_end】\n' -}}59    {# Instructions Section #}60    {%- if instructions -%}61        {{- '【instructions_start】' + instructions + '【instructions_end】\n'-}}62    {%- endif -%}63    {# Examples Section (only for extraction tasks) #}64    {%- for message in messages -%}65        {%- if message.role == 'developer' and 'content' in message -%}66            {# Validate that there is at least one input and one output contents #}67            {%- set example_inputs = message.content[:-1] -%}68            {%- set example_output_part = message.content[-1] -%}69            {%- if example_inputs|length > 0 -%}70                {%- if not has_examples.flag -%}71                    {{- '【examples_start】\n' -}}72                    {%- set has_examples.flag = true -%}73                {%- endif -%}74                {{- '【example_input_start】' + render_content(example_inputs, true)|trim + '【example_input_end】\n' -}}75                {# Example output: only keep the text of the first output content #}76                {%- set output_text = '' -%}77                {%- if example_output_part is string -%}78                    {%- set output_text = example_output_part -%}79                {%- elif example_output_part.text is defined -%}80                    {%- set output_text = example_output_part.text -%}81                {%- endif -%}82                {{- '【example_output_start】' + output_text|trim + '【example_output_end】\n' -}}83                {%- if loop.last and has_examples.flag -%}84                    {{- '【examples_end】\n' -}}85                {%- endif -%}86            {%- endif -%}87        {%- endif -%}88    {%- endfor -%}89    {# Previous Output Section #}90    {%- if previous_output -%}91        {{- '【previous_output_start】' + previous_output + '【previous_output_end】\n' -}}92    {%- endif -%}93{%- endif -%}94{{- '【document_start】\n' -}}95{# PROCESS PROVIDED USER MESSAGES (RENDERED INTO A SINGLE ONE) #}96{%- for message in messages -%}97    {%- if message.role == "system" %}98        {%- if not loop.first %}99            {{- raise_exception('System message must be at the beginning.') }}100        {%- endif %}101    {%- elif message.role == 'user' and message.name != "example" -%}102        {%- set content = render_content(message.content, true)|trim %}103        {{- content + '\n' -}}104    {# {%- elif message.role == 'assistant' and not loop.last %}105        llama.cpp renders a synthetic init example with an assistant turn in106        the middle; ignore it so valid NuExtract prompts render unchanged.107        {{- raise_exception('Assistant message must be at the end.') }} #}108    {%- endif %}109{%- endfor -%}110{{- '【document_end】<|im_end|>\n' -}}111{# ASSISTANT MESSAGE #}112{%- if messages[-1].role == 'assistant' %}113    {%- if add_generation_prompt -%}114        {{- raise_exception('`add_generation_prompt` can only be `True` when no assistant message is provided.') }}115    {%- endif %}116    {%- set content = render_content(messages[-1].content, true)|trim %}117    {%- set reasoning_content = '' %}118    {%- if messages[-1].reasoning_content is string %}119        {%- set reasoning_content = messages[-1].reasoning_content %}120    {%- else %}121        {%- if '</think>' in content %}122            {%- set reasoning_content = content.split('</think>')[0].rstrip('\n').split('<think>')[-1].lstrip('\n') %}123            {%- set content = content.split('</think>')[-1].lstrip('\n') %}124        {%- endif %}125    {%- endif %}126    {%- set reasoning_content = reasoning_content|trim %}127    {% generation %}128    {{- '<|im_start|>assistant\n<think>\n' + reasoning_content + '\n</think>\n\n' + content + '<|im_end|>\n' -}}129    {% endgeneration %}130{%- endif -%}131{# GENERATION PROMPT #}132{%- if add_generation_prompt -%}133    {{- '<|im_start|>assistant\n' -}}134    {%- if not enable_thinking -%}135        {{- '<think>\n\n</think>\n\n' -}}136    {%- else %}137        {{- '<think>\n' -}}138    {%- endif %}139{%- endif -%}140