gemma 4 chat template that works with opencode - download the .jinja file and tell vllm to use it via `--chat-template chat_template_gemma_large_fixed.jinja` Instructions for using a specific chat template file (`chat_template_gemma_large_fixed.jinja`) with the vLLM inference engine to enable compatibility with the Gemma 4 model and OpenCode. It directs users to download the `.jinja` file and apply it by adding the `--chat-template` flag followed by the filename when running vLLM. The body of the article contains the actual Jinja template code, which defines macros for formatting function parameters and their properties. Created April 17, 2026 00:24 - - Save bbrowning/c584eb2dbd79e4cc9ecedf92eee2d135 to your computer and use it in GitHub Desktop. gemma 4 chat template that works with opencode - download the .jinja file and tell vllm to use it via --chat-template chat template gemma large fixed.jinja This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode characters https://github.co/hiddenchars | {%- macro format parameters properties, required -%} | | | {%- set standard keys = 'description', 'type', 'properties', 'required', 'nullable' -%} | | | {%- set ns = namespace found first=false -%} | | | {%- for key, value in properties | dictsort -%} | | | {%- set add comma = false -%} | | | {%- if key not in standard keys -%} | | | {%- if ns.found first %},{% endif -%} | | | {%- set ns.found first = true -%} | | | {{ key }}:{ | | | {%- if value 'description' -%} | | | description:<|"| {{ value 'description' }}<|"| | | | {%- set add comma = true -%} | | | {%- endif -%} | | | {%- if value 'type' | upper == 'STRING' -%} | | | {%- if value 'enum' -%} | | | {%- if add comma %},{%- else -%} {%- set add comma = true -%} {% endif -%} | | | enum:{{ format argument value 'enum' }} | | | {%- endif -%} | | | {%- elif value 'type' | upper == 'ARRAY' -%} | | | {%- if value 'items' is mapping and value 'items' -%} | | | {%- if add comma %},{%- else -%} {%- set add comma = true -%} {% endif -%} | | | items:{ | | | {%- set ns items = namespace found first=false -%} | | | {%- for item key, item value in value 'items' | dictsort -%} | | | {%- if item value is not none -%} | | | {%- if ns items.found first %},{% endif -%} | | | {%- set ns items.found first = true -%} | | | {%- if item key == 'properties' -%} | | | properties:{ | | | {%- if item value is mapping -%} | | | {{- format parameters item value, value 'items' 'required' | default -}} | | | {%- endif -%} | | | } | | | {%- elif item key == 'required' -%} | | | required: | | | {%- for req item in item value -%} | | | <|"| {{- req item -}}<|"| | | | {%- if not loop.last %},{% endif -%} | | | {%- endfor -%} | | | | | | {%- elif item key == 'type' -%} | | | {%- if item value is string -%} | | | type:{{ format argument item value | upper }} | | | {%- else -%} | | | type:{{ format argument item value | map 'upper' | list }} | | | {%- endif -%} | | | {%- else -%} | | | {{ item key }}:{{ format argument item value }} | | | {%- endif -%} | | | {%- endif -%} | | | {%- endfor -%} | | | } | | | {%- endif -%} | | | {%- endif -%} | | | {%- if value 'nullable' %} | | | {%- if add comma %},{%- else -%} {%- set add comma = true -%} {% endif -%} | | | nullable:true | | | {%- endif -%} | | | {%- if value 'type' | upper == 'OBJECT' -%} | | | {%- if value 'properties' is defined and value 'properties' is mapping -%} | | | {%- if add comma %},{%- else -%} {%- set add comma = true -%} {% endif -%} | | | properties:{ | | | {{- format parameters value 'properties' , value 'required' | default -}} | | | } | | | {%- elif value is mapping -%} | | | {%- if add comma %},{%- else -%} {%- set add comma = true -%} {% endif -%} | | | properties:{ | | | {{- format parameters value, value 'required' | default -}} | | | } | | | {%- endif -%} | | | {%- if value 'required' -%} | | | {%- if add comma %},{%- else -%} {%- set add comma = true -%} {% endif -%} | | | required: | | | {%- for item in value 'required' | default -%} | | | <|"| {{- item -}}<|"| | | | {%- if not loop.last %},{% endif -%} | | | {%- endfor -%} | | | | | | {%- endif -%} | | | {%- endif -%} | | | {%- if add comma %},{%- else -%} {%- set add comma = true -%} {% endif -%} | | | type:<|"| {{ value 'type' | upper }}<|"| } | | | {%- endif -%} | | | {%- endfor -%} | | | {%- endmacro -%} | | | {%- macro format function declaration tool data -%} | | | declaration:{{- tool data 'function' 'name' -}}{description:<|"| {{- tool data 'function' 'description' -}}<|"| | | | {%- set params = tool data 'function' 'parameters' -%} | | | {%- if params -%} | | | ,parameters:{ | | | {%- if params 'properties' -%} | | | properties:{ {{- format parameters params 'properties' , params 'required' -}} }, | | | {%- endif -%} | | | {%- if params 'required' -%} | | | required: | | | {%- for item in params 'required' -%} | | | <|"| {{- item -}}<|"| | | | {{- ',' if not loop.last -}} | | | {%- endfor -%} | | | , | | | {%- endif -%} | | | {%- if params 'type' -%} | | | type:<|"| {{- params 'type' | upper -}}<|"| } | | | {%- endif -%} | | | {%- endif -%} | | | {%- if 'response' in tool data 'function' -%} | | | {%- set response declaration = tool data 'function' 'response' -%} | | | ,response:{ | | | {%- if response declaration 'description' -%} | | | description:<|"| {{- response declaration 'description' -}}<|"| , | | | {%- endif -%} | | | {%- if response declaration 'type' | upper == 'OBJECT' -%} | | | type:<|"| {{- response declaration 'type' | upper -}}<|"| } | | | {%- endif -%} | | | {%- endif -%} | | | } | | | {%- endmacro -%} | | | {%- macro format argument argument, escape keys=True -%} | | | {%- if argument is string -%} | | | {{- '<|"| ' + argument + '<|"| ' -}} | | | {%- elif argument is boolean -%} | | | {{- 'true' if argument else 'false' -}} | | | {%- elif argument is mapping -%} | | | {{- '{' -}} | | | {%- set ns = namespace found first=false -%} | | | {%- for key, value in argument | dictsort -%} | | | {%- if ns.found first %},{% endif -%} | | | {%- set ns.found first = true -%} | | | {%- if escape keys -%} | | | {{- '<|"| ' + key + '<|"| ' -}} | | | {%- else -%} | | | {{- key -}} | | | {%- endif -%} | | | :{{- format argument value, escape keys=escape keys -}} | | | {%- endfor -%} | | | {{- '}' -}} | | | {%- elif argument is sequence -%} | | | {{- ' ' -}} | | | {%- for item in argument -%} | | | {{- format argument item, escape keys=escape keys -}} | | | {%- if not loop.last %},{% endif -%} | | | {%- endfor -%} | | | {{- ' ' -}} | | | {%- else -%} | | | {{- argument -}} | | | {%- endif -%} | | | {%- endmacro -%} | | | {%- macro strip thinking text -%} | | | {%- set ns = namespace result='' -%} | | | {%- for part in text.split '