@cloudbase/agent-observability 0.0.20 → 0.0.21

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/dist/langchain.js CHANGED
@@ -809,63 +809,98 @@ function createParentContext(parentSpanContext) {
809
809
  if (!parentSpanContext) return;
810
810
  return import_api4.trace.setSpanContext(import_api4.context.active(), parentSpanContext);
811
811
  }
812
- function startObservation(name, attributes, options) {
813
- const { asType = "chain", ...observationOptions } = options || {};
814
- const otelSpan = createOtelSpan({
815
- name,
816
- ...observationOptions
817
- });
812
+ function createNoopSpan() {
813
+ return import_api4.trace.wrapSpanContext(import_api4.INVALID_SPAN_CONTEXT);
814
+ }
815
+ function createNoopObservation(asType = "chain") {
816
+ const otelSpan = createNoopSpan();
818
817
  switch (asType) {
819
818
  case "llm":
820
- return new ObservationLLM({
821
- otelSpan,
822
- attributes
823
- });
819
+ return new ObservationLLM({ otelSpan });
824
820
  case "embedding":
825
- return new ObservationEmbedding({
826
- otelSpan,
827
- attributes
828
- });
821
+ return new ObservationEmbedding({ otelSpan });
829
822
  case "agent":
830
- return new ObservationAgent({
831
- otelSpan,
832
- attributes
833
- });
823
+ return new ObservationAgent({ otelSpan });
834
824
  case "tool":
835
- return new ObservationTool({
836
- otelSpan,
837
- attributes
838
- });
839
- case "chain":
840
- return new ObservationChain({
841
- otelSpan,
842
- attributes
843
- });
825
+ return new ObservationTool({ otelSpan });
844
826
  case "retriever":
845
- return new ObservationRetriever({
846
- otelSpan,
847
- attributes
848
- });
827
+ return new ObservationRetriever({ otelSpan });
849
828
  case "reranker":
850
- return new ObservationReranker({
851
- otelSpan,
852
- attributes
853
- });
829
+ return new ObservationReranker({ otelSpan });
854
830
  case "evaluator":
855
- return new ObservationEvaluator({
856
- otelSpan,
857
- attributes
858
- });
831
+ return new ObservationEvaluator({ otelSpan });
859
832
  case "guardrail":
860
- return new ObservationGuardrail({
861
- otelSpan,
862
- attributes
863
- });
833
+ return new ObservationGuardrail({ otelSpan });
834
+ case "chain":
864
835
  default:
865
- return new ObservationChain({
866
- otelSpan,
867
- attributes
868
- });
836
+ return new ObservationChain({ otelSpan });
837
+ }
838
+ }
839
+ function startObservation(name, attributes, options) {
840
+ const { asType = "chain", ...observationOptions } = options || {};
841
+ try {
842
+ const otelSpan = createOtelSpan({
843
+ name,
844
+ ...observationOptions
845
+ });
846
+ switch (asType) {
847
+ case "llm":
848
+ return new ObservationLLM({
849
+ otelSpan,
850
+ attributes
851
+ });
852
+ case "embedding":
853
+ return new ObservationEmbedding({
854
+ otelSpan,
855
+ attributes
856
+ });
857
+ case "agent":
858
+ return new ObservationAgent({
859
+ otelSpan,
860
+ attributes
861
+ });
862
+ case "tool":
863
+ return new ObservationTool({
864
+ otelSpan,
865
+ attributes
866
+ });
867
+ case "chain":
868
+ return new ObservationChain({
869
+ otelSpan,
870
+ attributes
871
+ });
872
+ case "retriever":
873
+ return new ObservationRetriever({
874
+ otelSpan,
875
+ attributes
876
+ });
877
+ case "reranker":
878
+ return new ObservationReranker({
879
+ otelSpan,
880
+ attributes
881
+ });
882
+ case "evaluator":
883
+ return new ObservationEvaluator({
884
+ otelSpan,
885
+ attributes
886
+ });
887
+ case "guardrail":
888
+ return new ObservationGuardrail({
889
+ otelSpan,
890
+ attributes
891
+ });
892
+ default:
893
+ return new ObservationChain({
894
+ otelSpan,
895
+ attributes
896
+ });
897
+ }
898
+ } catch (err) {
899
+ console.warn(
900
+ `[Observability] Failed to create observation "${name}":`,
901
+ err instanceof Error ? err.message : err
902
+ );
903
+ return createNoopObservation(asType);
869
904
  }
870
905
  }
871
906
  function updateActiveTrace(attributes) {
@@ -906,67 +941,81 @@ function wrapPromise(promise, span, endOnExit) {
906
941
  }
907
942
  function startActiveObservation(name, fn, options) {
908
943
  const { asType = "chain", endOnExit, ...observationOptions } = options || {};
909
- return getTracer().startActiveSpan(
910
- name,
911
- { startTime: observationOptions?.startTime },
912
- createParentContext(observationOptions?.parentSpanContext) ?? import_api4.context.active(),
913
- (span) => {
914
- try {
915
- let observation;
916
- switch (asType) {
917
- case "llm":
918
- observation = new ObservationLLM({ otelSpan: span });
919
- break;
920
- case "embedding":
921
- observation = new ObservationEmbedding({ otelSpan: span });
922
- break;
923
- case "agent":
924
- observation = new ObservationAgent({ otelSpan: span });
925
- break;
926
- case "tool":
927
- observation = new ObservationTool({ otelSpan: span });
928
- break;
929
- case "retriever":
930
- observation = new ObservationRetriever({ otelSpan: span });
931
- break;
932
- case "reranker":
933
- observation = new ObservationReranker({ otelSpan: span });
934
- break;
935
- case "evaluator":
936
- observation = new ObservationEvaluator({ otelSpan: span });
937
- break;
938
- case "guardrail":
939
- observation = new ObservationGuardrail({ otelSpan: span });
940
- break;
941
- case "chain":
942
- default:
943
- observation = new ObservationChain({ otelSpan: span });
944
- }
945
- const result = fn(observation);
946
- if (result instanceof Promise) {
947
- return wrapPromise(
948
- result,
949
- span,
950
- endOnExit
951
- );
952
- } else {
944
+ let fnCalled = false;
945
+ try {
946
+ return getTracer().startActiveSpan(
947
+ name,
948
+ { startTime: observationOptions?.startTime },
949
+ createParentContext(observationOptions?.parentSpanContext) ?? import_api4.context.active(),
950
+ (span) => {
951
+ try {
952
+ let observation;
953
+ switch (asType) {
954
+ case "llm":
955
+ observation = new ObservationLLM({ otelSpan: span });
956
+ break;
957
+ case "embedding":
958
+ observation = new ObservationEmbedding({ otelSpan: span });
959
+ break;
960
+ case "agent":
961
+ observation = new ObservationAgent({ otelSpan: span });
962
+ break;
963
+ case "tool":
964
+ observation = new ObservationTool({ otelSpan: span });
965
+ break;
966
+ case "retriever":
967
+ observation = new ObservationRetriever({ otelSpan: span });
968
+ break;
969
+ case "reranker":
970
+ observation = new ObservationReranker({ otelSpan: span });
971
+ break;
972
+ case "evaluator":
973
+ observation = new ObservationEvaluator({ otelSpan: span });
974
+ break;
975
+ case "guardrail":
976
+ observation = new ObservationGuardrail({ otelSpan: span });
977
+ break;
978
+ case "chain":
979
+ default:
980
+ observation = new ObservationChain({ otelSpan: span });
981
+ }
982
+ fnCalled = true;
983
+ const result = fn(observation);
984
+ if (result instanceof Promise) {
985
+ return wrapPromise(
986
+ result,
987
+ span,
988
+ endOnExit
989
+ );
990
+ } else {
991
+ if (endOnExit !== false) {
992
+ span.end();
993
+ }
994
+ return result;
995
+ }
996
+ } catch (err) {
997
+ span.setStatus({
998
+ code: import_api4.SpanStatusCode.ERROR,
999
+ message: err instanceof Error ? err.message : "Unknown error"
1000
+ });
953
1001
  if (endOnExit !== false) {
954
1002
  span.end();
955
1003
  }
956
- return result;
957
- }
958
- } catch (err) {
959
- span.setStatus({
960
- code: import_api4.SpanStatusCode.ERROR,
961
- message: err instanceof Error ? err.message : "Unknown error"
962
- });
963
- if (endOnExit !== false) {
964
- span.end();
1004
+ throw err;
965
1005
  }
966
- throw err;
967
1006
  }
1007
+ );
1008
+ } catch (err) {
1009
+ if (fnCalled) {
1010
+ throw err;
968
1011
  }
969
- );
1012
+ console.warn(
1013
+ `[Observability] startActiveObservation "${name}" failed, falling back to no-op:`,
1014
+ err instanceof Error ? err.message : err
1015
+ );
1016
+ const noopObservation = createNoopObservation(asType);
1017
+ return fn(noopObservation);
1018
+ }
970
1019
  }
971
1020
  function updateActiveObservation(attributes) {
972
1021
  const span = import_api4.trace.getActiveSpan();
@@ -992,41 +1041,59 @@ function observe(fn, options = {}) {
992
1041
  } = options;
993
1042
  const wrappedFunction = function(...args) {
994
1043
  const name = fn.name || "anonymous-function";
995
- const inputData = captureInput ? _captureArguments(args) : void 0;
996
- const observation = startObservation(
997
- name,
998
- inputData ? { input: inputData } : {},
999
- {
1000
- ...observationOptions,
1001
- asType
1002
- }
1003
- );
1004
- const activeContext = import_api4.trace.setSpan(import_api4.context.active(), observation.otelSpan);
1005
- const result = import_api4.context.with(activeContext, () => fn.apply(this, args));
1006
- if (result instanceof Promise) {
1007
- return result.then(
1008
- (value) => {
1009
- if (captureOutput) {
1010
- observation.update({ output: value });
1011
- }
1012
- observation.end();
1013
- return value;
1014
- },
1015
- (err) => {
1016
- observation.update({
1017
- level: "ERROR",
1018
- statusMessage: err instanceof Error ? err.message : "Unknown error"
1019
- });
1020
- observation.end();
1021
- throw err;
1044
+ let observation;
1045
+ let fnCalled = false;
1046
+ try {
1047
+ const inputData = captureInput ? _captureArguments(args) : void 0;
1048
+ observation = startObservation(
1049
+ name,
1050
+ inputData ? { input: inputData } : {},
1051
+ {
1052
+ ...observationOptions,
1053
+ asType
1022
1054
  }
1023
1055
  );
1056
+ const activeContext = import_api4.trace.setSpan(import_api4.context.active(), observation.otelSpan);
1057
+ fnCalled = true;
1058
+ const result = import_api4.context.with(activeContext, () => fn.apply(this, args));
1059
+ if (result instanceof Promise) {
1060
+ return result.then(
1061
+ (value) => {
1062
+ if (captureOutput) {
1063
+ observation.update({ output: value });
1064
+ }
1065
+ observation.end();
1066
+ return value;
1067
+ },
1068
+ (err) => {
1069
+ observation.update({
1070
+ level: "ERROR",
1071
+ statusMessage: err instanceof Error ? err.message : "Unknown error"
1072
+ });
1073
+ observation.end();
1074
+ throw err;
1075
+ }
1076
+ );
1077
+ }
1078
+ if (captureOutput) {
1079
+ observation.update({ output: result });
1080
+ }
1081
+ observation.end();
1082
+ return result;
1083
+ } catch (err) {
1084
+ if (fnCalled) {
1085
+ throw err;
1086
+ }
1087
+ console.warn(
1088
+ `[Observability] observe "${name}" failed, falling back to direct call:`,
1089
+ err instanceof Error ? err.message : err
1090
+ );
1091
+ try {
1092
+ observation?.end();
1093
+ } catch {
1094
+ }
1095
+ return fn.apply(this, args);
1024
1096
  }
1025
- if (captureOutput) {
1026
- observation.update({ output: result });
1027
- }
1028
- observation.end();
1029
- return result;
1030
1097
  };
1031
1098
  Object.defineProperty(wrappedFunction, "name", { value: fn.name });
1032
1099
  Object.defineProperty(wrappedFunction, "length", { value: fn.length });
@@ -1488,6 +1555,11 @@ var CallbackHandler = class extends import_base.BaseCallbackHandler {
1488
1555
  }
1489
1556
  );
1490
1557
  this.runMap.set(runId, observation);
1558
+ if (this.runMap.size > 1e3) {
1559
+ this.logger.warn?.(
1560
+ `runMap size (${this.runMap.size}) exceeds 1000. Possible missing end callbacks.`
1561
+ );
1562
+ }
1491
1563
  return observation;
1492
1564
  }
1493
1565
  handleObservationEnd(params) {