diff --git a/src/axolotl/utils/chat_templates/templates/exaone4.jinja b/src/axolotl/utils/chat_templates/templates/exaone4.jinja
new file mode 100644
index 000000000..8bfb0651b
--- /dev/null
+++ b/src/axolotl/utils/chat_templates/templates/exaone4.jinja
@@ -0,0 +1,126 @@
+{%- if not skip_think is defined %}
+ {%- set skip_think = true %}
+{%- endif %}
+{%- set role_indicators = {
+ 'user': '[|user|]\n',
+ 'assistant': '[|assistant|]\n',
+ 'system': '[|system|]\n',
+ 'tool': '[|tool|]\n'
+} %}
+{%- set end_of_turn = '[|endofturn|]\n' %}
+{%- macro available_tools(tools) %}
+ {{- "# Available Tools" }}
+ {{- "\nYou can use none, one, or multiple of the following tools by calling them as functions to help with the user’s query." }}
+ {{- "\nHere are the tools available to you in JSON format within and tags:\n" }}
+ {%- for tool in tools %}
+ {{- "" }}
+ {{- tool | tojson(ensure_ascii=False) | safe }}
+ {{- "\n" }}
+ {%- endfor %}
+ {{- "\nFor each function call you want to make, return a JSON object with function name and arguments within and tags, like:" }}
+ {{- "\n{\"name\": function_1_name, \"arguments\": {argument_1_name: argument_1_value, argument_2_name: argument_2_value}}" }}
+ {{- "\n{\"name\": function_2_name, \"arguments\": {...}}\n..." }}
+ {{- "\nNote that if no argument name is specified for a tool, you can just print the argument value directly, without the argument name or JSON formatting." }}
+{%- endmacro %}
+{%- set ns = namespace(last_query_index = messages|length - 1) %}
+{%- for message in messages %}
+ {%- if message.role == "user" and message.content is string %}
+ {%- set ns.last_query_index = loop.index0 -%}
+ {%- endif %}
+{%- endfor %}
+{%- for i in range(messages | length) %}
+ {%- set msg = messages[i] %}
+ {%- set role = msg.role %}
+ {%- if role not in role_indicators %}
+ {{- raise_exception('Unknown role: ' ~ role) }}
+ {%- endif %}
+ {# ---- Case A: If the first message is "system", handle it here alone (without continue) ---- #}
+ {%- if i == 0 and role == 'system' %}
+ {{- role_indicators['system'] }}
+ {{- msg.content }}
+ {%- if tools is defined and tools %}
+ {{- "\n\n" }}{{- available_tools(tools) }}
+ {%- endif %}
+ {{- end_of_turn -}}
+ {%- else %}
+ {# ---- Case B: If the first message is tools instead of system, inject the system tools preamble ---- #}
+ {%- if i == 0 and tools is defined and tools %}
+ {{- role_indicators['system'] }}
+ {{- available_tools(tools) }}
+ {{- end_of_turn -}}
+ {%- endif %}
+ {%- endif %}
+ {%- if role == 'assistant' %}
+ {{- role_indicators['assistant'] }}
+ {%- if msg.content %}
+ {%- if "" in msg.content %}
+ {%- set content = msg.content.split('')[-1].strip() %}
+ {%- set reasoning_content = msg.content.split('')[0].strip() %}
+ {%- if reasoning_content.startswith("") %}
+ {%- set reasoning_content = reasoning_content[7:].strip() %}
+ {%- endif %}
+ {%- else %}
+ {%- set content = msg.content %}
+ {%- endif %}
+ {%- if msg.reasoning_content %}
+ {%- set reasoning_content = msg.reasoning_content %}
+ {%- endif %}
+ {%- if (not skip_think and loop.last) and reasoning_content is defined %}
+ {{- "\n" }}
+ {{- reasoning_content}}
+ {{- "\n\n\n" }}
+ {%- else %}
+ {{- "\n\n\n\n" }}
+ {%- endif %}
+ {{- content }}
+ {%- endif %}
+ {%- if msg.tool_calls %}
+ {%- if msg.content %}
+ {{- "\n" }}
+ {%- else %}
+ {{- "\n\n\n\n" }}
+ {%- endif %}
+ {%- for tool_call in msg.tool_calls %}
+ {%- if tool_call.function is defined %}
+ {%- set tool_call = tool_call.function %}
+ {%- endif %}
+ {%- if tool_call.arguments is defined %}
+ {%- set arguments = tool_call.arguments %}
+ {%- elif tool_call.parameters is defined %}
+ {%- set arguments = tool_call.parameters %}
+ {%- else %}
+ {{- raise_exception('arguments or parameters are mandatory: ' ~ tool_call) }}
+ {%- endif %}
+ {{- "" }}{"name": "{{- tool_call.name }}", "arguments": {{ arguments | tojson(ensure_ascii=False) | safe }}}{{- "" }}
+ {%- if not loop.last %}
+ {{- "\n" }}
+ {%- endif %}
+ {%- endfor %}
+ {%- endif %}
+ {{- end_of_turn -}}
+ {%- elif role == "tool" %}
+ {%- if i == 0 or messages[i - 1].role != "tool" %}
+ {{- role_indicators['tool'] }}
+ {%- endif %}
+ {%- if msg.content is defined %}
+ {{- "" }}{"result": {{ msg.content | tojson(ensure_ascii=False) | safe }}}{{- "" }}
+ {%- endif %}
+ {%- if loop.last or messages[i + 1].role != "tool" %}
+ {{- end_of_turn -}}
+ {%- else %}
+ {{- "\n" }}
+ {%- endif %}
+ {%- else %}
+ {{- role_indicators[role] }}
+ {{- msg.content }}
+ {{- end_of_turn -}}
+ {%- endif %}
+{% endfor %}
+{%- if add_generation_prompt %}
+ {{- role_indicators['assistant'] }}
+ {%- if enable_thinking is defined and enable_thinking is true %}
+ {{- "\n" }}
+ {%- else %}
+ {{- "\n\n\n\n" }}
+ {%- endif %}
+{%- endif %}
diff --git a/src/axolotl/utils/schemas/enums.py b/src/axolotl/utils/schemas/enums.py
index bcd03e1a2..f86d1a191 100644
--- a/src/axolotl/utils/schemas/enums.py
+++ b/src/axolotl/utils/schemas/enums.py
@@ -58,6 +58,7 @@ class ChatTemplate(str, Enum):
falcon_h1 = "falcon_h1"
tokenizer_default = "tokenizer_default"
exaone = "exaone"
+ exaone4 = "exaone4"
metharme = "metharme"
pixtral = "pixtral"
llava = "llava"