weflayr 0.24.0 → 0.26.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.
- package/README.md +2 -2
- package/dist/{api → src/api}/generated/facade.gen.d.ts +86 -12
- package/dist/{api → src/api}/generated/facade.gen.js +4 -2
- package/dist/src/api/generated/index.d.ts +2 -0
- package/dist/{api → src/api}/generated/index.js +3 -1
- package/dist/{api → src/api}/generated/sdk.gen.d.ts +11 -3
- package/dist/{api → src/api}/generated/sdk.gen.js +34 -4
- package/{src/api/generated/types.gen.ts → dist/src/api/generated/types.gen.d.ts} +436 -153
- package/dist/{api → src/api}/makeEndpoint.js +1 -3
- package/dist/src/auto-instrument.d.ts +42 -0
- package/dist/src/auto-instrument.js +156 -0
- package/dist/src/index.d.ts +9 -0
- package/dist/src/index.js +49 -0
- package/dist/src/instrumentation/anthropic/get_cache_and_reasoning_telemetry.d.ts +20 -0
- package/dist/src/instrumentation/anthropic/get_cache_and_reasoning_telemetry.js +114 -0
- package/dist/src/instrumentation/anthropic/get_cache_config_telemetry.d.ts +28 -0
- package/dist/src/instrumentation/anthropic/get_cache_config_telemetry.js +92 -0
- package/dist/src/instrumentation/anthropic/get_streaming_accumulation_telemetry.d.ts +25 -0
- package/dist/src/instrumentation/anthropic/get_streaming_accumulation_telemetry.js +141 -0
- package/dist/src/instrumentation/anthropic/get_structured_output_schema_telemetry.d.ts +9 -0
- package/dist/src/instrumentation/anthropic/get_structured_output_schema_telemetry.js +17 -0
- package/dist/src/instrumentation/anthropic/get_tool_definitions_telemetry.d.ts +15 -0
- package/dist/src/instrumentation/anthropic/get_tool_definitions_telemetry.js +50 -0
- package/dist/src/instrumentation/anthropic/set_telemetry_attributes.d.ts +15 -0
- package/dist/src/instrumentation/anthropic/set_telemetry_attributes.js +39 -0
- package/dist/src/instrumentation/bedrock/get_cache_config_telemetry.d.ts +22 -0
- package/dist/src/instrumentation/bedrock/get_cache_config_telemetry.js +97 -0
- package/dist/src/instrumentation/bedrock/get_cache_telemetry.d.ts +22 -0
- package/dist/src/instrumentation/bedrock/get_cache_telemetry.js +102 -0
- package/dist/src/instrumentation/bedrock/get_input_message_content_telemetry.d.ts +15 -0
- package/dist/src/instrumentation/bedrock/get_input_message_content_telemetry.js +91 -0
- package/dist/src/instrumentation/bedrock/get_model_id_telemetry.d.ts +21 -0
- package/dist/src/instrumentation/bedrock/get_model_id_telemetry.js +54 -0
- package/dist/src/instrumentation/bedrock/get_reasoning_output_telemetry.d.ts +19 -0
- package/dist/src/instrumentation/bedrock/get_reasoning_output_telemetry.js +81 -0
- package/dist/src/instrumentation/bedrock/get_streaming_output_message_telemetry.d.ts +27 -0
- package/dist/src/instrumentation/bedrock/get_streaming_output_message_telemetry.js +126 -0
- package/dist/src/instrumentation/bedrock/get_tool_call_output_telemetry.d.ts +17 -0
- package/dist/src/instrumentation/bedrock/get_tool_call_output_telemetry.js +85 -0
- package/dist/src/instrumentation/bedrock/get_tool_definitions_telemetry.d.ts +15 -0
- package/dist/src/instrumentation/bedrock/get_tool_definitions_telemetry.js +68 -0
- package/dist/src/instrumentation/bedrock/set_telemetry_attributes.d.ts +18 -0
- package/dist/src/instrumentation/bedrock/set_telemetry_attributes.js +47 -0
- package/dist/src/instrumentation/cohere/get_chat_telemetry.d.ts +23 -0
- package/dist/src/instrumentation/cohere/get_chat_telemetry.js +77 -0
- package/dist/src/instrumentation/cohere/get_embeddings_telemetry.d.ts +18 -0
- package/dist/src/instrumentation/cohere/get_embeddings_telemetry.js +88 -0
- package/dist/src/instrumentation/cohere/get_structured_output_schema_telemetry.d.ts +12 -0
- package/dist/src/instrumentation/cohere/get_structured_output_schema_telemetry.js +18 -0
- package/dist/src/instrumentation/cohere/get_tool_call_output_telemetry.d.ts +31 -0
- package/dist/src/instrumentation/cohere/get_tool_call_output_telemetry.js +106 -0
- package/dist/src/instrumentation/cohere/get_tool_definitions_telemetry.d.ts +27 -0
- package/dist/src/instrumentation/cohere/get_tool_definitions_telemetry.js +75 -0
- package/dist/src/instrumentation/cohere/set_telemetry_attributes.d.ts +17 -0
- package/dist/src/instrumentation/cohere/set_telemetry_attributes.js +44 -0
- package/dist/src/instrumentation/elevenlabs/full_instrumentation.d.ts +28 -0
- package/dist/src/instrumentation/elevenlabs/full_instrumentation.js +209 -0
- package/dist/src/instrumentation/google/get_audio_telemetry.d.ts +9 -0
- package/dist/src/instrumentation/google/get_audio_telemetry.js +28 -0
- package/dist/src/instrumentation/google/get_cache_operations_telemetry.d.ts +23 -0
- package/dist/src/instrumentation/google/get_cache_operations_telemetry.js +154 -0
- package/dist/src/instrumentation/google/get_cache_telemetry.d.ts +16 -0
- package/{src → dist/src}/instrumentation/google/get_cache_telemetry.js +18 -19
- package/dist/src/instrumentation/google/get_embeddings_telemetry.d.ts +12 -0
- package/dist/src/instrumentation/google/get_embeddings_telemetry.js +85 -0
- package/dist/src/instrumentation/google/get_provider_name.d.ts +11 -0
- package/{src → dist/src}/instrumentation/google/get_provider_name.js +11 -12
- package/{src/instrumentation/google/get_reasoning_telemetry.js → dist/src/instrumentation/google/get_reasoning_telemetry.d.ts} +1 -11
- package/dist/src/instrumentation/google/get_reasoning_telemetry.js +21 -0
- package/dist/src/instrumentation/google/get_structured_output_schema_telemetry.d.ts +12 -0
- package/dist/src/instrumentation/google/get_structured_output_schema_telemetry.js +19 -0
- package/dist/src/instrumentation/google/set_telemetry_attributes.d.ts +18 -0
- package/dist/src/instrumentation/google/set_telemetry_attributes.js +98 -0
- package/dist/src/instrumentation/openai/get_audio_telemetry.d.ts +25 -0
- package/dist/src/instrumentation/openai/get_audio_telemetry.js +123 -0
- package/dist/src/instrumentation/openai/get_bedrock_mantle_telemetry.d.ts +35 -0
- package/dist/src/instrumentation/openai/get_bedrock_mantle_telemetry.js +148 -0
- package/dist/src/instrumentation/openai/get_cache_and_reasoning_telemetry.d.ts +27 -0
- package/dist/src/instrumentation/openai/get_cache_and_reasoning_telemetry.js +72 -0
- package/dist/src/instrumentation/openai/get_cache_config_telemetry.d.ts +28 -0
- package/dist/src/instrumentation/openai/get_cache_config_telemetry.js +91 -0
- package/dist/src/instrumentation/openai/get_embeddings_telemetry.d.ts +18 -0
- package/dist/src/instrumentation/openai/get_embeddings_telemetry.js +86 -0
- package/dist/src/instrumentation/openai/get_streaming_usage.d.ts +21 -0
- package/dist/src/instrumentation/openai/get_streaming_usage.js +74 -0
- package/dist/src/instrumentation/openai/get_structured_output_schema_telemetry.d.ts +12 -0
- package/dist/src/instrumentation/openai/get_structured_output_schema_telemetry.js +20 -0
- package/dist/src/instrumentation/openai/set_telemetry_attributes.d.ts +17 -0
- package/dist/src/instrumentation/openai/set_telemetry_attributes.js +47 -0
- package/dist/src/instrumentation/shared/get_structured_output_schema_telemetry.d.ts +35 -0
- package/dist/src/instrumentation/shared/get_structured_output_schema_telemetry.js +76 -0
- package/dist/src/instrumentation/vercel/full_instrumentation.d.ts +3 -0
- package/dist/src/instrumentation/vercel/full_instrumentation.js +54 -0
- package/dist/src/instrumentation/vercel/get_cache_creation_telemetry.d.ts +22 -0
- package/dist/src/instrumentation/vercel/get_cache_creation_telemetry.js +66 -0
- package/dist/src/instrumentation/vercel/get_structured_output_schema_telemetry.d.ts +24 -0
- package/dist/src/instrumentation/vercel/get_structured_output_schema_telemetry.js +84 -0
- package/dist/src/logger.d.ts +1 -0
- package/dist/src/logger.js +6 -0
- package/dist/src/otel/exporter.d.ts +19 -0
- package/dist/src/otel/exporter.js +94 -0
- package/dist/src/otel/propagation.d.ts +46 -0
- package/dist/src/otel/propagation.js +110 -0
- package/dist/src/otel/span-filter.d.ts +3 -0
- package/dist/src/otel/span-filter.js +61 -0
- package/dist/src/otel/span-processor.d.ts +55 -0
- package/dist/src/otel/span-processor.js +169 -0
- package/dist/src/otel/vercel-ai-sdk-span-filter.d.ts +12 -0
- package/dist/src/otel/vercel-ai-sdk-span-filter.js +88 -0
- package/dist/src/setup.d.ts +50 -0
- package/dist/src/setup.js +155 -0
- package/package.json +11 -5
- package/.prettierignore +0 -2
- package/.prettierrc.json +0 -7
- package/LICENSE-MIT +0 -21
- package/NOTICE +0 -12
- package/dist/api/generated/index.d.ts +0 -2
- package/dist/api/generated/types.gen.d.ts +0 -1005
- package/eslint.config.mjs +0 -36
- package/index.d.ts +0 -170
- package/openapi-ts.config.mjs +0 -9
- package/scripts/generate_facade.mjs +0 -86
- package/src/api/caseConversion.ts +0 -58
- package/src/api/generated/client/client.gen.ts +0 -277
- package/src/api/generated/client/index.ts +0 -27
- package/src/api/generated/client/types.gen.ts +0 -218
- package/src/api/generated/client/utils.gen.ts +0 -316
- package/src/api/generated/client.gen.ts +0 -16
- package/src/api/generated/core/auth.gen.ts +0 -48
- package/src/api/generated/core/bodySerializer.gen.ts +0 -82
- package/src/api/generated/core/params.gen.ts +0 -178
- package/src/api/generated/core/pathSerializer.gen.ts +0 -171
- package/src/api/generated/core/queryKeySerializer.gen.ts +0 -117
- package/src/api/generated/core/serverSentEvents.gen.ts +0 -242
- package/src/api/generated/core/types.gen.ts +0 -110
- package/src/api/generated/core/utils.gen.ts +0 -140
- package/src/api/generated/facade.gen.ts +0 -104
- package/src/api/generated/index.ts +0 -4
- package/src/api/generated/sdk.gen.ts +0 -175
- package/src/api/index.ts +0 -45
- package/src/api/makeEndpoint.ts +0 -54
- package/src/auto-instrument.js +0 -172
- package/src/index.js +0 -19
- package/src/instrumentation/anthropic/get_cache_and_reasoning_telemetry.js +0 -118
- package/src/instrumentation/anthropic/get_cache_config_telemetry.js +0 -90
- package/src/instrumentation/anthropic/get_streaming_stop_reason_telemetry.js +0 -121
- package/src/instrumentation/anthropic/get_tool_definitions_telemetry.js +0 -55
- package/src/instrumentation/anthropic/set_telemetry_attributes.js +0 -39
- package/src/instrumentation/bedrock/get_cache_config_telemetry.js +0 -106
- package/src/instrumentation/bedrock/get_cache_telemetry.js +0 -109
- package/src/instrumentation/bedrock/get_input_message_content_telemetry.js +0 -94
- package/src/instrumentation/bedrock/get_streaming_output_message_telemetry.js +0 -87
- package/src/instrumentation/bedrock/set_telemetry_attributes.js +0 -40
- package/src/instrumentation/cohere/get_chat_telemetry.js +0 -88
- package/src/instrumentation/cohere/get_embeddings_telemetry.js +0 -107
- package/src/instrumentation/cohere/set_telemetry_attributes.js +0 -32
- package/src/instrumentation/elevenlabs/full_instrumentation.js +0 -236
- package/src/instrumentation/google/get_audio_telemetry.js +0 -30
- package/src/instrumentation/google/get_cache_operations_telemetry.js +0 -171
- package/src/instrumentation/google/get_embeddings_telemetry.js +0 -99
- package/src/instrumentation/google/set_telemetry_attributes.js +0 -104
- package/src/instrumentation/openai/get_audio_telemetry.js +0 -149
- package/src/instrumentation/openai/get_cache_and_reasoning_telemetry.js +0 -71
- package/src/instrumentation/openai/get_cache_config_telemetry.js +0 -63
- package/src/instrumentation/openai/get_embeddings_telemetry.js +0 -107
- package/src/instrumentation/openai/get_streaming_usage.js +0 -81
- package/src/instrumentation/openai/set_telemetry_attributes.js +0 -41
- package/src/instrumentation/vercel/full_instrumentation.js +0 -52
- package/src/instrumentation/vercel/get_cache_creation_telemetry.js +0 -70
- package/src/logger.js +0 -8
- package/src/otel/exporter.js +0 -108
- package/src/otel/propagation.js +0 -146
- package/src/otel/span-filter.js +0 -69
- package/src/otel/span-processor.js +0 -170
- package/src/otel/vercel-ai-sdk-span-filter.js +0 -79
- package/src/setup.js +0 -167
- package/tests/api/index.test.js +0 -437
- package/tests/index.test.js +0 -884
- package/tests/instrumentation/anthropic/get_cache_and_reasoning_telemetry.test.js +0 -181
- package/tests/instrumentation/anthropic/get_cache_config_telemetry.test.js +0 -92
- package/tests/instrumentation/anthropic/get_streaming_stop_reason_telemetry.test.js +0 -117
- package/tests/instrumentation/anthropic/get_tool_definitions_telemetry.test.js +0 -97
- package/tests/instrumentation/bedrock/get_cache_config_telemetry.test.js +0 -107
- package/tests/instrumentation/bedrock/get_cache_telemetry.test.js +0 -118
- package/tests/instrumentation/bedrock/get_input_message_content_telemetry.test.js +0 -89
- package/tests/instrumentation/bedrock/get_streaming_output_message_telemetry.test.js +0 -87
- package/tests/instrumentation/cohere/get_chat_telemetry.test.js +0 -148
- package/tests/instrumentation/cohere/get_embeddings_telemetry.test.js +0 -132
- package/tests/instrumentation/elevenlabs/full_instrumentation.test.js +0 -258
- package/tests/instrumentation/google/get_cache_operations_telemetry.test.js +0 -130
- package/tests/instrumentation/google/get_embeddings_telemetry.test.js +0 -128
- package/tests/instrumentation/google/get_reasoning_telemetry.test.js +0 -41
- package/tests/instrumentation/google/set_telemetry_attributes.test.js +0 -219
- package/tests/instrumentation/openai/get_audio_telemetry.test.js +0 -170
- package/tests/instrumentation/openai/get_cache_and_reasoning_telemetry.test.js +0 -83
- package/tests/instrumentation/openai/get_cache_config_telemetry.test.js +0 -83
- package/tests/instrumentation/openai/get_embeddings_telemetry.test.js +0 -145
- package/tests/instrumentation/openai/get_streaming_usage.test.js +0 -105
- package/tests/instrumentation/vercel/full_instrumentation.test.js +0 -16
- package/tests/instrumentation/vercel/get_cache_creation_telemetry.test.js +0 -96
- package/tests/otel/vercel-ai-sdk-span-filter.test.js +0 -159
- package/tsconfig.json +0 -18
- /package/dist/{api → src/api}/caseConversion.d.ts +0 -0
- /package/dist/{api → src/api}/caseConversion.js +0 -0
- /package/dist/{api → src/api}/generated/client/client.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/client/client.gen.js +0 -0
- /package/dist/{api → src/api}/generated/client/index.d.ts +0 -0
- /package/dist/{api → src/api}/generated/client/index.js +0 -0
- /package/dist/{api → src/api}/generated/client/types.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/client/types.gen.js +0 -0
- /package/dist/{api → src/api}/generated/client/utils.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/client/utils.gen.js +0 -0
- /package/dist/{api → src/api}/generated/client.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/client.gen.js +0 -0
- /package/dist/{api → src/api}/generated/core/auth.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/core/auth.gen.js +0 -0
- /package/dist/{api → src/api}/generated/core/bodySerializer.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/core/bodySerializer.gen.js +0 -0
- /package/dist/{api → src/api}/generated/core/params.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/core/params.gen.js +0 -0
- /package/dist/{api → src/api}/generated/core/pathSerializer.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/core/pathSerializer.gen.js +0 -0
- /package/dist/{api → src/api}/generated/core/queryKeySerializer.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/core/queryKeySerializer.gen.js +0 -0
- /package/dist/{api → src/api}/generated/core/serverSentEvents.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/core/serverSentEvents.gen.js +0 -0
- /package/dist/{api → src/api}/generated/core/types.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/core/types.gen.js +0 -0
- /package/dist/{api → src/api}/generated/core/utils.gen.d.ts +0 -0
- /package/dist/{api → src/api}/generated/core/utils.gen.js +0 -0
- /package/dist/{api → src/api}/generated/types.gen.js +0 -0
- /package/dist/{api → src/api}/index.d.ts +0 -0
- /package/dist/{api → src/api}/index.js +0 -0
- /package/dist/{api → src/api}/makeEndpoint.d.ts +0 -0
package/src/auto-instrument.js
DELETED
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { registerInstrumentations } = require('@opentelemetry/instrumentation');
|
|
4
|
-
|
|
5
|
-
const { debug } = require('./logger');
|
|
6
|
-
const { setup, _state } = require('./setup');
|
|
7
|
-
|
|
8
|
-
const AiSdk = Object.freeze({
|
|
9
|
-
OPENAI: 'openai',
|
|
10
|
-
ANTHROPIC: 'anthropic',
|
|
11
|
-
BEDROCK: 'bedrock',
|
|
12
|
-
COHERE: 'cohere',
|
|
13
|
-
GOOGLE_GENAI: 'google-genai',
|
|
14
|
-
ELEVENLABS: 'elevenlabs',
|
|
15
|
-
VERCEL_AI_GATEWAY: 'vercel_ai_gateway',
|
|
16
|
-
});
|
|
17
|
-
|
|
18
|
-
// Allowed values for `propagateMetadata({ providerName })`: the actual AI
|
|
19
|
-
// providers a call can be attributed to. Unlike AiSdk this names providers,
|
|
20
|
-
// not SDKs — google-genai is an SDK whose calls are labelled gemini or vertex,
|
|
21
|
-
// and mistral has no Node OTel instrumentor so it is reached through the
|
|
22
|
-
// OpenAI SDK (OpenAI-compatible endpoint) but reported as itself.
|
|
23
|
-
const AIProviderName = Object.freeze({
|
|
24
|
-
OPENAI: 'openai',
|
|
25
|
-
AZURE_OPENAI: 'azure',
|
|
26
|
-
ANTHROPIC: 'anthropic',
|
|
27
|
-
BEDROCK: 'bedrock',
|
|
28
|
-
COHERE: 'cohere',
|
|
29
|
-
ELEVENLABS: 'elevenlabs',
|
|
30
|
-
MISTRAL: 'mistral',
|
|
31
|
-
VERCEL_AI_GATEWAY: 'vercel_ai_gateway',
|
|
32
|
-
GEMINI: 'gemini',
|
|
33
|
-
VERTEX: 'vertex',
|
|
34
|
-
});
|
|
35
|
-
|
|
36
|
-
// The primary instrumentor for each provider SDK. Most are third-party
|
|
37
|
-
// traceloop packages, loaded by `package` name. Providers with no usable
|
|
38
|
-
// third-party instrumentor (e.g. ElevenLabs) instead carry a `requirePath` +
|
|
39
|
-
// `className` pointing at the instrumentor weflayr ships itself; `package` then
|
|
40
|
-
// names the provider SDK to suggest installing if its import fails.
|
|
41
|
-
const REGISTRY = {
|
|
42
|
-
[AiSdk.OPENAI]: { package: '@traceloop/instrumentation-openai' },
|
|
43
|
-
[AiSdk.ANTHROPIC]: { package: '@traceloop/instrumentation-anthropic' },
|
|
44
|
-
[AiSdk.BEDROCK]: { package: '@traceloop/instrumentation-bedrock' },
|
|
45
|
-
[AiSdk.COHERE]: { package: '@traceloop/instrumentation-cohere' },
|
|
46
|
-
[AiSdk.GOOGLE_GENAI]: { package: '@traceloop/instrumentation-google-generativeai' },
|
|
47
|
-
[AiSdk.ELEVENLABS]: {
|
|
48
|
-
package: '@elevenlabs/elevenlabs-js',
|
|
49
|
-
requirePath: './instrumentation/elevenlabs/full_instrumentation',
|
|
50
|
-
className: 'ElevenLabsInstrumentor',
|
|
51
|
-
},
|
|
52
|
-
[AiSdk.VERCEL_AI_GATEWAY]: {
|
|
53
|
-
package: 'ai',
|
|
54
|
-
requirePath: './instrumentation/vercel/full_instrumentation',
|
|
55
|
-
className: 'VercelAiSdkInstrumentor',
|
|
56
|
-
},
|
|
57
|
-
};
|
|
58
|
-
|
|
59
|
-
// One complementary instrumentor per provider: a `set_telemetry_attributes`
|
|
60
|
-
// orchestrator under `instrumentation/<provider>/` that wires every weflayr patch
|
|
61
|
-
// the traceloop instrumentor misses (the orchestrator itself groups the per-patch
|
|
62
|
-
// `get_*` files, so a single entry per provider suffices).
|
|
63
|
-
const COMPLEMENTARY_INSTRUMENTOR = {
|
|
64
|
-
[AiSdk.OPENAI]: {
|
|
65
|
-
requirePath: './instrumentation/openai/set_telemetry_attributes',
|
|
66
|
-
className: 'OpenAITelemetryInstrumentor',
|
|
67
|
-
},
|
|
68
|
-
[AiSdk.ANTHROPIC]: {
|
|
69
|
-
requirePath: './instrumentation/anthropic/set_telemetry_attributes',
|
|
70
|
-
className: 'AnthropicTelemetryInstrumentor',
|
|
71
|
-
},
|
|
72
|
-
[AiSdk.BEDROCK]: {
|
|
73
|
-
requirePath: './instrumentation/bedrock/set_telemetry_attributes',
|
|
74
|
-
className: 'BedrockTelemetryInstrumentor',
|
|
75
|
-
},
|
|
76
|
-
[AiSdk.COHERE]: {
|
|
77
|
-
requirePath: './instrumentation/cohere/set_telemetry_attributes',
|
|
78
|
-
className: 'CohereTelemetryInstrumentor',
|
|
79
|
-
},
|
|
80
|
-
[AiSdk.GOOGLE_GENAI]: {
|
|
81
|
-
requirePath: './instrumentation/google/set_telemetry_attributes',
|
|
82
|
-
className: 'GoogleTelemetryInstrumentor',
|
|
83
|
-
},
|
|
84
|
-
};
|
|
85
|
-
|
|
86
|
-
const SETUP_OPTION_KEYS = [
|
|
87
|
-
'apiKey',
|
|
88
|
-
'baseUrl',
|
|
89
|
-
'defaultTags',
|
|
90
|
-
'exportMode',
|
|
91
|
-
'mask',
|
|
92
|
-
'captureMessageContent',
|
|
93
|
-
'warnOnExportError',
|
|
94
|
-
];
|
|
95
|
-
|
|
96
|
-
function _instantiateInstrumentation(instrumentationPkg) {
|
|
97
|
-
for (const value of Object.values(instrumentationPkg)) {
|
|
98
|
-
if (typeof value === 'function' && /Instrumentation$/.test(value.name)) {
|
|
99
|
-
return new value();
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
if (typeof instrumentationPkg.default === 'function') return new instrumentationPkg.default();
|
|
103
|
-
throw new Error('No Instrumentation class found in module exports');
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
async function _instrumentAiSdk(aiSdk) {
|
|
107
|
-
if (!(aiSdk in REGISTRY)) {
|
|
108
|
-
throw new Error(
|
|
109
|
-
`weflayr.autoInstrument: unknown provider "${aiSdk}". Known: ${Object.keys(REGISTRY).join(', ')}`
|
|
110
|
-
);
|
|
111
|
-
}
|
|
112
|
-
const entry = REGISTRY[aiSdk];
|
|
113
|
-
|
|
114
|
-
if (entry.requirePath) {
|
|
115
|
-
// No usable third-party instrumentor — use the hand-written one bundled
|
|
116
|
-
// with weflayr (it covers every endpoint of the provider).
|
|
117
|
-
const Instrumentor = require(entry.requirePath)[entry.className];
|
|
118
|
-
new Instrumentor().instrument();
|
|
119
|
-
debug('autoInstrument: registered aiSdk=%s package=%s', aiSdk, entry.package);
|
|
120
|
-
return;
|
|
121
|
-
}
|
|
122
|
-
|
|
123
|
-
let instrumentationPkg;
|
|
124
|
-
try {
|
|
125
|
-
instrumentationPkg = require(entry.package);
|
|
126
|
-
} catch (err) {
|
|
127
|
-
throw new Error(
|
|
128
|
-
`weflayr.autoInstrument("${aiSdk}"): failed to load "${entry.package}". ` +
|
|
129
|
-
`Install it with: npm install ${entry.package}\nUnderlying error: ${err.message}`
|
|
130
|
-
);
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
const instrumentation = _instantiateInstrumentation(instrumentationPkg);
|
|
134
|
-
registerInstrumentations({ instrumentations: [instrumentation] });
|
|
135
|
-
|
|
136
|
-
const complementary = COMPLEMENTARY_INSTRUMENTOR[aiSdk];
|
|
137
|
-
if (complementary) {
|
|
138
|
-
const InstrumentorClass = require(complementary.requirePath)[complementary.className];
|
|
139
|
-
new InstrumentorClass().instrument(instrumentation);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
debug('autoInstrument: registered aiSdk=%s package=%s', aiSdk, entry.package);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Register an OTel Instrumentor for one or more LLM provider SDKs.
|
|
147
|
-
*
|
|
148
|
-
* Convenience: pass `apiKey` (+ other `setup()` options) here to skip a
|
|
149
|
-
* separate `weflayr.setup()` call. If `apiKey` is omitted, `setup()` must
|
|
150
|
-
* have been called beforehand.
|
|
151
|
-
*/
|
|
152
|
-
async function autoInstrument({ aiSdks, ...options } = {}) {
|
|
153
|
-
if (aiSdks === undefined) {
|
|
154
|
-
throw new Error('weflayr.autoInstrument: `aiSdks` is required.');
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
if (!_state.processor) {
|
|
158
|
-
// setup() picks up WEFLAYR_API_KEY from the env if not passed here.
|
|
159
|
-
const setupOptions = {};
|
|
160
|
-
for (const key of SETUP_OPTION_KEYS) {
|
|
161
|
-
if (options[key] !== undefined) setupOptions[key] = options[key];
|
|
162
|
-
}
|
|
163
|
-
setup(setupOptions);
|
|
164
|
-
}
|
|
165
|
-
|
|
166
|
-
const list = Array.isArray(aiSdks) ? aiSdks : [aiSdks];
|
|
167
|
-
for (const aiSdk of list) {
|
|
168
|
-
await _instrumentAiSdk(aiSdk);
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
module.exports = { autoInstrument, AiSdk, AIProviderName, REGISTRY };
|
package/src/index.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
const { setup, flush } = require('./setup');
|
|
4
|
-
const { autoInstrument, AiSdk, AIProviderName } = require('./auto-instrument');
|
|
5
|
-
const { propagateMetadata } = require('./otel/propagation');
|
|
6
|
-
// Public-API client (revenue, key metrics, customer tags), compiled from the
|
|
7
|
-
// TypeScript in src/api by `npm run build`.
|
|
8
|
-
const api = require('../dist/api');
|
|
9
|
-
|
|
10
|
-
module.exports = {
|
|
11
|
-
setup,
|
|
12
|
-
flush,
|
|
13
|
-
autoInstrument,
|
|
14
|
-
AiSdk,
|
|
15
|
-
AIProviderName,
|
|
16
|
-
propagateMetadata,
|
|
17
|
-
client: api.client,
|
|
18
|
-
api,
|
|
19
|
-
};
|
|
@@ -1,118 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Cached-prompt token enrichment complement for the non-streamed Anthropic path.
|
|
5
|
-
*
|
|
6
|
-
* `@traceloop/instrumentation-anthropic` reads the response's
|
|
7
|
-
* `usage.cache_creation_input_tokens` / `cache_read_input_tokens` but never writes
|
|
8
|
-
* them to a `gen_ai.usage.cache_*` span attribute (its semantic conventions define
|
|
9
|
-
* no such key), so cache-hit spans carry no cached-token counts. This stamps the
|
|
10
|
-
* underscored attributes the worker reads. (The Python instrumentor emits them
|
|
11
|
-
* natively, under the dotted `cache_read.input_tokens` form, which the worker also
|
|
12
|
-
* accepts.)
|
|
13
|
-
*
|
|
14
|
-
* It wraps the instrumentor instance's `_endSpan({ span, type, result })`, which
|
|
15
|
-
* finalizes the span after the response resolves, letting us read `result.usage`
|
|
16
|
-
* while the span is still open.
|
|
17
|
-
*/
|
|
18
|
-
|
|
19
|
-
const CACHE_READ_INPUT_TOKENS_ATTR = 'gen_ai.usage.cache_read_input_tokens';
|
|
20
|
-
const CACHE_CREATION_INPUT_TOKENS_ATTR = 'gen_ai.usage.cache_creation_input_tokens';
|
|
21
|
-
const CACHE_CREATION_ATTR = 'weflayr.cache.creation';
|
|
22
|
-
const INPUT_TOKENS_ATTR = 'gen_ai.usage.input_tokens';
|
|
23
|
-
const THINKING_TOKENS_ATTR = 'gen_ai.usage.output_tokens_details.thinking_tokens';
|
|
24
|
-
|
|
25
|
-
// Stamp `usage.cache_creation` verbatim (the written tokens per TTL, billed at
|
|
26
|
-
// different rates); skipped when nothing was written so non-caching calls
|
|
27
|
-
// carry no attribute. The normalizer owns the mapping to TTL tiers.
|
|
28
|
-
function _setCacheCreation(span, cacheCreation) {
|
|
29
|
-
if (!cacheCreation) return;
|
|
30
|
-
if (!Object.values(cacheCreation).some(Boolean)) return;
|
|
31
|
-
span.setAttribute(CACHE_CREATION_ATTR, JSON.stringify(cacheCreation));
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Stamp cache counts (and the raw uncached input) from an Anthropic usage object.
|
|
35
|
-
// The instrumentor emits no `gen_ai.usage.cache_*` attribute; `input_tokens` in
|
|
36
|
-
// the stream events is the raw uncached count (cached tokens are reported
|
|
37
|
-
// separately), so it matches the non-streamed override. The extended-thinking
|
|
38
|
-
// count (`output_tokens_details.thinking_tokens`, a subset of output_tokens) is
|
|
39
|
-
// likewise dropped by the instrumentor, so stamp it for the normalizer.
|
|
40
|
-
function _setUsage(span, usage) {
|
|
41
|
-
if (!usage || !span || !span.isRecording || !span.isRecording()) return;
|
|
42
|
-
if (usage.cache_read_input_tokens) {
|
|
43
|
-
span.setAttribute(CACHE_READ_INPUT_TOKENS_ATTR, usage.cache_read_input_tokens);
|
|
44
|
-
}
|
|
45
|
-
if (usage.cache_creation_input_tokens) {
|
|
46
|
-
span.setAttribute(CACHE_CREATION_INPUT_TOKENS_ATTR, usage.cache_creation_input_tokens);
|
|
47
|
-
}
|
|
48
|
-
_setCacheCreation(span, usage.cache_creation);
|
|
49
|
-
if (typeof usage.input_tokens === 'number') {
|
|
50
|
-
span.setAttribute(INPUT_TOKENS_ATTR, usage.input_tokens);
|
|
51
|
-
}
|
|
52
|
-
const thinking = usage.output_tokens_details && usage.output_tokens_details.thinking_tokens;
|
|
53
|
-
if (thinking) {
|
|
54
|
-
span.setAttribute(THINKING_TOKENS_ATTR, thinking);
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
class AnthropicPromptCachingInstrumentor {
|
|
59
|
-
constructor() {
|
|
60
|
-
// [instrumentation, methodName, originalFunction] for uninstrument().
|
|
61
|
-
this._patched = [];
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// No-op (and never throws) if the instrumentor's internals have changed shape —
|
|
65
|
-
// the worst case is missing cached-token counts, never a crash.
|
|
66
|
-
instrument(instrumentation) {
|
|
67
|
-
if (!instrumentation) return;
|
|
68
|
-
|
|
69
|
-
// Non-streamed: the instrumentor finalizes via `_endSpan({ span, result })`.
|
|
70
|
-
const endSpanOriginal = instrumentation._endSpan;
|
|
71
|
-
if (typeof endSpanOriginal === 'function') {
|
|
72
|
-
instrumentation._endSpan = function endSpanWithCache(args) {
|
|
73
|
-
try {
|
|
74
|
-
_setUsage(args && args.span, args && args.result && args.result.usage);
|
|
75
|
-
} catch {
|
|
76
|
-
// Never break span finalization over an enrichment failure.
|
|
77
|
-
}
|
|
78
|
-
return endSpanOriginal.call(this, args);
|
|
79
|
-
};
|
|
80
|
-
this._patched.push([instrumentation, '_endSpan', endSpanOriginal]);
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
// Streamed: cache + raw input arrive in the `message_start` (and `message_delta`)
|
|
84
|
-
// usage events; observe the chunks as they pass through the streaming handler.
|
|
85
|
-
const streamOriginal = instrumentation._streamingWrapPromise;
|
|
86
|
-
if (typeof streamOriginal === 'function') {
|
|
87
|
-
instrumentation._streamingWrapPromise = function streamWithCache(...streamArgs) {
|
|
88
|
-
const opts = streamArgs[streamArgs.length - 1];
|
|
89
|
-
const span = opts && opts.span;
|
|
90
|
-
const result = streamOriginal.apply(this, streamArgs);
|
|
91
|
-
if (!span || !result || typeof result[Symbol.asyncIterator] !== 'function') return result;
|
|
92
|
-
return (async function* observeCache() {
|
|
93
|
-
for await (const chunk of result) {
|
|
94
|
-
try {
|
|
95
|
-
const usage =
|
|
96
|
-
(chunk && chunk.type === 'message_start' && chunk.message && chunk.message.usage) ||
|
|
97
|
-
(chunk && chunk.usage);
|
|
98
|
-
_setUsage(span, usage);
|
|
99
|
-
} catch {
|
|
100
|
-
// Never break the caller's stream over an enrichment failure.
|
|
101
|
-
}
|
|
102
|
-
yield chunk;
|
|
103
|
-
}
|
|
104
|
-
})();
|
|
105
|
-
};
|
|
106
|
-
this._patched.push([instrumentation, '_streamingWrapPromise', streamOriginal]);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
uninstrument() {
|
|
111
|
-
for (const [owner, methodName, original] of this._patched) {
|
|
112
|
-
owner[methodName] = original;
|
|
113
|
-
}
|
|
114
|
-
this._patched = [];
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
module.exports = { AnthropicPromptCachingInstrumentor };
|
|
@@ -1,90 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Request-side prompt-caching config capture for Anthropic spans.
|
|
5
|
-
*
|
|
6
|
-
* Anthropic callers opt into caching by placing `cache_control` breakpoints on
|
|
7
|
-
* content blocks (`system` text blocks, message content blocks, tool
|
|
8
|
-
* definitions), each with an optional `ttl` ("5m" default, or "1h"). The
|
|
9
|
-
* traceloop instrumentor never records them, so cache-hit analysis cannot tell
|
|
10
|
-
* what the request asked to cache or for how long.
|
|
11
|
-
*
|
|
12
|
-
* Wrap `startSpan({ type, params })` (covering the streamed and non-streamed
|
|
13
|
-
* paths) to stamp every breakpoint found in the request as
|
|
14
|
-
* `weflayr.cache.breakpoints`: a JSON list of `{location, ttl}` where location
|
|
15
|
-
* is `system`, `messages[i]` or `tools[i]` and `ttl` is the raw cache_control
|
|
16
|
-
* string, omitted when the breakpoint sets none; the normalizer owns the TTL
|
|
17
|
-
* vocabulary.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
const BREAKPOINTS_ATTR = 'weflayr.cache.breakpoints';
|
|
21
|
-
|
|
22
|
-
// A breakpoint as location + the raw cache_control `ttl` string, omitted when
|
|
23
|
-
// the request sets none.
|
|
24
|
-
function _breakpointEntry(location, cacheControl) {
|
|
25
|
-
const ttl = cacheControl && cacheControl.ttl;
|
|
26
|
-
return ttl ? { location, ttl: String(ttl) } : { location };
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
function _cacheControlsInBlocks(blocks) {
|
|
30
|
-
if (!Array.isArray(blocks)) return [];
|
|
31
|
-
return blocks.map((block) => block && block.cache_control).filter(Boolean);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
// Every `cache_control` breakpoint in the request, as location + the raw
|
|
35
|
-
// `ttl` string (omitted when the breakpoint sets none).
|
|
36
|
-
function extractCacheBreakpoints(params) {
|
|
37
|
-
const breakpoints = [];
|
|
38
|
-
for (const cacheControl of _cacheControlsInBlocks(params.system)) {
|
|
39
|
-
breakpoints.push(_breakpointEntry('system', cacheControl));
|
|
40
|
-
}
|
|
41
|
-
(params.messages || []).forEach((message, index) => {
|
|
42
|
-
for (const cacheControl of _cacheControlsInBlocks(message && message.content)) {
|
|
43
|
-
breakpoints.push(_breakpointEntry(`messages[${index}]`, cacheControl));
|
|
44
|
-
}
|
|
45
|
-
});
|
|
46
|
-
(params.tools || []).forEach((tool, index) => {
|
|
47
|
-
if (tool && tool.cache_control) {
|
|
48
|
-
breakpoints.push(_breakpointEntry(`tools[${index}]`, tool.cache_control));
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
return breakpoints;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
class AnthropicCacheConfigInstrumentor {
|
|
55
|
-
constructor() {
|
|
56
|
-
// [instrumentation, methodName, originalFunction] for uninstrument().
|
|
57
|
-
this._patched = [];
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
// No-op (and never throws) if the instrumentor's internals have changed shape —
|
|
61
|
-
// the worst case is missing cache-config capture, never a crash.
|
|
62
|
-
instrument(instrumentation) {
|
|
63
|
-
if (!instrumentation) return;
|
|
64
|
-
const startSpanOriginal = instrumentation.startSpan;
|
|
65
|
-
if (typeof startSpanOriginal !== 'function') return;
|
|
66
|
-
|
|
67
|
-
instrumentation.startSpan = function startSpanWithCacheConfig(request) {
|
|
68
|
-
const span = startSpanOriginal.call(this, request);
|
|
69
|
-
try {
|
|
70
|
-
const breakpoints = extractCacheBreakpoints((request && request.params) || {});
|
|
71
|
-
if (breakpoints.length) {
|
|
72
|
-
span.setAttribute(BREAKPOINTS_ATTR, JSON.stringify(breakpoints));
|
|
73
|
-
}
|
|
74
|
-
} catch {
|
|
75
|
-
// Never break span creation over an enrichment failure.
|
|
76
|
-
}
|
|
77
|
-
return span;
|
|
78
|
-
};
|
|
79
|
-
this._patched.push([instrumentation, 'startSpan', startSpanOriginal]);
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
uninstrument() {
|
|
83
|
-
for (const [owner, methodName, original] of this._patched) {
|
|
84
|
-
owner[methodName] = original;
|
|
85
|
-
}
|
|
86
|
-
this._patched = [];
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
module.exports = { AnthropicCacheConfigInstrumentor, extractCacheBreakpoints };
|
|
@@ -1,121 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Streamed stop-reason enrichment for the Anthropic chat span.
|
|
5
|
-
*
|
|
6
|
-
* `@traceloop/instrumentation-anthropic` accumulates a streamed response into a
|
|
7
|
-
* result object but never reads the `message_delta` chunk's `delta.stop_reason`,
|
|
8
|
-
* so streamed spans format their output message with an empty `finish_reason`.
|
|
9
|
-
*
|
|
10
|
-
* `_streamingWrapPromise(client, moduleExports, { span, type, promise })`
|
|
11
|
-
* returns `new moduleExports.APIPromise(...)` whose parse step wraps the real
|
|
12
|
-
* SDK stream with the instrumentor's accumulating iterator. This complement
|
|
13
|
-
* hands it a patched `moduleExports` whose APIPromise interposes on that parse
|
|
14
|
-
* step, observing the chunks (outside the accumulating iterator, so every chunk
|
|
15
|
-
* is seen before the iterator finishes) to capture the stop reason — which is
|
|
16
|
-
* then injected into the accumulated result just before `_endSpan` formats the
|
|
17
|
-
* output message.
|
|
18
|
-
*/
|
|
19
|
-
|
|
20
|
-
class AnthropicStreamingStopReasonInstrumentor {
|
|
21
|
-
constructor() {
|
|
22
|
-
// [instrumentation, methodName, originalFunction] for uninstrument().
|
|
23
|
-
this._patched = [];
|
|
24
|
-
// span -> stop_reason captured from the stream's message_delta chunk.
|
|
25
|
-
this._stopReasonBySpan = new WeakMap();
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
// No-op (and never throws) if the instrumentor's internals have changed shape —
|
|
29
|
-
// the worst case is an empty streamed finish_reason, never a crash.
|
|
30
|
-
instrument(instrumentation) {
|
|
31
|
-
if (!instrumentation) return;
|
|
32
|
-
|
|
33
|
-
const stopReasonBySpan = this._stopReasonBySpan;
|
|
34
|
-
|
|
35
|
-
async function* observeStopReason(stream, span) {
|
|
36
|
-
for await (const chunk of stream) {
|
|
37
|
-
try {
|
|
38
|
-
if (
|
|
39
|
-
chunk &&
|
|
40
|
-
chunk.type === 'message_delta' &&
|
|
41
|
-
chunk.delta &&
|
|
42
|
-
chunk.delta.stop_reason != null
|
|
43
|
-
) {
|
|
44
|
-
stopReasonBySpan.set(span, chunk.delta.stop_reason);
|
|
45
|
-
}
|
|
46
|
-
} catch {
|
|
47
|
-
// Never break the caller's stream over an enrichment failure.
|
|
48
|
-
}
|
|
49
|
-
yield chunk;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
const streamOriginal = instrumentation._streamingWrapPromise;
|
|
54
|
-
if (typeof streamOriginal === 'function') {
|
|
55
|
-
instrumentation._streamingWrapPromise = function streamWithStopReason(
|
|
56
|
-
client,
|
|
57
|
-
moduleExports,
|
|
58
|
-
opts
|
|
59
|
-
) {
|
|
60
|
-
const span = opts && opts.span;
|
|
61
|
-
if (!span || !moduleExports || typeof moduleExports.APIPromise !== 'function') {
|
|
62
|
-
return streamOriginal.call(this, client, moduleExports, opts);
|
|
63
|
-
}
|
|
64
|
-
class APIPromiseWithStopReason extends moduleExports.APIPromise {
|
|
65
|
-
constructor(promiseClient, responsePromise, parseResponse) {
|
|
66
|
-
super(promiseClient, responsePromise, async (parseClient, props) => {
|
|
67
|
-
const stream = await parseResponse(parseClient, props);
|
|
68
|
-
try {
|
|
69
|
-
if (
|
|
70
|
-
stream &&
|
|
71
|
-
typeof stream[Symbol.asyncIterator] === 'function' &&
|
|
72
|
-
typeof stream.constructor === 'function'
|
|
73
|
-
) {
|
|
74
|
-
return new stream.constructor(
|
|
75
|
-
() => observeStopReason(stream, span),
|
|
76
|
-
stream.controller
|
|
77
|
-
);
|
|
78
|
-
}
|
|
79
|
-
} catch {
|
|
80
|
-
// Fall through to the unobserved stream.
|
|
81
|
-
}
|
|
82
|
-
return stream;
|
|
83
|
-
});
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
|
-
// The SDK's module exports are non-writable, so the override is an own
|
|
87
|
-
// defined property shadowing the inherited one.
|
|
88
|
-
const patchedModuleExports = Object.create(moduleExports, {
|
|
89
|
-
APIPromise: { value: APIPromiseWithStopReason, configurable: true },
|
|
90
|
-
});
|
|
91
|
-
return streamOriginal.call(this, client, patchedModuleExports, opts);
|
|
92
|
-
};
|
|
93
|
-
this._patched.push([instrumentation, '_streamingWrapPromise', streamOriginal]);
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
const endSpanOriginal = instrumentation._endSpan;
|
|
97
|
-
if (typeof endSpanOriginal === 'function') {
|
|
98
|
-
instrumentation._endSpan = function endSpanWithStopReason(args) {
|
|
99
|
-
try {
|
|
100
|
-
const captured = args && args.span && stopReasonBySpan.get(args.span);
|
|
101
|
-
if (captured != null && args.result && args.result.stop_reason == null) {
|
|
102
|
-
args.result.stop_reason = captured;
|
|
103
|
-
}
|
|
104
|
-
} catch {
|
|
105
|
-
// Never break span finalization over an enrichment failure.
|
|
106
|
-
}
|
|
107
|
-
return endSpanOriginal.call(this, args);
|
|
108
|
-
};
|
|
109
|
-
this._patched.push([instrumentation, '_endSpan', endSpanOriginal]);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
uninstrument() {
|
|
114
|
-
for (const [owner, methodName, original] of this._patched) {
|
|
115
|
-
owner[methodName] = original;
|
|
116
|
-
}
|
|
117
|
-
this._patched = [];
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
module.exports = { AnthropicStreamingStopReasonInstrumentor };
|
|
@@ -1,55 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Tool-definitions enrichment for the Anthropic chat span.
|
|
5
|
-
*
|
|
6
|
-
* `@traceloop/instrumentation-anthropic` records the request model/temperature
|
|
7
|
-
* attributes in `startSpan({ type, params })` but never the request's `tools`,
|
|
8
|
-
* so tool-using calls carry no `gen_ai.tool.definitions`. Wrap `startSpan` to
|
|
9
|
-
* stamp them in the same `{name, description, input_schema}` shape the request
|
|
10
|
-
* uses. The span processor strips the attribute when message-content capture is
|
|
11
|
-
* disabled.
|
|
12
|
-
*/
|
|
13
|
-
|
|
14
|
-
class AnthropicToolDefinitionsInstrumentor {
|
|
15
|
-
constructor() {
|
|
16
|
-
// [instrumentation, methodName, originalFunction] for uninstrument().
|
|
17
|
-
this._patched = [];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
// No-op (and never throws) if the instrumentor's internals have changed shape —
|
|
21
|
-
// the worst case is missing tool definitions, never a crash.
|
|
22
|
-
instrument(instrumentation) {
|
|
23
|
-
if (!instrumentation) return;
|
|
24
|
-
const startSpanOriginal = instrumentation.startSpan;
|
|
25
|
-
if (typeof startSpanOriginal !== 'function') return;
|
|
26
|
-
|
|
27
|
-
instrumentation.startSpan = function startSpanWithToolDefinitions(request) {
|
|
28
|
-
const span = startSpanOriginal.call(this, request);
|
|
29
|
-
try {
|
|
30
|
-
const tools = request && request.params && request.params.tools;
|
|
31
|
-
if (Array.isArray(tools) && tools.length) {
|
|
32
|
-
// cache_control is dropped from the stamped definitions — the
|
|
33
|
-
// breakpoint is captured separately in cache_config.
|
|
34
|
-
const definitions = tools.map(
|
|
35
|
-
({ cache_control: _cacheControl, ...definition }) => definition
|
|
36
|
-
);
|
|
37
|
-
span.setAttribute('gen_ai.tool.definitions', JSON.stringify(definitions));
|
|
38
|
-
}
|
|
39
|
-
} catch {
|
|
40
|
-
// Never break span creation over an enrichment failure.
|
|
41
|
-
}
|
|
42
|
-
return span;
|
|
43
|
-
};
|
|
44
|
-
this._patched.push([instrumentation, 'startSpan', startSpanOriginal]);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
uninstrument() {
|
|
48
|
-
for (const [owner, methodName, original] of this._patched) {
|
|
49
|
-
owner[methodName] = original;
|
|
50
|
-
}
|
|
51
|
-
this._patched = [];
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
module.exports = { AnthropicToolDefinitionsInstrumentor };
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Anthropic telemetry complement — the registered orchestrator.
|
|
5
|
-
*
|
|
6
|
-
* Wires the weflayr-supplied patches the traceloop Anthropic instrumentor
|
|
7
|
-
* misses: cached-prompt token counts on the chat span (it reads them off the
|
|
8
|
-
* response but writes no `gen_ai.usage.cache_*` attribute), the request's tool
|
|
9
|
-
* definitions, and the streamed stop reason (its stream accumulator drops it,
|
|
10
|
-
* leaving an empty finish_reason on the output message).
|
|
11
|
-
*/
|
|
12
|
-
|
|
13
|
-
const { AnthropicCacheConfigInstrumentor } = require('./get_cache_config_telemetry');
|
|
14
|
-
const { AnthropicPromptCachingInstrumentor } = require('./get_cache_and_reasoning_telemetry');
|
|
15
|
-
const {
|
|
16
|
-
AnthropicStreamingStopReasonInstrumentor,
|
|
17
|
-
} = require('./get_streaming_stop_reason_telemetry');
|
|
18
|
-
const { AnthropicToolDefinitionsInstrumentor } = require('./get_tool_definitions_telemetry');
|
|
19
|
-
|
|
20
|
-
class AnthropicTelemetryInstrumentor {
|
|
21
|
-
constructor() {
|
|
22
|
-
this._subInstrumentors = [
|
|
23
|
-
new AnthropicPromptCachingInstrumentor(),
|
|
24
|
-
new AnthropicCacheConfigInstrumentor(),
|
|
25
|
-
new AnthropicStreamingStopReasonInstrumentor(),
|
|
26
|
-
new AnthropicToolDefinitionsInstrumentor(),
|
|
27
|
-
];
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
instrument(instrumentation) {
|
|
31
|
-
for (const sub of this._subInstrumentors) sub.instrument(instrumentation);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
uninstrument() {
|
|
35
|
-
for (const sub of this._subInstrumentors) sub.uninstrument();
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
module.exports = { AnthropicTelemetryInstrumentor };
|