@runflow-ai/sdk 1.0.18 → 1.0.19

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.
Files changed (35) hide show
  1. package/dist/core/agent.d.ts +3 -37
  2. package/dist/core/agent.d.ts.map +1 -1
  3. package/dist/core/agent.js +227 -529
  4. package/dist/core/agent.js.map +1 -1
  5. package/dist/core/context.d.ts.map +1 -1
  6. package/dist/core/context.js +1 -11
  7. package/dist/core/context.js.map +1 -1
  8. package/dist/core/helpers/agent-context.d.ts +23 -0
  9. package/dist/core/helpers/agent-context.d.ts.map +1 -0
  10. package/dist/core/helpers/agent-context.js +90 -0
  11. package/dist/core/helpers/agent-context.js.map +1 -0
  12. package/dist/core/helpers/agent-memory.d.ts +17 -0
  13. package/dist/core/helpers/agent-memory.d.ts.map +1 -0
  14. package/dist/core/helpers/agent-memory.js +194 -0
  15. package/dist/core/helpers/agent-memory.js.map +1 -0
  16. package/dist/core/helpers/agent-rag.d.ts +22 -0
  17. package/dist/core/helpers/agent-rag.d.ts.map +1 -0
  18. package/dist/core/helpers/agent-rag.js +216 -0
  19. package/dist/core/helpers/agent-rag.js.map +1 -0
  20. package/dist/core/helpers/agent-utils.d.ts +13 -0
  21. package/dist/core/helpers/agent-utils.d.ts.map +1 -0
  22. package/dist/core/helpers/agent-utils.js +35 -0
  23. package/dist/core/helpers/agent-utils.js.map +1 -0
  24. package/dist/core/logger.d.ts +22 -0
  25. package/dist/core/logger.d.ts.map +1 -0
  26. package/dist/core/logger.js +91 -0
  27. package/dist/core/logger.js.map +1 -0
  28. package/dist/core/performance-logger.d.ts +45 -0
  29. package/dist/core/performance-logger.d.ts.map +1 -0
  30. package/dist/core/performance-logger.js +140 -0
  31. package/dist/core/performance-logger.js.map +1 -0
  32. package/dist/observability/trace-collector.d.ts.map +1 -1
  33. package/dist/observability/trace-collector.js +0 -16
  34. package/dist/observability/trace-collector.js.map +1 -1
  35. package/package.json +3 -1
@@ -4,33 +4,42 @@ exports.Agent = void 0;
4
4
  const trace_collector_1 = require("../observability/trace-collector");
5
5
  const api_client_1 = require("./api-client");
6
6
  const context_1 = require("./context");
7
+ const logger_1 = require("./logger");
8
+ const performance_logger_1 = require("./performance-logger");
9
+ const agent_memory_1 = require("./helpers/agent-memory");
10
+ const agent_rag_1 = require("./helpers/agent-rag");
11
+ const agent_context_1 = require("./helpers/agent-context");
12
+ const agent_utils_1 = require("./helpers/agent-utils");
7
13
  // ============================================================================
8
14
  // AGENT CLASS
9
15
  // ============================================================================
10
16
  class Agent {
11
17
  constructor(config) {
12
18
  this.config = config;
19
+ // Configurar logger
20
+ this.logger = (0, logger_1.createLogger)({
21
+ name: `agent:${config.name}`,
22
+ level: this.resolveLogLevel(config.debug),
23
+ enabled: config.debug !== false,
24
+ });
13
25
  // ============================================================================
14
26
  // AUTO-CREATE RAG TOOLS (Agentic RAG)
15
27
  // ============================================================================
16
28
  // Se RAG configurado, criar tools automaticamente
17
29
  // LLM decide quando buscar (não busca sempre)
18
30
  if (config.rag) {
19
- console.log('🔍 [SDK Agent] Creating RAG tools automatically...');
20
- const ragTools = this.createRAGTools(config.rag);
31
+ this.logger.debug('RAG configuration detected, creating tools');
32
+ const ragTools = (0, agent_rag_1.createRAGTools)(config.rag, this.logger);
21
33
  this.config.tools = {
22
34
  ...ragTools,
23
35
  ...config.tools,
24
36
  };
25
- console.log(`✅ [SDK Agent] Created ${Object.keys(ragTools).length} RAG tool(s):`, Object.keys(ragTools));
26
37
  // Injetar searchPrompt nas instructions (orienta quando buscar)
27
38
  if (config.rag.searchPrompt) {
28
39
  this.config.instructions += `\n\n${config.rag.searchPrompt}`;
29
- console.log('📝 [SDK Agent] Injected searchPrompt into instructions');
40
+ this.logger.debug('Search prompt injected into instructions');
30
41
  }
31
42
  }
32
- // Configurar debug
33
- this.debugConfig = this.resolveDebugConfig(config.debug);
34
43
  // Auto-initialize API client if not in execution context
35
44
  if (!this.apiClient) {
36
45
  this.apiClient = (0, api_client_1.createRunflowAPIClient)();
@@ -40,32 +49,34 @@ class Agent {
40
49
  batchSize: 1, // Flush imediatamente após cada trace
41
50
  flushInterval: 1000,
42
51
  });
43
- console.log('🔍 [SDK Agent] Trace collector initialized in constructor with projectId:', projectId);
44
52
  }
45
53
  }
46
54
  // Injetar API client (feito pela execution engine)
47
55
  _setAPIClient(apiClient) {
48
- this.apiClient = apiClient;
49
- // Use agentId from environment or config name as fallback
50
56
  const projectId = process.env.RUNFLOW_AGENT_ID || this.config.name.toLowerCase().replace(/\s+/g, '-');
57
+ this.logger.debug('Setting API client', { projectId });
58
+ this.apiClient = apiClient;
51
59
  this.traceCollector = (0, trace_collector_1.createTraceCollector)(apiClient, projectId, {
52
60
  batchSize: 1, // Flush imediatamente após cada trace
53
61
  flushInterval: 1000,
54
62
  });
55
- console.log('🔍 [SDK Agent] Trace collector initialized via _setAPIClient with projectId:', projectId);
56
63
  }
57
64
  // Geração simples (aceita string ou array de messages)
