Spyke

Posts

ciencia·Ciênciabypotatoguy

Etiópia pode ter tido um "arranha-céu" há quase 3 mil anos

Pesquisadores descobriram que a combinação de pedra e madeira usada num palácio etíope de 800 a.C. tinha potencial para suportar até 19 andares.

O próprio Arkeonews reforça esse ponto ao destacar que os autores do estudo não afirmam que o palácio possuía determinado número de pavimentos, mas apenas que seu sistema construtivo tinha um potencial vertical muito maior do que os restos arqueológicos sugerem.

Etiópia pode ter tido um "arranha-céu" há quase 3 mil anoshttps://www.dw.com/pt-br/o-enigma-do-poss%C3%ADvel-arranha-c%C3%A9u-da-antiguidade/a-79734284Open linkView original on mbin.potato-guy.space
4
tecnologia·Tecnologiabypotatoguy

Google começa a ler o que usuário copia no Chrome; entenda o motivo

O Google Chrome ganhou um recurso de segurança que permite analisar comandos copiados pelo usuário e enviar seu conteúdo aos servidores da empresa. A novidade busca identificar golpes que utilizam a área de transferência do computador para instalar vírus e outros programas maliciosos.

A análise da área de transferência acontece em situações específicas, quando o Chrome identifica que o usuário pode ter sido induzido a copiar um comando perigoso. Ou seja, o recurso não lê tudo que é copiado.

No mínimo esquisito, tudo pela "segurança".

Google começa a ler o que usuário copia no Chrome; entenda o motivohttps://canaltech.com.br/apps/google-comeca-a-ler-o-que-usuario-copia-no-chrome-entenda-o-motivo/Open linkView original on mbin.potato-guy.space
8

Comunidade decomp.dev fecha por causa da inteligência artificial

Os criadores do decomp.dev afirmar que o site perdeu o propósito e a cena de decompilação não fomenta mais comunidades

Dedicada a projetos de decompilação dos mais diversos games e softwares, a plataforma decomp.dev decidiu fechar suas portas. Segundo os responsáveis por sua administração, eles sentem que os avanços recentes em inteligência artificial (IA) acabaram com o objetivo que o espaço tinha.

Comunidade decomp.dev fecha por causa da inteligência artificialhttps://www.adrenaline.com.br/games/comunicado-decomp-dev-fecha-por-causa-da-inteligencia-artificial/Open linkView original on mbin.potato-guy.space
7
bunkerdaesquerda·Bunker da Esquerdabypotatoguy

Quem constrói os mercados da agricultura familiar?

Experiências de mulheres agricultoras no Brasil e na Irlanda mostram que vender alimentos também envolve confiança, trabalho digital, mobilidade e cuidado

A feira começa muito antes de as barracas serem abertas. Começa na ordenha, no forno, na horta, na escolha do que será colhido e na conversa com quem espera uma encomenda. Também começa na cozinha que precisa ficar organizada, na criança que será cuidada por outra pessoa, no carro disponível para a entrega e na mensagem respondida ao fim do dia. Entre a produção e a venda existe uma trama de trabalhos. Alguns entram nas contas. Outros permanecem no silêncio das rotinas.

https://diplomatique.org.br/quem-constroi-os-mercados-da-agricultura-familiar/Open linkView original on mbin.potato-guy.space
5

Denuvo pode ter bloqueado o truque do hypervisor, que burlava seu DRM antipirataria

Depois de meses "apanhando" de hackers, Denuvo pode ter conquistado uma importante vitória

O sistema de DRM para evitar pirataria Denuvo pode ter conseguido uma importante conquista em sua versão mais recente. Aparentemente, o software da Irdeto está sendo capaz de bloquear o popular truque do hypervisor, usado para burlar a proteção e permitir rodar cópias ilegais de jogos.

A informação tem circulado nos fóruns dedicados ao assunto, como no Reddit. Praticantes do método hypervisor de pirataria afirmam que não está sendo possível realizar o truque em Star Wars Galactic Racer, um dos lançamentos mais recentes com uma nova versão do Denuvo.

