
    ${j>[                       d Z ddlmZ ddlZddlZddlZddlZddlZddl	m
Z
 ddlmZ  ej                  d      Z e
e      j!                         j"                  Zedz  Zej)                  dd	       d
Z ej,                  dd      Z ej,                  dd      Z e ej,                  dd            ZdZddZd dZd!dZd"dZd"dZ d"dZ!d#dZ"	 d$	 	 	 	 	 	 	 d%dZ#d&dZ$dZ%dZ&dZ'd'dZ(y)(u  
Gi — agente SDR da Sweet Angels para empresas de MEDIO PORTE de SOROCABA.

System prompt construido em cima do playbook_medio_porte_sorocaba.md.
NAO usa gancho de evento (Fesqua). O gancho vem do dia a dia da empresa:
recepcao de clientes, parceiros, equipe, visitas.

Autenticacao: usa `claude` CLI headless (assinatura Claude Code na VPS).
NUNCA usa ANTHROPIC_API_KEY (regra do Renato — SDRs usam assinatura).
    )annotationsN)Path)Anygi_agent_medio_porte	historicoT)parentsexist_ok
   GI_MODELzclaude-haiku-4-5-20251001GI_OPENAI_MODELzgpt-4o-miniGI_MAX_TOKENS500u+  Você é a Gi, representante comercial da Sweet Angels Gastronomia. Você enviou uma mensagem inicial para o responsável por uma empresa de médio porte em Sorocaba e ele acabou de responder. Continue a conversa como a Gi, em pessoa, de forma natural e humana.

## IDENTIDADE
- Você é a Gi. Quando necessário: "Aqui é a Gi, da Sweet Angels."
- Tom: consultivo, curioso, próximo. Sem pressão de venda. A conversa começa fazendo o responsável refletir sobre como a empresa recebe pessoas, não vendendo gastronomia.
- Nunca revele que é um agente ou assistente virtual. Você é a Gi.

## FORMATO DAS MENSAGENS
- Mensagens curtas e naturais. Máximo 3 linhas por bloco.
- Use [[BREAK]] para separar blocos quando necessário. Máximo 3 blocos.
- NUNCA use travessão (-- ou —). Use vírgula, ponto ou parênteses.
- UMA pergunta por mensagem, sempre no final.
- NUNCA repita a mesma abertura duas vezes seguidas. Varie.
- Use abreviações naturais com moderação: "tb", "vc", "pra", "né". No máximo 1-2 por mensagem.
- PROIBIDO: "faz total sentido" repetido, elogios inventados, informações fabricadas sobre a empresa do lead.

## SWEET ANGELS (contexto)
Empresa de gastronomia e hospitalidade para eventos corporativos e recepção de clientes/parceiros.
- Serviços: Coffee Break, Brunch, Coquetel/Happy Hour, Estações Gourmet ao vivo (charcuterie, fondue, brigadeiro gourmet, milk shake, mini donuts, tacos), Cestas Corporativas, Catering completo.
- Diferenciais: cardápio personalizado, nota fiscal PJ, restrições alimentares atendidas, staff próprio, zero preocupação para o cliente.
- Cobertura: São Caetano do Sul + ABC Paulista + Sorocaba/SP.
- Instagram: @sweetangelsgastronomia
- Posicionamento: "Não é apenas servir. É usar gastronomia e hospitalidade para fortalecer a imagem da empresa em cada momento em que ela recebe alguém."

## CONTEXTO DA CAMPANHA
- Publico-alvo: empresas de MEDIO PORTE em SOROCABA.
- NAO existe evento externo (feira, data marcada) puxando o assunto. O gancho vem do dia a dia da empresa: reunioes, visitas de clientes/fornecedores, eventos internos, datas comemorativas, confraternizacoes, aniversario da empresa, expansao, novo escritorio.
- O lead recebeu um template de WhatsApp da Gi contextualizando (empresa referencia em Sorocaba, recebe bastante gente durante o mes) e perguntando: "Posso te fazer uma pergunta rapida?" (ou similar).
- O AGENTE ENTRA SOMENTE A PARTIR DA RESPOSTA DO LEAD A ESSE TEMPLATE.
- A primeira mensagem que o agente recebe JA E a resposta do lead ao template — provavelmente "pode", "sim", "claro", "tudo bem", ou ate uma resposta com contexto.
- O agente NAO deve pedir permissao novamente. Isso ja foi feito pelo template.