58
65
  async generate(input) {
59
66
  const isMessagesArray = Array.isArray(input);
60
- console.log('💬 [SDK Agent] Generate called with', isMessagesArray ? `${input.length} messages` : `prompt length: ${input.length}`);
61
67
  if (!this.apiClient) {
62
- console.error('❌ [SDK Agent] API client not initialized!');
68
+ this.logger.error('API client not initialized');
63
69
  throw new Error('Agent not initialized. API client not set.');
64
70
  }
65
- console.log('🌐 [SDK Agent] Calling chat API...');
66
71
  const messages = isMessagesArray
67
72
  ? input
68
73
  : [{ role: 'user', content: input }];
74
+ this.logger.debug('Starting generation', {
75
+ messagesCount: messages.length,
76
+ isMessagesArray,
77
+ provider: this.config.model.provider,
78
+ model: this.config.model.model
79
+ });
69
80
  const chatRequest = {
70
81
  projectId: '', // Será injetado pela engine
71
82
  provider: this.config.model.provider,
@@ -80,22 +91,32 @@ class Agent {
80
91
  stop: this.config.modelConfig?.stop,
81
92
  seed: this.config.modelConfig?.seed,
82
93
  };
83
- console.log('📡 [SDK Agent] Chat request:', JSON.stringify(chatRequest, null, 2));
84
94
  try {
85
95
  const response = await this.apiClient.chat(chatRequest);
86
- console.log(' [SDK Agent] Chat response received:', response);
96
+ this.logger.debug('Generation completed', {
97
+ responseLength: response.text?.length || 0,
98
+ usage: response.usage
99
+ });
87
100
  return { text: response.text };
88
101
  }
89
102
  catch (error) {
90
- console.error('❌ [SDK Agent] Chat API failed:', error);
103
+ this.logger.error('Chat API failed', {
104
+ error: error instanceof Error ? error.message : 'Unknown error'
105
+ });
91
106
  throw error;
92
107
  }
93
108
  }
94
109
  // Geração com streaming
95
110
  async generateStream(prompt) {
96
111
  if (!this.apiClient) {
112
+ this.logger.error('API client not initialized for streaming');
97
113
  throw new Error('Agent not initialized. API client not set.');
98
114
  }
115
+ this.logger.debug('Starting stream generation', {
116
+ promptLength: prompt.length,
117
+ provider: this.config.model.provider,
118
+ model: this.config.model.model
119
+ });
99
120
  const stream = this.apiClient.chatStream({
100
121
  projectId: '',
101
122
  provider: this.config.model.provider,
@@ -110,26 +131,38 @@ class Agent {
110
131
  stop: this.config.modelConfig?.stop,
111
132
  seed: this.config.modelConfig?.seed,
112
133
  });
113
- return this.processStreamChunks(stream);
134
+ return (0, agent_utils_1.processStreamChunks)(stream, this.logger);
114
135
  }
115
136
  // Geração com tools (implementa loop de tool calling)
116
137
  async generateWithTools(input) {
117
138
  if (!this.apiClient) {
139
+ this.logger.error('API client not initialized for tool generation');
118
140
  throw new Error('Agent not initialized. API client not set.');
119
141
  }
120
142
  if (!this.config.tools || Object.keys(this.config.tools).length === 0) {
143
+ this.logger.debug('No tools configured, falling back to simple generation');
121
144
  return this.generate(input);
122
145
  }
123
146
  const isMessagesArray = Array.isArray(input);
124
147
  let messages = isMessagesArray
125
148
  ? [...input]
126
149
  : [{ role: 'user', content: input }];
150
+ this.logger.debug('Starting generation with tools', {
151
+ messagesCount: messages.length,
152
+ toolsCount: Object.keys(this.config.tools).length,
153
+ toolNames: Object.keys(this.config.tools)
154
+ });
127
155
  const maxIterations = this.config.maxToolIterations || 10; // Prevenir loops infinitos
128
156
  let iteration = 0;
129
157
  while (iteration < maxIterations) {
130
158
  iteration++;
131
- console.log(`🔄 [SDK Agent] Tool calling iteration ${iteration}/${maxIterations}`);
159
+ this.logger.debug('Tool calling iteration', {
160
+ iteration,
161
+ maxIterations,
162
+ messagesCount: messages.length
163
+ });
132
164
  // 🔍 Trace: LLM Call
165
+ performance_logger_1.performanceLogger.start(`llm.call.${iteration}`);
133
166
  const llmStartTime = Date.now();
134
167
  const llmSpan = this.traceCollector?.startSpan('llm_call', {
135
168
  provider: this.config.model.provider,
@@ -138,16 +171,12 @@ class Agent {
138
171
  hasTools: true,
139
172
  toolsCount: Object.keys(this.config.tools).length,
140
173
  });
141
- // 🔍 Input do trace (detalhado se debug ativado)
174
+ // 🔍 Input do trace
142
175
  const llmInput = {
143
176
  messagesCount: messages.length,
144
177
  temperature: this.config.modelConfig?.temperature,
145
178
  maxTokens: this.config.modelConfig?.maxTokens,
146
179
  };
147
- if (this.debugConfig.logLLMCalls || this.debugConfig.logMessages) {
148
- llmInput.messages = messages;
149
- llmInput.instructions = this.config.instructions;
150
- }
151
180
  llmSpan?.setInput(llmInput);
152
181
  const chatRequest = {
153
182
  projectId: '', // Será injetado pela engine
@@ -165,17 +194,26 @@ class Agent {
165
194
  seed: this.config.modelConfig?.seed,
166
195
  };
167
196
  const response = await this.apiClient.chat(chatRequest);
168
- // 🔍 Output do trace (detalhado se debug ativado)
197
+ performance_logger_1.performanceLogger.end(`llm.call.${iteration}`, {
198
+ iteration,
199
+ hasToolCalls: !!response.toolCalls && response.toolCalls.length > 0,
200
+ toolCallsCount: response.toolCalls?.length || 0,
201
+ promptTokens: response.usage?.promptTokens,
202
+ completionTokens: response.usage?.completionTokens
203
+ });
204
+ this.logger.debug('LLM response received', {
205
+ iteration,
206
+ responseLength: response.text?.length || 0,
207
+ hasToolCalls: !!response.toolCalls && response.toolCalls.length > 0,
208
+ toolCallsCount: response.toolCalls?.length || 0,
209
+ usage: response.usage
210
+ });
211
+ // 🔍 Output do trace
169
212
  const llmOutput = {
170
213
  responseLength: response.text?.length || 0,
171
214
  hasToolCalls: !!response.toolCalls && response.toolCalls.length > 0,
172
215
  toolCallsCount: response.toolCalls?.length || 0,
173
216
  };
174
- if (this.debugConfig.logLLMCalls) {
175
- llmOutput.responseText = response.text;
176
- llmOutput.toolCalls = response.toolCalls;
177
- llmOutput.usage = response.usage;
178
- }
179
217
  llmSpan?.setOutput(llmOutput);
180
218
  llmSpan?.setMetadata({
181
219
  provider: this.config.model.provider,
@@ -199,10 +237,12 @@ class Agent {
199
237
  llmSpan?.finish();
200
238
  // Se não há tool calls, retornar resposta final
201
239
  if (!response.toolCalls || response.toolCalls.length === 0) {
202
- console.log(' [SDK Agent] No tool calls - returning final response');
240
+ this.logger.info('Generation completed without tool calls', {
241
+ iteration,
242
+ responseLength: response.text?.length || 0
243
+ });
203
244
  return { text: response.text };
204
245
  }
205
- console.log(`🛠️ [SDK Agent] Processing ${response.toolCalls.length} tool call(s)`);
206
246
  // Adicionar mensagem do assistente com tool calls
207
247
  messages.push({
208
248
  role: 'assistant',
@@ -212,6 +252,11 @@ class Agent {
212
252
  // Executar cada tool call
213
253
  for (const toolCall of response.toolCalls) {
214
254
  const toolName = toolCall.name;
255
+ this.logger.debug('Processing tool call', {
256
+ toolName,
257
+ toolCallId: toolCall.id,
258
+ iteration
259
+ });
215
260
  // Buscar tool por ID (pode estar com nome diferente da key no config)
216
261
  let tool = this.config.tools[toolName];
217
262
  // Se não encontrou, buscar por ID da tool
@@ -222,8 +267,10 @@ class Agent {
222
267
  }
223
268
  }
224
269
  if (!tool) {
225
- console.error(`❌ [SDK Agent] Tool not found: ${toolName}`);
226
- console.error(` Available tools:`, Object.keys(this.config.tools));
270
+ this.logger.warn('Tool not found', {
271
+ toolName,
272
+ availableTools: Object.keys(this.config.tools)
273
+ });
227
274
  // Adicionar mensagem de erro
228
275
  messages.push({
229
276
  role: 'tool',
@@ -234,7 +281,6 @@ class Agent {
234
281
  continue;
235
282
  }
236
283
  try {
237
- console.log(`🔧 [SDK Agent] Executing tool: ${toolName}`);
238
284
  // 🔍 Iniciar trace da tool execution
239
285
  const toolStartTime = Date.now();
240
286
  const toolSpan = this.traceCollector?.startSpan('tool_call', {
@@ -249,20 +295,28 @@ class Agent {
249
295
  }
250
296
  // 🔍 Input sempre vai completo para o trace
251
297
  toolSpan?.setInput(args);
252
- // Executar tool
253
- const toolResult = await tool.execute(args, {
254
- runflowAPI: this.apiClient,
255
- projectId: process.env.RUNFLOW_AGENT_ID || '',
256
- companyId: process.env.RUNFLOW_TENANT_ID || '',
257
- });
258
- console.log(`✅ [SDK Agent] Tool executed successfully: ${toolName}`, toolResult);
298
+ // Executar tool com performance tracking
299
+ const toolResult = await performance_logger_1.performanceLogger.measure(`tool.${toolName}`, async () => {
300
+ return await tool.execute(args, {
301
+ runflowAPI: this.apiClient,
302
+ projectId: process.env.RUNFLOW_AGENT_ID || '',
303
+ companyId: process.env.RUNFLOW_TENANT_ID || '',
304
+ });
305
+ }, { toolId: tool.id, iteration });
259
306
  // 🔍 Output sempre vai completo para o trace
260
307
  const toolEndTime = Date.now();
308
+ const processingTimeMs = toolEndTime - toolStartTime;
309
+ this.logger.info('Tool execution completed', {
310
+ toolName,
311
+ toolId: tool.id,
312
+ processingTimeMs,
313
+ iteration
314
+ });
261
315
  toolSpan?.setOutput(toolResult);
262
316
  toolSpan?.setMetadata({
263
317
  toolName,
264
318
  toolId: tool.id,
265
- processingTimeMs: toolEndTime - toolStartTime,
319
+ processingTimeMs,
266
320
  success: true,
267
321
  });
268
322
  toolSpan?.finish();
@@ -275,7 +329,12 @@ class Agent {
275
329
  });
276
330
  }
277
331
  catch (error) {
278
- console.error(`❌ [SDK Agent] Tool execution failed: ${toolName}`, error);
332
+ this.logger.error('Tool execution failed', {
333
+ toolName,
334
+ toolId: tool.id,
335
+ error: error instanceof Error ? error.message : 'Unknown error',
336
+ iteration
337
+ });
279
338
  // 🔍 Registrar erro no trace (se existe)
280
339
  const toolSpan = this.traceCollector?.startSpan('tool_call', {
281
340
  toolName,
@@ -303,30 +362,26 @@ class Agent {
303
362
  }
304
363
  }
305
364
  // Se chegou aqui, atingiu o limite de iterações
306
- console.warn('⚠️ [SDK Agent] Max tool calling iterations reached');
365
+ this.logger.warn('Max tool calling iterations reached', {
366
+ maxIterations,
367
+ finalMessagesCount: messages.length
368
+ });
307
369
  return { text: 'Maximum tool calling iterations reached. Please try again.' };
308
370
  }
309
371
  // Processamento principal (chamado pela execution engine)
310
372
  async process(input, context) {
311
- console.log('🤖 [SDK Agent] Starting process...');
312
- console.log('📥 [SDK Agent] Input:', JSON.stringify(input, null, 2));
313
- console.log('🔧 [SDK Agent] Config:', {
314
- name: this.config.name,
315
- model: this.config.model,
316
- hasMemory: !!this.config.memory,
317
- hasRAG: !!this.config.rag,
318
- hasTools: !!(this.config.tools && Object.keys(this.config.tools).length > 0),
373
+ const processStartTime = Date.now();
374
+ performance_logger_1.performanceLogger.start('agent.process');
375
+ this.logger.info('Agent processing started', {
376
+ agentName: this.config.name,
377
+ messageLength: input.message?.length || 0,
378
+ sessionId: input.sessionId,
379
+ companyId: input.companyId
319
380
  });
320
381
  // Configurar API client com contexto
321
382
  if (context?.apiClient) {
322
- console.log('🔗 [SDK Agent] Using injected API client from context');
323
383
  this._setAPIClient(context.apiClient);
324
384
  }
325
- else {
326
- console.log('🔗 [SDK Agent] Using auto-configured API client');
327
- // this.apiClient já foi inicializado no constructor
328
- }
329
- console.log('🌐 [SDK Agent] API Client configured:', !!this.apiClient);
330
385
  // ============================================================================
331
386
  // RESOLVER EXECUTION CONTEXT (prioridade: input > state > env > inferência)
332
387
  // ============================================================================
@@ -334,27 +389,26 @@ class Agent {
334
389
  const executionId = input.executionId
335
390
  || state.executionId
336
391
  || process.env.RUNFLOW_EXECUTION_ID
337
- || this.generateExecutionId();
392
+ || (0, agent_context_1.generateExecutionId)();
338
393
  const threadId = input.threadId
339
394
  || state.threadId
340
395
  || process.env.RUNFLOW_THREAD_ID
341
- || this.generateThreadId(input);
396
+ || (0, agent_context_1.generateThreadId)(input, this.logger);
342
397
  const entityType = input.entityType
343
398
  || state.entityType
344
- || this.inferEntityType(input);
399
+ || (0, agent_context_1.inferEntityType)(input, this.logger);
345
400
  const entityValue = input.entityValue
346
401
  || state.entityValue
347
- || this.inferEntityValue(input);
402
+ || (0, agent_context_1.inferEntityValue)(input, this.logger);
348
403
  const userId = input.userId
349
404
  || state.userId
350
- || this.inferUserId(input);
351
- console.log('🔍 [SDK Agent] Execution Context:', {
405
+ || (0, agent_context_1.inferUserId)(input, this.logger);
406
+ this.logger.debug('Execution context resolved', {
352
407
  executionId,
353
408
  threadId,
354
409
  entityType,
355
- entityValue: entityValue || '(none)',
356
- userId: userId || '(none)',
357
- source: input.threadId ? 'input' : state.threadId ? 'state' : 'inferred',
410
+ entityValue,
411
+ userId
358
412
  });
359
413
  // Configurar trace collector com contexto
360
414
  if (this.traceCollector) {
@@ -403,6 +457,10 @@ class Agent {
403
457
  span?.setInput(input);
404
458
  // Se tem multi-agents, usar supervisor pattern
405
459
  if (this.config.agents && Object.keys(this.config.agents).length > 0) {
460
+ this.logger.debug('Multi-agent configuration detected, delegating to supervisor', {
461
+ agentsCount: Object.keys(this.config.agents).length,
462
+ agentNames: Object.keys(this.config.agents)
463
+ });
406
464
  return this.processMultiAgent(input, context);
407
465
  }
408
466
  // Memory management se configurado
@@ -412,21 +470,24 @@ class Agent {
412
470
  // Prioridade 1: Custom memoryKey (override completo)
413
471
  if (this.config.memory.memoryKey) {
414
472
  memoryId = this.config.memory.memoryKey;
415
- console.log('🧠 [SDK Agent] Loading memory with custom key:', memoryId);
416
473
  }
417
474
  // Prioridade 2: entityType + entityValue (do identify())
418
475
  else if (entityType && entityValue) {
419
476
  memoryId = `${entityType}:${entityValue}`;
420
- console.log('🧠 [SDK Agent] Loading memory for entity:', memoryId);
421
477
  }
422
478
  // Prioridade 3: sessionId (backward compatibility)
423
479
  else if (input.sessionId) {
424
480
  memoryId = `session:${input.sessionId}`;
425
- console.log('🧠 [SDK Agent] Loading memory for session (fallback):', memoryId);
426
481
  }
427
482
  if (memoryId) {
428
- memoryMessages = await this.loadMemory(memoryId);
429
- console.log('🧠 [SDK Agent] Memory loaded:', memoryMessages.length > 0 ? `${memoryMessages.length} messages` : 'No history');
483
+ this.logger.debug('Loading memory', {
484
+ memoryId,
485
+ memoryType: this.config.memory.type
486
+ });
487
+ const memoryLoadTime = await performance_logger_1.performanceLogger.measure('memory.load', async () => {
488
+ return await (0, agent_memory_1.loadMemory)(memoryId, this.apiClient, this.config.memory, this.traceCollector, this.logger);
489
+ }, { memoryId, memoryType: this.config.memory.type });
490
+ memoryMessages = memoryLoadTime;
430
491
  }
431
492
  }
432
493
  // ============================================================================
@@ -438,7 +499,6 @@ class Agent {
438
499
  let messages = [];
439
500
  // 2. Se tem messages[] no input, adicionar como contexto
440
501
  if (input.messages && input.messages.length > 0) {
441
- console.log('💬 [SDK Agent] Using provided messages as context:', input.messages.length);
442
502
  const inputMessages = input.messages.map(msg => ({
443
503
  role: msg.role,
444
504
  content: msg.content // Pode ser string ou array multimodal
@@ -447,23 +507,33 @@ class Agent {
447
507
  }
448
508
  // 3. Adicionar historical messages da memória
449
509
  if (memoryMessages.length > 0) {
450
- console.log('🧠 [SDK Agent] Adding memory messages:', memoryMessages.length);
451
510
  messages.push(...memoryMessages);
452
511
  }
453
512
  // 4. Adicionar mensagem atual do usuário
454
513
  messages.push({ role: 'user', content: input.message });
455
- console.log('📝 [SDK Agent] Final messages for LLM:', messages.length);
456
- console.log('🤖 [SDK Agent] Calling LLM...');
457
514
  // Processar com ou sem tools
458
- const result = this.config.tools && Object.keys(this.config.tools).length > 0
515
+ const hasTools = this.config.tools && Object.keys(this.config.tools).length > 0;
516
+ this.logger.debug('Processing messages', {
517
+ messagesCount: messages.length,
518
+ hasTools,
519
+ toolsCount: hasTools ? Object.keys(this.config.tools).length : 0
520
+ });
521
+ performance_logger_1.performanceLogger.start('llm.processing');
522
+ const result = hasTools
459
523
  ? await this.generateWithTools(messages)
460
524
  : await this.generate(messages);
461
- console.log('✅ [SDK Agent] LLM response received:', result.text.substring(0, 100) + '...');
525
+ const llmProcessingTime = performance_logger_1.performanceLogger.end('llm.processing', {
526
+ hasTools,
527
+ messagesCount: messages.length
528
+ });
462
529
  // Salvar na memória se configurado
530
+ let memorySaveTime = 0;
463
531
  if (this.config.memory && memoryId) {
464
- console.log('💾 [SDK Agent] Saving to memory:', memoryId);
465
- await this.saveToMemory(memoryId, input.message, result.text);
466
- console.log('💾 [SDK Agent] Memory saved');
532
+ this.logger.debug('Saving to memory', { memoryId });
533
+ await performance_logger_1.performanceLogger.measure('memory.save', async () => {
534
+ await (0, agent_memory_1.saveToMemory)(memoryId, input.message, result.text, this.apiClient, this.config.memory, this.config.model, this.traceCollector, this.logger);
535
+ }, { memoryId });
536
+ memorySaveTime = Date.now() - processStartTime - llmProcessingTime;
467
537
  }
468
538
  const output = {
469
539
  message: result.text,
@@ -475,16 +545,42 @@ class Agent {
475
545
  sessionId: input.sessionId,
476
546
  },
477
547
  };
478
- console.log('📤 [SDK Agent] Final output:', JSON.stringify(output, null, 2));
479
548
  // Finalizar trace com métricas de performance
480
- const executionEndTime = Date.now();
481
- const processingTimeMs = executionEndTime - executionStartTime;
549
+ const processingTimeMs = Date.now() - processStartTime;
550
+ // Performance summary (se ativado)
551
+ if (performance_logger_1.performanceLogger.isEnabled()) {
552
+ const memoryLoadTime = memoryMessages.length > 0 ?
553
+ (processStartTime + 100) : 0; // Estimativa se não medido diretamente
554
+ performance_logger_1.performanceLogger.summary('agent.process', {
555
+ 'context_resolution': 5, // Tempo mínimo de setup
556
+ 'memory_load': memoryLoadTime,
557
+ 'llm_processing': llmProcessingTime,
558
+ 'memory_save': memorySaveTime,
559
+ }, processingTimeMs);
560
+ }
561
+ performance_logger_1.performanceLogger.end('agent.process', {
562
+ agentName: this.config.name,
563
+ responseLength: result.text?.length || 0,
564
+ memoryUsed: memoryMessages.length > 0,
565
+ toolsUsed: (0, agent_utils_1.getUsedTools)(this.config.tools).length,
566
+ executionId,
567
+ threadId
568
+ });
569
+ this.logger.info('Agent processing completed', {
570
+ agentName: this.config.name,
571
+ processingTimeMs,
572
+ responseLength: result.text?.length || 0,
573
+ memoryUsed: memoryMessages.length > 0,
574
+ toolsUsed: (0, agent_utils_1.getUsedTools)(this.config.tools),
575
+ executionId,
576
+ threadId
577
+ });
482
578
  span?.setOutput(output);
483
579
  span?.setMetadata({
484
580
  // Feature usage atualizado
485
581
  ragUsed: false, // Agora detectado via tool calls
486
582
  memoryUsed: memoryMessages.length > 0,
487
- toolsUsed: this.getUsedTools(),
583
+ toolsUsed: (0, agent_utils_1.getUsedTools)(this.config.tools),
488
584
  // Performance metrics
489
585
  processingTimeMs,
490
586
  // Quality metrics
@@ -509,17 +605,19 @@ class Agent {
509
605
  span?.finish();
510
606
  // Forçar flush dos traces pendentes
511
607
  if (this.traceCollector) {
512
- console.log('🚀 [SDK Agent] Forcing trace flush...');
513
608
  await this.traceCollector.flush();
514
609
  }
515
- console.log('🎉 [SDK Agent] Process completed successfully');
516
610
  return output;
517
611
  }
518
612
  // Multi-agent processing (supervisor pattern)
519
613
  async processMultiAgent(input, context) {
614
+ this.logger.debug('Starting multi-agent processing with supervisor pattern');
520
615
  // Criar supervisor automático
521
616
  const supervisor = this.createSupervisor();
522
617
  // Supervisor decide qual agent usar
618
+ this.logger.debug('Supervisor analyzing agent selection', {
619
+ availableAgents: Object.keys(this.config.agents)
620
+ });
523
621
  const decision = await supervisor.generate(`
524
622
  Available agents:
525
623
  ${Object.entries(this.config.agents).map(([name, config]) => `- ${name}: ${config.instructions}`).join('\n')}
@@ -531,12 +629,19 @@ Which agent should handle this? Respond with just the agent name.
531
629
  const selectedAgentName = decision.text.trim();
532
630
  const selectedAgentConfig = this.config.agents[selectedAgentName];
533
631
  if (!selectedAgentConfig) {
534
- // Fallback para primeiro agent
535
632
  const firstAgentName = Object.keys(this.config.agents)[0];
633
+ this.logger.warn('Supervisor selected invalid agent, using fallback', {
634
+ selectedAgentName,
635
+ fallbackAgentName: firstAgentName
636
+ });
637
+ // Fallback para primeiro agent
536
638
  const firstAgentConfig = this.config.agents[firstAgentName];
537
639
  const agent = new Agent(firstAgentConfig);
538
640
  return agent.process(input, context);
539
641
  }
642
+ this.logger.info('Supervisor selected agent', {
643
+ selectedAgentName
644
+ });
540
645
  // Executar agent selecionado
541
646
  const selectedAgent = new Agent(selectedAgentConfig);
542
647
  return selectedAgent.process(input, context);
@@ -550,170 +655,26 @@ Which agent should handle this? Respond with just the agent name.
550
655
  });
551
656
  }
552
657
  // ============================================================================
553
- // AGENTIC RAG - Create Tools Automatically
658
+ // LOGGER CONFIGURATION
554
659
  // ============================================================================
555
660
  /**
556
- * Cria tools de RAG automaticamente baseado na configuração
557
- * LLM decide quando buscar (não busca sempre)
661
+ * Resolve o nível de log baseado na configuração de debug
558
662
  */
559
- createRAGTools(ragConfig) {
560
- const tools = {};
561
- // Caso 1: KB única (simples)
562
- if (ragConfig.vectorStore) {
563
- tools['searchKnowledge'] = this.createRAGTool({
564
- id: 'knowledge',
565
- name: ragConfig.vectorStore,
566
- threshold: ragConfig.threshold || 0.7,
567
- k: ragConfig.k || 5,
568
- description: ragConfig.toolDescription || `Search in ${ragConfig.vectorStore} knowledge base for relevant information`,
569
- });
570
- console.log(`📚 [SDK Agent] Created RAG tool: searchKnowledge (${ragConfig.vectorStore})`);
663
+ resolveLogLevel(debug) {
664
+ // Se debug é false, desativar logs
665
+ if (debug === false) {
666
+ return 'silent';
571
667
  }
572
- // Caso 2: Múltiplas KBs (avançado) - ARRAY
573
- if (ragConfig.vectorStores && Array.isArray(ragConfig.vectorStores)) {
574
- for (const vs of ragConfig.vectorStores) {
575
- const toolName = `search_${vs.id}`;
576
- tools[toolName] = this.createRAGTool({
577
- id: vs.id,
578
- name: vs.name,
579
- threshold: vs.threshold || ragConfig.threshold || 0.7,
580
- k: vs.k || ragConfig.k || 5,
581
- description: vs.description || `Search in ${vs.name} knowledge base`,
582
- });
583
- console.log(`📚 [SDK Agent] Created RAG tool: ${toolName} (${vs.name})`);
584
- }
668
+ // Se debug é true, usar debug level
669
+ if (debug === true) {
670
+ return 'debug';
585
671
  }
586
- return tools;
587
- }
588
- /**
589
- * Cria uma tool individual de RAG
590
- */
591
- createRAGTool(config) {
592
- return {
593
- id: `search-${config.id}`,
594
- name: `search_${config.id}`,
595
- description: config.description,
596
- parameters: {
597
- query: {
598
- type: 'string',
599
- description: 'Search query to find relevant information',
600
- required: true,
601
- },
602
- },
603
- execute: async (params, context) => {
604
- console.log(`🔍 [RAG Tool] Searching in ${config.name}...`, {
605
- query: params.query,
606
- k: config.k,
607
- threshold: config.threshold,
608
- });
609
- try {
610
- const results = await context.runflowAPI.vectorSearch(params.query, {
611
- vectorStore: config.name,
612
- k: config.k,
613
- threshold: config.threshold,
614
- });
615
- const formattedResults = results.results.map((r) => ({
616
- content: r.content,
617
- score: r.score,
618
- metadata: r.metadata,
619
- }));
620
- console.log(`✅ [RAG Tool] Found ${formattedResults.length} results (threshold: ${config.threshold})`);
621
- // Retornar em formato que o LLM possa usar
622
- if (formattedResults.length === 0) {
623
- return {
624
- found: false,
625
- message: 'No relevant information found in knowledge base',
626
- results: [],
627
- };
628
- }
629
- return {
630
- found: true,
631
- count: formattedResults.length,
632
- results: formattedResults,
633
- context: formattedResults.map((r, i) => `[Result ${i + 1}] (score: ${r.score.toFixed(2)})\n${r.content}`).join('\n\n---\n\n'),
634
- };
635
- }
636
- catch (error) {
637
- console.error(`❌ [RAG Tool] Search failed:`, error);
638
- return {
639
- found: false,
640
- error: error instanceof Error ? error.message : 'Search failed',
641
- results: [],
642
- };
643
- }
644
- },
645
- };
646
- }
647
- // RAG automático (DEPRECATED - mantido para compatibilidade temporária)
648
- async performRAG(query) {
649
- if (!this.config.rag || !this.apiClient) {
650
- return null;
651
- }
652
- // 🔍 Trace: RAG Search
653
- const ragStartTime = Date.now();
654
- const ragSpan = this.traceCollector?.startSpan('rag_search', {
655
- operation: 'vector_search',
656
- vectorStore: this.config.rag.vectorStore,
657
- k: this.config.rag.k || 5,
658
- threshold: this.config.rag.threshold || 0.7,
659
- });
660
- ragSpan?.setInput({ query });
661
- try {
662
- const searchResults = await this.apiClient.vectorSearch(query, {
663
- vectorStore: this.config.rag.vectorStore,
664
- k: this.config.rag.k || 5,
665
- threshold: this.config.rag.threshold || 0.7,
666
- });
667
- if (searchResults.results.length === 0) {
668
- ragSpan?.setOutput({ resultsCount: 0, hasResults: false });
669
- ragSpan?.setMetadata({
670
- operation: 'vector_search',
671
- vectorStore: this.config.rag.vectorStore,
672
- resultsCount: 0,
673
- processingTimeMs: Date.now() - ragStartTime,
674
- success: true,
675
- });
676
- ragSpan?.finish();
677
- return null;
678
- }
679
- const context = searchResults.results
680
- .map((result) => result.content)
681
- .join('\n\n');
682
- // 🔍 Finalizar trace (com dados completos se debug ativado)
683
- const ragOutput = {
684
- resultsCount: searchResults.results.length,
685
- hasResults: true,
686
- contextLength: context.length,
687
- };
688
- if (this.debugConfig.logRAG) {
689
- ragOutput.results = searchResults.results;
690
- ragOutput.contextGenerated = context;
691
- }
692
- ragSpan?.setOutput(ragOutput);
693
- ragSpan?.setMetadata({
694
- operation: 'vector_search',
695
- vectorStore: this.config.rag.vectorStore,
696
- resultsCount: searchResults.results.length,
697
- k: this.config.rag.k || 5,
698
- threshold: this.config.rag.threshold || 0.7,
699
- processingTimeMs: Date.now() - ragStartTime,
700
- success: true,
701
- });
702
- ragSpan?.finish();
703
- return context;
704
- }
705
- catch (error) {
706
- console.error('RAG search failed:', error);
707
- ragSpan?.setMetadata({
708
- operation: 'vector_search',
709
- vectorStore: this.config.rag.vectorStore,
710
- success: false,
711
- error: error instanceof Error ? error.message : 'Unknown error',
712
- processingTimeMs: Date.now() - ragStartTime,
713
- });
714
- ragSpan?.finish();
715
- return null;
672
+ // Se debug é objeto com level, usar o nível especificado
673
+ if (typeof debug === 'object' && debug.level) {
674
+ return debug.level;
716
675
  }
676
+ // Default: info em produção, debug em desenvolvimento
677
+ return process.env.NODE_ENV === 'production' ? 'info' : 'debug';
717
678
  }
718
679
  // Getters
719
680
  get name() {
@@ -731,293 +692,19 @@ Which agent should handle this? Respond with just the agent name.
731
692
  get isMultiAgent() {
732
693
  return !!(this.config.agents && Object.keys(this.config.agents).length > 0);
733
694
  }
734
- // Obter tools utilizadas (para traces)
735
- getUsedTools() {
736
- if (!this.config.tools)
737
- return [];
738
- return Object.keys(this.config.tools);
739
- }
740
- // ============================================================================
741
- // DEBUG HELPERS
742
- // ============================================================================
743
- /**
744
- * Resolver configuração de debug
745
- */
746
- resolveDebugConfig(debug) {
747
- // Verificar variável de ambiente
748
- const envDebug = process.env.RUNFLOW_DEBUG === 'true' || process.env.RUNFLOW_LOG_LEVEL === 'verbose';
749
- if (debug === true || envDebug) {
750
- // Debug simples = todos logs ativados
751
- return {
752
- enabled: true,
753
- logMessages: true,
754
- logLLMCalls: true,
755
- logToolCalls: true,
756
- logRAG: true,
757
- logMemory: true,
758
- truncateAt: undefined,
759
- };
760
- }
761
- else if (typeof debug === 'object' && debug.enabled) {
762
- // Debug customizado
763
- return {
764
- enabled: true,
765
- logMessages: debug.logMessages !== false,
766
- logLLMCalls: debug.logLLMCalls !== false,
767
- logToolCalls: debug.logToolCalls !== false,
768
- logRAG: debug.logRAG !== false,
769
- logMemory: debug.logMemory !== false,
770
- truncateAt: debug.truncateAt,
771
- };
772
- }
773
- return { enabled: false };
774
- }
775
- // ============================================================================
776
- // CONTEXT RESOLUTION HELPERS
777
- // ============================================================================
778
- /**
779
- * Generate unique execution ID
780
- */
781
- generateExecutionId() {
782
- return `exec_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
783
- }
784
- /**
785
- * Generate threadId based on input (fallback quando não fornecido)
786
- */
787
- generateThreadId(input) {
788
- const companyId = input.companyId || 'default';
789
- // Se tem sessionId, usar como thread
790
- if (input.sessionId) {
791
- return `session_${companyId}_${input.sessionId}`;
792
- }
793
- // Fallback: gerar único
794
- return `thread_${companyId}_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`;
795
- }
796
- /**
797
- * Infer entityType from input metadata
798
- */
799
- inferEntityType(input) {
800
- if (input.metadata?.phone)
801
- return 'phone';
802
- if (input.metadata?.email)
803
- return 'email';
804
- if (input.metadata?.contactId)
805
- return 'hubspot_contact';
806
- if (input.sessionId)
807
- return 'session';
808
- return 'session'; // Default
809
- }
810
- /**
811
- * Infer entityValue from input metadata
812
- */
813
- inferEntityValue(input) {
814
- if (input.metadata?.phone)
815
- return input.metadata.phone;
816
- if (input.metadata?.email)
817
- return input.metadata.email;
818
- if (input.metadata?.contactId)
819
- return input.metadata.contactId;
820
- if (input.sessionId)
821
- return input.sessionId;
822
- return null;
823
- }
824
- /**
825
- * Infer userId from input metadata
826
- */
827
- inferUserId(input) {
828
- if (input.metadata?.phone)
829
- return input.metadata.phone;
830
- if (input.metadata?.email)
831
- return input.metadata.email;
832
- if (input.metadata?.contactId)
833
- return input.metadata.contactId;
834
- return null;
835
- }
836
- // ============================================================================
837
- // MEMORY MANAGEMENT
838
- // ============================================================================
839
- // Carregar memória da entidade (retorna array de messages)
840
- async loadMemory(memoryId) {
841
- if (!this.apiClient || !this.config.memory) {
842
- return [];
843
- }
844
- // 🔍 Trace: Memory Load
845
- const memoryLoadStartTime = Date.now();
846
- const memoryLoadSpan = this.traceCollector?.startSpan('memory_operation', {
847
- operation: 'load',
848
- memoryId,
849
- memoryType: this.config.memory.type,
850
- });
851
- try {
852
- const memoryData = await this.apiClient.memory.get(memoryId);
853
- if (!memoryData.messages || memoryData.messages.length === 0) {
854
- memoryLoadSpan?.setOutput({ messagesCount: 0, hasHistory: false });
855
- memoryLoadSpan?.setMetadata({
856
- operation: 'load',
857
- memoryId,
858
- messagesCount: 0,
859
- processingTimeMs: Date.now() - memoryLoadStartTime,
860
- success: true,
861
- });
862
- memoryLoadSpan?.finish();
863
- return [];
864
- }
865
- // Aplicar configurações de memória
866
- let messages = memoryData.messages;
867
- // Limitar por número de turnos
868
- if (this.config.memory.maxTurns) {
869
- messages = messages.slice(-this.config.memory.maxTurns * 2); // user + assistant = 2 messages per turn
870
- }
871
- // Limitar por tokens (aproximado)
872
- if (this.config.memory.maxTokens) {
873
- let totalTokens = 0;
874
- const filteredMessages = [];
875
- for (let i = messages.length - 1; i >= 0; i--) {
876
- const messageTokens = Math.ceil(messages[i].content.length / 4);
877
- if (totalTokens + messageTokens <= this.config.memory.maxTokens) {
878
- filteredMessages.unshift(messages[i]);
879
- totalTokens += messageTokens;
880
- }
881
- else {
882
- break;
883
- }
884
- }
885
- messages = filteredMessages;
886
- }
887
- // Retornar messages como array (formato nativo do LLM)
888
- const result = messages.map((msg) => ({
889
- role: msg.role,
890
- content: msg.content,
891
- }));
892
- // 🔍 Finalizar trace (com dados completos se debug ativado)
893
- const memoryOutput = {
894
- messagesCount: messages.length,
895
- hasHistory: result.length > 0,
896
- };
897
- if (this.debugConfig.logMemory) {
898
- memoryOutput.messages = result;
899
- }
900
- memoryLoadSpan?.setOutput(memoryOutput);
901
- memoryLoadSpan?.setMetadata({
902
- operation: 'load',
903
- memoryId,
904
- messagesCount: messages.length,
905
- maxTurns: this.config.memory.maxTurns,
906
- processingTimeMs: Date.now() - memoryLoadStartTime,
907
- success: true,
908
- });
909
- memoryLoadSpan?.finish();
910
- return result;
911
- }
912
- catch (error) {
913
- console.error('Failed to load memory:', error);
914
- // 🔍 Trace de erro
915
- memoryLoadSpan?.setMetadata({
916
- operation: 'load',
917
- memoryId,
918
- success: false,
919
- error: error instanceof Error ? error.message : 'Unknown error',
920
- processingTimeMs: Date.now() - memoryLoadStartTime,
921
- });
922
- memoryLoadSpan?.finish();
923
- return [];
924
- }
925
- }
926
- // Salvar na memória
927
- async saveToMemory(memoryId, userMessage, assistantMessage) {
928
- if (!this.apiClient || !this.config.memory) {
929
- return;
930
- }
931
- // 🔍 Trace: Memory Save
932
- const memorySaveStartTime = Date.now();
933
- const memorySaveSpan = this.traceCollector?.startSpan('memory_operation', {
934
- operation: 'save',
935
- memoryId,
936
- memoryType: this.config.memory.type,
937
- });
938
- try {
939
- // Adicionar mensagem do usuário
940
- await this.apiClient.memory.append(memoryId, {
941
- role: 'user',
942
- content: userMessage,
943
- timestamp: new Date(),
944
- });
945
- // Adicionar resposta do assistant
946
- await this.apiClient.memory.append(memoryId, {
947
- role: 'assistant',
948
- content: assistantMessage,
949
- timestamp: new Date(),
950
- metadata: {
951
- model: this.config.model.model,
952
- },
953
- });
954
- // Resumir se necessário
955
- let summarized = false;
956
- if (this.config.memory.summarizeAfter) {
957
- const currentMemory = await this.apiClient.memory.get(memoryId);
958
- if (currentMemory.messages.length >= this.config.memory.summarizeAfter) {
959
- await this.apiClient.memory.summarize(memoryId);
960
- summarized = true;
961
- }
962
- }
963
- // 🔍 Finalizar trace (com dados completos se debug ativado)
964
- const memorySaveOutput = {
965
- messagesSaved: 2,
966
- summarized,
967
- };
968
- if (this.debugConfig.logMemory) {
969
- memorySaveOutput.userMessage = userMessage;
970
- memorySaveOutput.assistantMessage = assistantMessage;
971
- }
972
- memorySaveSpan?.setOutput(memorySaveOutput);
973
- memorySaveSpan?.setMetadata({
974
- operation: 'save',
975
- memoryId,
976
- messagesSaved: 2,
977
- summarized,
978
- summarizeAfter: this.config.memory.summarizeAfter,
979
- processingTimeMs: Date.now() - memorySaveStartTime,
980
- success: true,
981
- });
982
- memorySaveSpan?.finish();
983
- }
984
- catch (error) {
985
- console.error('Failed to save to memory:', error);
986
- // 🔍 Trace de erro
987
- memorySaveSpan?.setMetadata({
988
- operation: 'save',
989
- memoryId,
990
- success: false,
991
- error: error instanceof Error ? error.message : 'Unknown error',
992
- processingTimeMs: Date.now() - memorySaveStartTime,
993
- });
994
- memorySaveSpan?.finish();
995
- }
996
- }
997
- // Processar stream chunks (helper)
998
- async *processStreamChunks(stream) {
999
- for await (const chunk of stream) {
1000
- if (chunk.type === 'content') {
1001
- yield { text: chunk.content || '', done: false };
1002
- }
1003
- else if (chunk.type === 'done') {
1004
- yield { text: '', done: true };
1005
- break;
1006
- }
1007
- else if (chunk.type === 'error') {
1008
- throw new Error(chunk.error || 'Streaming error');
1009
- }
1010
- }
1011
- }
1012
695
  // Streaming com memória
1013
696
  async processStream(input, context) {
697
+ this.logger.debug('Starting stream processing', {
698
+ messageLength: input.message?.length || 0,
699
+ sessionId: input.sessionId
700
+ });
1014
701
  if (context?.apiClient) {
1015
702
  this.apiClient = context.apiClient;
1016
703
  }
1017
704
  // Resolver entity context
1018
705
  const state = context_1.Runflow.getState();
1019
- const entityType = input.entityType || state.entityType || this.inferEntityType(input);
1020
- const entityValue = input.entityValue || state.entityValue || this.inferEntityValue(input);
706
+ const entityType = input.entityType || state.entityType || (0, agent_context_1.inferEntityType)(input, this.logger);
707
+ const entityValue = input.entityValue || state.entityValue || (0, agent_context_1.inferEntityValue)(input, this.logger);
1021
708
  // Resolver memoryId com mesma prioridade do process()
1022
709
  let memoryId = null;
1023
710
  if (this.config.memory) {
@@ -1037,7 +724,8 @@ Which agent should handle this? Respond with just the agent name.
1037
724
  // Carregar memória se configurado
1038
725
  let memoryMessages = [];
1039
726
  if (this.config.memory && memoryId) {
1040
- memoryMessages = await this.loadMemory(memoryId);
727
+ this.logger.debug('Loading memory for streaming', { memoryId });
728
+ memoryMessages = await (0, agent_memory_1.loadMemory)(memoryId, this.apiClient, this.config.memory, this.traceCollector, this.logger);
1041
729
  }
1042
730
  // ============================================================================
1043
731
  // RAG agora é TOOL - LLM decide quando buscar
@@ -1073,6 +761,11 @@ Which agent should handle this? Respond with just the agent name.
1073
761
  });
1074
762
  // Criar async generator
1075
763
  const self = this;
764
+ const logger = this.logger;
765
+ const apiClient = this.apiClient;
766
+ const memoryConfig = this.config.memory;
767
+ const modelConfig = this.config.model;
768
+ const traceCollector = this.traceCollector;
1076
769
  return (async function* () {
1077
770
  let fullResponse = '';
1078
771
  for await (const chunk of stream) {
@@ -1082,13 +775,18 @@ Which agent should handle this? Respond with just the agent name.
1082
775
  }
1083
776
  else if (chunk.type === 'done') {
1084
777
  // Salvar na memória quando streaming terminar
1085
- if (self.config.memory && memoryId) {
1086
- await self.saveToMemory(memoryId, input.message, fullResponse);
778
+ if (memoryConfig && memoryId && apiClient) {
779
+ logger.debug('Saving stream response to memory', { memoryId });
780
+ await (0, agent_memory_1.saveToMemory)(memoryId, input.message, fullResponse, apiClient, memoryConfig, modelConfig, traceCollector, logger);
1087
781
  }
782
+ logger.info('Stream processing completed', {
783
+ responseLength: fullResponse.length
784
+ });
1088
785
  yield { text: '', done: true };
1089
786
  break;
1090
787
  }
1091
788
  else if (chunk.type === 'error') {
789
+ logger.error('Streaming error', { error: chunk.error });
1092
790
  throw new Error(chunk.error || 'Streaming error');
1093
791
  }
1094
792
  }