langwatch 0.3.2 → 0.4.0

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 (202) hide show
  1. package/dist/{add-LBBS4I3H.js → add-35QACTIV.js} +34 -28
  2. package/dist/add-35QACTIV.js.map +1 -0
  3. package/dist/{add-RD3ZKFAT.mjs → add-TRJAXM4D.mjs} +22 -16
  4. package/dist/add-TRJAXM4D.mjs.map +1 -0
  5. package/dist/chunk-4ZSSHX6F.js +636 -0
  6. package/dist/chunk-4ZSSHX6F.js.map +1 -0
  7. package/dist/chunk-5EVBOHJY.js +155 -0
  8. package/dist/chunk-5EVBOHJY.js.map +1 -0
  9. package/dist/{chunk-YN4436PK.mjs → chunk-CU3443HD.mjs} +14 -9
  10. package/dist/{chunk-2JU376G7.js → chunk-D2CSG4SJ.js} +4 -4
  11. package/dist/chunk-D2CSG4SJ.js.map +1 -0
  12. package/dist/chunk-DISMHYXC.js +184 -0
  13. package/dist/chunk-DISMHYXC.js.map +1 -0
  14. package/dist/{chunk-E7UE2MPD.mjs → chunk-ECUXLXFT.mjs} +2 -2
  15. package/dist/chunk-EJWJXTPU.mjs +626 -0
  16. package/dist/chunk-EJWJXTPU.mjs.map +1 -0
  17. package/dist/chunk-GQMDZ4GY.mjs +155 -0
  18. package/dist/chunk-GQMDZ4GY.mjs.map +1 -0
  19. package/dist/{chunk-3GKPQB4R.mjs → chunk-HUI45ULC.mjs} +4 -4
  20. package/dist/chunk-HUI45ULC.mjs.map +1 -0
  21. package/dist/{chunk-HJU67C7H.js → chunk-K64Y6YUG.js} +10 -10
  22. package/dist/{chunk-HJU67C7H.js.map → chunk-K64Y6YUG.js.map} +1 -1
  23. package/dist/chunk-LP76VXI3.mjs +636 -0
  24. package/dist/chunk-LP76VXI3.mjs.map +1 -0
  25. package/dist/chunk-M4VUHTT2.js +626 -0
  26. package/dist/chunk-M4VUHTT2.js.map +1 -0
  27. package/dist/{chunk-PR3JDWC3.mjs → chunk-N2V6J3U2.mjs} +28 -3
  28. package/dist/chunk-N2V6J3U2.mjs.map +1 -0
  29. package/dist/chunk-OUCVXP4G.js +258 -0
  30. package/dist/chunk-OUCVXP4G.js.map +1 -0
  31. package/dist/{chunk-FJLK5CFL.js → chunk-OXBO24RB.js} +13 -8
  32. package/dist/chunk-OXBO24RB.js.map +1 -0
  33. package/dist/chunk-PGWR3OQY.mjs +258 -0
  34. package/dist/chunk-PGWR3OQY.mjs.map +1 -0
  35. package/dist/{chunk-SMXXAVMB.js → chunk-SGNJDRCT.js} +2 -2
  36. package/dist/chunk-SGNJDRCT.js.map +1 -0
  37. package/dist/{chunk-W5ZEP3CI.mjs → chunk-SYMZPWZE.mjs} +2 -2
  38. package/dist/chunk-SYMZPWZE.mjs.map +1 -0
  39. package/dist/{chunk-KGDAENGD.js → chunk-YH5TIVK2.js} +28 -3
  40. package/dist/chunk-YH5TIVK2.js.map +1 -0
  41. package/dist/chunk-YNQ44U6D.mjs +184 -0
  42. package/dist/chunk-YNQ44U6D.mjs.map +1 -0
  43. package/dist/cli/index.js +8 -8
  44. package/dist/cli/index.mjs +8 -8
  45. package/dist/{create-G5MTGOOH.js → create-7K2CC4KQ.js} +11 -11
  46. package/dist/{create-G5MTGOOH.js.map → create-7K2CC4KQ.js.map} +1 -1
  47. package/dist/{create-QUZYBMQB.mjs → create-MK7NEGCM.mjs} +8 -8
  48. package/dist/implementation-C4lvooSg.d.mts +576 -0
  49. package/dist/implementation-CzemP9jY.d.ts +576 -0
  50. package/dist/index-DTEZr0Jn.d.mts +34 -0
  51. package/dist/index-DTEZr0Jn.d.ts +34 -0
  52. package/dist/index.d.mts +121 -47
  53. package/dist/index.d.ts +121 -47
  54. package/dist/index.js +16 -12
  55. package/dist/index.js.map +1 -1
  56. package/dist/index.mjs +27 -23
  57. package/dist/index.mjs.map +1 -1
  58. package/dist/init-GDKJICSS.js +16 -0
  59. package/dist/{init-XU2JFY6N.js.map → init-GDKJICSS.js.map} +1 -1
  60. package/dist/{init-H67RW22E.mjs → init-RINSTP4L.mjs} +5 -5
  61. package/dist/{list-7NPSX2E4.mjs → list-7L23G5DY.mjs} +28 -16
  62. package/dist/list-7L23G5DY.mjs.map +1 -0
  63. package/dist/{list-ZXFLAF52.js → list-OLLQ7XKZ.js} +29 -17
  64. package/dist/list-OLLQ7XKZ.js.map +1 -0
  65. package/dist/{login-EK4WVOI2.mjs → login-RCNKL5AM.mjs} +6 -5
  66. package/dist/login-RCNKL5AM.mjs.map +1 -0
  67. package/dist/{login-76NQIHKR.js → login-XF3BQQPV.js} +7 -6
  68. package/dist/login-XF3BQQPV.js.map +1 -0
  69. package/dist/observability-sdk/index.d.mts +134 -0
  70. package/dist/observability-sdk/index.d.ts +134 -0
  71. package/dist/observability-sdk/index.js +41 -0
  72. package/dist/observability-sdk/index.js.map +1 -0
  73. package/dist/observability-sdk/index.mjs +41 -0
  74. package/dist/observability-sdk/instrumentation/langchain/index.d.mts +69 -0
  75. package/dist/observability-sdk/instrumentation/langchain/index.d.ts +69 -0
  76. package/dist/observability-sdk/instrumentation/langchain/index.js +518 -0
  77. package/dist/observability-sdk/instrumentation/langchain/index.js.map +1 -0
  78. package/dist/observability-sdk/instrumentation/langchain/index.mjs +518 -0
  79. package/dist/observability-sdk/instrumentation/langchain/index.mjs.map +1 -0
  80. package/dist/observability-sdk/setup/node/index.d.mts +368 -0
  81. package/dist/observability-sdk/setup/node/index.d.ts +368 -0
  82. package/dist/observability-sdk/setup/node/index.js +276 -0
  83. package/dist/observability-sdk/setup/node/index.js.map +1 -0
  84. package/dist/observability-sdk/setup/node/index.mjs +276 -0
  85. package/dist/observability-sdk/setup/node/index.mjs.map +1 -0
  86. package/dist/{remove-SDJYEPAY.mjs → remove-3VLQNVHN.mjs} +11 -8
  87. package/dist/remove-3VLQNVHN.mjs.map +1 -0
  88. package/dist/{remove-XBNGIVMR.js → remove-L6JVJBWY.js} +18 -15
  89. package/dist/remove-L6JVJBWY.js.map +1 -0
  90. package/dist/{sync-ST2IWXSB.mjs → sync-DPMTUTVL.mjs} +39 -33
  91. package/dist/sync-DPMTUTVL.mjs.map +1 -0
  92. package/dist/{sync-EISKGPTL.js → sync-PSU3F5Z4.js} +52 -46
  93. package/dist/sync-PSU3F5Z4.js.map +1 -0
  94. package/dist/{prompt-D-jpMrLS.d.mts → types-1q5wIYP5.d.mts} +628 -14
  95. package/dist/{prompt-D-jpMrLS.d.ts → types-C9k5gGhU.d.ts} +628 -14
  96. package/dist/types-DRiQaKFG.d.mts +254 -0
  97. package/dist/types-DRiQaKFG.d.ts +254 -0
  98. package/dist/types-Dmazk5Bk.d.mts +44 -0
  99. package/dist/types-Dmazk5Bk.d.ts +44 -0
  100. package/package.json +39 -39
  101. package/dist/add-LBBS4I3H.js.map +0 -1
  102. package/dist/add-RD3ZKFAT.mjs.map +0 -1
  103. package/dist/chunk-2JU376G7.js.map +0 -1
  104. package/dist/chunk-2ODBGSBI.js +0 -4
  105. package/dist/chunk-2ODBGSBI.js.map +0 -1
  106. package/dist/chunk-3GKPQB4R.mjs.map +0 -1
  107. package/dist/chunk-52GXX3MA.js +0 -426
  108. package/dist/chunk-52GXX3MA.js.map +0 -1
  109. package/dist/chunk-5NC5ILKA.js +0 -94
  110. package/dist/chunk-5NC5ILKA.js.map +0 -1
  111. package/dist/chunk-AAROJADR.mjs +0 -49
  112. package/dist/chunk-AAROJADR.mjs.map +0 -1
  113. package/dist/chunk-DTEKFQ4U.js +0 -159
  114. package/dist/chunk-DTEKFQ4U.js.map +0 -1
  115. package/dist/chunk-F63YKTXA.mjs +0 -47
  116. package/dist/chunk-F63YKTXA.mjs.map +0 -1
  117. package/dist/chunk-FJLK5CFL.js.map +0 -1
  118. package/dist/chunk-GJSEBQXF.mjs +0 -392
  119. package/dist/chunk-GJSEBQXF.mjs.map +0 -1
  120. package/dist/chunk-IGHXIIIK.js +0 -49
  121. package/dist/chunk-IGHXIIIK.js.map +0 -1
  122. package/dist/chunk-J7ICRUU4.mjs +0 -426
  123. package/dist/chunk-J7ICRUU4.mjs.map +0 -1
  124. package/dist/chunk-KGDAENGD.js.map +0 -1
  125. package/dist/chunk-LD74LVRU.js +0 -47
  126. package/dist/chunk-LD74LVRU.js.map +0 -1
  127. package/dist/chunk-PCQVQ7SB.js +0 -45
  128. package/dist/chunk-PCQVQ7SB.js.map +0 -1
  129. package/dist/chunk-PR3JDWC3.mjs.map +0 -1
  130. package/dist/chunk-PWZBLTHR.js +0 -118
  131. package/dist/chunk-PWZBLTHR.js.map +0 -1
  132. package/dist/chunk-QEWDG5QE.mjs +0 -45
  133. package/dist/chunk-QEWDG5QE.mjs.map +0 -1
  134. package/dist/chunk-SMXXAVMB.js.map +0 -1
  135. package/dist/chunk-STV4ZVNA.mjs +0 -118
  136. package/dist/chunk-STV4ZVNA.mjs.map +0 -1
  137. package/dist/chunk-T5AZMMVS.mjs +0 -94
  138. package/dist/chunk-T5AZMMVS.mjs.map +0 -1
  139. package/dist/chunk-UU33HCCZ.mjs +0 -159
  140. package/dist/chunk-UU33HCCZ.mjs.map +0 -1
  141. package/dist/chunk-VGHLQXKB.js +0 -392
  142. package/dist/chunk-VGHLQXKB.js.map +0 -1
  143. package/dist/chunk-W5ZEP3CI.mjs.map +0 -1
  144. package/dist/chunk-Y666BJA5.mjs +0 -4
  145. package/dist/chunk-YN4436PK.mjs.map +0 -1
  146. package/dist/client-B2HqIKg6.d.ts +0 -51
  147. package/dist/client-XyCqclCi.d.mts +0 -51
  148. package/dist/client-browser.d.mts +0 -8
  149. package/dist/client-browser.d.ts +0 -8
  150. package/dist/client-browser.js +0 -88
  151. package/dist/client-browser.js.map +0 -1
  152. package/dist/client-browser.mjs +0 -88
  153. package/dist/client-browser.mjs.map +0 -1
  154. package/dist/client-node.d.mts +0 -8
  155. package/dist/client-node.d.ts +0 -8
  156. package/dist/client-node.js +0 -95
  157. package/dist/client-node.js.map +0 -1
  158. package/dist/client-node.mjs +0 -95
  159. package/dist/client-node.mjs.map +0 -1
  160. package/dist/evaluation/index.d.mts +0 -897
  161. package/dist/evaluation/index.d.ts +0 -897
  162. package/dist/evaluation/index.js +0 -14
  163. package/dist/evaluation/index.js.map +0 -1
  164. package/dist/evaluation/index.mjs +0 -14
  165. package/dist/filterable-batch-span-processor-zO5kcjBY.d.mts +0 -64
  166. package/dist/filterable-batch-span-processor-zO5kcjBY.d.ts +0 -64
  167. package/dist/init-XU2JFY6N.js +0 -16
  168. package/dist/list-7NPSX2E4.mjs.map +0 -1
  169. package/dist/list-ZXFLAF52.js.map +0 -1
  170. package/dist/login-76NQIHKR.js.map +0 -1
  171. package/dist/login-EK4WVOI2.mjs.map +0 -1
  172. package/dist/observability/index.d.mts +0 -260
  173. package/dist/observability/index.d.ts +0 -260
  174. package/dist/observability/index.js +0 -21
  175. package/dist/observability/index.js.map +0 -1
  176. package/dist/observability/index.mjs +0 -21
  177. package/dist/observability/index.mjs.map +0 -1
  178. package/dist/observability/instrumentation/langchain/index.d.mts +0 -40
  179. package/dist/observability/instrumentation/langchain/index.d.ts +0 -40
  180. package/dist/observability/instrumentation/langchain/index.js +0 -668
  181. package/dist/observability/instrumentation/langchain/index.js.map +0 -1
  182. package/dist/observability/instrumentation/langchain/index.mjs +0 -668
  183. package/dist/observability/instrumentation/langchain/index.mjs.map +0 -1
  184. package/dist/prompt/index.d.mts +0 -10
  185. package/dist/prompt/index.d.ts +0 -10
  186. package/dist/prompt/index.js +0 -22
  187. package/dist/prompt/index.js.map +0 -1
  188. package/dist/prompt/index.mjs +0 -22
  189. package/dist/prompt/index.mjs.map +0 -1
  190. package/dist/record-evaluation-CmxMXa-3.d.mts +0 -25
  191. package/dist/record-evaluation-CmxMXa-3.d.ts +0 -25
  192. package/dist/remove-SDJYEPAY.mjs.map +0 -1
  193. package/dist/remove-XBNGIVMR.js.map +0 -1
  194. package/dist/sync-EISKGPTL.js.map +0 -1
  195. package/dist/sync-ST2IWXSB.mjs.map +0 -1
  196. package/dist/trace-CqaKo0kZ.d.ts +0 -622
  197. package/dist/trace-DtVc5GhF.d.mts +0 -622
  198. /package/dist/{chunk-Y666BJA5.mjs.map → chunk-CU3443HD.mjs.map} +0 -0
  199. /package/dist/{chunk-E7UE2MPD.mjs.map → chunk-ECUXLXFT.mjs.map} +0 -0
  200. /package/dist/{create-QUZYBMQB.mjs.map → create-MK7NEGCM.mjs.map} +0 -0
  201. /package/dist/{init-H67RW22E.mjs.map → init-RINSTP4L.mjs.map} +0 -0
  202. /package/dist/{evaluation → observability-sdk}/index.mjs.map +0 -0
