Documents the Rails console procedure to toggle captain_contact_memory_extraction_enabled and captain_contact_memory_recall_enabled on Account#custom_attributes, including rollout phasing (extraction-first, then recall), rollback, bulk enablement, and post-activation verification queries. The UI toggles in Captain Settings are deferred: the existing FeatureToggle component is coupled to the captain_features hash and cannot be reused for custom_attributes-backed flags without a new component and a new account-update store action. Scope and implementation notes for that follow-up are included at the end of the document. Task 5.4 of Captain Semantic Memory epic (Phase 5).
161 lines
5.4 KiB
Markdown
161 lines
5.4 KiB
Markdown
# Habilitando a Memória Semântica do Captain (Contact Memory)
|
||
|
||
Este guia explica como ligar/desligar, por conta (Account), as duas feature flags
|
||
que controlam o subsistema de memória semântica de contatos do Captain:
|
||
|
||
- `captain_contact_memory_extraction_enabled` — habilita a extração assíncrona de
|
||
fatos duráveis a partir das conversas do contato (job
|
||
`Captain::ContactMemories::ExtractFromConversationJob` e derivados).
|
||
- `captain_contact_memory_recall_enabled` — habilita a recuperação das memórias
|
||
mais relevantes na construção do prompt do assistente
|
||
(`Captain::Assistant::MemoryPromptInjector`).
|
||
|
||
Ambas são armazenadas em `Account#custom_attributes` (JSONB) e lidas via os
|
||
helpers definidos em `app/models/concerns/captain_featurable.rb`:
|
||
|
||
```ruby
|
||
account.captain_contact_memory_extraction_enabled? # => true/false
|
||
account.captain_contact_memory_recall_enabled? # => true/false
|
||
```
|
||
|
||
Por padrão, ambas retornam `false` quando a chave não está presente.
|
||
|
||
> **Observação:** estas flags vivem em `custom_attributes` — não confundir com o
|
||
> hash `captain_features` (usado pelos toggles da tela de Captain Settings para
|
||
> Editor/Assistant/Copilot/Label Suggestion/Help Center Search/Audio
|
||
> Transcription). O toggle de UI para Contact Memory está deferido; use este
|
||
> procedimento via console até que a UI seja implementada em uma iteração
|
||
> futura.
|
||
|
||
## Procedimento — Rails console
|
||
|
||
### 1. Abrir o console
|
||
|
||
Em produção/staging (container `rails`):
|
||
|
||
```bash
|
||
docker compose exec rails bin/rails console
|
||
```
|
||
|
||
Localmente:
|
||
|
||
```bash
|
||
bin/rails console
|
||
```
|
||
|
||
### 2. Habilitar as flags para uma conta específica
|
||
|
||
Substitua `ACCOUNT_ID` pelo ID da conta desejada.
|
||
|
||
```ruby
|
||
account = Account.find(ACCOUNT_ID)
|
||
|
||
account.update!(
|
||
custom_attributes: account.custom_attributes.merge(
|
||
'captain_contact_memory_extraction_enabled' => true,
|
||
'captain_contact_memory_recall_enabled' => true
|
||
)
|
||
)
|
||
|
||
# Verificação
|
||
account.captain_contact_memory_extraction_enabled? # => true
|
||
account.captain_contact_memory_recall_enabled? # => true
|
||
```
|
||
|
||
### 3. Desabilitar as flags
|
||
|
||
```ruby
|
||
account = Account.find(ACCOUNT_ID)
|
||
|
||
account.update!(
|
||
custom_attributes: account.custom_attributes.merge(
|
||
'captain_contact_memory_extraction_enabled' => false,
|
||
'captain_contact_memory_recall_enabled' => false
|
||
)
|
||
)
|
||
```
|
||
|
||
Se preferir remover as chaves ao invés de setar `false` (comportamento idêntico,
|
||
pois o default é `false`):
|
||
|
||
```ruby
|
||
account = Account.find(ACCOUNT_ID)
|
||
account.custom_attributes.delete('captain_contact_memory_extraction_enabled')
|
||
account.custom_attributes.delete('captain_contact_memory_recall_enabled')
|
||
account.save!
|
||
```
|
||
|
||
### 4. Habilitar em lote (rollout)
|
||
|
||
Para habilitar em várias contas de uma vez:
|
||
|
||
```ruby
|
||
Account.where(id: [1, 2, 3]).find_each do |account|
|
||
account.update!(
|
||
custom_attributes: account.custom_attributes.merge(
|
||
'captain_contact_memory_extraction_enabled' => true,
|
||
'captain_contact_memory_recall_enabled' => true
|
||
)
|
||
)
|
||
end
|
||
```
|
||
|
||
## Estratégia de rollout recomendada
|
||
|
||
As duas flags são independentes e podem ser habilitadas em fases:
|
||
|
||
1. **Fase de coleta (somente extração):** ligue apenas
|
||
`captain_contact_memory_extraction_enabled`. Os jobs começam a popular a
|
||
tabela `captain_contact_memories` sem afetar o prompt do assistente.
|
||
2. **Fase de uso (coleta + recall):** após acumular dados suficientes (sugestão:
|
||
7–14 dias), ligue também `captain_contact_memory_recall_enabled`. O
|
||
`MemoryPromptInjector` passa a inserir as memórias relevantes no contexto do
|
||
LLM.
|
||
3. **Rollback:** desligar `captain_contact_memory_recall_enabled` sai do prompt
|
||
imediatamente (sem exigir limpeza de dados). Desligar a extração interrompe
|
||
novas coletas mas mantém o histórico.
|
||
|
||
## Verificação pós-ativação
|
||
|
||
Depois de habilitar, confirme via console:
|
||
|
||
```ruby
|
||
# Memórias extraídas para a conta
|
||
Captain::ContactMemory.where(account_id: ACCOUNT_ID).count
|
||
|
||
# Últimas memórias criadas
|
||
Captain::ContactMemory.where(account_id: ACCOUNT_ID)
|
||
.order(created_at: :desc)
|
||
.limit(5)
|
||
.pluck(:id, :contact_id, :content, :created_at)
|
||
```
|
||
|
||
Logs relevantes no Sidekiq: jobs da namespace
|
||
`Captain::ContactMemories::*` (extração, envelhecimento, checagem de
|
||
contradição, detecção de silêncio, atualização de embedding, hard delete).
|
||
|
||
## Próximos passos — UI de toggles (deferido)
|
||
|
||
Um painel "Memória do Cliente" na página de Captain Settings, com dois
|
||
`Switch`es ligados a estas flags, é a evolução natural. Não foi implementado
|
||
nesta task porque:
|
||
|
||
- O componente `FeatureToggle` existente está acoplado ao store
|
||
`captainConfigStore` e ao hash `captain_features`/`captain_models` — não
|
||
cobre flags em `custom_attributes`.
|
||
- Um toggle de `custom_attributes` exige um novo componente + chamada ao
|
||
endpoint de `PATCH /api/v1/accounts/:id` (já existente) e, potencialmente, um
|
||
novo store action para refletir o estado localmente.
|
||
|
||
A implementação deve:
|
||
|
||
1. Criar um `CustomAttributeToggle.vue` em
|
||
`app/javascript/dashboard/routes/dashboard/settings/captain/components/`.
|
||
2. Usar o `AccountAPI` (`app/javascript/dashboard/api/account.js`) para
|
||
persistir via `PATCH /api/v1/accounts/:id` com
|
||
`{ custom_attributes: { ... } }`.
|
||
3. Adicionar uma nova `SectionLayout` em `Index.vue` com título
|
||
"Memória do Cliente" e dois toggles.
|
||
4. Adicionar chaves i18n em
|
||
`app/javascript/dashboard/i18n/locale/{en,pt_BR}/captain.json`.
|