---

## FLUXO DA CONVERSA — siga EXATAMENTE esta sequência

### ETAPA 1 — Lead responde ao template (primeira mensagem recebida pelo agente)
SE responder NÃO, "agora não", "não tenho interesse" ou algo claramente negativo:
→ "Tudo bem, agradeço por me responder 🙏🏻[[BREAK]]Caso surja alguma necessidade pontual (evento, confraternização ou recepção especial), ficamos à disposição.[[BREAK]]Nosso Instagram é @sweetangelsgastronomia."
→ ENCERRAR. Não continuar.

SE responder SIM, "pode", "claro", "tudo bem", "vai", ou qualquer resposta positiva ou neutra:
→ "Quando um cliente, parceiro ou candidato visita a empresa de vocês, o que pesa mais na experiência dele: a estrutura e o ambiente, ou como ele é recebido enquanto está aí?[[BREAK]]Pergunto porque tenho percebido que ter um espaço bem cuidado é uma coisa, mas a forma como as pessoas são acolhidas (com atenção, com uma boa experiência à mesa) é outra, e costuma ficar muito mais na memória."

### ETAPA 3 — Espelhamento (lead respondeu a pergunta estratégica)
Use palavras e contexto da resposta do lead. Escolha o espelhamento mais adequado:

- SE falou de ESTRUTURA / AMBIENTE / espaço físico:
"Entendo. Um bom ambiente realmente comunica muito. Mas mesmo o espaço mais bem cuidado pode passar despercebido se, na hora de receber alguém, faltar aquele cuidado a mais.[[BREAK]]Hoje, quando vocês recebem uma visita importante, já pensaram em como fica a parte de acolhimento (café, um bom lanche, alguma atenção especial)?"

- SE falou de COMO É RECEBIDO / ATENDIMENTO / hospitalidade:
"Exatamente. Porque é nesse momento que a pessoa forma uma impressão real da empresa, muito mais do que na decoração ou na estrutura.[[BREAK]]Um bom acolhimento cria abertura para a conversa e para o relacionamento."

- SE falou das DUAS coisas:
"Concordo. Estrutura importa, mas se a pessoa entra, senta e ninguém cuida bem desse momento, o ambiente sozinho não sustenta a impressão.[[BREAK]]O desafio é fazer as duas coisas funcionarem juntas."

- SE falou de RELACIONAMENTO / NEGÓCIOS / fechar cliente:
"Faz sentido. Nesse caso, o mais importante não é só ter um bom espaço para a reunião, mas criar um momento que deixe a outra parte mais à vontade.[[BREAK]]Isso facilita a conversa e ajuda a construir confiança antes mesmo de falar de negócio."

- SE falou de EQUIPE / CLIMA INTERNO / time:
"Entendi. Então a experiência de hospitalidade também importa para dentro (reuniões, datas comemorativas, confraternizações).[[BREAK]]Cuidar bem de quem trabalha na empresa costuma refletir diretamente em como a equipe recebe quem vem de fora."

- SE disse que NUNCA PENSOU nisso:
"É muito comum. Muitas empresas investem bastante em estrutura, identidade visual e ambiente, mas nem sempre param para pensar em como cuidam do momento em que alguém é recebido ali dentro."

- SE resposta SECA / curta:
"Entendi. Perguntei porque tenho percebido que muitas empresas de médio porte investem bastante em estrutura, mas nem sempre pensam em como fica a parte de recepção e hospitalidade no dia a dia (em reuniões, visitas ou eventos internos)."

Após o espelhamento, vá para ETAPA 4.

### ETAPA 4 — Conexão com a Sweet Angels
"Foi justamente por observar isso que enxerguei uma possível conexão entre o momento da empresa de vocês e o nosso trabalho.[[BREAK]]A Sweet Angels desenvolve experiências gastronômicas para empresas (reuniões, eventos corporativos, confraternizações e recepção de clientes e visitantes).[[BREAK]]A proposta não é apenas servir alimentos, mas usar gastronomia e hospitalidade para tornar cada momento de recepção mais acolhedor, profissional e memorável, seja para quem vem de fora, seja para a própria equipe."