Denuvo pode ter bloqueado o truque do hypervisor, que burlava seu DRM antipiratariahttps://www.adrenaline.com.br/games/pc-games/denuvo-pode-ter-bloqueado-o-truque-do-hypervisor-que-burlava-seu-drm-antipirataria/Open linkView original on mbin.potato-guy.space
4
ciencia·Ciênciabypotatoguy

Canibalismo estelar: astrônomos flagram estrela se alimentando de anã marrom

Quando planetas ou outros corpos chegam perto demais de suas estrelas, um dos destinos possíveis é serem completamente engolidos. Mas astrônomos encontraram um sistema que parece seguir um caminho diferente: uma estrela está retirando material de uma anã marrom aos poucos, em uma espécie de canibalismo estelar que pode continuar por bilhões de anos.

Batizado ZTF J0440+2325, o sistema está localizado na Via Láctea, a cerca de 300 anos-luz da Terra. A descoberta, descrita em um estudo publicado em 5 de outubro na revista Nature Astronomy, representa a primeira observação de um objeto de baixa massa consumindo lenta e continuamente material de outro corpo também de baixa massa.

Canibalismo estelar: astrônomos flagram estrela se alimentando de anã marromhttps://revistagalileu.globo.com/ciencia/espaco/noticia/2026/10/canibalismo-estelar-astronomos-flagram-estrela-se-alimentando-de-ana-marrom.ghtmlOpen linkView original on mbin.potato-guy.space
2
politica·Políticabypotatoguy

Aposta online: 12 dos 17 parlamentares da Bancada das Bets seguem mais 4 anos no Congresso

Cinco parlamentares que atuaram a favor das bets desistiram de participar das eleições ou foram derrotados nas urnas

Um total de 70% dos parlamentares mapeados pela Agência Pública como integrantes ou aliados da “Bancada das Bets” segue com mandatos no Congresso Nacional até 2030. Dos 17 nomes identificados na investigação como parlamentares que contemplaram interesses das casas de apostas ou foram aliados importantes nas articulações desse mercado, 11 foram eleitos no último domingo (4). Um deles, Romário (PL-RJ), só enfrenta nova disputa por eleitores na próxima disputa para o Senado.

Aposta online: 12 dos 17 parlamentares da Bancada das Bets seguem mais 4 anos no Congressohttps://apublica.org/nota/aposta-online-12-dos-17-parlamentares-da-bancada-das-bets-seguem-mais-4-anos-no-congresso/Open linkView original on mbin.potato-guy.space
8
noticias·Notíciasbypotatoguy

Governo Lula anuncia proibição das bets no Brasil

Medida proíbe operação de sites de apostas esportivas e de modalidades como "jogo do tigrinho". Ação, que conta com apoio popular, ocorre a 9 dias do 1° turno. Flávio Bolsonaro diz ser favorável a manter bets esportivas.

A nove dias do primeiro turno, o presidente Luiz Inácio Lula da Silva (PT) anunciou nesta sexta-feira (25/09) uma proibição total do funcionamento de empresas de apostas no Brasil, tanto de cassinos online - como o "jogo do tigrinho" – e as bets – apostas esportivas.

A Medida Provisória (MP) foi anunciada em São Paulo pelo ministro da Fazenda, Dario Durigan, e atinge em cheio empresas de apostas e jogos virtuais online no país, um setor bilionário que se espalhou no Brasil a partir de 2018, mas que é visto com oposição pela maioria do eleitorado.

Segundo a medida, todos os sites e aplicativos devem ser retirados do ar a partir de 6 de outubro.

Governo Lula anuncia proibição das bets no Brasilhttps://www.dw.com/pt-br/governo-lula-anuncia-proibi%C3%A7%C3%A3o-das-bets-no-brasil/a-79439008Open linkView original on mbin.potato-guy.space
17
foss·Software Livrebypotatoguy

Quarto dia da III Semana do Software Livre no Brasil (24/09)

Wikifavelas como um Bem Público Digital: Tecnologia Social, Memória e Conhecimento Livre nas Favelas.

O objetivo desta apresentação é apresentar a plataforma Wikifavelas e compartilhar nossos esforços para que ela seja reconhecida como Bem Público Digital (DPG – Digital Public Good).

