Macros de mapa difuso e lógica de colchetes

Aura suporta o agrupamento de múltiplas regras de pré-processamento em arquivos FUZZY_MAP_pre.py para executá-los sequencialmente como um pipeline coeso assim que uma “Regra inicial” for acionada. Este documento descreve a filosofia de design, a sintaxe e o fluxo de execução deste recurso.

Princípios Básicos de Design

  1. Redundância zero: as regras dentro de um grupo permanecem tuplas padrão do Python: ('replacement_text', r'regex_pattern', limite, flags_and_options)

  2. Dupla usabilidade: regras individuais dentro de um grupo são regras independentes totalmente funcionais. Se o grupo não for acionado, eles serão avaliados normalmente no loop pai.

  3. Marcador de final passivo: O final de um grupo é definido por uma entrada de regra passiva que nunca é correspondida por si só. Ele atua puramente como um marcador de limite para o analisador.

  4. Fallback híbrido (anexar em não correspondência): quando um grupo está ativo, cada regra interna deve contribuir para a saída. Se a regex de uma regra interna corresponder ao texto, a substituição normal ocorrerá. Se não corresponder, o texto substituto será anexado ao texto atual com um espaço.


Sintaxe e Estrutura

Um grupo de macros é definido agrupando uma série de regras padrão entre uma Regra inicial e uma Regra final em FUZZY_MAP_pre.py.

1. A regra inicial

A regra inicial é uma regra padrão que aciona a macro quando correspondida. Inclui uma chave 'group_start' em seu dicionário de opções:

('replacement', r'start_pattern', 100, {'group_start': 'unique_group_name'})

2. Regras Internas

Regras internas são regras padrão colocadas sequencialmente após a Regra Inicial. Eles não requerem nenhum metadado especial:

('inner_replacement', r'inner_pattern', 100, {})

3. A regra final (marcador passivo)

A regra final tem uma substituição None, um padrão vazio e uma chave 'group_end' em seu dicionário de opções:

(None, r'', 100, {'group_end': 'unique_group_name'})

Exemplo concreto

Aqui está um caso de teste prático definido em um arquivo FUZZY_MAP_pre.py:

CODE_BLOCO_3

Cenários de fluxo de execução:

  • Cenário A (Macro acionada):

  • Entrada: "iniciar sandbox com apfel"

  • Fluxo esperado:

  1. A regra inicial corresponde a "start sandbox" e a substitui por "Sandbox:" -> texto atual: "Sandbox: mit apfel".

  2. O grupo 'sandbox_test' é acionado.

  3. Executamos as regras internas recursivamente em "Sandbox: mit apfel":

  • A regra interna 1 corresponde a "apfel" e substitui por "birne" -> texto atual: "Sandbox: mit birne".

  • A regra interna 2 não corresponde a "banane". Como o grupo está ativo, ele volta a anexar "banane" -> Texto atual: "Sandbox: mit birne banane".

  1. O texto final "Sandbox: mit birne banane" é retornado e corrigido pelo LanguageTool.

  • Saída: "Sandbox: com Birne Banane"

  • Cenário B (Macro não acionada - Dupla usabilidade):

  • Entrada: "ein apfel und eine kirsche"

  • Fluxo esperado:

  1. A regra inicial não corresponde. O grupo 'sandbox_test' permanece inativo.

  2. O loop prossegue para a próxima regra.

  3. Regra interna 1: Corresponde a "apfel" e substitui-o por "birne" -> Texto atual: "ein birne und eine kirsche".

  4. Regra Interna 2: Não corresponde. Como o grupo não foi acionado, a regra se comporta como uma regra autônoma normal e nada é anexado.

  5. A Regra Final é ignorada.

  • Saída: "ein birne und eine kirsche"


Detalhes técnicos (sob o capô)

  • Recursão isolada: Quando um grupo é acionado, o mecanismo invoca recursivamente process_text_in_background com custom_rules=[inner_rule]. Isso permite que cada regra interna seja executada em uma passagem de pipeline síncrona e completa.

  • Proteções de desempenho e estabilidade:

  • Sequence Bypass: execuções recursivas internas ignoram a fila de sequência chunk_id para evitar conflitos e atrasos de execução.

  • Supressão de E/S e TTS: execuções recursivas suprimem a gravação de arquivos intermediários e as saídas de fala TTS, garantindo que apenas o texto final estabilizado seja escrito e falado.

  • Proteção de estabilidade: execuções recursivas são interrompidas estritamente após uma iteração para evitar loops infinitos de estabilidade durante acréscimos de fallback.

  • Terminação Segura: A verificação de estabilidade depende estritamente da contagem máxima de iterações (MAX_ITERATIONS_FOR_SAFETY) para evitar loops infinitos, ignorando a limitação baseada em tempo que poderia abortar prematuramente execuções de macros legítimas e mais lentas.

FUZZY_MAP_pre = [
    # Start Rule: Triggers the group 'sandbox_test' when "start sandbox" matches
    ('Sandbox:', r'start\w* sandbox', 100, {'group_start': 'sandbox_test'}),
    
    # Inner Rule 1: Replaces "apfel" with "birne" if present
    ('birne', r'apfel', 100, {}),
    
    # Inner Rule 2: Replaces "banane" if present, otherwise appends "banane"
    ('banane', r'banane', 100, {}),
    
    # End Rule: Passive boundary marker
    (None, r'', 100, {'group_end': 'sandbox_test'}),
]