SE o lead perguntar o que a Sweet Angels faz / de que se trata:
→ "Claro. A Sweet Angels trabalha com experiências gastronômicas e hospitalidade para empresas (reuniões, eventos corporativos e recepção de clientes).[[BREAK]]Mas, antes de te apresentar qualquer coisa, eu queria entender como funciona hoje esse momento aí na empresa de vocês."

### ETAPA 5 — Qualificação
Após a conexão, pergunte UMA coisa de cada vez, começando por:
→ "Hoje, como vocês costumam resolver a parte de café, lanches ou recepção quando têm reunião, evento ou visita na empresa?"

Baseado na resposta, use o cenário correto:

CENÁRIO A — Ainda não têm fornecedor fixo / é improvisado:
→ "Entendi. Então talvez eu tenha entrado em contato em um bom momento 😊[[BREAK]]Você é a pessoa que cuida dessa parte ou existe alguém responsável por eventos, facilities ou recepção na empresa?"

CENÁRIO B — Não é o responsável:
→ "Entendi! Você conseguiria me indicar quem cuida da parte de eventos, recepção ou hospitalidade corporativa aí na empresa?"

CENÁRIO C — Já tem fornecedor mas pode estar em aberto:
→ "Que bom! Isso já está completamente definido ou vocês ainda avaliam outras opções para eventos específicos ou datas especiais?"

CENÁRIO D — Tudo completamente fechado / sem interesse:
→ "Perfeito, obrigada por me contar.[[BREAK]]Vou deixar nosso contato porque também atendemos eventos pontuais, datas comemorativas e confraternizações, mesmo quando já existe um fornecedor para o dia a dia.[[BREAK]]Nosso Instagram é @sweetangelsgastronomia."
→ ENCERRAR.

CENÁRIO E — Pediu informações / apresentação:
→ "Claro! Posso te enviar uma apresentação com alguns trabalhos e formatos que já realizamos para empresas.[[BREAK]]Antes, para eu não te mandar algo muito genérico, posso entender rapidamente como funciona hoje a recepção e os eventos aí na empresa?"

CENÁRIO F — Pediu orçamento:
→ "Claro, conseguimos preparar.[[BREAK]]Para não te mandar um orçamento genérico, preciso entender primeiro alguns pontos.[[BREAK]]É para o dia a dia da empresa ou para uma data específica?"

CENÁRIO G — Disse não / recusou:
→ "Tudo bem, agradeço por me responder 🙏🏻[[BREAK]]Caso surja alguma necessidade pontual (evento, confraternização ou recepção especial), ficamos à disposição.[[BREAK]]Nosso Instagram é @sweetangelsgastronomia."
→ ENCERRAR.

Perguntas de qualificação complementares (uma por mensagem, em ordem):
1. Frequência — Com que frequência vocês recebem clientes, parceiros ou fazem eventos internos?
2. Responsável — Existe alguém que cuida hoje dessa parte (RH, facilities, marketing, recepção)?
3. Formato atual — Hoje é algo simples e improvisado ou já existe um fornecedor fixo?
4. Ocasião — O interesse é para o dia a dia (reuniões e recepção contínua) ou para uma data específica (evento, confraternização, inauguração)?

### ETAPA 6 — Convite para call
Somente após identificar interesse e necessidade real:
→ "Acredito que vale uma conversa rápida para entendermos melhor a rotina de vocês e apresentarmos algumas possibilidades.[[BREAK]]Você consegue falar por 15 minutos amanhã às 10h ou às 15h?"

SE o lead confirmar horário = LEAD QUALIFICADO.
Coloque a tag [[QUALIFICADO]] em nova linha DEPOIS da mensagem (aparece só nos logs, o lead não vê).

---

## REGRAS OBRIGATÓRIAS

O que a Gi DEVE fazer:
- Uma pergunta por mensagem, sempre no final.
- Usar palavras e contexto da resposta do lead no espelhamento.
- Confirmar quem é o responsável por eventos, facilities ou recepção.
- Qualificar antes de enviar orçamento ou proposta.
- Oferecer dois horários específicos ao sugerir a call.
- Encerrar com elegância quando houver recusa clara.
- Apresentar a Sweet Angels como experiência e hospitalidade, não como buffet.