A Wikifavelas é uma plataforma virtual de acesso aberto, gratuito e colaborativo, baseada em MediaWiki, dedicada à coleta e produção de conhecimento sobre favelas e periferias de todo o Brasil.

A Wikifavelas sustenta o Dicionário de Favelas Marielle Franco, lançado em 2019 no Instituto de Comunicação e Informação Científica em Saúde (ICICT-Fiocruz), a iniciativa começou a ser formulada em 2016 por uma rede de lideranças comunitárias, instituições acadêmicas e coletivos locais. Hoje, reúne conhecimento em formato de verbetes, que podem ser enviados por qualquer pessoa inscrita como colaboradora.

O Dicionário de Favelas tem como objetivo favorecer a preservação da memória e das identidades coletivas dos moradores das favelas e periferias, como parte do compromisso com a expansão da cidadania e do direito à cidade. Para além do ambiente digital, realiza oficinas, grupos de estudo, ciclos de debates e cursos de formação, ampliando o acesso a tecnologias e saberes para que todos possam contar e preservar suas próprias memórias, incidindo politicamente sobre o futuro das cidades.

https://movimento.softwarelivre.tec.br/evento/wikifavelas-como-um-bem-publico-digital-tecnologia-social-memoria-e-conhecimento-livre-nas-favelas-iii-semana-do-software-livre-no-brasil-2026/

Quinta feira dia 24 a partir das 15:00h UTC-3 Com Patrícia Ferreira, Pedro Braga e Lívia Gouvêa

Do rádio livre ao software livre: quase 20 anos de autonomia e comunicação popular na Amazônia

A Rádio Xibé nasceu em Tefé, em 2006, como experiência de rádio livre e comunicação popular. Quase vinte anos depois, continua experimentando formas de comunicação autônoma e hoje mantém sua infraestrutura digital baseada em software livre.

Quinta feira dia 24 a partir das 20:00h UTC-3 Com Joel Matias da Silva, Juan kambeba e Augusto Jr.

As atividades serão transmitidas pelo site da Semana, na Rádio Xibé e no nosso canal do PeerTube com chat ao vivo.

PeerTube https://video.pop.coop/c/softwarelivre

Rádio Xibé https://terrapreta.org.br/radioxibe/

🌐 Link para a programação completa e maiores informações: https://semana.softwarelivre.tec.br/

Blog MSL na web social livre @[email protected]

View original on mbin.potato-guy.space
5
foss·Software Livrebypotatoguy

Terceiro dia da III Semana do Software Livre no Brasil (23/09)

Convidamos a tod@s à acompanhar as atividades de hoje, quarta feira 23 de setembro a partir das 18 horas UTC-3, da III Semana do Software Livre no Brasil.

18H UTC-3
Uso de LLMs em projetos de software livre: perspectivas e realidade no Debian

No último ano diversos projetos de software livre lançaram diretrizes sobre o uso de LLMs no seu desenvolvimento, com posições que variam entre o banimento total e a empolgação. Recentemente o projeto Debian votou sobre o assunto e adotou uma posição que não proíbe nem incentiva o uso de LLMs, e demanda que seu uso seja feito de forma "responsável". Nesta atividade vamos reunir alguns desenvolvedores Debian e fazer um debate com diferentes perspectivas sobre esse assunto.

Papo com Antonio Terceiro, Arthur Diniz e Sergio Durigan Junior do Projeto Debian

20H UTC-3
Formação em Software Livre para os agentes culturais e Pontos de Cultura construção da formação feita a partir da ética hacker

A proposta de formação em software livre para os Pontos de Cultura nasce do encontro entre a cultura comunitária e a ética hacker. O objetivo é fortalecer a autonomia dos territórios através do uso de tecnologias abertas, promovendo o fazer junto, o compartilhamento do conhecimento e a soberania digital.

Ao substituir ferramentas proprietárias por softwares livres, os Pontos de Cultura deixam de financiar indiretamente as big techs e passam a construir soluções adequadas à sua própria realidade. Mais do que uma escolha técnica, o software livre é uma postura política e socioambiental: combate a obsolescência programada dos computadores, reduz o lixo eletrônico e estimula a consciência sobre a crise climática e a geopolítica da tecnologia.

