From 1ce07cc78c4dbbf13515f9b1bd7bee30dec2f9e4 Mon Sep 17 00:00:00 2001 From: Rodribm10 Date: Sun, 19 Apr 2026 01:52:13 -0300 Subject: [PATCH] docs(captain-memory): add operator guide for enabling Contact Memory flags (UI toggles deferred) 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). --- docs/captain/enabling-semantic-memory.md | 160 +++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 docs/captain/enabling-semantic-memory.md diff --git a/docs/captain/enabling-semantic-memory.md b/docs/captain/enabling-semantic-memory.md new file mode 100644 index 000000000..48606166c --- /dev/null +++ b/docs/captain/enabling-semantic-memory.md @@ -0,0 +1,160 @@ +# 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`.