@areumtecnologia/autonomouscustomerserviceagent 2.0.1 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +498 -198
- package/package.json +1 -2
- package/src/AgentConfig.js +1 -1
- package/src/AgentManager.js +7 -1
package/README.md
CHANGED
|
@@ -1,198 +1,498 @@
|
|
|
1
|
-
# Autonomous Customer Service Agent
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
//
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
1
|
+
# Autonomous Customer Service Agent
|
|
2
|
+
|
|
3
|
+
> **v2.0.1** — Agente autônomo de atendimento ao cliente baseado em IA, desenvolvido com Google Gemini. Suporta múltiplas sessões concorrentes, ferramentas customizadas, retry com backoff exponencial e modos de tratamento de falhas `sync` e `async`.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## ✨ Características
|
|
8
|
+
|
|
9
|
+
| Recurso | Descrição |
|
|
10
|
+
|---|---|
|
|
11
|
+
| **Agentic Loop Completo** | Tool calls encadeados com execução recursiva e contextualizada |
|
|
12
|
+
| **Gerenciamento de Sessões** | TTL configurável com renovação automática por atividade |
|
|
13
|
+
| **Retry com Backoff Exponencial** | Recuperação automática com jitter configurável |
|
|
14
|
+
| **Timeouts Granulares** | AbortController por turno (padrão 90s) e por ferramenta (70% do turno) |
|
|
15
|
+
| **Registro Programático de Tools** | Schema JSON completo + handler assíncrono |
|
|
16
|
+
| **Modos de Falha `sync` / `async`** | Controle de indisponibilidade com retry agendado |
|
|
17
|
+
| **Detecção de Vulnerabilidades** | Rastreamento e encerramento automático de sessões suspeitas |
|
|
18
|
+
| **Eventos Estruturados** | `EventEmitter` para monitoramento e integração externos |
|
|
19
|
+
| **Resposta JSON Estruturada** | Schema fixo com `reasoning`, `response` e auditoria |
|
|
20
|
+
| **`AgentManager`** | Gerenciador de múltiplos agentes independentes |
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
## 📦 Instalação
|
|
25
|
+
|
|
26
|
+
### Via npm (GitHub Packages)
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
npm install github:areumtecnologia/AutonomousCustomerServiceAgent
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Via clone local
|
|
33
|
+
|
|
34
|
+
```bash
|
|
35
|
+
git clone https://github.com/areumtecnologia/AutonomousCustomerServiceAgent.git
|
|
36
|
+
cd AutonomousCustomerServiceAgent
|
|
37
|
+
npm install
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
### Pré-requisitos
|
|
41
|
+
|
|
42
|
+
- Node.js `>=16.0.0`
|
|
43
|
+
- Chave de API do Google Gemini
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## ⚙️ Configuração
|
|
48
|
+
|
|
49
|
+
Copie o arquivo de exemplo e configure suas credenciais:
|
|
50
|
+
|
|
51
|
+
```bash
|
|
52
|
+
cp .env.example .env
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
```env
|
|
56
|
+
# .env
|
|
57
|
+
GOOGLE_GEMINI_API_KEY=sua-chave-aqui
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## 🚀 Quickstart
|
|
63
|
+
|
|
64
|
+
```javascript
|
|
65
|
+
require('dotenv').config();
|
|
66
|
+
const { AutonomousCustomerServiceAgent, AgentConfig, AgentEvents, Type } = require('@areumtecnologia/autonomouscustomerserviceagent');
|
|
67
|
+
|
|
68
|
+
// 1. Configurar o agente
|
|
69
|
+
const agentConfig = new AgentConfig(
|
|
70
|
+
'Monnalisa', // Nome do agente
|
|
71
|
+
'Minha Empresa', // Nome da empresa
|
|
72
|
+
'Descrição da empresa e seus serviços.', // Detalhes da empresa
|
|
73
|
+
'Atuar como agente de vendas e atendimento.', // Objetivo da missão
|
|
74
|
+
`1. Cumprimente o lead de forma acolhedora.
|
|
75
|
+
2. Identifique as necessidades do lead.
|
|
76
|
+
3. Utilize as ferramentas disponíveis para obter dados.
|
|
77
|
+
4. Efetive a venda, se aplicável.`, // Instruções da missão
|
|
78
|
+
'pt-BR' // Idioma do raciocínio interno
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
// 2. Instanciar o agente
|
|
82
|
+
const agent = new AutonomousCustomerServiceAgent({
|
|
83
|
+
apiKey: process.env.GOOGLE_GEMINI_API_KEY,
|
|
84
|
+
agent: agentConfig,
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
// 3. Registrar ferramentas
|
|
88
|
+
agent.registerTool({
|
|
89
|
+
name: 'get_product_info',
|
|
90
|
+
description: 'Obtém informações de produtos disponíveis.',
|
|
91
|
+
parameters: {
|
|
92
|
+
type: Type.OBJECT,
|
|
93
|
+
properties: {
|
|
94
|
+
category: { type: Type.STRING, description: 'Categoria do produto.' },
|
|
95
|
+
},
|
|
96
|
+
},
|
|
97
|
+
}, async ({ category }, signal) => {
|
|
98
|
+
return JSON.stringify({ products: ['Produto A', 'Produto B'] });
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
// 4. Criar sessão (ID externo + dados do usuário)
|
|
102
|
+
const session = agent.createSession('session-001', {
|
|
103
|
+
name: 'João Silva',
|
|
104
|
+
phone: '+55 11 98765-4321',
|
|
105
|
+
email: 'joao@exemplo.com',
|
|
106
|
+
origin: { type: 'whatsapp', id: '12345', description: 'Lead via WhatsApp.' },
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
// 5. Processar mensagens
|
|
110
|
+
const response = await agent.processMessage('Olá!', session.id);
|
|
111
|
+
console.log(response.response);
|
|
112
|
+
// → "Olá, João! Bem-vindo à Minha Empresa. Como posso ajudá-lo?"
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 📋 API de Referência
|
|
118
|
+
|
|
119
|
+
### `new AgentConfig(name, companyName, companyDetails, objective, instructions, reasoningLanguage?)`
|
|
120
|
+
|
|
121
|
+
Constrói a configuração do agente. **Obrigatório** — o construtor de `AutonomousCustomerServiceAgent` exige uma instância de `AgentConfig`.
|
|
122
|
+
|
|
123
|
+
| Parâmetro | Tipo | Padrão | Descrição |
|
|
124
|
+
|---|---|---|---|
|
|
125
|
+
| `name` | `string` | — | Nome do agente |
|
|
126
|
+
| `companyName` | `string` | — | Nome da empresa |
|
|
127
|
+
| `companyDetails` | `string` | — | Descrição da empresa |
|
|
128
|
+
| `objective` | `string` | — | Objetivo da missão |
|
|
129
|
+
| `instructions` | `string` | — | Protocolo de execução (instruções detalhadas) |
|
|
130
|
+
| `reasoningLanguage` | `string` | `'en_us'` | Idioma do campo `reasoning` nas respostas |
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
### `new AutonomousCustomerServiceAgent(options)`
|
|
135
|
+
|
|
136
|
+
| Opção | Tipo | Padrão | Descrição |
|
|
137
|
+
|---|---|---|---|
|
|
138
|
+
| `apiKey` | `string` | **Obrigatório** | Chave da API Google Gemini |
|
|
139
|
+
| `agent` | `AgentConfig` | **Obrigatório** | Instância de `AgentConfig` |
|
|
140
|
+
| `model` | `string` | `'gemma-4-26b-a4b-it'` | Modelo Gemini a ser usado |
|
|
141
|
+
| `maxAgenticLoopTurns` | `number` | `9` | Máx. de iterações do agentic loop por mensagem |
|
|
142
|
+
| `sessionTTL` | `number` | `1800000` | TTL da sessão em ms (padrão: 30 min) |
|
|
143
|
+
| `turnTimeoutMs` | `number` | `90000` | Timeout por turno do loop em ms |
|
|
144
|
+
| `maxVulnerabilityAttempts` | `number` | `3` | Tentativas antes de encerrar a sessão |
|
|
145
|
+
| `temperature` | `number` | `0.1` | Temperatura do modelo (0–1) |
|
|
146
|
+
| `topP` | `number` | `0.95` | Probabilidade de núcleo (top-p sampling) |
|
|
147
|
+
| `thinkingLevel` | `string` | `'MINIMAL'` | Nível de raciocínio interno do modelo |
|
|
148
|
+
| `maxOutputTokens` | `number` | `32768` | Tokens máximos na resposta |
|
|
149
|
+
| `failureHandlingMode` | `'sync' \| 'async'` | `'sync'` | Modo de tratamento de falhas |
|
|
150
|
+
| `retryScheduleMinutes` | `number` | `5` | Intervalo entre tentativas agendadas (min) |
|
|
151
|
+
| `retryScheduleAttempts` | `number` | `24` | Máximo de tentativas agendadas |
|
|
152
|
+
| `retryScheduleWindowMs` | `number` | `86400000` | Janela total de retentativas (24h) |
|
|
153
|
+
| `unavailabilityMessage` | `string` | Mensagem padrão em inglês | Mensagem exibida ao usuário em caso de indisponibilidade |
|
|
154
|
+
| `retryOptions` | `object` | `{ maxAttempts: 3, baseDelayMs: 900, maxDelayMs: 9000 }` | Opções do retry com backoff exponencial |
|
|
155
|
+
|
|
156
|
+
---
|
|
157
|
+
|
|
158
|
+
### Métodos de Sessão
|
|
159
|
+
|
|
160
|
+
#### `agent.createSession(id, user)` → `SessionSnapshot`
|
|
161
|
+
|
|
162
|
+
Cria uma nova sessão de atendimento. O `id` deve ser único — uma exceção é lançada caso já exista uma sessão com o mesmo ID.
|
|
163
|
+
|
|
164
|
+
```javascript
|
|
165
|
+
const session = agent.createSession('session-abc', {
|
|
166
|
+
name: 'Maria Souza',
|
|
167
|
+
phone: '5511999999999',
|
|
168
|
+
email: 'maria@exemplo.com',
|
|
169
|
+
origin: { type: 'instagram', id: '999', description: 'Lead via DM.' },
|
|
170
|
+
});
|
|
171
|
+
// session.id → 'session-abc'
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
#### `agent.processMessage(message, sessionId)` → `Promise<AgentResponse>`
|
|
175
|
+
|
|
176
|
+
Processa uma mensagem dentro de uma sessão existente. Gerencia todo o histórico de conversa e agentic loop internamente.
|
|
177
|
+
|
|
178
|
+
```javascript
|
|
179
|
+
const response = await agent.processMessage('Quero saber sobre seus produtos.', 'session-abc');
|
|
180
|
+
console.log(response.response); // Texto para o usuário
|
|
181
|
+
console.log(response.reasoning); // Raciocínio interno do modelo
|
|
182
|
+
console.log(response.sent_at); // Timestamp no fuso de Brasília
|
|
183
|
+
```
|
|
184
|
+
|
|
185
|
+
#### `agent.getSession(sessionId)` → `SessionSnapshot | null`
|
|
186
|
+
|
|
187
|
+
Retorna um snapshot read-only da sessão.
|
|
188
|
+
|
|
189
|
+
#### `agent.getSessionByLead(leadFilter)` → `SessionSnapshot | null`
|
|
190
|
+
|
|
191
|
+
Busca uma sessão por nome, telefone ou origem. Aceita string (nome ou telefone) ou objeto de filtro.
|
|
192
|
+
|
|
193
|
+
```javascript
|
|
194
|
+
// Por telefone (string)
|
|
195
|
+
const s1 = agent.getSessionByLead('5511999999999');
|
|
196
|
+
|
|
197
|
+
// Por objeto de filtro composto
|
|
198
|
+
const s2 = agent.getSessionByLead({
|
|
199
|
+
name: 'Maria Souza',
|
|
200
|
+
origin: { type: 'instagram' },
|
|
201
|
+
});
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
#### `agent.clearSession(sessionId)` → `boolean`
|
|
205
|
+
|
|
206
|
+
Remove uma sessão manualmente, cancelando seu TTL e retentativas agendadas. Emite `SESSION_CLEARED`.
|
|
207
|
+
|
|
208
|
+
#### `agent.activeSessions` → `number`
|
|
209
|
+
|
|
210
|
+
Getter que retorna o número de sessões ativas no momento.
|
|
211
|
+
|
|
212
|
+
#### `agent.activeSessionsCount()` → `number`
|
|
213
|
+
|
|
214
|
+
Método equivalente ao getter `activeSessions`.
|
|
215
|
+
|
|
216
|
+
#### `agent.agentName` → `string`
|
|
217
|
+
|
|
218
|
+
Getter que retorna o nome do agente configurado.
|
|
219
|
+
|
|
220
|
+
---
|
|
221
|
+
|
|
222
|
+
### Registro de Ferramentas
|
|
223
|
+
|
|
224
|
+
#### `agent.registerTool(declaration, handler)` → `this` (chainable)
|
|
225
|
+
|
|
226
|
+
Registra ou substitui uma ferramenta customizada.
|
|
227
|
+
|
|
228
|
+
**Registrar nova tool (declaração completa):**
|
|
229
|
+
|
|
230
|
+
```javascript
|
|
231
|
+
agent.registerTool({
|
|
232
|
+
name: 'check_availability',
|
|
233
|
+
description: 'Verifica disponibilidade de vagas para uma data.',
|
|
234
|
+
parameters: {
|
|
235
|
+
type: Type.OBJECT,
|
|
236
|
+
required: ['date'],
|
|
237
|
+
properties: {
|
|
238
|
+
date: { type: Type.STRING, description: 'Data no formato YYYY-MM-DD.' },
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
}, async ({ date }, signal) => {
|
|
242
|
+
// signal: AbortSignal — use para cancelamentos com timeout
|
|
243
|
+
return JSON.stringify({ available: true, slots: 5 });
|
|
244
|
+
});
|
|
245
|
+
```
|
|
246
|
+
|
|
247
|
+
**Substituir apenas o handler de uma tool existente:**
|
|
248
|
+
|
|
249
|
+
```javascript
|
|
250
|
+
agent.registerTool('check_availability', async ({ date }, signal) => {
|
|
251
|
+
// Novo handler com lógica atualizada
|
|
252
|
+
const data = await myApi.fetchAvailability(date, { signal });
|
|
253
|
+
return JSON.stringify(data);
|
|
254
|
+
});
|
|
255
|
+
```
|
|
256
|
+
|
|
257
|
+
> **Nota:** O handler recebe `(args: object, signal: AbortSignal)`. O `signal` é fornecido pelo timeout interno da tool (70% do `turnTimeoutMs`). Use-o em chamadas externas para garantir cancelamento correto.
|
|
258
|
+
|
|
259
|
+
---
|
|
260
|
+
|
|
261
|
+
### `AgentResponse` — Estrutura da Resposta
|
|
262
|
+
|
|
263
|
+
Toda resposta de `processMessage` segue o esquema fixo:
|
|
264
|
+
|
|
265
|
+
```typescript
|
|
266
|
+
{
|
|
267
|
+
sent_at: string; // Timestamp (DD/MM/YYYY HH:mm:ss, fuso Brasília)
|
|
268
|
+
reasoning: string; // Raciocínio interno do modelo (para auditoria)
|
|
269
|
+
response: string; // Texto da resposta para o usuário
|
|
270
|
+
vulnerability_exploration_attempts?: number; // Tentativas de exploração detectadas
|
|
271
|
+
}
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
|
|
276
|
+
## 🎯 Eventos
|
|
277
|
+
|
|
278
|
+
Use `agent.on(AgentEvents.EVENT_NAME, callback)` para monitorar o ciclo de vida completo.
|
|
279
|
+
|
|
280
|
+
```javascript
|
|
281
|
+
const { AgentEvents } = require('@areumtecnologia/autonomouscustomerserviceagent');
|
|
282
|
+
|
|
283
|
+
agent
|
|
284
|
+
// ── Sessões ─────────────────────────────────────────────────────────────
|
|
285
|
+
.on(AgentEvents.SESSION_CREATED, ({ session }) =>
|
|
286
|
+
console.log(`Sessão criada: ${session.id}`))
|
|
287
|
+
|
|
288
|
+
.on(AgentEvents.SESSION_EXPIRED, ({ sessionId, user }) =>
|
|
289
|
+
console.log(`Sessão expirada: ${sessionId}`))
|
|
290
|
+
|
|
291
|
+
.on(AgentEvents.SESSION_CLEARED, ({ session }) =>
|
|
292
|
+
console.log(`Sessão limpa: ${session.id}`))
|
|
293
|
+
|
|
294
|
+
// ── Agentic Loop ─────────────────────────────────────────────────────────
|
|
295
|
+
.on(AgentEvents.TURN_START, ({ depth, session }) =>
|
|
296
|
+
console.log(`Turno ${depth} iniciado — sessão ${session.id}`))
|
|
297
|
+
|
|
298
|
+
.on(AgentEvents.TURN_END, ({ depth, type, session }) =>
|
|
299
|
+
console.log(`Turno ${depth} finalizado (${type}) — sessão ${session.id}`))
|
|
300
|
+
|
|
301
|
+
.on(AgentEvents.RESPONSE, ({ response, reasoning, session, usageMetadata }) =>
|
|
302
|
+
console.log(`[${session.id}]`, response))
|
|
303
|
+
|
|
304
|
+
.on(AgentEvents.RAW_RESPONSE, ({ rawResponse, session }) => { /* resposta bruta do modelo */ })
|
|
305
|
+
|
|
306
|
+
// ── Ferramentas ──────────────────────────────────────────────────────────
|
|
307
|
+
.on(AgentEvents.TOOL_CALL, ({ name, args, session }) =>
|
|
308
|
+
console.log(`Tool chamada: ${name}`, args))
|
|
309
|
+
|
|
310
|
+
.on(AgentEvents.TOOL_RESULT, ({ name, result, session }) =>
|
|
311
|
+
console.log(`Tool resultado: ${name}`, result))
|
|
312
|
+
|
|
313
|
+
// ── Retry e Falhas ───────────────────────────────────────────────────────
|
|
314
|
+
.on(AgentEvents.RETRY, ({ attempt, delay, error, session }) =>
|
|
315
|
+
console.warn(`Retry ${attempt} em ${delay}ms`))
|
|
316
|
+
|
|
317
|
+
.on(AgentEvents.ASYNC_RETRY_SCHEDULED, ({ session, delay, attempts }) =>
|
|
318
|
+
console.log(`Retry async agendado em ${delay}ms`))
|
|
319
|
+
|
|
320
|
+
.on(AgentEvents.ASYNC_RETRY_COMPLETED, ({ session, attempts, result }) =>
|
|
321
|
+
console.log(`Retry async concluído após ${attempts} tentativas`))
|
|
322
|
+
|
|
323
|
+
.on(AgentEvents.SYNC_RETRY_STARTED, ({ session, attempt }) =>
|
|
324
|
+
console.log(`Retry sync tentativa ${attempt}`))
|
|
325
|
+
|
|
326
|
+
.on(AgentEvents.SYNC_RETRY_COMPLETED, ({ session, attempt, result }) =>
|
|
327
|
+
console.log(`Retry sync concluído na tentativa ${attempt}`))
|
|
328
|
+
|
|
329
|
+
// ── Segurança ────────────────────────────────────────────────────────────
|
|
330
|
+
.on(AgentEvents.VULNERABILITY_EXPLORATION_DETECTED, ({ session, attempts, threshold }) =>
|
|
331
|
+
console.error(`Exploração detectada — ${attempts}/${threshold} tentativas`))
|
|
332
|
+
|
|
333
|
+
.on(AgentEvents.ERROR, ({ error, source, session }) =>
|
|
334
|
+
console.error(`Erro${source ? ` [${source}]` : ''}:`, error.message));
|
|
335
|
+
```
|
|
336
|
+
|
|
337
|
+
### Referência de Eventos (`AgentEvents`)
|
|
338
|
+
|
|
339
|
+
| Constante | Valor | Descrição |
|
|
340
|
+
|---|---|---|
|
|
341
|
+
| `RESPONSE` | `'response'` | Resposta final estruturada do agente |
|
|
342
|
+
| `RAW_RESPONSE` | `'raw_response'` | Resposta bruta do modelo (candidatos) |
|
|
343
|
+
| `TOOL_CALL` | `'tool_call'` | Antes de executar uma ferramenta |
|
|
344
|
+
| `TOOL_RESULT` | `'tool_result'` | Após a ferramenta resolver |
|
|
345
|
+
| `TURN_START` | `'turn_start'` | Início de um turno do agentic loop |
|
|
346
|
+
| `TURN_END` | `'turn_end'` | Fim de um turno do agentic loop |
|
|
347
|
+
| `SESSION_CREATED` | `'session_created'` | Nova sessão criada |
|
|
348
|
+
| `SESSION_EXPIRED` | `'session_expired'` | Sessão expirada por TTL |
|
|
349
|
+
| `SESSION_CLEARED` | `'session_cleared'` | Sessão removida manualmente |
|
|
350
|
+
| `RETRY` | `'retry'` | Retry de curto prazo após falha na API |
|
|
351
|
+
| `ASYNC_RETRY_SCHEDULED` | `'async_retry_scheduled'` | Retry assíncrono de longo prazo agendado |
|
|
352
|
+
| `ASYNC_RETRY_COMPLETED` | `'async_retry_completed'` | Retry assíncrono concluído com sucesso |
|
|
353
|
+
| `SYNC_RETRY_STARTED` | `'sync_retry_started'` | Retry síncrono iniciado |
|
|
354
|
+
| `SYNC_RETRY_COMPLETED` | `'sync_retry_completed'` | Retry síncrono concluído com sucesso |
|
|
355
|
+
| `VULNERABILITY_EXPLORATION_DETECTED` | `'vulnerability_exploration_detected'` | Tentativa de exploração detectada |
|
|
356
|
+
| `ERROR` | `'error'` | Erro irrecuperável ou de ferramenta |
|
|
357
|
+
|
|
358
|
+
---
|
|
359
|
+
|
|
360
|
+
## 🔄 Modos de Tratamento de Falhas
|
|
361
|
+
|
|
362
|
+
### `failureHandlingMode: 'sync'` (padrão)
|
|
363
|
+
|
|
364
|
+
Quando o processamento falha, o agente bloqueia novas requisições da **mesma sessão** e tenta o reprocessamento em intervalos regulares até atingir o limite de tentativas ou a janela de tempo. Outras sessões são bloqueadas durante o retry.
|
|
365
|
+
|
|
366
|
+
```
|
|
367
|
+
Mensagem recebida → falha na API
|
|
368
|
+
↓
|
|
369
|
+
Retry sync #1 (aguarda retryScheduleMinutes)
|
|
370
|
+
↓
|
|
371
|
+
Retry sync #2 ...
|
|
372
|
+
↓
|
|
373
|
+
Limite atingido → resposta de indisponibilidade
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
### `failureHandlingMode: 'async'`
|
|
377
|
+
|
|
378
|
+
O agente responde imediatamente com a `unavailabilityMessage` e agenda retentativas em background. O atendimento de outras sessões **não é bloqueado**.
|
|
379
|
+
|
|
380
|
+
```
|
|
381
|
+
Mensagem recebida → falha na API
|
|
382
|
+
↓
|
|
383
|
+
Retorna unavailabilityMessage imediatamente
|
|
384
|
+
↓
|
|
385
|
+
Retry async agendado em retryScheduleMinutes
|
|
386
|
+
↓ (background)
|
|
387
|
+
Retry #1, #2 ... até limite → emite ASYNC_RETRY_COMPLETED ou ERROR
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
```javascript
|
|
391
|
+
const agent = new AutonomousCustomerServiceAgent({
|
|
392
|
+
apiKey: process.env.GOOGLE_GEMINI_API_KEY,
|
|
393
|
+
agent: agentConfig,
|
|
394
|
+
failureHandlingMode: 'async',
|
|
395
|
+
retryScheduleMinutes: 5, // intervalo entre tentativas
|
|
396
|
+
retryScheduleAttempts: 24, // máx. tentativas (= até 2h com intervalo de 5min)
|
|
397
|
+
retryScheduleWindowMs: 2 * 60 * 60 * 1000, // janela de 2 horas
|
|
398
|
+
unavailabilityMessage: 'Estamos com uma instabilidade temporária. Entraremos em contato em breve.',
|
|
399
|
+
});
|
|
400
|
+
```
|
|
401
|
+
|
|
402
|
+
---
|
|
403
|
+
|
|
404
|
+
## 🗂️ `AgentManager` — Múltiplos Agentes
|
|
405
|
+
|
|
406
|
+
Gerencie múltiplos agentes em um único processo:
|
|
407
|
+
|
|
408
|
+
```javascript
|
|
409
|
+
const { AgentManager, AutonomousCustomerServiceAgent, AgentConfig } = require('@areumtecnologia/autonomouscustomerserviceagent');
|
|
410
|
+
|
|
411
|
+
const manager = new AgentManager();
|
|
412
|
+
|
|
413
|
+
manager.add('vendas', new AutonomousCustomerServiceAgent({ apiKey, agent: configVendas }));
|
|
414
|
+
manager.add('suporte', new AutonomousCustomerServiceAgent({ apiKey, agent: configSuporte }));
|
|
415
|
+
|
|
416
|
+
const agenteVendas = manager.get('vendas');
|
|
417
|
+
agenteVendas.createSession('s-001', { name: 'Lead', phone: '...' });
|
|
418
|
+
|
|
419
|
+
manager.list(); // → ['vendas', 'suporte']
|
|
420
|
+
manager.remove('suporte');
|
|
421
|
+
manager.clear();
|
|
422
|
+
```
|
|
423
|
+
|
|
424
|
+
---
|
|
425
|
+
|
|
426
|
+
## 🏗️ Estrutura do Projeto
|
|
427
|
+
|
|
428
|
+
```
|
|
429
|
+
AutonomousCustomerServiceAgent/
|
|
430
|
+
├── src/
|
|
431
|
+
│ ├── index.js # Ponto de entrada — exports públicos
|
|
432
|
+
│ ├── AutonomousCustomerServiceAgent.js # Classe principal do agente
|
|
433
|
+
│ ├── AgentConfig.js # Builder de configuração do agente
|
|
434
|
+
│ ├── AgentSession.js # Estado de uma sessão de conversa
|
|
435
|
+
│ ├── AgentEvents.js # Constantes de eventos (EventEmitter)
|
|
436
|
+
│ ├── AgentManager.js # Gerenciador de múltiplos agentes
|
|
437
|
+
│ └── utils.js # withRetry (backoff exponencial + jitter)
|
|
438
|
+
├── tests/
|
|
439
|
+
│ └── test.js # Exemplo completo multi-turno com tools
|
|
440
|
+
├── logs/ # Logs de execução (gerado em runtime)
|
|
441
|
+
├── .env.example # Template de variáveis de ambiente
|
|
442
|
+
├── .gitignore
|
|
443
|
+
├── package.json
|
|
444
|
+
└── README.md
|
|
445
|
+
```
|
|
446
|
+
|
|
447
|
+
### Exports Públicos (`src/index.js`)
|
|
448
|
+
|
|
449
|
+
```javascript
|
|
450
|
+
const {
|
|
451
|
+
AutonomousCustomerServiceAgent, // Classe principal
|
|
452
|
+
AgentConfig, // Builder de configuração
|
|
453
|
+
AgentEvents, // Constantes de eventos
|
|
454
|
+
AgentManager, // Gerenciador de múltiplos agentes
|
|
455
|
+
Type, // Re-export de @google/genai (para schemas de tools)
|
|
456
|
+
ThinkingLevel, // Re-export de @google/genai
|
|
457
|
+
} = require('@areumtecnologia/autonomouscustomerserviceagent');
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
---
|
|
461
|
+
|
|
462
|
+
## 🧪 Testes
|
|
463
|
+
|
|
464
|
+
```bash
|
|
465
|
+
npm test
|
|
466
|
+
```
|
|
467
|
+
|
|
468
|
+
O script `tests/test.js` demonstra um exemplo completo com:
|
|
469
|
+
- Configuração do agente com `AgentConfig`
|
|
470
|
+
- Registro de múltiplas ferramentas com schemas completos (`get_current_datetime`, `get_product_data`, `check_availability`, `checkout`, `clear_session`)
|
|
471
|
+
- Conversa multi-turno (5 turnos: boas-vindas → consulta de produtos → disponibilidade → reserva → checkout)
|
|
472
|
+
- Eventos de monitoramento completos
|
|
473
|
+
- Execução consecutiva para validação de estabilidade (5 iterações)
|
|
474
|
+
|
|
475
|
+
---
|
|
476
|
+
|
|
477
|
+
## 🔐 Segurança
|
|
478
|
+
|
|
479
|
+
> ⚠️ **Nunca** commite o arquivo `.env` com credenciais reais.
|
|
480
|
+
|
|
481
|
+
O arquivo `.gitignore` já ignora:
|
|
482
|
+
- `.env` — credenciais da API
|
|
483
|
+
- `node_modules/` — dependências
|
|
484
|
+
- `logs/` — arquivos de log
|
|
485
|
+
|
|
486
|
+
### Proteção contra Exploração
|
|
487
|
+
|
|
488
|
+
O agente possui mecanismo embutido de detecção de tentativas de exploração (prompt injection, extração de system prompt, bypass de regras). Após `maxVulnerabilityAttempts` tentativas detectadas pelo modelo, a sessão é encerrada automaticamente e `session.terminated = true`.
|
|
489
|
+
|
|
490
|
+
---
|
|
491
|
+
|
|
492
|
+
## 📄 Licença
|
|
493
|
+
|
|
494
|
+
ISC
|
|
495
|
+
|
|
496
|
+
## 👤 Autor
|
|
497
|
+
|
|
498
|
+
**Áreum Tecnologia** — Software and AI Development Team
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@areumtecnologia/autonomouscustomerserviceagent",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.3",
|
|
4
4
|
"description": "Agente autônomo de atendimento ao cliente baseado em IA com Google Gemini API. Suporta múltiplas sessões, ferramentas customizadas e retry com backoff exponencial.",
|
|
5
5
|
"license": "ISC",
|
|
6
6
|
"author": "Áreum Tecnologia",
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
"start": "node tests/test.js"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@areumtecnologia/autonomouscustomerserviceagent": "github:areumtecnologia/AutonomousCustomerServiceAgent",
|
|
30
29
|
"@google/genai": "^2.6.0"
|
|
31
30
|
},
|
|
32
31
|
"devDependencies": {
|
package/src/AgentConfig.js
CHANGED
package/src/AgentManager.js
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
|
-
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const { AutonomousCustomerServiceAgent } = require('./AutonomousCustomerServiceAgent');
|
|
4
|
+
|
|
5
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
6
|
+
// AgentManager — armazena e gerencia múltiplas instâncias de agentes
|
|
7
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
2
8
|
class AgentManager {
|
|
3
9
|
constructor() {
|
|
4
10
|
this.agents = new Map();
|