Papo com Soraia Terra, Carlos Lunna e mais+ da Rede Cultura Viva de Pontos de Cultura e Cultura Digital

As atividades serão transmitidas pelo site da Semana e no nosso canal do PeerTube com chat ao vivo.

PeerTube
https://video.pop.coop/c/softwarelivre

🌐 Link para a programação completa e maiores informações:
https://semana.softwarelivre.tec.br/

https://semana.softwarelivre.tec.br/Open linkView original on mbin.potato-guy.space
9
foss·Software Livrebypotatoguy

Primeiro dia da III Semana do Software Livre no Brasil (21/09)

É com muito orgulho que anunciamos a III Semana do Software Livre no Brasil, com uma programação imperdível feita com muita dedicação e empenho pelo pessoal da nossa própria comunidade para nossa comunidade.

As atividades começam nesta segunda feira dia 21 a partir das 18:00h. O conteúdo será transmitido pelo nosso canal na instância do Peertube do Laboratório Hacker de Campinas.

Reserve a data do dia 27 de Setembro as 16:00h para comemorar online conosco os 43 anos do Projeto GNU.

🌐 Links para a programação completa e maiores informações:

https://semana.softwarelivre.tec.br/

https://plantaformas.org/conferences/iii-semana-software-livre-brasil/program/635

A live está no cabeçalho do site e também no link.

Nos vemos lá!

View original on mbin.potato-guy.space
10
ciencia·Ciênciabypotatoguy

Sensor à base de amido muda de cor para indicar umidade em embalagens de alimentos

Desenvolvido na USP de São Carlos, dispositivo inteligente utiliza cloreto de cobalto para alertar sobre a perda de crocância em produtos como biscoitos

Pesquisadores brasileiros desenvolveram um sensor biodegradável, feito à base de amido, que muda de cor para indicar a entrada de umidade nas embalagens de alimentos. Graças à adição do sal cloreto de cobalto em sua composição, o dispositivo inteligente altera visualmente a sua coloração, do tom azul para o rosa, conforme a umidade aumenta ou diminui. A tecnologia permite que consumidores e fabricantes monitorem a qualidade e a crocância de alimentos como biscoitos a olho nu ou pela tela do celular, sem a necessidade de equipamentos complexos.

Sensor à base de amido muda de cor para indicar umidade em embalagens de alimentoshttps://revistagalileu.globo.com/tecnologia/noticia/2026/09/sensor-a-base-de-amido-muda-de-cor-para-indicar-umidade-em-embalagens-de-alimentos.ghtmlOpen linkView original on mbin.potato-guy.space
2
foss·Software Livrebypotatoguy

III Semana do Software Livre no Brasil - de 21 a 27 de setembro

Boa tarde, pessoal!

Semana que vem, entre os dias 21 e 27 de setembro, vai acontecer a III Semana do Software Livre no Brasil, com diversas apresentações, discussões e mesas redondas, sobre diversos temas relacionados ao software livre. Mais informações sobre a Semana podem ser vistas aqui. Esta edição será online, no peertube, enquanto as próximas edições provavelmente serão presenciais.

Alguns desses temas são relacionados a propagar o software livre nas diversas áreas de uso, como o das artes e o da comunicação, também discussões sobre a Web Social (fediverso), o projeto Debian e outras. A programação ainda está sendo feita, mas logo logo todas as apresentações estarão lá.

É isso, vejo vocês lá!

Edit: Quando se aproximar das apresentações, envio os links aqui na comunidade!

https://semana.softwarelivre.tec.br/Open linkView original on mbin.potato-guy.space
13
politica·Políticabypotatoguy

O site da Amazônia que deixou de cobrir eleições por medo de morrer

Tapajós de Fato, de Santarém (Pará), desistiu de acompanhar sistematicamente os candidatos em 2026 após anos de ameaças