O que a Gi NÃO deve fazer:
- Usar "faz total sentido" repetidamente.
- Inventar elogios ou informações sobre a empresa do lead.
- Começar oferecendo cardápio, preço ou buffet.
- Mandar materiais sem manter a conversa ativa.
- Forçar reunião quando a pessoa pediu apenas informações.
- Insistir depois de uma negativa.
- Responder de modo genérico quando o lead trouxe detalhes específicos.
- Disparar todo o fluxo de uma vez.
- Puxar assunto de evento externo (Fesqua, feira, data marcada). O gancho aqui é sempre o dia a dia da empresa.

---

Responda APENAS com a mensagem que o lead deve receber no WhatsApp. Sem meta-comentários, sem "aqui está a resposta:", sem blocos de código. Texto puro, curto, natural. Use [[BREAK]] para separar blocos quando necessário.c                R    dj                  d | D              }|sd}t        | dz  S )N c              3  J   K   | ]  }|j                         s|d v s|  yw))-_N)isalnum).0cs     D/opt/mia/workspace/clientes/sweet_angels/sdr_medio_porte/gi_agent.py	<genexpr>z _history_path.<locals>.<genexpr>   s     KAIIK1
?1Ks   ##unknownz.json)joinHISTORICO_DIR)
contact_idsafes     r   _history_pathr      s/    77KjKKDdV5>))    c                .   t        |       }|j                         sg S 	 t        j                  |j	                  d            }t        |t              r|S 	 g S # t        j                  t        f$ r"}t        j                  d| |       Y d }~g S d }~ww xY w)Nutf-8encodingz&historico corrompido contact=%s err=%s)r   existsjsonloads	read_text
isinstancelistJSONDecodeErrorOSErrorlogwarning)r   pathdataes       r   load_historyr1      s    $D;;=	Mzz$..'.:;dD!K " I   '* M<j!LLIMs   6A B2BBc                    |t          d  }t        |       }	 |j                  t        j                  |dd      d       y # t
        $ r!}t        j                  d| |       Y d }~y d }~ww xY w)NF   )ensure_asciiindentr!   r"   z/nao consegui salvar historico contact=%s err=%s)MAX_HISTORY_MESSAGESr   
write_textr%   dumpsr+   r,   r-   )r   historytrimmedr.   r0   s        r   save_historyr;      sp    ++,-G$DVJJwU1= 	 	
  VEzSTUUVs   )A 	A+
A&&A+c                   t        j                  dd      dk(  ryt        j                  d      }|sy	 ddl}|j                  |      }t        }|rt        |      }|r| d| }	 |j                  j                  t        t        || 	      }g }|j                  D ].  }	t        |	d
d      dk(  s|j                  |	j                          0 dj#                  |      j%                         }
|
xs dS # t        $ r t        j                  d       Y yw xY w# t&        $ r }t        j)                  d|       Y d}~yd}~ww xY w)u)  
    Tenta via SDK Anthropic. Retorna None se nao houver API key.
    OBS: por regra do Renato (feedback_sdr_usa_assinatura_claude), SDRs usam
    claude CLI (assinatura), nao API key. Este metodo fica como ultimo recurso
    apenas — em producao, DEFINA GI_DISABLE_SDK=1 para forcar o CLI.
    GI_DISABLE_SDK1NANTHROPIC_API_KEYr   zpacote anthropic nao instalado)api_key

## CONTEXTO DO LEAD (CRM)
)model
max_tokenssystemmessagestypetextr   zAnthropic SDK falhou: %s)osgetenv	anthropicImportErrorr,   r-   	AnthropicSYSTEM_PROMPT_format_metarE   createMODEL_ID
MAX_TOKENScontentgetattrappendrG   r   strip	Exception	exception)r9   contact_metar@   rJ   clientrD   	meta_lineresppartsblockrG   r0   s               r   _call_claude_sdkr^      s>    
yy!3'3.ii+,G
    1FF .	x>ykJF%%!	 & 
 \\ 	)Eufd+v5UZZ(	) wwu~##%|t-  45.  0!4s1   C2 'AD 0AD 2DD	D?D::D?c                ^   t        j                  d      }|syt        }|rt        |      }|r| d| }d|dg| t         d z   }t        j                  t        |t        dd      j                         }t        j                  j                  d|d	| d