@@ -0,0 +1,69 @@
1
+ import * as _opentelemetry_api from '@opentelemetry/api';
2
+ import { Attributes } from '@opentelemetry/api';
3
+ import { L as LangWatchSpan, a as LangWatchTracer, C as ChatMessage } from '../../../types-C9k5gGhU.js';
4
+ import { AgentAction, AgentFinish } from '@langchain/core/agents';
5
+ import { BaseCallbackHandler } from '@langchain/core/callbacks/base';
6
+ import { DocumentInterface } from '@langchain/core/documents';
7
+ import { Serialized } from '@langchain/core/load/serializable';
8
+ import { BaseMessage } from '@langchain/core/messages';
9
+ import { LLMResult } from '@langchain/core/outputs';
10
+ import { ChainValues } from '@langchain/core/utils/types';
11
+ import '../../../types-DRiQaKFG.js';
12
+ import '@opentelemetry/api-logs';
13
+ import '@opentelemetry/semantic-conventions';
14
+ import '@opentelemetry/semantic-conventions/incubating';
15
+
16
+ type RunKind = "llm" | "chat" | "chain" | "tool" | "retriever";
17
+ declare class LangWatchCallbackHandler extends BaseCallbackHandler {
18
+ name: string;
19
+ tracer: LangWatchTracer;
20
+ private spans;
21
+ private parentOf;
22
+ private skipped;
23
+ private seenStarts;
24
+ private startRunSpan;
25
+ private finishRun;
26
+ handleLLMStart(llm: Serialized, prompts: string[], runId: string, parentRunId?: string, extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, name?: string): Promise<void>;
27
+ handleChatModelStart(llm: Serialized, messages: BaseMessage[][], runId: string, parentRunId?: string, extraParams?: Record<string, unknown>, tags?: string[], metadata?: Record<string, unknown>, name?: string): Promise<void>;
28
+ handleLLMEnd(response: LLMResult, runId: string, parentRunId?: string): Promise<void>;
29
+ handleLLMError(err: Error, runId: string, parentRunId?: string): Promise<void>;
30
+ handleChainStart(chain: Serialized, inputs: ChainValues, runId: string, parentRunId?: string, tags?: string[], metadata?: Record<string, unknown>, _runType?: string, name?: string): Promise<void>;
31
+ handleChainEnd(output: ChainValues, runId: string, parentRunId?: string): Promise<void>;
32
+ handleChainError(err: Error, runId: string, parentRunId?: string, tags?: string[], kwargs?: {
33
+ inputs?: Record<string, unknown> | undefined;
34
+ }): Promise<void>;
35
+ handleToolStart(tool: Serialized, input: string, runId: string, parentRunId?: string, tags?: string[], metadata?: Record<string, unknown>, name?: string): Promise<void>;
36
+ handleToolEnd(output: string, runId: string, parentRunId?: string): Promise<void>;
37
+ handleToolError(err: Error, runId: string, parentRunId?: string, tags?: string[]): Promise<void>;
38
+ handleRetrieverStart(retriever: Serialized, query: string, runId: string, parentRunId?: string, tags?: string[], metadata?: Record<string, unknown>, name?: string): Promise<void>;
39
+ handleRetrieverEnd(documents: DocumentInterface<Record<string, any>>[], runId: string, parentRunId?: string, tags?: string[]): Promise<void>;
40
+ handleRetrieverError(err: Error, runId: string, parentRunId?: string, tags?: string[]): Promise<void>;
41
+ handleAgentAction(_action: AgentAction, runId: string, parentRunId?: string, tags?: string[]): Promise<void>;
42
+ handleAgentEnd(action: AgentFinish, runId: string, parentRunId?: string, tags?: string[]): Promise<void>;
43
+ }
44
+ declare function convertFromLangChainMessages(messages: BaseMessage[]): ChatMessage[];
45
+ declare function className(serialized?: Serialized): string;
46
+ declare function shorten(str: string, max?: number): string;
47
+ declare function previewInput(v: unknown): string | undefined;
48
+ declare function ctxSkip(serialized?: Serialized, tags?: string[]): boolean;
49
+ declare function wrapNonScalarValues(value: unknown): string | number | boolean | undefined;
50
+ declare function addLangChainEvent(span: LangWatchSpan, eventName: string, runId: string, parentRunId: string | undefined, tags?: string[], metadata?: Record<string, unknown>, attributes?: Attributes): void;
51
+ declare function setLangGraphAttributes(span: LangWatchSpan, metadata?: Record<string, unknown>): void;
52
+ declare function buildLangChainMetadataAttributes(metadata: Record<string, unknown>): {
53
+ [k: string]: string | number | boolean | undefined;
54
+ };
55
+ declare function applyGenAIAttrs(span: LangWatchSpan, metadata?: Record<string, unknown>, extraParams?: Record<string, unknown>): void;
56
+ declare function getResolvedParentContext(runId: string | undefined, spans: Record<string, LangWatchSpan | undefined>, parentOf: Record<string, string | undefined>): _opentelemetry_api.Context;
57
+ declare function deriveNameAndType(opts: {
58
+ runType: RunKind;
59
+ name?: string;
60
+ serialized?: Serialized;
61
+ metadata?: Record<string, unknown>;
62
+ tags?: string[];
63
+ inputs?: unknown;
64
+ }): {
65
+ name: string;
66
+ type: "llm" | "chain" | "tool" | "rag" | "component";
67
+ };
68
+
69
+ export { LangWatchCallbackHandler, addLangChainEvent, applyGenAIAttrs, buildLangChainMetadataAttributes, className, convertFromLangChainMessages, ctxSkip, deriveNameAndType, getResolvedParentContext, previewInput, setLangGraphAttributes, shorten, wrapNonScalarValues };
@@ -0,0 +1,518 @@
1
+ "use strict";Object.defineProperty(exports, "__esModule", {value: true});
2
+
3
+
4
+ var _chunkM4VUHTT2js = require('../../../chunk-M4VUHTT2.js');
5
+
6
+
7
+
8
+ var _chunkDISMHYXCjs = require('../../../chunk-DISMHYXC.js');
9
+
10
+
11
+ var _chunkOXBO24RBjs = require('../../../chunk-OXBO24RB.js');
12
+
13
+ // src/observability-sdk/instrumentation/langchain/index.ts
14
+ var _base = require('@langchain/core/callbacks/base');
15
+
16
+
17
+
18
+
19
+ var _api = require('@opentelemetry/api');
20
+ var LANGGRAPH_METADATA_KEYS = /* @__PURE__ */ new Set([
21
+ "thread_id",
22
+ "langgraph_step",
23
+ "langgraph_node",
24
+ "langgraph_triggers",
25
+ "langgraph_path",
26
+ "langgraph_checkpoint_ns",
27
+ "__pregel_task_id",
28
+ "checkpoint_ns"
29
+ ]);
30
+ var LangWatchCallbackHandler = class extends _base.BaseCallbackHandler {
31
+ constructor() {
32
+ super(...arguments);
33
+ this.name = "LangWatchCallbackHandler";
34
+ this.tracer = _chunkM4VUHTT2js.getLangWatchTracer.call(void 0, "langwatch.instrumentation.langchain");
35
+ this.spans = {};
36
+ this.parentOf = {};
37
+ this.skipped = {};
38
+ this.seenStarts = /* @__PURE__ */ new Set();
39
+ }
40
+ startRunSpan(args) {
41
+ var _a;
42
+ const { runId, parentRunId, serialized, tags } = args;
43
+ this.parentOf[runId] = parentRunId;
44
+ if (ctxSkip(serialized, tags)) {
45
+ this.skipped[runId] = true;
46
+ return;
47
+ }
48
+ if (this.seenStarts.has(runId)) return;
49
+ this.seenStarts.add(runId);
50
+ const parentCtx = getResolvedParentContext(
51
+ parentRunId,
52
+ this.spans,
53
+ this.parentOf
54
+ );
55
+ const parentSpan = parentRunId ? this.spans[parentRunId] : void 0;
56
+ const links = parentSpan ? [{ context: parentSpan.spanContext() }] : void 0;
57
+ const { name, type } = deriveNameAndType({
58
+ runType: args.kind,
59
+ name: args.name,
60
+ serialized: args.serialized,
61
+ metadata: args.metadata,
62
+ tags: args.tags,
63
+ inputs: args.input
64
+ });
65
+ const span = this.tracer.startSpan(name, { links }, parentCtx);
66
+ span.setType(type);
67
+ if ((_a = args.tags) == null ? void 0 : _a.length)
68
+ span.setAttribute("langwatch.langchain.run.tags", args.tags.slice(0, 50));
69
+ if (_chunkDISMHYXCjs.shouldCaptureInput.call(void 0, ) && args.input !== void 0) {
70
+ const i = args.input;
71
+ if (i && typeof i === "object" && "type" in i && "value" in i) {
72
+ span.setInput(i.type, i.value);
73
+ } else {
74
+ span.setInput(i);
75
+ }
76
+ }
77
+ if (args.extraParams) {
78
+ span.setAttributes(
79
+ Object.fromEntries(
80
+ Object.entries(args.extraParams).map(([k, v]) => [
81
+ `langwatch.langchain.run.extra_params.${k}`,
82
+ wrapNonScalarValues(v)
83
+ ])
84
+ )
85
+ );
86
+ }
87
+ if (args.metadata) {
88
+ applyGenAIAttrs(span, args.metadata, args.extraParams);
89
+ setLangGraphAttributes(span, args.metadata);
90
+ span.setAttributes(buildLangChainMetadataAttributes(args.metadata));
91
+ }
92
+ this.spans[runId] = span;
93
+ }
94
+ finishRun(runId, end) {
95
+ const span = this.spans[runId];
96
+ if (!span) return;
97
+ addLangChainEvent(
98
+ span,
99
+ end.event,
100
+ runId,
101
+ end.parentRunId,
102
+ end.tags,
103
+ end.md,
104
+ end.extra
105
+ );
106
+ if (end.err) {
107
+ span.recordException(end.err);
108
+ span.setStatus({ code: _api.SpanStatusCode.ERROR, message: end.err.message });
109
+ } else if (_chunkDISMHYXCjs.shouldCaptureOutput.call(void 0, ) && end.output !== void 0) {
110
+ span.setOutput(end.output);
111
+ }
112
+ span.end();
113
+ delete this.spans[runId];
114
+ delete this.parentOf[runId];
115
+ delete this.skipped[runId];
116
+ this.seenStarts.delete(runId);
117
+ }
118
+ async handleLLMStart(llm, prompts, runId, parentRunId, extraParams, tags, metadata, name) {
119
+ const input = _chunkDISMHYXCjs.shouldCaptureInput.call(void 0, ) && prompts ? {
120
+ type: "list",
121
+ value: prompts.map((p) => ({ type: "text", value: p }))
122
+ } : void 0;
123
+ this.startRunSpan({
124
+ kind: "llm",
125
+ runId,
126
+ parentRunId,
127
+ serialized: llm,
128
+ metadata,
129
+ tags,
130
+ name,
131
+ extraParams,
132
+ input
133
+ });
134
+ }
135
+ async handleChatModelStart(llm, messages, runId, parentRunId, extraParams, tags, metadata, name) {
136
+ const input = _chunkDISMHYXCjs.shouldCaptureInput.call(void 0, ) ? {
137
+ type: "chat_messages",
138
+ value: messages.flatMap(convertFromLangChainMessages)
139
+ } : void 0;
140
+ this.startRunSpan({
141
+ kind: "chat",
142
+ runId,
143
+ parentRunId,
144
+ serialized: llm,
145
+ metadata,
146
+ tags,
147
+ name,
148
+ extraParams,
149
+ input
150
+ });
151
+ }
152
+ async handleLLMEnd(response, runId, parentRunId) {
153
+ var _a, _b, _c, _d;
154
+ const span = this.spans[runId];
155
+ const tu = (_a = response.llmOutput) == null ? void 0 : _a.tokenUsage;
156
+ if (span && tu) {
157
+ span.setAttributes({
158
+ "gen_ai.usage.prompt_tokens": (_b = tu.promptTokens) != null ? _b : 0,
159
+ "gen_ai.usage.completion_tokens": (_c = tu.completionTokens) != null ? _c : 0,
160
+ "gen_ai.usage.total_tokens": (_d = tu.totalTokens) != null ? _d : 0
161
+ });
162
+ }
163
+ const outputs = _chunkDISMHYXCjs.shouldCaptureOutput.call(void 0, ) ? response.generations.flat().map((g) => {
164
+ if ("message" in g && g.message) {
165
+ return convertFromLangChainMessages([
166
+ g.message
167
+ ]);
168
+ } else if ("text" in g && g.text) {
169
+ return g.text;
170
+ }
171
+ return g;
172
+ }) : void 0;
173
+ this.finishRun(runId, {
174
+ output: outputs,
175
+ event: "handleLLMEnd",
176
+ parentRunId
177
+ });
178
+ }
179
+ async handleLLMError(err, runId, parentRunId) {
180
+ this.finishRun(runId, { err, event: "handleLLMError", parentRunId });
181
+ }
182
+ async handleChainStart(chain, inputs, runId, parentRunId, tags, metadata, _runType, name) {
183
+ this.startRunSpan({
184
+ kind: "chain",
185
+ runId,
186
+ parentRunId,
187
+ serialized: chain,
188
+ metadata,
189
+ tags,
190
+ name,
191
+ input: _chunkDISMHYXCjs.shouldCaptureInput.call(void 0, ) ? inputs : void 0
192
+ });
193
+ if (_runType) {
194
+ const span = this.spans[runId];
195
+ if (span) span.setAttribute("langwatch.langchain.run.type", _runType);
196
+ }
197
+ }
198
+ async handleChainEnd(output, runId, parentRunId) {
199
+ this.finishRun(runId, { output, event: "handleChainEnd", parentRunId });
200
+ }
201
+ async handleChainError(err, runId, parentRunId, tags, kwargs) {
202
+ this.finishRun(runId, {
203
+ err,
204
+ event: "handleChainError",
205
+ parentRunId,
206
+ tags,
207
+ md: kwargs
208
+ });
209
+ }
210
+ async handleToolStart(tool, input, runId, parentRunId, tags, metadata, name) {
211
+ this.startRunSpan({
212
+ kind: "tool",
213
+ runId,
214
+ parentRunId,
215
+ serialized: tool,
216
+ metadata,
217
+ tags,
218
+ name,
219
+ input: _chunkDISMHYXCjs.shouldCaptureInput.call(void 0, ) ? { type: "text", value: input } : void 0
220
+ });
221
+ const span = this.spans[runId];
222
+ if (span) {
223
+ span.setAttributes({
224
+ "langwatch.langchain.run.id": runId,
225
+ "langwatch.langchain.run.parent_id": parentRunId
226
+ });
227
+ }
228
+ }
229
+ async handleToolEnd(output, runId, parentRunId) {
230
+ this.finishRun(runId, {
231
+ output: _chunkDISMHYXCjs.shouldCaptureOutput.call(void 0, ) ? { type: "text", value: output } : void 0,
232
+ event: "handleToolEnd",
233
+ parentRunId
234
+ });
235
+ }
236
+ async handleToolError(err, runId, parentRunId, tags) {
237
+ this.finishRun(runId, { err, event: "handleToolError", parentRunId, tags });
238
+ }
239
+ async handleRetrieverStart(retriever, query, runId, parentRunId, tags, metadata, name) {
240
+ this.startRunSpan({
241
+ kind: "retriever",
242
+ runId,
243
+ parentRunId,
244
+ serialized: retriever,
245
+ metadata,
246
+ tags,
247
+ name,
248
+ input: _chunkDISMHYXCjs.shouldCaptureInput.call(void 0, ) ? { type: "text", value: query } : void 0
249
+ });
250
+ const span = this.spans[runId];
251
+ if (span) {
252
+ span.setAttributes({
253
+ "langwatch.langchain.run.id": runId,
254
+ "langwatch.langchain.run.parent_id": parentRunId
255
+ });
256
+ }
257
+ }
258
+ async handleRetrieverEnd(documents, runId, parentRunId, tags) {
259
+ const span = this.spans[runId];
260
+ if (span && _chunkDISMHYXCjs.shouldCaptureOutput.call(void 0, )) {
261
+ span.setOutput(documents);
262
+ }
263
+ if (span && _chunkDISMHYXCjs.shouldCaptureInput.call(void 0, )) {
264
+ span.setRAGContexts(
265
+ documents.map((document) => ({
266
+ document_id: document.metadata.id,
267
+ chunk_id: document.metadata.chunk_id,
268
+ content: document.pageContent
269
+ }))
270
+ );
271
+ }
272
+ this.finishRun(runId, { event: "handleRetrieverEnd", parentRunId, tags });
273
+ }
274
+ async handleRetrieverError(err, runId, parentRunId, tags) {
275
+ this.finishRun(runId, {
276
+ err,
277
+ event: "handleRetrieverError",
278
+ parentRunId,
279
+ tags
280
+ });
281
+ }
282
+ async handleAgentAction(_action, runId, parentRunId, tags) {
283
+ const span = this.spans[runId];
284
+ if (span) {
285
+ addLangChainEvent(span, "handleAgentAction", runId, parentRunId, tags);
286
+ span.setType("agent");
287
+ }
288
+ }
289
+ async handleAgentEnd(action, runId, parentRunId, tags) {
290
+ this.finishRun(runId, {
291
+ output: _chunkDISMHYXCjs.shouldCaptureOutput.call(void 0, ) ? { type: "json", value: action.returnValues } : void 0,
292
+ event: "handleAgentEnd",
293
+ parentRunId,
294
+ tags
295
+ });
296
+ }
297
+ };
298
+ function convertFromLangChainMessages(messages) {
299
+ const out = [];
300
+ for (const message of messages) {
301
+ out.push(
302
+ convertFromLangChainMessage(message)
303
+ );
304
+ }
305
+ return out;
306
+ }
307
+ function convertFromLangChainMessage(message) {
308
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j;
309
+ let role = "user";
310
+ const msgType = message.type;
311
+ if (msgType === "human") role = "user";
312
+ else if (msgType === "ai") role = "assistant";
313
+ else if (msgType === "system") role = "system";
314
+ else if (msgType === "function") role = "function";
315
+ else if (msgType === "tool") role = "tool";
316
+ else {
317
+ if (((_a = message == null ? void 0 : message._getType) == null ? void 0 : _a.call(message)) === "human" || ((_b = message.id) == null ? void 0 : _b[message.id.length - 1]) === "HumanMessage") {
318
+ role = "user";
319
+ } else if (((_c = message == null ? void 0 : message._getType) == null ? void 0 : _c.call(message)) === "ai" || ((_d = message.id) == null ? void 0 : _d[message.id.length - 1]) === "AIMessage") {
320
+ role = "assistant";
321
+ } else if (((_e = message == null ? void 0 : message._getType) == null ? void 0 : _e.call(message)) === "system" || ((_f = message.id) == null ? void 0 : _f[message.id.length - 1]) === "SystemMessage") {
322
+ role = "system";
323
+ } else if (((_g = message == null ? void 0 : message._getType) == null ? void 0 : _g.call(message)) === "function" || ((_h = message.id) == null ? void 0 : _h[message.id.length - 1]) === "FunctionMessage") {
324
+ role = "function";
325
+ } else if (((_i = message == null ? void 0 : message._getType) == null ? void 0 : _i.call(message)) === "tool" || ((_j = message.id) == null ? void 0 : _j[message.id.length - 1]) === "ToolMessage") {
326
+ role = "tool";
327
+ }
328
+ }
329
+ const content = typeof message.content === "string" ? message.content : message.content == null ? null : Array.isArray(message.content) ? message.content.map(
330
+ (c) => (c == null ? void 0 : c.type) === "text" ? { type: "text", text: c.text } : (c == null ? void 0 : c.type) === "image_url" ? { type: "image_url", image_url: c.image_url } : { type: "text", text: JSON.stringify(c) }
331
+ ) : JSON.stringify(message.content);
332
+ const functionCall = message.additional_kwargs;
333
+ return _chunkOXBO24RBjs.__spreadValues.call(void 0, {
334
+ role,
335
+ content
336
+ }, functionCall && typeof functionCall === "object" && Object.keys(functionCall).length > 0 ? { function_call: functionCall } : {});
337
+ }
338
+ function className(serialized) {
339
+ const id = serialized == null ? void 0 : serialized.id;
340
+ if (Array.isArray(id) && id.length) return String(id[id.length - 1]);
341
+ const ns = serialized == null ? void 0 : serialized.lc_namespace;
342
+ if (Array.isArray(ns) && ns.length) return String(ns[ns.length - 1]);
343
+ return "";
344
+ }
345
+ function shorten(str, max = 120) {
346
+ return typeof str === "string" && str.length > max ? str.slice(0, max - 1) + "\u2026" : str;
347
+ }
348
+ function previewInput(v) {
349
+ if (typeof v === "string") {
350
+ const s = v.trim();
351
+ return s ? shorten(s, 120) : void 0;
352
+ }
353
+ return void 0;
354
+ }
355
+ function ctxSkip(serialized, tags) {
356
+ var _a;
357
+ const cls = className(serialized);
358
+ return cls.startsWith("ChannelWrite") || ((_a = tags == null ? void 0 : tags.includes("langsmith:hidden")) != null ? _a : false);
359
+ }
360
+ function wrapNonScalarValues(value) {
361
+ if (value === void 0) return void 0;
362
+ if (value === null) return JSON.stringify(null);
363
+ if (typeof value === "string" || typeof value === "number" || typeof value === "boolean")
364
+ return value;
365
+ const chatMessages = _chunkM4VUHTT2js.chatMessageSchema.array().safeParse(value);
366
+ if (Array.isArray(value) && chatMessages.success) {
367
+ return JSON.stringify({ type: "chat_messages", value: chatMessages.data });
368
+ }
369
+ try {
370
+ const seen = /* @__PURE__ */ new WeakSet();
371
+ const json = JSON.stringify(value, (k, val) => {
372
+ if (typeof val === "object" && val !== null) {
373
+ if (seen.has(val)) return "[Circular]";
374
+ seen.add(val);
375
+ }
376
+ return val;
377
+ });
378
+ return json;
379
+ } catch (e) {
380
+ return JSON.stringify({ type: "raw", value: "[Non-Serializable]" });
381
+ }
382
+ }
383
+ function addLangChainEvent(span, eventName, runId, parentRunId, tags, metadata, attributes) {
384
+ const attrs = _chunkOXBO24RBjs.__spreadValues.call(void 0, {
385
+ "langwatch.langchain.run.id": runId,
386
+ "langwatch.langchain.run.parent_id": parentRunId,
387
+ "langwatch.langchain.event.name": eventName
388
+ }, attributes);
389
+ if (tags == null ? void 0 : tags.length) attrs["langwatch.langchain.run.tags"] = tags.slice(0, 50);
390
+ if (metadata) {
391
+ Object.entries(metadata).forEach(([key, value]) => {
392
+ attrs[key] = wrapNonScalarValues(value);
393
+ });
394
+ }
395
+ span.addEvent("langwatch.langchain.callback", attrs);
396
+ }
397
+ function setLangGraphAttributes(span, metadata) {
398
+ if (!metadata) return;
399
+ const keys = Object.keys(metadata);
400
+ for (const key of keys) {
401
+ const value = metadata[key];
402
+ if (value !== void 0) {
403
+ const wrapped = wrapNonScalarValues(value);
404
+ if (wrapped !== void 0) {
405
+ span.setAttribute(
406
+ `langwatch.langgraph.${key}`,
407
+ wrapped
408
+ );
409
+ }
410
+ }
411
+ }
412
+ }
413
+ function buildLangChainMetadataAttributes(metadata) {
414
+ if (!metadata) return {};
415
+ return Object.fromEntries(
416
+ Object.entries(metadata).filter(([key]) => !LANGGRAPH_METADATA_KEYS.has(key)).map(([key, value]) => [
417
+ `langwatch.langchain.run.metadata.${key}`,
418
+ wrapNonScalarValues(value)
419
+ ])
420
+ );
421
+ }
422
+ function applyGenAIAttrs(span, metadata, extraParams) {
423
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i;
424
+ const md = metadata != null ? metadata : {};
425
+ const ex = extraParams != null ? extraParams : {};
426
+ const provider = md.ls_provider;
427
+ const requestModel = (_d = (_b = md.ls_model_name) != null ? _b : (_a = md.kwargs) == null ? void 0 : _a.model) != null ? _d : (_c = ex.kwargs) == null ? void 0 : _c.model;
428
+ const temperature = (_h = (_f = md.ls_temperature) != null ? _f : (_e = md.kwargs) == null ? void 0 : _e.temperature) != null ? _h : (_g = ex.kwargs) == null ? void 0 : _g.temperature;
429
+ const responseModel = (_i = md.response_metadata) == null ? void 0 : _i.model_name;
430
+ if (provider) span.setAttribute("gen_ai.system", provider);
431
+ if (requestModel) span.setAttribute("gen_ai.request.model", requestModel);
432
+ if (typeof temperature === "number")
433
+ span.setAttribute("gen_ai.request.temperature", temperature);
434
+ if (responseModel) span.setAttribute("gen_ai.response.model", responseModel);
435
+ }
436
+ function getResolvedParentContext(runId, spans, parentOf) {
437
+ let cur = runId;
438
+ while (cur) {
439
+ const s = spans[cur];
440
+ if (s) return _api.trace.setSpan(_api.context.active(), s);
441
+ cur = parentOf[cur];
442
+ }
443
+ return _api.context.active();
444
+ }
445
+ function deriveNameAndType(opts) {
446
+ var _a, _b, _c, _d, _e, _f;
447
+ const { runType, name, serialized, metadata, inputs } = opts;
448
+ const hardName = (_a = name == null ? void 0 : name.trim()) != null ? _a : metadata == null ? void 0 : metadata.operation_name;
449
+ if (hardName) {
450
+ return {
451
+ name: hardName,
452
+ type: runType === "tool" ? "tool" : runType === "retriever" ? "rag" : runType === "llm" || runType === "chat" ? "llm" : "chain"
453
+ };
454
+ }
455
+ const cls = className(serialized);
456
+ const md = metadata != null ? metadata : {};
457
+ const hasNode = (md == null ? void 0 : md.langgraph_node) != null;
458
+ const hasTriggers = Array.isArray(md == null ? void 0 : md.langgraph_triggers) && md.langgraph_triggers.length > 0;
459
+ const isRouter = cls.startsWith("Branch<") || hasTriggers;
460
+ const isGraphRunner = (md == null ? void 0 : md.langgraph_path) && !(md == null ? void 0 : md.langgraph_node);
461
+ if (runType === "llm" || runType === "chat") {
462
+ const prov = (_b = md == null ? void 0 : md.ls_provider) != null ? _b : "LLM";
463
+ const model = (_c = md == null ? void 0 : md.ls_model_name) != null ? _c : cls || "call";
464
+ const temp = md == null ? void 0 : md.ls_temperature;
465
+ const tempStr = temp != null ? typeof temp === "number" ? temp.toString() : JSON.stringify(temp) : null;
466
+ const nm = tempStr != null ? `${prov} ${model} (temp ${tempStr})` : `${prov} ${model}`;
467
+ return { name: nm, type: "llm" };
468
+ }
469
+ if (isRouter) {
470
+ const pathArr = md == null ? void 0 : md.langgraph_path;
471
+ const fromNode = Array.isArray(pathArr) && pathArr.length ? pathArr[pathArr.length - 1] : void 0;
472
+ const decision = Array.isArray(md == null ? void 0 : md.langgraph_triggers) ? String(
473
+ (_d = md.langgraph_triggers.find(
474
+ (t) => String(t).startsWith("branch:")
475
+ )) != null ? _d : ""
476
+ ).replace(/^branch:(to:)?/, "") : void 0;
477
+ const nm = `Route: ${fromNode != null ? fromNode : "unknown"} \u2192 ${decision != null ? decision : "unknown"}`;
478
+ return { name: nm, type: "component" };
479
+ }
480
+ if (hasNode) {
481
+ const step = md == null ? void 0 : md.langgraph_step;
482
+ const nm = `Node: ${md.langgraph_node}${step != null ? ` (step ${String(step)})` : ""}`;
483
+ return { name: nm, type: "component" };
484
+ }
485
+ if (isGraphRunner && runType === "chain") {
486
+ return { name: "Graph: LangGraph", type: "chain" };
487
+ }
488
+ if (runType === "tool") {
489
+ const tool = (_e = metadata == null ? void 0 : metadata.name) != null ? _e : cls || "tool";
490
+ const prev = (_f = previewInput(inputs)) != null ? _f : previewInput(serialized == null ? void 0 : serialized.input);
491
+ return {
492
+ name: prev ? `Tool: ${tool} \u2014 ${prev}` : `Tool: ${tool}`,
493
+ type: "tool"
494
+ };
495
+ }
496
+ if (runType === "retriever") return { name: "Retriever", type: "rag" };
497
+ if (cls.includes("Agent"))
498
+ return { name: `Agent: ${cls}`, type: "component" };
499
+ if (cls.startsWith("Runnable"))
500
+ return { name: `Runnable: ${cls.replace(/^Runnable/, "")}`, type: "chain" };
501
+ return { name: cls || "LangChain operation", type: "chain" };
502
+ }
503
+
504
+
505
+
506
+
507
+
508
+
509
+
510
+
511
+
512
+
513
+
514
+
515
+
516
+
517
+ exports.LangWatchCallbackHandler = LangWatchCallbackHandler; exports.addLangChainEvent = addLangChainEvent; exports.applyGenAIAttrs = applyGenAIAttrs; exports.buildLangChainMetadataAttributes = buildLangChainMetadataAttributes; exports.className = className; exports.convertFromLangChainMessages = convertFromLangChainMessages; exports.ctxSkip = ctxSkip; exports.deriveNameAndType = deriveNameAndType; exports.getResolvedParentContext = getResolvedParentContext; exports.previewInput = previewInput; exports.setLangGraphAttributes = setLangGraphAttributes; exports.shorten = shorten; exports.wrapNonScalarValues = wrapNonScalarValues;
518
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["/home/runner/work/langwatch/langwatch/typescript-sdk/dist/observability-sdk/instrumentation/langchain/index.js","../../../../src/observability-sdk/instrumentation/langchain/index.ts"],"names":[],"mappings":"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","file":"/home/runner/work/langwatch/langwatch/typescript-sdk/dist/observability-sdk/instrumentation/langchain/index.js","sourcesContent":[null,"import type { AgentAction, AgentFinish } from \"@langchain/core/agents\";\nimport { BaseCallbackHandler } from \"@langchain/core/callbacks/base\";\nimport { type DocumentInterface } from \"@langchain/core/documents\";\nimport type { Serialized } from \"@langchain/core/load/serializable\";\nimport { type BaseMessage } from \"@langchain/core/messages\";\nimport type { ChatGeneration, LLMResult } from \"@langchain/core/outputs\";\nimport type {\n ChatMessage,\n ChatRichContent,\n} from \"../../../internal/generated/types/tracer\";\nimport type { ChainValues } from \"@langchain/core/utils/types\";\nimport { getLangWatchTracer } from \"../../tracer\";\nimport type { LangWatchSpan } from \"../../span\";\nimport {\n context,\n trace,\n SpanStatusCode,\n type Attributes,\n} from \"@opentelemetry/api\";\nimport { chatMessageSchema } from \"../../../internal/generated/types/tracer.generated\";\nimport { shouldCaptureInput, shouldCaptureOutput } from \"../../config\";\n\ntype RunKind = \"llm\" | \"chat\" | \"chain\" | \"tool\" | \"retriever\";\n\ntype StartArgs = {\n kind: RunKind;\n runId: string;\n parentRunId?: string;\n serialized?: Serialized;\n metadata?: Record<string, unknown>;\n tags?: string[];\n name?: string;\n extraParams?: Record<string, unknown>;\n input?: unknown; // already prepared for setInput()\n};\n\nconst LANGGRAPH_METADATA_KEYS = new Set<string>([\n \"thread_id\",\n \"langgraph_step\",\n \"langgraph_node\",\n \"langgraph_triggers\",\n \"langgraph_path\",\n \"langgraph_checkpoint_ns\",\n \"__pregel_task_id\",\n \"checkpoint_ns\",\n]);\n\nexport class LangWatchCallbackHandler extends BaseCallbackHandler {\n name = \"LangWatchCallbackHandler\";\n tracer = getLangWatchTracer(\"langwatch.instrumentation.langchain\");\n\n private spans: Record<string, LangWatchSpan | undefined> = {};\n private parentOf: Record<string, string | undefined> = {};\n private skipped: Record<string, true | undefined> = {};\n private seenStarts = new Set<string>();\n\n private startRunSpan(args: StartArgs) {\n const { runId, parentRunId, serialized, tags } = args;\n this.parentOf[runId] = parentRunId;\n\n // if we want to skip, we record as such as we cn do context matching latet\n if (ctxSkip(serialized, tags)) {\n this.skipped[runId] = true;\n return;\n }\n if (this.seenStarts.has(runId)) return;\n this.seenStarts.add(runId);\n\n const parentCtx = getResolvedParentContext(\n parentRunId,\n this.spans,\n this.parentOf\n );\n const parentSpan = parentRunId ? this.spans[parentRunId] : void 0;\n const links = parentSpan\n ? [{ context: parentSpan.spanContext() }]\n : void 0;\n\n const { name, type } = deriveNameAndType({\n runType: args.kind,\n name: args.name,\n serialized: args.serialized,\n metadata: args.metadata,\n tags: args.tags,\n inputs: args.input,\n });\n\n const span = this.tracer.startSpan(name, { links }, parentCtx);\n span.setType(type);\n\n if (args.tags?.length)\n span.setAttribute(\"langwatch.langchain.run.tags\", args.tags.slice(0, 50));\n\n if (shouldCaptureInput() && args.input !== void 0) {\n const i: any = args.input as any;\n if (i && typeof i === \"object\" && \"type\" in i && \"value\" in i) {\n span.setInput(i.type, i.value);\n } else {\n span.setInput(i);\n }\n }\n\n if (args.extraParams) {\n span.setAttributes(\n Object.fromEntries(\n Object.entries(args.extraParams).map(([k, v]) => [\n `langwatch.langchain.run.extra_params.${k}`,\n wrapNonScalarValues(v),\n ])\n )\n );\n }\n\n if (args.metadata) {\n applyGenAIAttrs(span, args.metadata, args.extraParams);\n setLangGraphAttributes(span, args.metadata);\n span.setAttributes(buildLangChainMetadataAttributes(args.metadata));\n }\n\n this.spans[runId] = span;\n }\n\n private finishRun(\n runId: string,\n end: {\n output?: unknown;\n err?: Error;\n event: string;\n parentRunId?: string;\n extra?: Attributes;\n tags?: string[];\n md?: Record<string, unknown>;\n }\n ) {\n const span = this.spans[runId];\n if (!span) return;\n\n addLangChainEvent(\n span,\n end.event,\n runId,\n end.parentRunId,\n end.tags,\n end.md,\n end.extra\n );\n\n if (end.err) {\n span.recordException(end.err);\n span.setStatus({ code: SpanStatusCode.ERROR, message: end.err.message });\n } else if (shouldCaptureOutput() && end.output !== undefined) {\n span.setOutput(end.output as any);\n }\n\n span.end();\n\n delete this.spans[runId];\n delete this.parentOf[runId];\n delete this.skipped[runId];\n this.seenStarts.delete(runId);\n }\n\n async handleLLMStart(\n llm: Serialized,\n prompts: string[],\n runId: string,\n parentRunId?: string,\n extraParams?: Record<string, unknown>,\n tags?: string[],\n metadata?: Record<string, unknown>,\n name?: string\n ): Promise<void> {\n const input = shouldCaptureInput() && prompts\n ? {\n type: \"list\",\n value: prompts.map((p) => ({ type: \"text\", value: p })),\n }\n : void 0;\n\n this.startRunSpan({\n kind: \"llm\",\n runId,\n parentRunId,\n serialized: llm,\n metadata,\n tags,\n name,\n extraParams,\n input,\n });\n }\n\n async handleChatModelStart(\n llm: Serialized,\n messages: BaseMessage[][],\n runId: string,\n parentRunId?: string,\n extraParams?: Record<string, unknown>,\n tags?: string[],\n metadata?: Record<string, unknown>,\n name?: string\n ): Promise<void> {\n const input = shouldCaptureInput()\n ? {\n type: \"chat_messages\",\n value: messages.flatMap(convertFromLangChainMessages),\n }\n : void 0;\n\n this.startRunSpan({\n kind: \"chat\",\n runId,\n parentRunId,\n serialized: llm,\n metadata,\n tags,\n name,\n extraParams,\n input,\n });\n }\n\n async handleLLMEnd(\n response: LLMResult,\n runId: string,\n parentRunId?: string\n ): Promise<void> {\n const span = this.spans[runId];\n const tu = (response.llmOutput as any)?.tokenUsage as\n | {\n promptTokens?: number;\n completionTokens?: number;\n totalTokens?: number;\n }\n | undefined;\n if (span && tu) {\n span.setAttributes({\n \"gen_ai.usage.prompt_tokens\": tu.promptTokens ?? 0,\n \"gen_ai.usage.completion_tokens\": tu.completionTokens ?? 0,\n \"gen_ai.usage.total_tokens\": tu.totalTokens ?? 0,\n });\n }\n\n const outputs = shouldCaptureOutput()\n ? response.generations.flat().map((g) => {\n if (\"message\" in g && g.message) {\n return convertFromLangChainMessages([\n (g as ChatGeneration).message,\n ]);\n } else if (\"text\" in g && g.text) {\n return g.text;\n }\n return g;\n })\n : undefined;\n\n this.finishRun(runId, {\n output: outputs,\n event: \"handleLLMEnd\",\n parentRunId,\n });\n }\n\n async handleLLMError(\n err: Error,\n runId: string,\n parentRunId?: string\n ): Promise<void> {\n this.finishRun(runId, { err, event: \"handleLLMError\", parentRunId });\n }\n\n async handleChainStart(\n chain: Serialized,\n inputs: ChainValues,\n runId: string,\n parentRunId?: string,\n tags?: string[],\n metadata?: Record<string, unknown>,\n _runType?: string,\n name?: string\n ): Promise<void> {\n this.startRunSpan({\n kind: \"chain\",\n runId,\n parentRunId,\n serialized: chain,\n metadata,\n tags,\n name,\n input: shouldCaptureInput() ? inputs : void 0,\n });\n\n if (_runType) {\n const span = this.spans[runId];\n if (span) span.setAttribute(\"langwatch.langchain.run.type\", _runType);\n }\n }\n\n async handleChainEnd(\n output: ChainValues,\n runId: string,\n parentRunId?: string\n ): Promise<void> {\n this.finishRun(runId, { output, event: \"handleChainEnd\", parentRunId });\n }\n\n async handleChainError(\n err: Error,\n runId: string,\n parentRunId?: string,\n tags?: string[],\n kwargs?: { inputs?: Record<string, unknown> | undefined }\n ): Promise<void> {\n this.finishRun(runId, {\n err,\n event: \"handleChainError\",\n parentRunId,\n tags,\n md: kwargs,\n });\n }\n\n async handleToolStart(\n tool: Serialized,\n input: string,\n runId: string,\n parentRunId?: string,\n tags?: string[],\n metadata?: Record<string, unknown>,\n name?: string\n ): Promise<void> {\n this.startRunSpan({\n kind: \"tool\",\n runId,\n parentRunId,\n serialized: tool,\n metadata,\n tags,\n name,\n input: shouldCaptureInput() ? { type: \"text\", value: input } : void 0,\n });\n\n const span = this.spans[runId];\n if (span) {\n span.setAttributes({\n \"langwatch.langchain.run.id\": runId,\n \"langwatch.langchain.run.parent_id\": parentRunId,\n });\n }\n }\n\n async handleToolEnd(\n output: string,\n runId: string,\n parentRunId?: string\n ): Promise<void> {\n this.finishRun(runId, {\n output: shouldCaptureOutput()\n ? { type: \"text\", value: output }\n : void 0,\n event: \"handleToolEnd\",\n parentRunId,\n });\n }\n\n async handleToolError(\n err: Error,\n runId: string,\n parentRunId?: string,\n tags?: string[]\n ): Promise<void> {\n this.finishRun(runId, { err, event: \"handleToolError\", parentRunId, tags });\n }\n\n async handleRetrieverStart(\n retriever: Serialized,\n query: string,\n runId: string,\n parentRunId?: string,\n tags?: string[],\n metadata?: Record<string, unknown>,\n name?: string\n ) {\n this.startRunSpan({\n kind: \"retriever\",\n runId,\n parentRunId,\n serialized: retriever,\n metadata,\n tags,\n name,\n input: shouldCaptureInput() ? { type: \"text\", value: query } : void 0,\n });\n\n const span = this.spans[runId];\n if (span) {\n span.setAttributes({\n \"langwatch.langchain.run.id\": runId,\n \"langwatch.langchain.run.parent_id\": parentRunId,\n });\n }\n }\n\n async handleRetrieverEnd(\n documents: DocumentInterface<Record<string, any>>[],\n runId: string,\n parentRunId?: string,\n tags?: string[]\n ) {\n const span = this.spans[runId];\n\n if (span && shouldCaptureOutput()) {\n span.setOutput(documents);\n }\n\n if (span && shouldCaptureInput()) {\n span.setRAGContexts(\n documents.map((document) => ({\n document_id: document.metadata.id,\n chunk_id: document.metadata.chunk_id,\n content: document.pageContent,\n }))\n );\n }\n\n this.finishRun(runId, { event: \"handleRetrieverEnd\", parentRunId, tags });\n }\n\n async handleRetrieverError(\n err: Error,\n runId: string,\n parentRunId?: string,\n tags?: string[]\n ) {\n this.finishRun(runId, {\n err,\n event: \"handleRetrieverError\",\n parentRunId,\n tags,\n });\n }\n\n async handleAgentAction(\n _action: AgentAction,\n runId: string,\n parentRunId?: string,\n tags?: string[]\n ): Promise<void> {\n const span = this.spans[runId];\n if (span) {\n addLangChainEvent(span, \"handleAgentAction\", runId, parentRunId, tags);\n span.setType(\"agent\");\n }\n }\n\n async handleAgentEnd(\n action: AgentFinish,\n runId: string,\n parentRunId?: string,\n tags?: string[]\n ): Promise<void> {\n this.finishRun(runId, {\n output: shouldCaptureOutput()\n ? { type: \"json\", value: action.returnValues }\n : void 0,\n event: \"handleAgentEnd\",\n parentRunId,\n tags,\n });\n }\n}\n\nexport function convertFromLangChainMessages(\n messages: BaseMessage[]\n): ChatMessage[] {\n const out: ChatMessage[] = [];\n for (const message of messages) {\n out.push(\n convertFromLangChainMessage(message as BaseMessage & { id?: string[] })\n );\n }\n return out;\n}\n\nfunction convertFromLangChainMessage(\n message: BaseMessage & { id?: string[] }\n): ChatMessage {\n let role: ChatMessage[\"role\"] = \"user\";\n\n const msgType = (message as any).type as string | undefined;\n if (msgType === \"human\") role = \"user\";\n else if (msgType === \"ai\") role = \"assistant\";\n else if (msgType === \"system\") role = \"system\";\n else if (msgType === \"function\") role = \"function\";\n else if (msgType === \"tool\") role = \"tool\";\n else {\n if (\n (message as any)?._getType?.() === \"human\" ||\n message.id?.[message.id.length - 1] === \"HumanMessage\"\n ) {\n role = \"user\";\n } else if (\n (message as any)?._getType?.() === \"ai\" ||\n message.id?.[message.id.length - 1] === \"AIMessage\"\n ) {\n role = \"assistant\";\n } else if (\n (message as any)?._getType?.() === \"system\" ||\n message.id?.[message.id.length - 1] === \"SystemMessage\"\n ) {\n role = \"system\";\n } else if (\n (message as any)?._getType?.() === \"function\" ||\n message.id?.[message.id.length - 1] === \"FunctionMessage\"\n ) {\n role = \"function\";\n } else if (\n (message as any)?._getType?.() === \"tool\" ||\n message.id?.[message.id.length - 1] === \"ToolMessage\"\n ) {\n role = \"tool\";\n }\n }\n\n const content: ChatMessage[\"content\"] =\n typeof (message as any).content === \"string\"\n ? ((message as any).content as string)\n : (message as any).content == null\n ? null\n : Array.isArray((message as any).content)\n ? (message as any).content.map(\n (c: any): ChatRichContent =>\n c?.type === \"text\"\n ? { type: \"text\", text: c.text }\n : c?.type === \"image_url\"\n ? { type: \"image_url\", image_url: c.image_url }\n : { type: \"text\", text: JSON.stringify(c) }\n )\n : JSON.stringify((message as any).content);\n\n const functionCall = (message as any).additional_kwargs;\n\n return {\n role,\n content,\n ...(functionCall &&\n typeof functionCall === \"object\" &&\n Object.keys(functionCall).length > 0\n ? { function_call: functionCall }\n : {}),\n };\n}\n\nfunction className(serialized?: Serialized): string {\n const id = (serialized as any)?.id;\n if (Array.isArray(id) && id.length) return String(id[id.length - 1]);\n const ns = (serialized as any)?.lc_namespace;\n if (Array.isArray(ns) && ns.length) return String(ns[ns.length - 1]);\n\n return \"\";\n}\n\nfunction shorten(str: string, max = 120): string {\n return typeof str === \"string\" && str.length > max\n ? str.slice(0, max - 1) + \"…\"\n : str;\n}\n\nfunction previewInput(v: unknown): string | undefined {\n if (typeof v === \"string\") {\n const s = v.trim();\n return s ? shorten(s, 120) : void 0;\n }\n return void 0;\n}\n\nfunction ctxSkip(serialized?: Serialized, tags?: string[]) {\n const cls = className(serialized);\n return (\n cls.startsWith(\"ChannelWrite\") ||\n (tags?.includes(\"langsmith:hidden\") ?? false)\n );\n}\n\nfunction wrapNonScalarValues(\n value: unknown\n): string | number | boolean | undefined {\n if (value === void 0) return void 0;\n if (value === null) return JSON.stringify(null);\n if (\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n typeof value === \"boolean\"\n )\n return value;\n\n // Special-case: ChatMessage[] detection via zod schema the project already has\n const chatMessages = chatMessageSchema.array().safeParse(value as any);\n if (Array.isArray(value) && chatMessages.success) {\n return JSON.stringify({ type: \"chat_messages\", value: chatMessages.data });\n }\n\n try {\n const seen = new WeakSet();\n const json = JSON.stringify(value as any, (k, val) => {\n if (typeof val === \"object\" && val !== null) {\n if (seen.has(val)) return \"[Circular]\";\n seen.add(val);\n }\n return val;\n });\n return json;\n } catch {\n return JSON.stringify({ type: \"raw\", value: \"[Non-Serializable]\" });\n }\n}\n\nfunction addLangChainEvent(\n span: LangWatchSpan,\n eventName: string,\n runId: string,\n parentRunId: string | undefined,\n tags?: string[],\n metadata?: Record<string, unknown>,\n attributes?: Attributes\n) {\n const attrs: Attributes = {\n \"langwatch.langchain.run.id\": runId,\n \"langwatch.langchain.run.parent_id\": parentRunId,\n \"langwatch.langchain.event.name\": eventName,\n ...attributes,\n };\n\n if (tags?.length) attrs[\"langwatch.langchain.run.tags\"] = tags.slice(0, 50);\n if (metadata) {\n Object.entries(metadata).forEach(([key, value]) => {\n attrs[key] = wrapNonScalarValues(value);\n });\n }\n\n span.addEvent(\"langwatch.langchain.callback\", attrs);\n}\n\nfunction setLangGraphAttributes(\n span: LangWatchSpan,\n metadata?: Record<string, unknown>\n) {\n if (!metadata) return;\n const keys = Object.keys(metadata);\n for (const key of keys) {\n const value = (metadata as any)[key];\n if (value !== undefined) {\n const wrapped = wrapNonScalarValues(value);\n if (wrapped !== undefined) {\n span.setAttribute(\n `langwatch.langgraph.${key}` as const,\n wrapped as any\n );\n }\n }\n }\n}\n\nfunction buildLangChainMetadataAttributes(metadata: Record<string, unknown>) {\n if (!metadata) return {};\n return Object.fromEntries(\n Object.entries(metadata)\n .filter(([key]) => !LANGGRAPH_METADATA_KEYS.has(key))\n .map(([key, value]) => [\n `langwatch.langchain.run.metadata.${key}`,\n wrapNonScalarValues(value),\n ])\n );\n}\n\nfunction applyGenAIAttrs(\n span: LangWatchSpan,\n metadata?: Record<string, unknown>,\n extraParams?: Record<string, unknown>\n) {\n const md = (metadata ?? {}) as any;\n const ex = (extraParams ?? {}) as any;\n\n const provider = md.ls_provider as string | undefined;\n const requestModel = md.ls_model_name ?? md.kwargs?.model ?? ex.kwargs?.model;\n const temperature =\n md.ls_temperature ?? md.kwargs?.temperature ?? ex.kwargs?.temperature;\n const responseModel = md.response_metadata?.model_name as string | undefined;\n\n if (provider) span.setAttribute(\"gen_ai.system\", provider);\n if (requestModel) span.setAttribute(\"gen_ai.request.model\", requestModel);\n if (typeof temperature === \"number\")\n span.setAttribute(\"gen_ai.request.temperature\", temperature);\n if (responseModel) span.setAttribute(\"gen_ai.response.model\", responseModel);\n}\n\nfunction getResolvedParentContext(\n runId: string | undefined,\n spans: Record<string, LangWatchSpan | undefined>,\n parentOf: Record<string, string | undefined>\n) {\n let cur = runId;\n while (cur) {\n const s = spans[cur];\n if (s) return trace.setSpan(context.active(), s);\n cur = parentOf[cur];\n }\n return context.active();\n}\n\nfunction deriveNameAndType(opts: {\n runType: RunKind;\n name?: string;\n serialized?: Serialized;\n metadata?: Record<string, unknown>;\n tags?: string[];\n inputs?: unknown;\n}): { name: string; type: \"llm\" | \"chain\" | \"tool\" | \"rag\" | \"component\" } {\n const { runType, name, serialized, metadata, inputs } = opts;\n\n // user-specified name / metadata override\n const hardName = (name?.trim() ?? (metadata as any)?.operation_name) as\n | string\n | undefined;\n if (hardName) {\n return {\n name: hardName,\n type:\n runType === \"tool\"\n ? \"tool\"\n : runType === \"retriever\"\n ? \"rag\"\n : runType === \"llm\" || runType === \"chat\"\n ? \"llm\"\n : \"chain\",\n };\n }\n\n const cls = className(serialized);\n const md = (metadata ?? {}) as any;\n\n // LangGraph node / router - prioritize routers over nodes\n const hasNode = md?.langgraph_node != null;\n const hasTriggers = Array.isArray(md?.langgraph_triggers) && md.langgraph_triggers.length > 0;\n const isRouter =\n cls.startsWith(\"Branch<\") || hasTriggers;\n const isGraphRunner = md?.langgraph_path && !md?.langgraph_node;\n\n // LLM / Chat - always prioritize runType over metadata\n if (runType === \"llm\" || runType === \"chat\") {\n const prov = (md?.ls_provider as string) ?? \"LLM\";\n const model = (md?.ls_model_name as string) ?? (cls || \"call\");\n const temp = md?.ls_temperature;\n const tempStr =\n temp != null\n ? typeof temp === \"number\"\n ? temp.toString()\n : JSON.stringify(temp)\n : null;\n const nm =\n tempStr != null\n ? `${prov} ${model} (temp ${tempStr})`\n : `${prov} ${model}`;\n return { name: nm, type: \"llm\" };\n }\n\n // Prioritize LangGraph routers over nodes (but after LLM/Chat)\n if (isRouter) {\n const pathArr = md?.langgraph_path as string[] | undefined;\n const fromNode =\n Array.isArray(pathArr) && pathArr.length\n ? pathArr[pathArr.length - 1]\n : undefined;\n const decision = Array.isArray(md?.langgraph_triggers)\n ? String(\n md.langgraph_triggers.find((t: any) =>\n String(t).startsWith(\"branch:\")\n ) ?? \"\"\n ).replace(/^branch:(to:)?/, \"\")\n : undefined;\n const nm = `Route: ${fromNode ?? \"unknown\"} → ${decision ?? \"unknown\"}`;\n return { name: nm, type: \"component\" };\n }\n\n if (hasNode) {\n const step = md?.langgraph_step;\n const nm = `Node: ${md.langgraph_node}${\n step != null ? ` (step ${String(step)})` : \"\"\n }`;\n return { name: nm, type: \"component\" };\n }\n if (isGraphRunner && runType === \"chain\") {\n return { name: \"Graph: LangGraph\", type: \"chain\" };\n }\n\n // Tool\n if (runType === \"tool\") {\n const tool = (metadata as any)?.name ?? (cls || \"tool\");\n const prev =\n previewInput(inputs) ?? previewInput((serialized as any)?.input);\n return {\n name: prev ? `Tool: ${tool} — ${prev}` : `Tool: ${tool}`,\n type: \"tool\",\n };\n }\n\n // Retriever\n if (runType === \"retriever\") return { name: \"Retriever\", type: \"rag\" };\n\n // Fallbacks\n if (cls.includes(\"Agent\"))\n return { name: `Agent: ${cls}`, type: \"component\" };\n if (cls.startsWith(\"Runnable\"))\n return { name: `Runnable: ${cls.replace(/^Runnable/, \"\")}`, type: \"chain\" };\n return { name: cls || \"LangChain operation\", type: \"chain\" };\n}\n\n// Export helper functions for testing\nexport {\n className,\n shorten,\n previewInput,\n ctxSkip,\n wrapNonScalarValues,\n addLangChainEvent,\n setLangGraphAttributes,\n buildLangChainMetadataAttributes,\n applyGenAIAttrs,\n getResolvedParentContext,\n deriveNameAndType,\n};\n"]}