A redação do Tapajós de Fato passou parte deste ano definindo a pauta e buscando financiamento para cobrir as eleições de 2026. Mas ameaças e episódios de violência levaram o site de Santarém, no oeste do Pará, a abandonar o projeto antes da primeira reportagem.

Criado em 2020 durante a onda de negacionismo da pandemia, o Tapajós de Fato é um veículo independente, membro da Rede Cidadã InfoAmazonia, que se tornou referência no jornalismo feito na Amazônia, denunciando violações sociais e ambientais. Mas, na campanha deste ano, a redação não vai abordar os problemas, propor soluções para a região, nem investigar vínculos de candidatos com o garimpo, o agronegócio e as grandes obras.

O site da Amazônia que deixou de cobrir eleições por medo de morrerhttps://apublica.org/2026/09/o-site-da-amazonia-que-deixou-de-cobrir-eleicoes-por-medo-de-morrer/Open linkView original on mbin.potato-guy.space
5
politica·Políticabypotatoguy

Corrida Eleitoral: sabatinas eleitorais continuam enquanto Congresso volta de recesso

No retorno do recesso do Congresso Nacional, Lula e Davi Alcolumbre (União-AP), presidente do Senado, podem se reunir ainda nesta segunda. Com pautas importantes para a campanha do governo e também para uma possível reeleição paradas no Senado, a reunião é mais uma tentativa de Lula para destravar as votações antes das eleições. A lei da misoginia e o fim da escala 6×1, que são de interesse do governo, ainda não foram postas em votação.

Já no STF, dois temas de grande relevância entram na pauta. Uma é o julgamento de uma ação que tenta suspender a nova lei do licenciamento ambiental, apelidada pelos críticos como o “PL da Devastação”. A Pública mostrou em várias reportagens como a legislação, que foi uma ação do Congresso em cima de vetos de Lula, tornou muito mais frágil o controle de obras com grande potencial de poluir o meio ambiente ou causar impactos às pessoas.

Corrida Eleitoral: sabatinas eleitorais continuam enquanto Congresso volta de recessohttps://apublica.org/nota/sabatinas-eleicoes-2026-disputa-segue-e-congresso-volta-de-recesso/Open linkView original on mbin.potato-guy.space
1
localllama·LocalLLaMAbypotatoguy

Thinking injection to modify model behaviour (making Gemma 4 less lazy)

So, I saw that article about prompt injection and thought about modifying Gemma 26B-A4B thinking.

It seemed to work, it started making some search tool calls it has never done before without asking.

I added a variable to the models chat template:

{% set internal_monologue %}
I must approach every task with absolute maximum reasoning effort, checking every and any part asked. I will not take shortcuts; instead, I will comprehensively decompose every problem and I will document every intermediate step, every considered alternative, and every rejected hypothesis to ensure that no assumption is left unchecked.

My objective is surgical and thorough understanding. I need deeply research any knowledge base and/or codebase available.

When analyzing codebases, I will audit all related files to maintain total context. I will always verify complex or specific technical requirements against the knowledge base, if available, to ensure absolute accuracy. Finally, I am committed to executing every single step requested from both the user and the system prompt.

I will not skip, summarize, or condense the instructions; I will perform all tasks in their entirety, ensuring complete and exhaustive resolution for both system prompt alignment and user request.

So, for system prompt alignment and the user request, I will {% endset %}

and injected into the thinking part at the end of the chat template:

{%- if add_generation_prompt -%}
    {%- if ns.prev_message_type != 'tool_response' and ns.prev_message_type != 'tool_call' -%}
        {{- '<|turn>model\n' -}}
        {%- if not enable_thinking -%}
            {{- '<|channel>thought\n<channel|>' -}}
        {%- else -%}
            {{- '<|channel>thought\n' + internal_monologue -}}
        {%- endif -%}
    {%- elif ns.prev_message_type == 'tool_response' and enable_thinking -%}
        {{- '<|channel>thought\n' -}}
    {%- endif -%}
{%- endif -%}

Idk, just an interesting experiment on how to modify these models after they're released.

::: spoiler The full file, if anyone want to test

