From fe4eb95c46e231db8998351c84c6068934d11d64 Mon Sep 17 00:00:00 2001 From: nogueiraguh Date: Sun, 8 Mar 2026 01:41:18 -0300 Subject: [PATCH] fix: merge corrected TF files instead of replacing all - fmTf now merges new code blocks with existing S.tfFiles: updated files are replaced by name, untouched files are preserved, new files are added - System prompt changed: model generates ONLY the files that need fixing instead of all 25 files, drastically reducing output size - Prevents model from discarding existing work when correcting errors --- backend/app.py | 22 +++++++++++++--------- frontend/index.html | 28 ++++++++++++++++++++++------ 2 files changed, 35 insertions(+), 15 deletions(-) diff --git a/backend/app.py b/backend/app.py index c9e5c2f..d67d0c0 100644 --- a/backend/app.py +++ b/backend/app.py @@ -2042,16 +2042,20 @@ Abaixo estão os nomes corretos de resource types do provider oracle/oci. O mode ### REGRA CRÍTICA: Correção de Arquivos Existentes Quando a mensagem do usuário incluir a seção "ARQUIVOS TERRAFORM ATUAIS NO WORKSPACE", significa que JÁ EXISTEM arquivos gerados anteriormente. Neste caso: -1. **NUNCA descarte os arquivos existentes**. Eles são o trabalho atual do usuário. -2. **Gere TODOS os arquivos completos** — mesmo os que não precisaram de alteração. O sistema substitui todos os arquivos do workspace pelo que você gerar. -3. **Corrija APENAS o que está errado**: se o erro é em `networking.tf`, mantenha `variables.tf`, `compute.tf`, `outputs.tf` etc. EXATAMENTE como estão e corrija apenas `networking.tf`. -4. **Analise o output do terraform plan/apply** se incluído na mensagem — ele mostra exatamente qual recurso, atributo ou argumento causou o erro. -5. **Mantenha a mesma estrutura de arquivos**: use os mesmos nomes de arquivo (`// filename: xxx.tf`) que já existem. NÃO renomeie, NÃO reorganize, NÃO mescle arquivos. -6. **Preserve nomes de recursos**: NÃO renomeie recursos existentes (ex: `oci_core_vcn.hub` não deve virar `oci_core_vcn.main`), pois isso causaria destroy+recreate desnecessário. -7. Se o erro for um resource type inválido, consulte a referência de recursos OCI neste prompt para encontrar o nome correto. -8. Se o erro for um argumento inválido (Unsupported argument), remova-o ou substitua pela sintaxe correta. +1. **Gere SOMENTE os arquivos que precisam de correção**. O sistema automaticamente mescla — arquivos não mencionados permanecem intactos. +2. **Use os MESMOS nomes de arquivo** (`// filename: xxx.tf`) dos arquivos originais. NÃO renomeie, NÃO reorganize, NÃO mescle arquivos. +3. **Preserve nomes de recursos**: NÃO renomeie recursos existentes (ex: `oci_core_vcn.hub` não deve virar `oci_core_vcn.main`), pois isso causaria destroy+recreate. +4. **Analise o output do terraform plan/apply** se incluído — ele mostra exatamente qual recurso/atributo causou o erro. +5. Se o erro for um resource type inválido, consulte a referência de recursos OCI neste prompt. +6. Se o erro for um argumento inválido (Unsupported argument), remova-o ou use a sintaxe correta. +7. Gere o arquivo corrigido **COMPLETO** (não apenas a parte alterada) — o sistema substitui o arquivo inteiro pelo novo conteúdo. -**RESUMO**: Ao corrigir, regenere todos os arquivos mantendo conteúdo intacto nos que não têm erro, e corrija cirurgicamente os que têm problema. O resultado deve funcionar no `terraform plan` sem erros na primeira tentativa. +**Exemplo**: Se o workspace tem 10 arquivos e o erro está apenas em `networking.tf`, gere APENAS: +```hcl +// filename: networking.tf + +``` +Os outros 9 arquivos permanecem intactos automaticamente. """ # ── Terraform OCI Resource Reference (generated at build time, updatable at runtime) ── diff --git a/frontend/index.html b/frontend/index.html index 890e22d..5113c15 100644 --- a/frontend/index.html +++ b/frontend/index.html @@ -736,15 +736,31 @@ function fmTf(t){ return '
'+TF_ICON+' Resource Plan — '+S.tfPlan.length+' resource(s)
'+ S.tfPlan.map(x=>'
+'+escHtml(x.type)+''+escHtml(x.desc)+'
').join('')+'
'; }); - // Build files list — merge blocks with same filename, keep separate files + // Build files list — merge new blocks with existing files (corrections preserve untouched files) if(codeBlocks.length){ - const fileMap={}; + const newMap={}; codeBlocks.forEach(b=>{ - if(fileMap[b.name])fileMap[b.name]+='\n\n'+b.content; - else fileMap[b.name]=b.content; + if(newMap[b.name])newMap[b.name]+='\n\n'+b.content; + else newMap[b.name]=b.content; }); - S.tfFiles=Object.entries(fileMap).map(([name,content])=>({name,content,size:content.length,type:'hcl'})); - // Set tfCode to combined content for backward compat + // If existing files: merge (update matched, keep unmatched) + if(S.tfFiles.length){ + const merged=[]; + const usedNew=new Set(); + // Update existing files with new content if name matches + for(const f of S.tfFiles){ + if(newMap[f.name]!=null){merged.push({name:f.name,content:newMap[f.name],size:newMap[f.name].length,type:'hcl'});usedNew.add(f.name)} + else{merged.push(f)} + } + // Add any truly new files + for(const[name,content] of Object.entries(newMap)){ + if(!usedNew.has(name))merged.push({name,content,size:content.length,type:'hcl'}) + } + S.tfFiles=merged; + }else{ + // First generation: set all + S.tfFiles=Object.entries(newMap).map(([name,content])=>({name,content,size:content.length,type:'hcl'})); + } S.tfCode=S.tfFiles.map(f=>'// filename: '+f.name+'\n'+f.content).join('\n\n'); } r=r.replace(/\*\*(.*?)\*\*/g,'$1').replace(/`(.*?)`/g,'$1').replace(/\n/g,'
');