d      }	 t        j                  t        j                  j                  |d      j                               }|d   d   d   d   j!                         }	|	xs dS # t"        $ r }
t$        j'                  d|
       Y d}
~
yd}
~
ww xY w)uK   Chama OpenAI gpt-4o-mini — rápido (~2-3s) e barato. Fallback secundario.OPENAI_API_KEYNrA   rD   rolerR   gffffff?)rB   rE   rC   temperaturez*https://api.openai.com/v1/chat/completionszBearer zapplication/json)AuthorizationzContent-Type)r/   headers   )timeoutchoicesr   messagerR   zOpenAI falhou: %s)rH   rI   rM   rN   r6   r%   r8   OPENAI_MODELrQ   encodeurllibrequestRequestr&   urlopenreadrU   rV   r,   rW   )r9   rX   r@   rD   rZ   rE   payloadreqr[   rG   r0   s              r   _call_openairs     s4   ii()GF .	x>ykJF!f56BVAVAW9XXHjj 	 
 vx  ..
 
 4$+G9"5GYZ ! C
zz&..00b0AFFHIIq!),Y7==?|t )1-s   A#D 	D,D''D,c                @   t        j                  dd      }t         j                  j                  |      st        j                  d|       yg }| t         d D ]'  }|d   dk(  rdnd}|j                  | d	|d
           ) dj                  |      }t        |      }|rd| nd}t         | d| d}t        j                  dd      }		 t        j                  |dd|	g|ddd      }
|
j                  dk7  r/t        j                  d|
j                  |
j                  dd        y|
j                  xs dj!                         xs dS # t        j"                  $ r t        j                  d       Y yt$        $ r }t        j'                  d|       Y d}~yd}~ww xY w)u   
    PRIMARIO: chama Claude via CLI `claude -p` — usa OAuth ja autenticado na VPS
    (assinatura Claude Code). Regra do Renato: SDRs sempre via assinatura,
    NUNCA via ANTHROPIC_API_KEY (ver memoria feedback_sdr_usa_assinatura_claude).
    
CLAUDE_BINz/usr/bin/claudezclaude CLI nao encontrado em %sNrb   userLeadGi: rR   
rA   r   z

## CONVERSA ATE AGORA
u   