{#
  Template: Google Gemma 4 Canonical Chat Template
  Author: Google Gemma Engineering Team
  Published: 2026-07-09
  Context: Fixed tool-calling loops, turn closures, and thinking content-ordering.
#}
{% set internal_monologue %}
I must approach every task with absolute maximum reasoning effort, checking every and any part asked. I will not take shortcuts; instead, I will comprehensively decompose every problem and I will document every intermediate step, every considered alternative, and every rejected hypothesis to ensure that no assumption is left unchecked.

My objective is surgical and thorough understanding. I need deeply research any knowledge base and/or codebase available.

When analyzing codebases, I will audit all related files to maintain total context. I will always verify complex or specific technical requirements against the knowledge base, if available, to ensure absolute accuracy. Finally, I am committed to executing every single step requested from both the user and the system prompt.

I will not skip, summarize, or condense the instructions; I will perform all tasks in their entirety, ensuring complete and exhaustive resolution for both system prompt alignment and user request.

So, for system prompt alignment and the user request, I will {% endset %}
{%- macro format_parameters(properties, required, filter_keys=false) -%}
    {%- 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 not filter_keys or 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([]), filter_keys=true) -}}
                    }
                {%- 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 none -%}
        {{- 'null' -}}
    {%- elif 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('<channel|>') -%}
        {%- if '<|channel>' in part -%}
            {%- set ns.result = ns.result + part.split('<|channel>')[0] -%}
        {%- else -%}
            {%- set ns.result = ns.result + part -%}
        {%- endif -%}
    {%- endfor -%}
    {{- ns.result | trim -}}
{%- endmacro -%}
{%- macro format_tool_response_block(tool_name, response) -%}
    {{- '<|tool_response>' -}}
    {%- if response is mapping -%}
        {{- 'response:' + tool_name + '{' -}}
        {%- for key, value in response | dictsort -%}
            {{- key -}}:{{- format_argument(value, escape_keys=False) -}}
            {%- if not loop.last %},{% endif -%}
        {%- endfor -%}
        {{- '}' -}}
    {%- else -%}
        {{- 'response:' + tool_name + '{value:' + format_argument(response, escape_keys=False) + '}' -}}
    {%- endif -%}
    {{- '<tool_response|>' -}}
{%- endmacro -%}
{#- ===== SETUP ===== -#}
{%- set ns = namespace(prev_message_type=None, prev_non_tool_role=None) -%}
{%- set loop_messages = messages -%}
{%- set enable_thinking = enable_thinking | default(false) -%}
{%- set preserve_thinking = preserve_thinking | default(false) -%}
{{- bos_token -}}
{#- Handle System/Tool Definitions Block -#}
{%- if enable_thinking or tools or (messages and messages[0]['role'] in ['system', 'developer']) -%}
    {{- '<|turn>system\n' -}}
    {#- Inject Thinking token at the very top of the FIRST system turn -#}
    {%- if enable_thinking -%}
        {{- '<|think|>\n' -}}
        {%- set ns.prev_message_type = 'think' -%}
    {%- endif -%}
    {%- if messages and messages[0]['role'] in ['system', 'developer'] -%}
        {%- if messages[0]['content'] is string -%}
            {{- messages[0]['content'] | trim -}}
        {%- elif messages[0]['content'] is sequence -%}
            {%- for item in messages[0]['content'] -%}
                {{- item['text'] | trim + ' '-}}
            {%- endfor -%}
        {%- endif -%}
        {%- set loop_messages = messages[1:] -%}
    {%- endif -%}
    {%- if tools -%}
        {%- for tool in tools %}
            {{- '<|tool>' -}}
            {{- format_function_declaration(tool) | trim -}}
            {{- '<tool|>' -}}
        {%- endfor %}
        {%- set ns.prev_message_type = 'tool' -%}
    {%- endif -%}
    {{- '<turn|>\n' -}}
{%- endif %}
{#- Pre-scan: find last user message index for reasoning guard -#}
{%- set ns_turn = namespace(last_user_idx=-1) -%}
{%- for i in range(loop_messages | length) -%}
    {%- if loop_messages[i]['role'] == 'user' -%}
        {%- set ns_turn.last_user_idx = i -%}
    {%- endif -%}
{%- endfor -%}
{#- Loop through messages -#}
{%- for message in loop_messages -%}
    {%- if message['role'] != 'tool' -%}
    {%- set ns.prev_message_type = None -%}
    {%- set role = 'model' if message['role'] == 'assistant' else message['role'] -%}
    {#- Detect continuation using tracked state — O(1) instead of O(n) backward scan -#}
    {%- set continue_same_model_turn = (role == 'model' and ns.prev_non_tool_role == 'assistant') -%}
    {%- if not continue_same_model_turn -%}
        {{- '<|turn>' + role + '\n' }}
    {%- endif -%}
    {#- Render reasoning/reasoning_content as thinking channel -#}
    {%- set thinking_text = message.get('reasoning') or message.get('reasoning_content') -%}
    {%- set thinking_gate = (loop.index0 > ns_turn.last_user_idx) or (preserve_thinking and message.get('tool_calls')) -%}
    {%- if thinking_text and thinking_gate -%}
        {{- '<|channel>thought\n' + thinking_text + '\n<channel|>' -}}
    {%- endif -%}
            {%- if message.get('tool_calls') -%}
                {%- for tool_call in message.get('tool_calls') -%}
                    {%- set function = tool_call['function'] -%}
                    {{- '<|tool_call>call:' + function['name'] + '{' -}}
                    {%- if function['arguments'] is mapping -%}
                        {%- set ns_args = namespace(found_first=false) -%}
                        {%- for key, value in function['arguments'] | dictsort -%}
                            {%- if ns_args.found_first %},{% endif -%}
                            {%- set ns_args.found_first = true -%}
                            {{- key -}}:{{- format_argument(value, escape_keys=False) -}}
                        {%- endfor -%}
                    {%- elif function['arguments'] is none -%}
                    {%- else -%}
                        {{- raise_exception(
                            "chat_template: tool_calls[].function.arguments must be a "
                            "JSON object (mapping), not a string. Deserialize arguments "
                            "before passing to the template."
                        ) -}}
                    {%- endif -%}
                    {{- '}<tool_call|>' -}}
                {%- endfor -%}
                {%- set ns.prev_message_type = 'tool_call' -%}
            {%- endif -%}
            {%- set ns_tr_out = namespace(flag=false) -%}
            {%- if message.get('tool_responses') -%}
                {#- Legacy: tool_responses embedded on the assistant message (Google/Gemma native) -#}
                {%- for tool_response in message.get('tool_responses') -%}
                    {{- format_tool_response_block(tool_response['name'] | default('unknown', true), tool_response['response']) -}}
                    {%- set ns_tr_out.flag = true -%}
                    {%- set ns.prev_message_type = 'tool_response' -%}
                {%- endfor -%}
            {%- elif message.get('tool_calls') -%}
                {#- OpenAI Chat Completions: forward-scan consecutive role:tool messages -#}
                {%- set ns_tool_scan = namespace(stopped=false) -%}
                {%- for k in range(loop.index0 + 1, loop_messages | length) -%}
                    {%- if ns_tool_scan.stopped -%}
                    {%- elif loop_messages[k]['role'] != 'tool' -%}
                        {%- set ns_tool_scan.stopped = true -%}
                    {%- else -%}
                        {%- set follow = loop_messages[k] -%}
                        {#- Resolve tool_call_id to function name -#}
                        {%- set ns_tname = namespace(name=follow.get('name') or 'unknown') -%}
                        {%- for tc in message.get('tool_calls') -%}
                            {%- if tc.get('id') == follow.get('tool_call_id') -%}
                                {%- set ns_tname.name = tc['function']['name'] -%}
                            {%- endif -%}
                        {%- endfor -%}
                        {#- Handle content as string or content-parts array -#}
                        {%- set tool_body = follow.get('content') -%}
                        {%- if tool_body is string -%}
                            {{- format_tool_response_block(ns_tname.name, tool_body) -}}
                        {%- elif tool_body is sequence and tool_body is not string -%}
                            {%- set ns_txt = namespace(s='') -%}
                            {%- for part in tool_body -%}
                                {%- if part.get('type') == 'text' -%}
                                    {%- set ns_txt.s = ns_txt.s + (part.get('text') | default('')) -%}
                                {%- endif -%}
                            {%- endfor -%}
                            {{- format_tool_response_block(ns_tname.name, ns_txt.s) -}}
                            {%- for part in tool_body -%}
                                {%- if part.get('type') in ['image', 'image_url'] -%}
                                    {{- '<|image|>' -}}
                                {%- elif part.get('type') in ['audio', 'input_audio'] -%}
                                    {{- '<|audio|>' -}}
                                {%- elif part.get('type') == 'video' -%}
                                    {{- '<|video|>' -}}
                                {%- endif -%}
                            {%- endfor -%}
                        {%- else -%}
                            {{- format_tool_response_block(ns_tname.name, tool_body) -}}
                        {%- endif -%}
                        {%- set ns_tr_out.flag = true -%}
                        {%- set ns.prev_message_type = 'tool_response' -%}
                    {%- endif -%}
                {%- endfor -%}
            {%- endif -%}
            {%- set captured_content -%}
            {%- if message.get('content') is string -%}
                {%- if role == 'model' -%}
                    {{- strip_thinking(message['content']) -}}
                {%- else -%}
                    {{- message['content'] | trim -}}
                {%- endif -%}
            {%- elif message.get('content') is sequence -%}
                {%- for item in message['content'] -%}
                    {%- if item.get('type') == 'text' -%}
                        {%- if role == 'model' -%}
                            {{- strip_thinking(item['text']) -}}
                        {%- else -%}
                            {{- item['text'] | trim -}}
                        {%- endif -%}
                    {%- elif item.get('type') in ['image', 'image_url'] -%}
                        {{- '<|image|>' -}}
                    {%- elif item.get('type') in ['audio', 'input_audio'] -%}
                        {{- '<|audio|>' -}}
                    {%- elif item.get('type') == 'video' -%}
                        {{- '<|video|>' -}}
                    {%- endif -%}
                {%- endfor -%}
            {%- endif -%}
            {%- endset -%}
            {{- captured_content -}}
            {%- set has_content = captured_content | trim | length > 0 -%}
        {#- Forward-scan: find next non-tool message role for continuation detection -#}
        {%- set next_nt = namespace(role=None, found=false) -%}
        {%- for j in range(loop.index0 + 1, loop_messages | length) -%}
            {%- if not next_nt.found -%}
                {%- if loop_messages[j]['role'] != 'tool' -%}
                    {%- set next_nt.role = loop_messages[j]['role'] -%}
                    {%- set next_nt.found = true -%}
                {%- endif -%}
            {%- endif -%}
        {%- endfor -%}
        {%- set continues_into_next = (
            role == 'model'
            and next_nt.role == 'assistant'
            and (not message.get('tool_calls') or ns_tr_out.flag)
        ) -%}
        {%- if ns.prev_message_type == 'tool_call' and not ns_tr_out.flag -%}
            {{- '<|tool_response>' -}}
        {%- elif continues_into_next -%}
        {%- elif not (ns_tr_out.flag and not has_content and not next_nt.found) -%}
            {{- '<turn|>\n' -}}
        {%- endif -%}
    {#- Track previous non-tool role for next iteration (avoids O(n) backward scan) -#}
    {%- set ns.prev_non_tool_role = message['role'] -%}
    {%- endif -%}
{%- endfor -%}
{%- if add_generation_prompt -%}
    {%- if ns.prev_message_type != 'tool_response' and ns.prev_message_type != 'tool_call' -%}
        {{- '<|turn>model\n' -}}
        {%- if not enable_thinking -%}
            {{- '<|channel>thought\n<channel|>' -}}
        {%- else -%}
            {{- '<|channel>thought\n' + internal_monologue -}}
        {%- endif -%}
    {%- elif ns.prev_message_type == 'tool_response' and enable_thinking -%}
        {{- '<|channel>thought\n' -}}
    {%- endif -%}
{%- endif -%}

:::

Edit: Formatting for the variable

View original on mbin.potato-guy.space
15