Skip to content

fix(agent): o reparo carimbava um modelo com desligamento marcado (CRM-464) - #61

Merged
gomessguii merged 2 commits into
developfrom
danilocarneiro/crm-464-default-de-reparo-modelo-vigente
Aug 31, 2026
Merged

fix(agent): o reparo carimbava um modelo com desligamento marcado (CRM-464)#61
gomessguii merged 2 commits into
developfrom
danilocarneiro/crm-464-default-de-reparo-modelo-vigente

Conversation

@daniloleonecarneiro

@daniloleonecarneiro daniloleonecarneiro commented Aug 31, 2026

Copy link
Copy Markdown
Contributor

O problema

Dois pontos deste serviço repetem o reparo do agente sequential/parallel/loop que está sem sub_agentsget_agent e get_agents_by_account. Os dois coagem para llm e, quando o agente não tem modelo próprio, atribuíam gpt-4.1-nano, que a OpenAI desliga em 23/10/2026.

O reparo faz db.commit(), então o id morto era gravado no agente do cliente, não apenas tentado uma vez.

O que muda

O default passa a ser openai/gpt-5.6-luna, numa constante de módulo — o valor estava escrito duas vezes, e a constante faz a próxima varredura achar os dois pontos de uma vez.

Sobre a escolha: tier econômico da família vigente, conferido contra catálogo JSON (canonical_slug: openai/gpt-5.6-luna-20260709), e já uma das opções do ModelSelector.

Sobre o prefixo de provider: aqui ele pesa mais do que no core-service, porque é este serviço que monta o LiteLlm em llm_agent_builder.py. Verificado na LiteLLM pinada (1.68.2):

id resolve para
gpt-4.1-nano openai
gpt-5.6-luna openai
luna-5.6 BadRequestError: LLM Provider NOT provided
openai/some-new-model openai

O nome cru só resolve quando casa com uma família que a LiteLLM já conhece. Com prefixo, qualquer id futuro roteia. normalize_model_for_provider não interfere neste caminho — ela só age em openrouter.

O agente que já roda não é tocado

O reparo só atribui modelo quando o agente não tem nenhum. Um agente com modelo já escolhido passa pelo reparo e sai com o que tinha, inclusive um modelo perto do fim de vida — é a garantia de que apertar a lista de modelos oferecidos não desliga fluxo de cliente em execução. Coberto por teste.

Verificação

Três testes novos em tests/unit/test_agent_repair_default_model.py, exercitando os dois pontos de entrada de verdade (não a constante): o reparo por get_agent carimba o modelo vigente e comita, o reparo por get_agents_by_account carimba o mesmo, e nenhum dos dois reaponta um modelo que o agente já tinha.

Provados por mutação — revertendo a constante para gpt-4.1-nano, os dois primeiros caem. As asserções usam a string literal em vez de importar DEFAULT_REPAIR_MODEL, senão passariam com qualquer coisa em que a constante apodrecesse.

80 passed no recorte -k "agent or model or litellm". tests/unit/test_exception_handlers.py não coleta na develop por um ImportError de generic_exception_handler que não tem relação com esta mudança — confirmei que já falha sem ela.

Nota para quem revisar

O mesmo default existia no evo-ai-core-service-community (agent_service.go), corrigido em PR irmão. São 3 call sites em 2 repos e os dois lados precisam entrar.

Summary by Sourcery

Update agent repair logic to persist a current OpenAI model only when malformed agents lack an assigned model.

Bug Fixes:

  • Replace the retired agent-repair default model with the current provider-qualified model so malformed agents no longer persist an unavailable model identifier.
  • Preserve any model already assigned to an agent during repair.

Enhancements:

  • Centralize the repair default model in a module-level constant for consistent maintenance across repair entry points.

Tests:

  • Add coverage for both agent repair entry points, including model persistence and preservation of existing models.

…M-464)

Mesma correção do core-service, nos dois call sites que o Python tem: get_agent
e get_agents_by_account repetem o reparo do agente sequential/parallel/loop sem
sub_agents, e ambos atribuíam gpt-4.1-nano quando o agente não tinha modelo
próprio. A OpenAI desliga esse modelo em 23/10/2026, e o reparo faz db.commit()
— o id morto era gravado no agente do cliente, não apenas tentado uma vez.