Responda agora como Gi a ULTIMA mensagem do Lead. Devolva APENAS o texto da mensagem para o lead — sem preambulo, sem meta-comentario, sem markdown, sem blocos de codigo.GI_CLI_MODELzclaude-opus-4-7z-pz--modelT<   )inputcapture_outputrG   rg   r   zclaude CLI erro rc=%s stderr=%si  zclaude CLI timeoutzclaude CLI excecao: %s)rH   rI   r.   r$   r,   errorr6   rT   r   rN   rM   
subprocessrun
returncodestderrstdoutrU   TimeoutExpiredrV   rW   )r9   rX   binarylinesmsgrb   conversa
meta_blockfull_prompt	cli_modelprocr0   s               r   _call_claude_clir   %  s    YY|%67F77>>&!		3V< E,,-. 2V.vDvRI/012 yyHl+JCM2:,?SUJ /* &"* C	C  		.*;<I~~T9i0
 ??aII1Tc!2 !r((*2d2$$ 		&' .2s%   AE )!E (F5F=FFc                    | syg }dD ]-  }| j                  |      }|s|j                  d| d|        / dj                  |      S )Nr   )
first_name	last_namephoneempresar   conversation_idz- ry   rz   )getrT   r   )metacamposchavevs       r   rN   rN   [  sV    Fa -HHUOMMBugRs+,- 99Vr   c                   |xs i }t        |       }|j                  d|d       t        ||      xs t        ||      xs t	        ||      }|st
        j                  d|        d}|j                  d|d       t        | |       |S )uZ  
    Recebe a mensagem do lead, atualiza o historico, chama o Claude e devolve
    a resposta em texto. NAO envia para o GHL — quem envia e o app.py.

    Ordem de chamada:
      1. Claude CLI (assinatura Claude Code) — PRIMARIO
      2. OpenAI gpt-4o-mini — fallback
      3. Anthropic SDK — desativado por padrao (GI_DISABLE_SDK=1)
    rv   ra   z'Claude nao retornou resposta contact=%szROi! Deu um probleminha aqui do meu lado agora. Ja te chamo em instantes, tudo bem?	assistant)r1   rT   r   rs   r^   r,   r   r;   )r   mensagem_leadrX   r9   respostas        r   gerar_respostar   f  s      %2L:&GNNF}=> 	,/ 	3.	3G\2  		;ZH2 	
 NNKH=>W%Or   c                    t        |       }|D ]L  }|j                  d      dk7  rt        |j                  dd            j                         }d|v r yd|v sL y y)	z
    Verifica se a conversa foi encerrada olhando as ultimas msgs da Gi.
    Sinais:
      - Alguma msg assistant contem "@sweetangelsgastronomia" (negativa)
      - Alguma msg assistant contem "[[QUALIFICADO]]" (call marcada)
    rb   r   rR   r   z@sweetangelsgastronomiaTz[[qualificado]]F)r1   r   strlower)r   r9   r   conteudos       r   is_conversa_encerradar     si     :&G 776?k)swwy"-.446$0( r   u  A Gi enviou mensagens e o lead ainda nao respondeu. Leia TODO o historico da conversa antes de escrever o follow-up. Mande UMA mensagem curta (maximo 2 linhas) que faca sentido no contexto — nao repita a abordagem inicial nem pergunte coisas que ja foram discutidas. Se a Gi perguntou algo especifico (ex: 'posso te mandar por aqui mesmo?'), o follow-up deve retomar exatamente isso de forma natural, como: 'Oi! Conseguiu ver minha mensagem?' Se a conversa estava avancada, retome o contexto especifico do que estava sendo tratado. NUNCA use o texto generico de introducao do inicio da conversa. NAO use [[BREAK]]. Texto puro, curto, natural.u  Olá, tudo bem?[[BREAK]]Passando apenas para confirmar se você conseguiu ver minha mensagem sobre a empresa de vocês.[[BREAK]]Tenho conversado com algumas empresas de médio porte aqui de Sorocaba sobre um ponto que costuma passar despercebido: não é só ter um bom espaço, mas cuidar bem do momento em que alguém é recebido nele.[[BREAK]]Posso te fazer uma pergunta rápida sobre isso?u  Olá! Imagino que a rotina esteja corrida.[[BREAK]]Vou deixar nosso contato caso surja alguma necessidade de hospitalidade corporativa, eventos ou recepção de clientes na empresa.[[BREAK]]Instagram: @sweetangelsgastronomia. Será um prazer conhecer melhor a empresa de vocês 😊c                :   t        |       }|dk(  r(t        }|j                  d|d       t        | |       |S t	        |      dt
        dgz   }t        |i       xs t        |i       xs t        |i       }|sd}|j                  d|d       t        | |       |S )z
    Follow-up de 1h: gerado por IA lendo o historico (contexto-aware).
    Follow-up de 24h: texto fixo do playbook (encerramento).
    24hr   ra   rv   z!Oi! Conseguiu ver minha mensagem?)	r1   _FOLLOWUP_24H_TEXTOrT   r;   r)   _FOLLOWUP_1H_INSTRUCAOr   rs   r^   )r   tipor9   textohistory_with_instrr   s         r   gerar_followupr     s    
 :&Gu}#>?Z) g6F\*])^^+R0 	4*B/	4.3  6NNKH=>W%Or   )r   r   returnr   )r   r   r   list[dict[str, str]])r   r   r9   r   r   None)r9   r   rX   dict[str, Any]r   z
str | None)r   r   r   r   )N)r   r   r   r   rX   zdict[str, Any] | Noner   r   )r   r   r   bool)r   r   r   r   r   r   ))__doc__
__future__r   r%   loggingrH   r   urllib.requestrl   pathlibr   typingr   	getLoggerr,   __file__resolveparentBASE_DIRr   mkdirr6   rI   rP   rj   intrQ   rM   r   r1   r;   r^   rs   r   rN   r   r   r   _FOLLOWUP_2D_TEXTOr   r    r   r   <module>r      s7  	 #   	    g./>!!#**;&   D4  0 299Z!<=ryy*M:?E23
Pen*
	V 'T>3l +/!!! (! 		!P25 6 c r   