|
1 | 1 | 'use strict'
|
2 | 2 |
|
3 |
| -const { MEASURED } = require('../../../ext/tags') |
4 |
| -const { storage } = require('../../datadog-core') |
5 |
| -const TracingPlugin = require('../../dd-trace/src/plugins/tracing') |
| 3 | +const LangChainTracingPlugin = require('./tracing') |
| 4 | +const LangChainLLMObsPlugin = require('../../dd-trace/src/llmobs/plugins/langchain') |
| 5 | +const CompositePlugin = require('../../dd-trace/src/plugins/composite') |
6 | 6 |
|
7 |
| -const API_KEY = 'langchain.request.api_key' |
8 |
| -const MODEL = 'langchain.request.model' |
9 |
| -const PROVIDER = 'langchain.request.provider' |
10 |
| -const TYPE = 'langchain.request.type' |
11 |
| - |
12 |
| -const LangChainHandler = require('./handlers/default') |
13 |
| -const LangChainChatModelHandler = require('./handlers/language_models/chat_model') |
14 |
| -const LangChainLLMHandler = require('./handlers/language_models/llm') |
15 |
| -const LangChainChainHandler = require('./handlers/chain') |
16 |
| -const LangChainEmbeddingHandler = require('./handlers/embedding') |
17 |
| - |
18 |
| -class LangChainPlugin extends TracingPlugin { |
| 7 | +class LangChainPlugin extends CompositePlugin { |
19 | 8 | static get id () { return 'langchain' }
|
20 |
| - static get operation () { return 'invoke' } |
21 |
| - static get system () { return 'langchain' } |
22 |
| - static get prefix () { |
23 |
| - return 'tracing:apm:langchain:invoke' |
24 |
| - } |
25 |
| - |
26 |
| - constructor () { |
27 |
| - super(...arguments) |
28 |
| - |
29 |
| - const langchainConfig = this._tracerConfig.langchain || {} |
30 |
| - this.handlers = { |
31 |
| - chain: new LangChainChainHandler(langchainConfig), |
32 |
| - chat_model: new LangChainChatModelHandler(langchainConfig), |
33 |
| - llm: new LangChainLLMHandler(langchainConfig), |
34 |
| - embedding: new LangChainEmbeddingHandler(langchainConfig), |
35 |
| - default: new LangChainHandler(langchainConfig) |
| 9 | + static get plugins () { |
| 10 | + return { |
| 11 | + // ordering here is important - the llm observability plugin must come first |
| 12 | + // so that we can add annotations associated with the span before it finishes. |
| 13 | + // however, because the tracing plugin uses `bindStart` vs the llmobs' `start`, |
| 14 | + // the span is guaranteed to be created in the tracing plugin before the llmobs one is called |
| 15 | + llmobs: LangChainLLMObsPlugin, |
| 16 | + tracing: LangChainTracingPlugin |
36 | 17 | }
|
37 | 18 | }
|
38 |
| - |
39 |
| - bindStart (ctx) { |
40 |
| - const { resource, type } = ctx |
41 |
| - const handler = this.handlers[type] |
42 |
| - |
43 |
| - const instance = ctx.instance |
44 |
| - const apiKey = handler.extractApiKey(instance) |
45 |
| - const provider = handler.extractProvider(instance) |
46 |
| - const model = handler.extractModel(instance) |
47 |
| - |
48 |
| - const tags = handler.getSpanStartTags(ctx, provider) || [] |
49 |
| - |
50 |
| - if (apiKey) tags[API_KEY] = apiKey |
51 |
| - if (provider) tags[PROVIDER] = provider |
52 |
| - if (model) tags[MODEL] = model |
53 |
| - if (type) tags[TYPE] = type |
54 |
| - |
55 |
| - const span = this.startSpan('langchain.request', { |
56 |
| - service: this.config.service, |
57 |
| - resource, |
58 |
| - kind: 'client', |
59 |
| - meta: { |
60 |
| - [MEASURED]: 1, |
61 |
| - ...tags |
62 |
| - } |
63 |
| - }, false) |
64 |
| - |
65 |
| - const store = storage.getStore() || {} |
66 |
| - ctx.currentStore = { ...store, span } |
67 |
| - |
68 |
| - return ctx.currentStore |
69 |
| - } |
70 |
| - |
71 |
| - asyncEnd (ctx) { |
72 |
| - const span = ctx.currentStore.span |
73 |
| - |
74 |
| - const { type } = ctx |
75 |
| - |
76 |
| - const handler = this.handlers[type] |
77 |
| - const tags = handler.getSpanEndTags(ctx) || {} |
78 |
| - |
79 |
| - span.addTags(tags) |
80 |
| - |
81 |
| - span.finish() |
82 |
| - } |
83 |
| - |
84 |
| - getHandler (type) { |
85 |
| - return this.handlers[type] || this.handlers.default |
86 |
| - } |
87 | 19 | }
|
88 | 20 |
|
89 | 21 | module.exports = LangChainPlugin
|
0 commit comments