@smythos/sre 1.7.41 → 1.7.42

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.
@@ -482,10 +482,14 @@ export class OTel extends TelemetryConnector {
482
482
  const accessCandidate = AccessCandidate.agent(agentId);
483
483
  if (OTEL_DEBUG_LOGS) outputLogger.debug('Conversation.streamPrompt completed', { processId }, accessCandidate);
484
484
 
485
+ // Handle curLLMGenSpan with error awareness
485
486
  if (hookContext.curLLMGenSpan) {
487
+ if (error) {
488
+ hookContext.curLLMGenSpan.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
489
+ }
486
490
  hookContext.curLLMGenSpan.addEvent('llm.gen.content', {
487
491
  'content.size': JSON.stringify(result || {}).length,
488
- 'content.preview': result.substring(0, 200),
492
+ 'content.preview': typeof result === 'string' ? result.substring(0, 200) : JSON.stringify(result || {}).substring(0, 200),
489
493
  });
490
494
  hookContext.curLLMGenSpan.end();
491
495
 
@@ -498,27 +502,69 @@ export class OTel extends TelemetryConnector {
498
502
 
499
503
  const spanCtx = convSpan.spanContext();
500
504
  const spanContext = trace.setSpan(context.active(), convSpan);
501
- context.with(spanContext, () => {
502
- logger.emit({
503
- severityNumber: SeverityNumber.INFO,
504
- severityText: 'INFO',
505
- body: `Conversation.streamPrompt completed: ${processId}`,
506
- attributes: {
507
- 'agent.id': agentId,
508
- 'conv.id': processId,
509
- 'output.size': JSON.stringify(result || {}).length,
510
- 'output.preview': result.substring(0, 2000),
511
- 'team.id': teamId,
512
- 'org.tier': orgTier,
513
- 'org.slot': orgSlot,
514
- 'agent.debug': isDebugSession,
515
- 'agent.isTest': isTestDomain,
516
- 'session.id': sessionId,
517
- 'workflow.id': workflowId,
518
- 'log.tags': logTags,
519
- },
505
+
506
+ if (error) {
507
+ // Error handling for conversation span
508
+ convSpan.recordException(error);
509
+ convSpan.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
510
+ convSpan.addEvent('conv.error', {
511
+ 'error.message': error.message,
520
512
  });
521
- });
513
+
514
+ // Emit ERROR log
515
+ context.with(spanContext, () => {
516
+ logger.emit({
517
+ severityNumber: SeverityNumber.ERROR,
518
+ severityText: 'ERROR',
519
+ body: `Conversation.streamPrompt failed: ${processId}`,
520
+ attributes: {
521
+ // Explicit trace correlation
522
+ trace_id: spanCtx.traceId,
523
+ span_id: spanCtx.spanId,
524
+ trace_flags: spanCtx.traceFlags,
525
+
526
+ 'agent.id': agentId,
527
+ 'conv.id': processId,
528
+ 'error.message': error.message,
529
+ 'error.stack': error.stack,
530
+ 'team.id': teamId,
531
+ 'org.tier': orgTier,
532
+ 'org.slot': orgSlot,
533
+ 'agent.debug': isDebugSession,
534
+ 'agent.isTest': isTestDomain,
535
+ 'session.id': sessionId,
536
+ 'workflow.id': workflowId,
537
+ 'log.tags': logTags,
538
+ },
539
+ });
540
+ });
541
+ } else {
542
+ // Success handling
543
+ convSpan.setStatus({ code: SpanStatusCode.OK });
544
+
545
+ context.with(spanContext, () => {
546
+ logger.emit({
547
+ severityNumber: SeverityNumber.INFO,
548
+ severityText: 'INFO',
549
+ body: `Conversation.streamPrompt completed: ${processId}`,
550
+ attributes: {
551
+ 'agent.id': agentId,
552
+ 'conv.id': processId,
553
+ 'output.size': JSON.stringify(result || {}).length,
554
+ 'output.preview':
555
+ typeof result === 'string' ? result.substring(0, 2000) : JSON.stringify(result || {}).substring(0, 2000),
556
+ 'team.id': teamId,
557
+ 'org.tier': orgTier,
558
+ 'org.slot': orgSlot,
559
+ 'agent.debug': isDebugSession,
560
+ 'agent.isTest': isTestDomain,
561
+ 'session.id': sessionId,
562
+ 'workflow.id': workflowId,
563
+ 'log.tags': logTags,
564
+ },
565
+ });
566
+ });
567
+ }
522
568
 
523
569
  convSpan.end();
524
570
 
@@ -684,12 +730,32 @@ export class OTel extends TelemetryConnector {
684
730
  const accessCandidate = AccessCandidate.agent(agentId);
685
731
  if (OTEL_DEBUG_LOGS) outputLogger.debug('SREAgent.process completed', { agentProcessId }, accessCandidate);
686
732
 
733
+ // Check for error indicators in result (process returned error without throwing)
734
+ const hasResultError = !error && (!!result?._error || !!result?.error);
735
+ const resultError = hasResultError ? result._error || result.error : null;
736
+ const resultErrorMessage = resultError?.message || (typeof resultError === 'string' ? resultError : null);
737
+
738
+ // Determine if this is an error case (either thrown error or result error)
739
+ const isError = !!error || hasResultError;
740
+ const errorMessage = error?.message || resultErrorMessage || 'Process returned error';
741
+
687
742
  if (error) {
688
743
  agentSpan.recordException(error);
689
744
  agentSpan.setStatus({ code: SpanStatusCode.ERROR, message: error.message });
690
745
  agentSpan.addEvent('skill.process.error', {
691
746
  'error.message': error.message,
692
747
  });
748
+ } else if (hasResultError) {
749
+ // Handle error in result (no exception thrown)
750
+ agentSpan.setStatus({ code: SpanStatusCode.ERROR, message: errorMessage });
751
+ agentSpan.addEvent('skill.process.error', {
752
+ 'error.message': errorMessage,
753
+ 'error.type': 'result_error',
754
+ });
755
+ agentSpan.setAttributes({
756
+ 'output.size': JSON.stringify(result || {}).length,
757
+ 'output.has_error': true,
758
+ });
693
759
  } else {
694
760
  agentSpan.setStatus({ code: SpanStatusCode.OK });
695
761
  agentSpan.addEvent('skill.process.completed', {
@@ -701,7 +767,7 @@ export class OTel extends TelemetryConnector {
701
767
  }
702
768
 
703
769
  // Emit log BEFORE ending span to ensure context is active
704
- const outputForLog = oTelInstance.formatOutputForLog(result, !!error);
770
+ const outputForLog = oTelInstance.formatOutputForLog(result, isError);
705
771
  const spanCtx = agentSpan.spanContext();
706
772
  const logAttributes: Record<string, any> = {
707
773
  // Explicit trace correlation (some backends need these)
@@ -710,9 +776,10 @@ export class OTel extends TelemetryConnector {
710
776
  trace_flags: spanCtx.traceFlags,
711
777
  'agent.id': agentId,
712
778
  'process.id': agentProcessId,
713
- hasError: !!error,
714
- 'error.message': error?.message,
779
+ hasError: isError,
780
+ 'error.message': isError ? errorMessage : undefined,
715
781
  'error.stack': error?.stack,
782
+ 'error.type': hasResultError ? 'result_error' : undefined,
716
783
  'team.id': teamId,
717
784
  'org.slot': orgSlot,
718
785
  'org.tier': orgTier,
@@ -734,9 +801,9 @@ export class OTel extends TelemetryConnector {
734
801
  const spanContext = trace.setSpan(context.active(), agentSpan);
735
802
  context.with(spanContext, () => {
736
803
  logger.emit({
737
- severityNumber: error ? SeverityNumber.ERROR : SeverityNumber.INFO,
738
- severityText: error ? 'ERROR' : 'INFO',
739
- body: `Agent process ${error ? 'failed' : 'completed'}: ${agentProcessId}`,
804
+ severityNumber: isError ? SeverityNumber.ERROR : SeverityNumber.INFO,
805
+ severityText: isError ? 'ERROR' : 'INFO',
806
+ body: `Agent process ${isError ? 'failed' : 'completed'}: ${agentProcessId}`,
740
807
  attributes: logAttributes,
741
808
  } as any);
742
809
  });
@@ -946,58 +1013,110 @@ export class OTel extends TelemetryConnector {
946
1013
  });
947
1014
  });
948
1015
  } else {
949
- span.setStatus({ code: SpanStatusCode.OK });
950
-
951
- // Add success event with output summary
1016
+ // Check if result contains an error indicator (component returned error without throwing)
1017
+ const hasResultError = !!result?._error || !!result?.error;
952
1018
  const resultStr = JSON.stringify(result || {});
953
- span.addEvent('cmp.call.result', {
954
- 'output.size': resultStr.length,
955
- 'output.preview': resultStr.substring(0, 200),
956
- });
957
1019
 
958
- // Add output attributes to span
959
- span.setAttributes({
960
- 'output.size': JSON.stringify(result || {}).length,
961
- 'output.has_error': !!result?._error,
962
- });
1020
+ if (hasResultError) {
1021
+ // Treat as error even though no exception was thrown
1022
+ const resultError = result._error || result.error;
1023
+ const errorMessage = resultError?.message || (typeof resultError === 'string' ? resultError : 'Component returned error');
963
1024
 
964
- // Emit success log with output (formatted safely)
965
- const outputForLog = oTelInstance.formatOutputForLog(result, false);
966
- const logAttributes: Record<string, any> = {
967
- 'agent.id': agentId,
968
- 'cmp.id': componentId,
969
- 'cmp.type': componentType,
970
- 'cmp.name': componentName,
971
- 'process.id': processId,
972
- 'event.id': eventId,
973
- 'cmp.output': result,
974
- 'team.id': teamId,
975
- 'org.slot': orgSlot,
976
- 'org.tier': orgTier,
977
- 'source.id': sourceId,
978
- 'source.name': sourceName,
979
- 'session.id': sessionId,
980
- 'workflow.id': workflowId,
981
- 'workflow.step': workflowStep,
982
- 'log.tags': logTags,
983
- 'agent.debug': isDebugSession,
984
- 'agent.isTest': isTestDomain,
985
- };
1025
+ span.setStatus({ code: SpanStatusCode.ERROR, message: errorMessage });
1026
+ span.addEvent('cmp.call.error', {
1027
+ 'event.id': eventId,
1028
+ 'cmp.id': componentId,
1029
+ 'cmp.type': componentType,
1030
+ 'cmp.name': componentName,
1031
+ 'error.type': 'result_error',
1032
+ 'error.message': errorMessage,
1033
+ });
986
1034
 
987
- // Only include output if formatOutputForLog returns a value
988
- // if (outputForLog !== undefined) {
989
- // logAttributes['cmp.output'] = outputForLog;
990
- // }
1035
+ // Add output attributes to span
1036
+ span.setAttributes({
1037
+ 'output.size': resultStr.length,
1038
+ 'output.has_error': true,
1039
+ });
991
1040
 
992
- const spanContext = trace.setSpan(context.active(), span);
993
- context.with(spanContext, () => {
994
- logger.emit({
995
- severityNumber: SeverityNumber.INFO,
996
- severityText: 'INFO',
997
- body: `Component ${componentType} (${componentId}) completed successfully`,
998
- attributes: logAttributes,
1041
+ // Emit ERROR log for result error
1042
+ const spanContext = trace.setSpan(context.active(), span);
1043
+ context.with(spanContext, () => {
1044
+ logger.emit({
1045
+ severityNumber: SeverityNumber.ERROR,
1046
+ severityText: 'ERROR',
1047
+ body: `Component ${componentType} (${componentId}) failed: ${errorMessage}`,
1048
+ attributes: {
1049
+ 'agent.id': agentId,
1050
+ 'process.id': processId,
1051
+ 'event.id': eventId,
1052
+ 'cmp.id': componentId,
1053
+ 'cmp.name': componentName,
1054
+ 'cmp.type': componentType,
1055
+ 'error.type': 'result_error',
1056
+ 'error.message': errorMessage,
1057
+ 'cmp.output': result,
1058
+ 'team.id': teamId,
1059
+ 'org.slot': orgSlot,
1060
+ 'org.tier': orgTier,
1061
+ 'source.id': sourceId,
1062
+ 'source.name': sourceName,
1063
+ 'session.id': sessionId,
1064
+ 'workflow.id': workflowId,
1065
+ 'workflow.step': workflowStep,
1066
+ 'log.tags': logTags,
1067
+ 'agent.debug': isDebugSession,
1068
+ 'agent.isTest': isTestDomain,
1069
+ },
1070
+ });
999
1071
  });
1000
- });
1072
+ } else {
1073
+ // True success case
1074
+ span.setStatus({ code: SpanStatusCode.OK });
1075
+
1076
+ // Add success event with output summary
1077
+ span.addEvent('cmp.call.result', {
1078
+ 'output.size': resultStr.length,
1079
+ 'output.preview': resultStr.substring(0, 200),
1080
+ });
1081
+
1082
+ // Add output attributes to span
1083
+ span.setAttributes({
1084
+ 'output.size': resultStr.length,
1085
+ 'output.has_error': false,
1086
+ });
1087
+
1088
+ // Emit success log with output (formatted safely)
1089
+ const logAttributes: Record<string, any> = {
1090
+ 'agent.id': agentId,
1091
+ 'cmp.id': componentId,
1092
+ 'cmp.type': componentType,
1093
+ 'cmp.name': componentName,
1094
+ 'process.id': processId,
1095
+ 'event.id': eventId,
1096
+ 'cmp.output': result,
1097
+ 'team.id': teamId,
1098
+ 'org.slot': orgSlot,
1099
+ 'org.tier': orgTier,
1100
+ 'source.id': sourceId,
1101
+ 'source.name': sourceName,
1102
+ 'session.id': sessionId,
1103
+ 'workflow.id': workflowId,
1104
+ 'workflow.step': workflowStep,
1105
+ 'log.tags': logTags,
1106
+ 'agent.debug': isDebugSession,
1107
+ 'agent.isTest': isTestDomain,
1108
+ };
1109
+
1110
+ const spanContext = trace.setSpan(context.active(), span);
1111
+ context.with(spanContext, () => {
1112
+ logger.emit({
1113
+ severityNumber: SeverityNumber.INFO,
1114
+ severityText: 'INFO',
1115
+ body: `Component ${componentType} (${componentId}) completed successfully`,
1116
+ attributes: logAttributes,
1117
+ });
1118
+ });
1119
+ }
1001
1120
  }
1002
1121
 
1003
1122
  span.end();