Passa a apontar para openai/gpt-5.6-luna, com prefixo de provider. Aqui o
prefixo importa mais do que no Go: é este serviço que monta o LiteLlm, e a
LiteLLM só adivinha um nome cru quando ele casa com uma família que ela já
conhece, levantando BadRequestError em qualquer outro. O valor sai de uma
constante de módulo para que a próxima varredura ache os dois pontos de uma vez.

Modelo só é atribuído quando o agente não tem nenhum — o que o cliente já
escolheu nunca é reapontado, e isso agora tem teste.
@sourcery-ai

sourcery-ai Bot commented Aug 31, 2026

Copy link
Copy Markdown

Reviewer's Guide

Atualiza o default persistido para agentes sequential/parallel/loop sem modelo próprio, centralizando o valor como openai/gpt-5.6-luna e cobrindo os dois caminhos de reparo com testes que também garantem a preservação de modelos existentes.

Sequence diagram for agent model repair and persistence

sequenceDiagram
    participant Caller
    participant AgentService
    participant Database

    Caller->>AgentService: get_agent(agent_id)
    AgentService->>AgentService: get_agents_by_account(account_id)
    alt agent.model is absent
        AgentService->>AgentService: DEFAULT_REPAIR_MODEL
        AgentService->>Database: db.commit()
    else agent.model already exists
        AgentService-->>Caller: preserve existing model
    end
    AgentService-->>Caller: repaired agent
Loading

File-Level Changes

Change Details Files
Substitui o modelo padrão usado no reparo de agentes malformados por um valor vigente e centralizado, preservando modelos já configurados.
  • Define DEFAULT_REPAIR_MODEL como openai/gpt-5.6-luna, incluindo o prefixo exigido pelo LiteLLM.
  • Usa a constante nos reparos executados por get_agent e get_agents_by_account.
  • Mantém o modelo existente quando o agente já possui um modelo.
src/services/agent_service.py
Adiciona testes de unidade que exercitam os dois pontos de entrada do reparo e verificam persistência e não-regressão.
  • Verifica que get_agent converte o agente, atribui o novo modelo e executa commit.
  • Verifica que get_agents_by_account atribui o mesmo modelo.
  • Verifica que um modelo previamente escolhido não é substituído.
  • Usa o valor esperado literal para detectar regressões na constante.
tests/unit/test_agent_repair_default_model.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've reviewed your changes and they look great!

Sourcery assessment

Needs a human reviewer. This changes the persisted default model for every malformed agent that enters the repair path, so an invalid, retired, or unsuitable model ID can immediately affect all such customers and cause failed or misrouted model requests. Reverting stops future assignments but does not restore model values already written to customer agents.


Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

…4 review)

Das tres portas de reparo, a de listagem era a unica sem asserir persistencia —
e e justo a que o PR chama de pior ("gravado no agente do cliente so por alguem
abrir a listagem"). test_get_agents_by_account_repair_stamps_the_same_model
passa a aferir db.commit.called, como o teste de get_agent ja fazia.

test_repair_keeps_a_model_the_agent_already_has passava a vazio pelo mesmo
motivo do lado Go: sem aferir que o agente foi coagido para llm, um guard de
sub_agents que parasse de casar deixaria o modelo intocado e o teste verde.

Provado por mutacao: removendo o db.commit() do bloco de reparo de
get_agents_by_account, so o teste novo cai; anulando o guard de sub_agents nas
duas portas, os tres testes caem (antes, o de preservacao passava).

O comentario da constante cai de 6 para 2 linhas e o docstring do teste perde o
id do card — o commit e a PR ja carregam CRM-464.
@gomessguii
gomessguii merged commit e84f828 into develop Aug 31, 2026
5 checks passed
@gomessguii
gomessguii deleted the danilocarneiro/crm-464-default-de-reparo-modelo-vigente branch August 31, 2026 16:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants