@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 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