@runflow-ai/sdk 1.0.0 → 1.0.2
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 +893 -0
- package/dist/agents/runflow-agent.d.ts +53 -0
- package/dist/agents/runflow-agent.d.ts.map +1 -0
- package/dist/agents/runflow-agent.js +263 -0
- package/dist/agents/runflow-agent.js.map +1 -0
- package/dist/agents/server.d.ts +45 -0
- package/dist/agents/server.d.ts.map +1 -0
- package/dist/agents/server.js +315 -0
- package/dist/agents/server.js.map +1 -0
- package/dist/config.d.ts +17 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +131 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +56 -3
- package/dist/index.js.map +1 -1
- package/dist/runflow-sdk.d.ts +29 -3
- package/dist/runflow-sdk.d.ts.map +1 -1
- package/dist/runflow-sdk.js +409 -53
- package/dist/runflow-sdk.js.map +1 -1
- package/dist/singleton.d.ts +37 -0
- package/dist/singleton.d.ts.map +1 -0
- package/dist/singleton.js +86 -0
- package/dist/singleton.js.map +1 -0
- package/dist/types.d.ts +64 -20
- package/dist/types.d.ts.map +1 -1
- package/dist/utils.d.ts +74 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +312 -0
- package/dist/utils.js.map +1 -0
- package/package.json +50 -38
package/README.md
ADDED
|
@@ -0,0 +1,893 @@
|
|
|
1
|
+
# Runflow SDK
|
|
2
|
+
|
|
3
|
+
Uma SDK completa para desenvolvimento de agentes na plataforma Runflow, oferecendo integração fácil e poderosa com os serviços da plataforma.
|
|
4
|
+
|
|
5
|
+
## 📦 Instalação
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @runflow-ai/sdk
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## ⚙️ Configuração
|
|
12
|
+
|
|
13
|
+
### Arquivo .runflow
|
|
14
|
+
|
|
15
|
+
Para usar o SDK, crie um arquivo `.runflow` na raiz do seu projeto com as seguintes configurações:
|
|
16
|
+
|
|
17
|
+
```json
|
|
18
|
+
{
|
|
19
|
+
"agentId": "123-456-789",
|
|
20
|
+
"tenantId": "tenant-123",
|
|
21
|
+
"apiKey": "sk-...",
|
|
22
|
+
"apiUrl": "https://api.runflow.ai"
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
O SDK carregará automaticamente essas configurações e definirá as seguintes variáveis de ambiente:
|
|
27
|
+
- `RUNFLOW_AGENT_ID`
|
|
28
|
+
- `RUNFLOW_TENANT_ID`
|
|
29
|
+
- `RUNFLOW_API_KEY`
|
|
30
|
+
- `RUNFLOW_API_URL`
|
|
31
|
+
|
|
32
|
+
> **Nota:** O arquivo `.runflow` é buscado a partir do diretório atual, subindo na hierarquia até encontrar o arquivo ou chegar na raiz do sistema.
|
|
33
|
+
|
|
34
|
+
### Configuração Manual (Alternativa)
|
|
35
|
+
|
|
36
|
+
Se preferir, você pode definir as variáveis de ambiente manualmente:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
export RUNFLOW_AGENT_ID="123-456-789"
|
|
40
|
+
export RUNFLOW_TENANT_ID="tenant-123"
|
|
41
|
+
export RUNFLOW_API_KEY="sk-..."
|
|
42
|
+
export RUNFLOW_API_URL="https://api.runflow.ai"
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### Utilitários de Configuração
|
|
46
|
+
|
|
47
|
+
O SDK fornece funções utilitárias para gerenciar configurações:
|
|
48
|
+
|
|
49
|
+
```typescript
|
|
50
|
+
import {
|
|
51
|
+
loadRunflowConfig,
|
|
52
|
+
ensureRunflowConfig,
|
|
53
|
+
checkEnvironmentVariables
|
|
54
|
+
} from '@runflow-ai/sdk';
|
|
55
|
+
|
|
56
|
+
// Carregar configurações manualmente (opcional - feito automaticamente no construtor)
|
|
57
|
+
const config = loadRunflowConfig();
|
|
58
|
+
|
|
59
|
+
// Forçar carregamento e falhar se não encontrar
|
|
60
|
+
const config = ensureRunflowConfig();
|
|
61
|
+
|
|
62
|
+
// Verificar se todas as variáveis estão definidas
|
|
63
|
+
const hasAllVars = checkEnvironmentVariables();
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## 🚀 Início Rápido
|
|
67
|
+
|
|
68
|
+
Agora você tem **4 formas diferentes** de usar o SDK, desde a mais simples até a mais avançada:
|
|
69
|
+
|
|
70
|
+
### 1. 🎯 **Forma Ultra-Simples** (Recomendada para iniciantes)
|
|
71
|
+
|
|
72
|
+
```typescript
|
|
73
|
+
import { getPrompt, getCredential, log } from '@runflow-ai/sdk';
|
|
74
|
+
|
|
75
|
+
export const handler = async (input, context) => {
|
|
76
|
+
// Usa singleton interno - sem "new" necessário!
|
|
77
|
+
const prompt = await getPrompt('welcome-message');
|
|
78
|
+
const credential = await getCredential('azure-gpt4');
|
|
79
|
+
|
|
80
|
+
log('Handler executado', { message: input.message });
|
|
81
|
+
|
|
82
|
+
return {
|
|
83
|
+
success: true,
|
|
84
|
+
data: {
|
|
85
|
+
answer: prompt,
|
|
86
|
+
answered_by: "assistant"
|
|
87
|
+
}
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
### 2. ⚡ **Forma Simplificada com Helper**
|
|
93
|
+
|
|
94
|
+
```typescript
|
|
95
|
+
import { createAgentHandler } from '@runflow-ai/sdk';
|
|
96
|
+
|
|
97
|
+
export const handler = createAgentHandler(async (sdk, input, context) => {
|
|
98
|
+
// SDK já vem pronto, sem instanciar!
|
|
99
|
+
const prompt = await sdk.getPrompt('welcome-message');
|
|
100
|
+
|
|
101
|
+
return {
|
|
102
|
+
success: true,
|
|
103
|
+
data: {
|
|
104
|
+
answer: prompt,
|
|
105
|
+
answered_by: "assistant"
|
|
106
|
+
}
|
|
107
|
+
};
|
|
108
|
+
});
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 3. 🔄 **Forma com Singleton Explícito**
|
|
112
|
+
|
|
113
|
+
```typescript
|
|
114
|
+
import { getSDK } from '@runflow-ai/sdk';
|
|
115
|
+
|
|
116
|
+
export const handler = async (input, context) => {
|
|
117
|
+
const sdk = getSDK(context); // Reutiliza a mesma instância
|
|
118
|
+
const prompt = await sdk.getPrompt('welcome-message');
|
|
119
|
+
|
|
120
|
+
return {
|
|
121
|
+
success: true,
|
|
122
|
+
data: {
|
|
123
|
+
answer: prompt,
|
|
124
|
+
answered_by: "assistant"
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
### 4. 🛠️ **Forma Tradicional** (Para casos avançados)
|
|
131
|
+
|
|
132
|
+
```typescript
|
|
133
|
+
import { RunflowSDK, createHandler } from '@runflow-ai/sdk';
|
|
134
|
+
|
|
135
|
+
export const handler = createHandler(async (input, context) => {
|
|
136
|
+
const sdk = new RunflowSDK(context); // Nova instância sempre
|
|
137
|
+
|
|
138
|
+
return {
|
|
139
|
+
success: true,
|
|
140
|
+
data: {
|
|
141
|
+
answer: "Olá! Como posso ajudar?",
|
|
142
|
+
answered_by: "assistant"
|
|
143
|
+
}
|
|
144
|
+
};
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### 🤔 **Qual Forma Usar?**
|
|
149
|
+
|
|
150
|
+
| Cenário | Forma Recomendada | Por que? |
|
|
151
|
+
|---------|-------------------|-----------|
|
|
152
|
+
| **Agente simples, poucos métodos** | 🎯 Ultra-Simples | Menos código, mais direto |
|
|
153
|
+
| **Agente complexo, muitos métodos SDK** | ⚡ Helper `createAgentHandler` | SDK injetado, tipagem completa |
|
|
154
|
+
| **Múltiplos handlers no mesmo arquivo** | 🔄 Singleton Explícito | Reutiliza instância, melhor performance |
|
|
155
|
+
| **Controle total sobre instância** | 🛠️ Tradicional | Máxima flexibilidade |
|
|
156
|
+
| **Testes unitários** | 🛠️ Tradicional + `resetSDK()` | Isolamento entre testes |
|
|
157
|
+
|
|
158
|
+
### 💡 **Funções de Conveniência Disponíveis**
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
// Todas essas funções usam o singleton interno
|
|
162
|
+
import {
|
|
163
|
+
getCredential, // Buscar credencial
|
|
164
|
+
getPrompt, // Buscar prompt
|
|
165
|
+
getAvailableVectorStores, // Listar vector stores
|
|
166
|
+
searchVectorStore, // Buscar em knowledge base
|
|
167
|
+
addDocument, // Adicionar documento ao vector store
|
|
168
|
+
listDocuments, // Listar documentos do vector store
|
|
169
|
+
deleteDocument, // Remover documento do vector store
|
|
170
|
+
getSession, // Gerenciar sessão
|
|
171
|
+
log, // Log estruturado
|
|
172
|
+
trace, // Tracing e observabilidade
|
|
173
|
+
// Utilitários
|
|
174
|
+
validateAgentInput, // Validação de entrada
|
|
175
|
+
sanitizeMetadata, // Limpeza de metadados
|
|
176
|
+
maskSensitiveData, // Mascarar dados sensíveis
|
|
177
|
+
HttpClient, // Cliente HTTP com retry
|
|
178
|
+
batchRequests, // Requests em lote
|
|
179
|
+
withTimeout, // Timeout para promises
|
|
180
|
+
debounce // Debounce para funções
|
|
181
|
+
} from '@runflow-ai/sdk';
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
## 🔧 Funcionalidades Principais
|
|
185
|
+
|
|
186
|
+
### 🔐 Gerenciamento de Credenciais
|
|
187
|
+
|
|
188
|
+
O SDK fornece acesso seguro às credenciais configuradas na plataforma:
|
|
189
|
+
|
|
190
|
+
```typescript
|
|
191
|
+
// Buscar uma credencial específica
|
|
192
|
+
const credential = await sdk.getCredential('api-key-openai');
|
|
193
|
+
|
|
194
|
+
console.log(credential.name); // 'api-key-openai'
|
|
195
|
+
console.log(credential.type); // 'API_KEY', 'OAUTH', ou 'JWT'
|
|
196
|
+
console.log(credential.apiKey); // A chave de acesso
|
|
197
|
+
console.log(credential.config); // Configurações adicionais
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
**Tipos de Credenciais Suportadas:**
|
|
201
|
+
- `API_KEY`: Chaves de API simples
|
|
202
|
+
- `OAUTH`: Tokens OAuth
|
|
203
|
+
- `JWT`: JSON Web Tokens
|
|
204
|
+
|
|
205
|
+
### 📝 Sistema de Prompts
|
|
206
|
+
|
|
207
|
+
Gerencie e utilize prompts dinâmicos com variáveis:
|
|
208
|
+
|
|
209
|
+
```typescript
|
|
210
|
+
// Prompt simples
|
|
211
|
+
consgit stt prompt = await sdk.getPrompt('greeting');
|
|
212
|
+
|
|
213
|
+
// Prompt com variáveis
|
|
214
|
+
const prompt = await sdk.getPrompt('personalized-greeting', {
|
|
215
|
+
name: 'João',
|
|
216
|
+
company: 'Acme Corp'
|
|
217
|
+
});
|
|
218
|
+
|
|
219
|
+
// O prompt pode conter: "Olá {{name}}, bem-vindo à {{company}}!"
|
|
220
|
+
// Resultado: "Olá João, bem-vindo à Acme Corp!"
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
### 🔍 Busca em Vector Stores
|
|
224
|
+
|
|
225
|
+
Realize buscas semânticas em bases de conhecimento:
|
|
226
|
+
|
|
227
|
+
```typescript
|
|
228
|
+
// Listar vector stores disponíveis
|
|
229
|
+
const vectorStores = await sdk.getAvailableVectorStores();
|
|
230
|
+
|
|
231
|
+
vectorStores.forEach(store => {
|
|
232
|
+
console.log(`${store.name}: ${store.description} (${store.type})`);
|
|
233
|
+
});
|
|
234
|
+
|
|
235
|
+
// Realizar busca semântica
|
|
236
|
+
const searchResults = await sdk.searchVectorStore(
|
|
237
|
+
'knowledge-base',
|
|
238
|
+
'Como configurar pagamentos?',
|
|
239
|
+
{
|
|
240
|
+
k: 5, // Número de resultados
|
|
241
|
+
threshold: 0.7 // Threshold de similaridade
|
|
242
|
+
}
|
|
243
|
+
);
|
|
244
|
+
|
|
245
|
+
searchResults.results.forEach(result => {
|
|
246
|
+
console.log(`Score: ${result.score}`);
|
|
247
|
+
console.log(`Conteúdo: ${result.content}`);
|
|
248
|
+
console.log(`Fonte: ${result.metadata.source}`);
|
|
249
|
+
});
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
**Tipos de Vector Stores Suportados:**
|
|
253
|
+
- Pinecone
|
|
254
|
+
- Weaviate
|
|
255
|
+
- Qdrant
|
|
256
|
+
|
|
257
|
+
### 📄 Gerenciamento de Documentos
|
|
258
|
+
|
|
259
|
+
Gerencie documentos nos vector stores:
|
|
260
|
+
|
|
261
|
+
```typescript
|
|
262
|
+
// Adicionar um documento
|
|
263
|
+
const documentResponse = await sdk.addDocument({
|
|
264
|
+
vectorStore: 'knowledge-base',
|
|
265
|
+
content: 'Como configurar pagamentos via PIX...',
|
|
266
|
+
metadata: {
|
|
267
|
+
source: 'manual-pagamentos.pdf',
|
|
268
|
+
category: 'financeiro',
|
|
269
|
+
version: '1.0'
|
|
270
|
+
}
|
|
271
|
+
});
|
|
272
|
+
|
|
273
|
+
console.log(`Documento adicionado: ${documentResponse.id}`);
|
|
274
|
+
|
|
275
|
+
// Listar documentos
|
|
276
|
+
const documents = await sdk.listDocuments('knowledge-base', {
|
|
277
|
+
limit: 20,
|
|
278
|
+
offset: 0
|
|
279
|
+
});
|
|
280
|
+
|
|
281
|
+
console.log(`Total de documentos: ${documents.total}`);
|
|
282
|
+
documents.documents.forEach(doc => {
|
|
283
|
+
console.log(`${doc.id}: ${doc.content.substring(0, 100)}...`);
|
|
284
|
+
});
|
|
285
|
+
|
|
286
|
+
// Remover um documento
|
|
287
|
+
const deleteResult = await sdk.deleteDocument('doc-123');
|
|
288
|
+
console.log(`Documento removido: ${deleteResult.success}`);
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
### 💬 Gerenciamento de Sessões
|
|
292
|
+
|
|
293
|
+
Mantenha contexto e histórico de conversas:
|
|
294
|
+
|
|
295
|
+
```typescript
|
|
296
|
+
// Obter gerenciador de sessão
|
|
297
|
+
const session = sdk.session.get('session-123');
|
|
298
|
+
|
|
299
|
+
// Adicionar mensagens
|
|
300
|
+
await session.addMessage('human', 'Qual é o status do meu pedido?');
|
|
301
|
+
await session.addMessage('ai', 'Seu pedido #1234 está em processamento.');
|
|
302
|
+
|
|
303
|
+
// Buscar histórico
|
|
304
|
+
const history = await session.getHistory({
|
|
305
|
+
limit: 10,
|
|
306
|
+
offset: 0
|
|
307
|
+
});
|
|
308
|
+
|
|
309
|
+
history.forEach(message => {
|
|
310
|
+
console.log(`[${message.role}] ${message.content}`);
|
|
311
|
+
console.log(`Timestamp: ${message.timestamp}`);
|
|
312
|
+
});
|
|
313
|
+
|
|
314
|
+
// Limpar histórico
|
|
315
|
+
await session.clear();
|
|
316
|
+
```
|
|
317
|
+
|
|
318
|
+
### 📊 Logs e Tracing
|
|
319
|
+
|
|
320
|
+
Sistema completo de observabilidade:
|
|
321
|
+
|
|
322
|
+
```typescript
|
|
323
|
+
// Log simples
|
|
324
|
+
sdk.log('Processando requisição do usuário');
|
|
325
|
+
|
|
326
|
+
// Log com dados estruturados
|
|
327
|
+
sdk.log('Busca realizada', {
|
|
328
|
+
query: 'pagamentos',
|
|
329
|
+
results: 5,
|
|
330
|
+
vectorStore: 'knowledge-base'
|
|
331
|
+
});
|
|
332
|
+
|
|
333
|
+
// Enviar trace - Formato Padrão (Recomendado)
|
|
334
|
+
const trace = await sdk.trace({
|
|
335
|
+
input: [
|
|
336
|
+
{ type: 'human', content: 'Como configurar pagamentos?' },
|
|
337
|
+
{ type: 'system', content: 'Contexto adicional...' }
|
|
338
|
+
],
|
|
339
|
+
output: 'Para configurar pagamentos via PIX...',
|
|
340
|
+
status: 'success'
|
|
341
|
+
});
|
|
342
|
+
|
|
343
|
+
console.log(`Trace ID: ${trace.traceId}`);
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
## 🛠️ Utilitários
|
|
347
|
+
|
|
348
|
+
### Validação e Segurança
|
|
349
|
+
|
|
350
|
+
```typescript
|
|
351
|
+
import { validateAgentInput, sanitizeMetadata, maskSensitiveData } from '@runflow-ai/sdk';
|
|
352
|
+
|
|
353
|
+
// Validar entrada do agente
|
|
354
|
+
const validation = validateAgentInput(input, {
|
|
355
|
+
requireCompanyId: true,
|
|
356
|
+
maxMessageLength: 5000,
|
|
357
|
+
allowedChannels: ['web', 'whatsapp', 'telegram']
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
if (!validation.isValid) {
|
|
361
|
+
console.log('Errors:', validation.errors);
|
|
362
|
+
return { success: false, error: validation.errors.join(', ') };
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
// Usar entrada sanitizada
|
|
366
|
+
const cleanInput = validation.sanitized;
|
|
367
|
+
|
|
368
|
+
// Limpar metadados
|
|
369
|
+
const cleanMetadata = sanitizeMetadata(rawMetadata, {
|
|
370
|
+
allowedKeys: ['source', 'version', 'category'],
|
|
371
|
+
maxDepth: 2,
|
|
372
|
+
maxStringLength: 500
|
|
373
|
+
});
|
|
374
|
+
|
|
375
|
+
// Mascarar dados sensíveis em logs
|
|
376
|
+
const logData = {
|
|
377
|
+
userEmail: 'user@example.com',
|
|
378
|
+
phone: '+5511999999999',
|
|
379
|
+
password: 'secret123'
|
|
380
|
+
};
|
|
381
|
+
|
|
382
|
+
const maskedData = maskSensitiveData(logData);
|
|
383
|
+
// Resultado: { userEmail: 'us***@example.com', phone: '***********', password: '***' }
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
### Cliente HTTP Avançado
|
|
387
|
+
|
|
388
|
+
```typescript
|
|
389
|
+
import { HttpClient, batchRequests, withTimeout, debounce } from '@runflow-ai/sdk';
|
|
390
|
+
|
|
391
|
+
// Cliente HTTP com retry automático
|
|
392
|
+
const client = new HttpClient();
|
|
393
|
+
|
|
394
|
+
const response = await client.post('https://api.external.com/data', {
|
|
395
|
+
query: 'example'
|
|
396
|
+
}, {
|
|
397
|
+
timeout: 5000,
|
|
398
|
+
retries: 3,
|
|
399
|
+
retryDelay: 1000
|
|
400
|
+
});
|
|
401
|
+
|
|
402
|
+
// Requests em lote com controle de concorrência
|
|
403
|
+
const requests = [
|
|
404
|
+
() => client.get('/api/data/1'),
|
|
405
|
+
() => client.get('/api/data/2'),
|
|
406
|
+
() => client.get('/api/data/3')
|
|
407
|
+
];
|
|
408
|
+
|
|
409
|
+
const results = await batchRequests(requests, { concurrent: 2 });
|
|
410
|
+
|
|
411
|
+
// Timeout para qualquer Promise
|
|
412
|
+
const timedResult = await withTimeout(
|
|
413
|
+
sdk.searchVectorStore('knowledge', 'query'),
|
|
414
|
+
3000
|
|
415
|
+
);
|
|
416
|
+
|
|
417
|
+
// Debounce para buscas
|
|
418
|
+
const debouncedSearch = debounce(async (query: string) => {
|
|
419
|
+
return await sdk.searchVectorStore('knowledge', query);
|
|
420
|
+
}, 300);
|
|
421
|
+
```
|
|
422
|
+
|
|
423
|
+
## 🏗️ Arquitetura
|
|
424
|
+
|
|
425
|
+
### Classes Principais
|
|
426
|
+
|
|
427
|
+
#### `RunflowSDK`
|
|
428
|
+
Classe principal que oferece acesso a todos os recursos da plataforma:
|
|
429
|
+
|
|
430
|
+
```typescript
|
|
431
|
+
class RunflowSDK {
|
|
432
|
+
constructor(context?: AgentContext)
|
|
433
|
+
|
|
434
|
+
// 🔐 Credenciais
|
|
435
|
+
async getCredential(name: string): Promise<Credential>
|
|
436
|
+
|
|
437
|
+
// 📝 Prompts
|
|
438
|
+
async getPrompt(name: string, variables?: Record<string, any>): Promise<string>
|
|
439
|
+
|
|
440
|
+
// 🔍 Vector Stores & Busca
|
|
441
|
+
async getAvailableVectorStores(): Promise<VectorStore[]>
|
|
442
|
+
async searchVectorStore(vectorStore: string, query: string, options?: SearchOptions): Promise<SearchResponse>
|
|
443
|
+
|
|
444
|
+
// 📄 Gerenciamento de Documentos
|
|
445
|
+
async addDocument(request: AddDocumentRequest): Promise<AddDocumentResponse>
|
|
446
|
+
async listDocuments(vectorStore: string, options?: ListDocumentsOptions): Promise<ListDocumentsResponse>
|
|
447
|
+
async deleteDocument(documentId: string): Promise<DeleteDocumentResponse>
|
|
448
|
+
|
|
449
|
+
// 📊 Observabilidade
|
|
450
|
+
log(message: string, data?: any): void
|
|
451
|
+
async trace(traceData: TraceData): Promise<TraceResponse>
|
|
452
|
+
|
|
453
|
+
// 💬 Sessões
|
|
454
|
+
session: { get(sessionId: string): SessionManager }
|
|
455
|
+
|
|
456
|
+
// ⚙️ Utilitários
|
|
457
|
+
async health(): Promise<any>
|
|
458
|
+
}
|
|
459
|
+
```
|
|
460
|
+
|
|
461
|
+
#### `SessionManager`
|
|
462
|
+
Gerenciador de sessões e histórico de conversas:
|
|
463
|
+
|
|
464
|
+
```typescript
|
|
465
|
+
class SessionManager {
|
|
466
|
+
async addMessage(role: 'human' | 'ai', content: string, metadata?: any): Promise<void>
|
|
467
|
+
async getHistory(options?: SessionHistoryOptions): Promise<SessionMessage[]>
|
|
468
|
+
async clear(): Promise<void>
|
|
469
|
+
}
|
|
470
|
+
```
|
|
471
|
+
|
|
472
|
+
### Interfaces e Tipos
|
|
473
|
+
|
|
474
|
+
#### `AgentContext`
|
|
475
|
+
Contexto de execução do agente:
|
|
476
|
+
|
|
477
|
+
```typescript
|
|
478
|
+
interface AgentContext {
|
|
479
|
+
tenantId: string; // ID do tenant
|
|
480
|
+
agentId: string; // ID do agente
|
|
481
|
+
requestId: string; // ID da requisição
|
|
482
|
+
sessionId?: string; // ID da sessão (opcional)
|
|
483
|
+
companyId?: string; // ID da empresa (opcional)
|
|
484
|
+
}
|
|
485
|
+
```
|
|
486
|
+
|
|
487
|
+
#### `AgentInput`
|
|
488
|
+
Entrada padrão dos handlers:
|
|
489
|
+
|
|
490
|
+
```typescript
|
|
491
|
+
interface AgentInput {
|
|
492
|
+
message: string; // Mensagem do usuário
|
|
493
|
+
companyId: string; // ID da empresa (obrigatório)
|
|
494
|
+
userId?: string; // ID do usuário
|
|
495
|
+
sessionId?: string; // ID da sessão
|
|
496
|
+
channel?: string; // Canal de origem
|
|
497
|
+
metadata?: Record<string, any>; // Metadados adicionais
|
|
498
|
+
// Compatibilidade com versões antigas
|
|
499
|
+
tab?: string;
|
|
500
|
+
preChatInfo?: string;
|
|
501
|
+
}
|
|
502
|
+
```
|
|
503
|
+
|
|
504
|
+
#### `AgentOutput`
|
|
505
|
+
Saída padrão dos handlers:
|
|
506
|
+
|
|
507
|
+
```typescript
|
|
508
|
+
interface AgentOutput {
|
|
509
|
+
message: string; // Resposta do agente
|
|
510
|
+
metadata?: {
|
|
511
|
+
llmProvider?: string; // Provedor do LLM usado
|
|
512
|
+
model?: string; // Modelo usado
|
|
513
|
+
toolsUsed?: string[]; // Ferramentas utilizadas
|
|
514
|
+
steps?: number; // Número de passos executados
|
|
515
|
+
[key: string]: any; // Metadados adicionais
|
|
516
|
+
};
|
|
517
|
+
}
|
|
518
|
+
```
|
|
519
|
+
|
|
520
|
+
## 🌍 Variáveis de Ambiente
|
|
521
|
+
|
|
522
|
+
O SDK utiliza as seguintes variáveis de ambiente, automaticamente configuradas pela plataforma Runflow:
|
|
523
|
+
|
|
524
|
+
### Obrigatórias
|
|
525
|
+
- `RUNFLOW_TENANT_ID`: ID do tenant
|
|
526
|
+
- `RUNFLOW_AGENT_ID`: ID do agente
|
|
527
|
+
- `RUNFLOW_API_KEY`: Chave de API para autenticação
|
|
528
|
+
|
|
529
|
+
### Opcionais
|
|
530
|
+
- `RUNFLOW_REQUEST_ID`: ID da requisição (gerado automaticamente se não fornecido)
|
|
531
|
+
- `RUNFLOW_SESSION_ID`: ID da sessão
|
|
532
|
+
- `RUNFLOW_API_URL`: URL da API (padrão: `http://localhost:3001`)
|
|
533
|
+
|
|
534
|
+
## 🤖 Agentes Avançados
|
|
535
|
+
|
|
536
|
+
O SDK inclui suporte completo para criação de agentes inteligentes:
|
|
537
|
+
|
|
538
|
+
### `RunflowAgent`
|
|
539
|
+
Classe para criar agentes inteligentes com IA e ferramentas:
|
|
540
|
+
|
|
541
|
+
```typescript
|
|
542
|
+
import { RunflowAgent } from '@runflow-ai/sdk';
|
|
543
|
+
|
|
544
|
+
const agent = new RunflowAgent({
|
|
545
|
+
llm: {
|
|
546
|
+
provider: 'anthropic', // ou 'openai'
|
|
547
|
+
model: 'claude-3-sonnet',
|
|
548
|
+
credential: 'claude-api',
|
|
549
|
+
temperature: 0.7
|
|
550
|
+
},
|
|
551
|
+
systemPrompt: 'customer-support', // Nome do prompt na plataforma
|
|
552
|
+
toolsPath: './tools', // Pasta com ferramentas customizadas
|
|
553
|
+
tools: ['search-knowledge'], // Ferramentas built-in
|
|
554
|
+
session: {
|
|
555
|
+
enabled: true,
|
|
556
|
+
historyLimit: 10
|
|
557
|
+
}
|
|
558
|
+
});
|
|
559
|
+
|
|
560
|
+
// Processar mensagem
|
|
561
|
+
const response = await agent.process({
|
|
562
|
+
message: 'Como posso cancelar meu pedido?',
|
|
563
|
+
companyId: 'company-123',
|
|
564
|
+
userId: 'user-456',
|
|
565
|
+
sessionId: 'session-789'
|
|
566
|
+
});
|
|
567
|
+
|
|
568
|
+
console.log(response.message);
|
|
569
|
+
```
|
|
570
|
+
|
|
571
|
+
### Ferramentas Customizadas
|
|
572
|
+
Crie ferramentas que o agente pode usar:
|
|
573
|
+
|
|
574
|
+
```typescript
|
|
575
|
+
// tools/order-lookup.ts
|
|
576
|
+
export const orderLookup = {
|
|
577
|
+
name: 'order_lookup',
|
|
578
|
+
description: 'Busca informações de um pedido pelo ID',
|
|
579
|
+
parameters: {
|
|
580
|
+
orderId: {
|
|
581
|
+
type: 'string',
|
|
582
|
+
required: true,
|
|
583
|
+
description: 'ID do pedido'
|
|
584
|
+
}
|
|
585
|
+
},
|
|
586
|
+
execute: async (params: { orderId: string }, context: ToolContext) => {
|
|
587
|
+
// Usar o SDK dentro da ferramenta
|
|
588
|
+
const orderData = await fetch(`/api/orders/${params.orderId}`);
|
|
589
|
+
|
|
590
|
+
// Log da operação
|
|
591
|
+
context.sdk.log('Pedido consultado', {
|
|
592
|
+
orderId: params.orderId,
|
|
593
|
+
companyId: context.companyId
|
|
594
|
+
});
|
|
595
|
+
|
|
596
|
+
return orderData;
|
|
597
|
+
}
|
|
598
|
+
};
|
|
599
|
+
```
|
|
600
|
+
|
|
601
|
+
### Servidor de Agente
|
|
602
|
+
Crie um servidor HTTP completo para seu agente:
|
|
603
|
+
|
|
604
|
+
```typescript
|
|
605
|
+
import { createAgentServer } from '@runflow-ai/sdk';
|
|
606
|
+
|
|
607
|
+
const server = createAgentServer({
|
|
608
|
+
llm: {
|
|
609
|
+
provider: 'anthropic',
|
|
610
|
+
model: 'claude-3-sonnet',
|
|
611
|
+
credential: 'claude-api'
|
|
612
|
+
},
|
|
613
|
+
systemPrompt: 'customer-support',
|
|
614
|
+
toolsPath: './tools'
|
|
615
|
+
}, {
|
|
616
|
+
port: 3000,
|
|
617
|
+
cors: true,
|
|
618
|
+
rateLimiting: true,
|
|
619
|
+
tracing: true, // Trace automático
|
|
620
|
+
hooks: {
|
|
621
|
+
beforeChat: async (req, res) => {
|
|
622
|
+
// Validações customizadas
|
|
623
|
+
console.log('Nova conversa iniciada');
|
|
624
|
+
},
|
|
625
|
+
afterChat: async (input, output, ctx) => {
|
|
626
|
+
// Pós-processamento
|
|
627
|
+
console.log(`Conversa processada em ${ctx.durationMs}ms`);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
});
|
|
631
|
+
|
|
632
|
+
server.start(); // Inicia na porta 3000
|
|
633
|
+
```
|
|
634
|
+
|
|
635
|
+
## 📚 Exemplos Avançados
|
|
636
|
+
|
|
637
|
+
### Agente com Busca em Conhecimento
|
|
638
|
+
|
|
639
|
+
```typescript
|
|
640
|
+
import { createAgentHandler } from '@runflow-ai/sdk';
|
|
641
|
+
|
|
642
|
+
export const handler = createAgentHandler(async (sdk, input, context) => {
|
|
643
|
+
try {
|
|
644
|
+
// Buscar informações relacionadas
|
|
645
|
+
const searchResults = await sdk.searchVectorStore(
|
|
646
|
+
'company-knowledge',
|
|
647
|
+
input.message,
|
|
648
|
+
{ k: 3, threshold: 0.8 }
|
|
649
|
+
);
|
|
650
|
+
|
|
651
|
+
// Preparar contexto para o prompt
|
|
652
|
+
const context_info = searchResults.results
|
|
653
|
+
.map(r => r.content)
|
|
654
|
+
.join('\n\n');
|
|
655
|
+
|
|
656
|
+
// Buscar prompt personalizado
|
|
657
|
+
const prompt = await sdk.getPrompt('answer-with-context', {
|
|
658
|
+
question: input.message,
|
|
659
|
+
context: context_info,
|
|
660
|
+
user_id: input.userId
|
|
661
|
+
});
|
|
662
|
+
|
|
663
|
+
// Log da operação
|
|
664
|
+
sdk.log('Busca realizada', {
|
|
665
|
+
query: input.message,
|
|
666
|
+
results: searchResults.results.length,
|
|
667
|
+
sources: searchResults.results.map(r => r.metadata.source)
|
|
668
|
+
});
|
|
669
|
+
|
|
670
|
+
// Trace para observabilidade
|
|
671
|
+
await sdk.trace({
|
|
672
|
+
operation: 'knowledge.search',
|
|
673
|
+
inputs: { query: input.message },
|
|
674
|
+
outputs: { results: searchResults.results.length },
|
|
675
|
+
status: 'success'
|
|
676
|
+
});
|
|
677
|
+
|
|
678
|
+
return {
|
|
679
|
+
success: true,
|
|
680
|
+
data: {
|
|
681
|
+
answer: prompt,
|
|
682
|
+
answered_by: 'knowledge-agent',
|
|
683
|
+
sources: searchResults.results.map(r => ({
|
|
684
|
+
content: r.content,
|
|
685
|
+
source: r.metadata.source,
|
|
686
|
+
score: r.score
|
|
687
|
+
}))
|
|
688
|
+
}
|
|
689
|
+
};
|
|
690
|
+
|
|
691
|
+
} catch (error) {
|
|
692
|
+
sdk.log('Erro no agente', error);
|
|
693
|
+
|
|
694
|
+
await sdk.trace({
|
|
695
|
+
operation: 'knowledge.search',
|
|
696
|
+
inputs: { query: input.message },
|
|
697
|
+
status: 'error',
|
|
698
|
+
error: error.message
|
|
699
|
+
});
|
|
700
|
+
|
|
701
|
+
return {
|
|
702
|
+
success: false,
|
|
703
|
+
error: 'Desculpe, ocorreu um erro interno.'
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
});
|
|
707
|
+
```
|
|
708
|
+
|
|
709
|
+
### Agente com Integração Externa
|
|
710
|
+
|
|
711
|
+
```typescript
|
|
712
|
+
import { createAgentHandler } from '@runflow-ai/sdk';
|
|
713
|
+
|
|
714
|
+
export const handler = createAgentHandler(async (sdk, input, context) => {
|
|
715
|
+
// Buscar credenciais para API externa
|
|
716
|
+
const apiCredential = await sdk.getCredential('external-api-key');
|
|
717
|
+
|
|
718
|
+
// Fazer chamada para API externa
|
|
719
|
+
const response = await fetch('https://api.externa.com/data', {
|
|
720
|
+
headers: {
|
|
721
|
+
'Authorization': `Bearer ${apiCredential.apiKey}`,
|
|
722
|
+
'Content-Type': 'application/json'
|
|
723
|
+
},
|
|
724
|
+
method: 'POST',
|
|
725
|
+
body: JSON.stringify({ query: input.message })
|
|
726
|
+
});
|
|
727
|
+
|
|
728
|
+
const data = await response.json();
|
|
729
|
+
|
|
730
|
+
// Gerenciar sessão
|
|
731
|
+
const session = sdk.session.get(input.sessionId || 'default');
|
|
732
|
+
await session.addMessage('human', input.message);
|
|
733
|
+
|
|
734
|
+
const answer = `Baseado nos dados externos: ${data.result}`;
|
|
735
|
+
await session.addMessage('ai', answer);
|
|
736
|
+
|
|
737
|
+
return {
|
|
738
|
+
success: true,
|
|
739
|
+
data: {
|
|
740
|
+
answer,
|
|
741
|
+
answered_by: 'external-api-agent',
|
|
742
|
+
metadata: [{ external_data: data }]
|
|
743
|
+
}
|
|
744
|
+
};
|
|
745
|
+
});
|
|
746
|
+
```
|
|
747
|
+
|
|
748
|
+
## 🔧 Desenvolvimento e Debug
|
|
749
|
+
|
|
750
|
+
### Configuração Local
|
|
751
|
+
|
|
752
|
+
Para desenvolvimento local, você pode configurar as variáveis de ambiente manualmente:
|
|
753
|
+
|
|
754
|
+
```bash
|
|
755
|
+
export RUNFLOW_TENANT_ID="your-tenant-id"
|
|
756
|
+
export RUNFLOW_AGENT_ID="your-agent-id"
|
|
757
|
+
export RUNFLOW_API_KEY="your-api-key"
|
|
758
|
+
export RUNFLOW_API_URL="http://localhost:3001"
|
|
759
|
+
```
|
|
760
|
+
|
|
761
|
+
### Debug de Sessões
|
|
762
|
+
|
|
763
|
+
```typescript
|
|
764
|
+
// Verificar estado da sessão
|
|
765
|
+
const history = await session.getHistory({ limit: 50 });
|
|
766
|
+
console.log(`Sessão tem ${history.length} mensagens`);
|
|
767
|
+
|
|
768
|
+
// Log detalhado
|
|
769
|
+
sdk.log('Estado da sessão', {
|
|
770
|
+
sessionId: input.sessionId,
|
|
771
|
+
messageCount: history.length,
|
|
772
|
+
lastMessage: history[0]?.content
|
|
773
|
+
});
|
|
774
|
+
```
|
|
775
|
+
|
|
776
|
+
## 🚨 Tratamento de Erros
|
|
777
|
+
|
|
778
|
+
O SDK fornece tratamento robusto de erros:
|
|
779
|
+
|
|
780
|
+
```typescript
|
|
781
|
+
try {
|
|
782
|
+
const credential = await sdk.getCredential('non-existent');
|
|
783
|
+
} catch (error) {
|
|
784
|
+
if (error.message.includes('HTTP 404')) {
|
|
785
|
+
console.log('Credencial não encontrada');
|
|
786
|
+
} else if (error.message.includes('RUNFLOW_API_KEY')) {
|
|
787
|
+
console.log('SDK não configurado corretamente');
|
|
788
|
+
} else {
|
|
789
|
+
console.log('Erro desconhecido:', error.message);
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
```
|
|
793
|
+
|
|
794
|
+
### Erros Comuns
|
|
795
|
+
|
|
796
|
+
1. **Variáveis de ambiente não configuradas**: Certifique-se de que o agente está sendo executado na plataforma Runflow
|
|
797
|
+
2. **Credencial não encontrada**: Verifique se a credencial foi configurada na plataforma
|
|
798
|
+
3. **Vector store indisponível**: Confirme se o vector store está ativo e acessível
|
|
799
|
+
4. **Prompt não encontrado**: Verifique se o prompt foi criado na plataforma
|
|
800
|
+
|
|
801
|
+
## 🌐 English Version
|
|
802
|
+
|
|
803
|
+
For English speakers, here's a concise overview of the SDK:
|
|
804
|
+
|
|
805
|
+
### Basic Usage
|
|
806
|
+
|
|
807
|
+
```typescript
|
|
808
|
+
import { createHandler } from '@runflow-ai/sdk';
|
|
809
|
+
|
|
810
|
+
export const handler = createHandler(async (input, context) => {
|
|
811
|
+
return { success: true };
|
|
812
|
+
});
|
|
813
|
+
```
|
|
814
|
+
|
|
815
|
+
### Available Methods
|
|
816
|
+
|
|
817
|
+
The SDK provides essential methods for daily development:
|
|
818
|
+
|
|
819
|
+
- `getCredential` – Get API credentials
|
|
820
|
+
- `getPrompt` – Get prompts with variable substitution
|
|
821
|
+
- `getAvailableVectorStores` – List available vector stores
|
|
822
|
+
- `searchVectorStore` – Semantic search in knowledge base
|
|
823
|
+
- `addDocument` – Add documents to vector store
|
|
824
|
+
- `listDocuments` – List documents in vector store
|
|
825
|
+
- `deleteDocument` – Remove documents from vector store
|
|
826
|
+
- `session.get()` – Session management
|
|
827
|
+
- `log` – Structured logging
|
|
828
|
+
- `trace` – Send traces for observability
|
|
829
|
+
- `health` – Health check
|
|
830
|
+
|
|
831
|
+
### Example: Health check
|
|
832
|
+
|
|
833
|
+
```typescript
|
|
834
|
+
import { RunflowSDK } from '@runflow-ai/sdk';
|
|
835
|
+
|
|
836
|
+
const sdk = new RunflowSDK({ tenantId: 't', agentId: 'a', requestId: 'r' });
|
|
837
|
+
const status = await sdk.health();
|
|
838
|
+
console.log(status);
|
|
839
|
+
```
|
|
840
|
+
|
|
841
|
+
### Example: Fetch prompt with variables
|
|
842
|
+
|
|
843
|
+
```typescript
|
|
844
|
+
import { RunflowSDK } from '@runflow-ai/sdk';
|
|
845
|
+
|
|
846
|
+
const sdk = new RunflowSDK({ tenantId: 't', agentId: 'a', requestId: 'r' });
|
|
847
|
+
const content = await sdk.getPrompt('welcome', {
|
|
848
|
+
userName: 'João',
|
|
849
|
+
company: 'Acme Corp'
|
|
850
|
+
});
|
|
851
|
+
console.log(content);
|
|
852
|
+
```
|
|
853
|
+
|
|
854
|
+
### Example: Search knowledge base
|
|
855
|
+
|
|
856
|
+
```typescript
|
|
857
|
+
import { searchVectorStore } from '@runflow-ai/sdk';
|
|
858
|
+
|
|
859
|
+
const results = await searchVectorStore(
|
|
860
|
+
'knowledge-base',
|
|
861
|
+
'How to configure payments?',
|
|
862
|
+
{ k: 5, threshold: 0.8 }
|
|
863
|
+
);
|
|
864
|
+
|
|
865
|
+
results.results.forEach(result => {
|
|
866
|
+
console.log(`${result.score}: ${result.content}`);
|
|
867
|
+
});
|
|
868
|
+
```
|
|
869
|
+
|
|
870
|
+
### Flow Diagram
|
|
871
|
+
|
|
872
|
+
```mermaid
|
|
873
|
+
sequenceDiagram
|
|
874
|
+
participant Client
|
|
875
|
+
participant SDK
|
|
876
|
+
participant API
|
|
877
|
+
Client->>SDK: createHandler(fn)
|
|
878
|
+
SDK->>API: calls /sdk endpoints
|
|
879
|
+
API-->>SDK: responses
|
|
880
|
+
```
|
|
881
|
+
|
|
882
|
+
## 📄 Licença
|
|
883
|
+
|
|
884
|
+
MIT License - veja o arquivo LICENSE para detalhes.
|
|
885
|
+
|
|
886
|
+
## 🤝 Contribuindo
|
|
887
|
+
|
|
888
|
+
Contribuições são bem-vindas! Por favor, abra uma issue ou pull request no repositório do projeto.
|
|
889
|
+
|
|
890
|
+
## 📞 Suporte
|
|
891
|
+
|
|
892
|
+
Para suporte técnico, entre em contato através dos canais oficiais da Runflow ou consulte a documentação completa da plataforma.
|
|
893
|
+
>>>>>>> 6435d75437a22d2d974b5406d5c881d3d016d76d
|