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
|
@@ -11,9 +11,7 @@
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.makeEndpoint = makeEndpoint;
|
|
13
13
|
const caseConversion_1 = require("./caseConversion");
|
|
14
|
-
function makeEndpoint(
|
|
15
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
16
|
-
wireFn) {
|
|
14
|
+
function makeEndpoint(wireFn) {
|
|
17
15
|
return async (options) => {
|
|
18
16
|
const wireOptions = { ...options };
|
|
19
17
|
for (const key of ['body', 'path', 'query']) {
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type SetupOptions } from './setup';
|
|
2
|
+
export declare const AiSdk: Readonly<{
|
|
3
|
+
OPENAI: "openai";
|
|
4
|
+
ANTHROPIC: "anthropic";
|
|
5
|
+
BEDROCK: "bedrock";
|
|
6
|
+
COHERE: "cohere";
|
|
7
|
+
GOOGLE_GENAI: "google-genai";
|
|
8
|
+
ELEVENLABS: "elevenlabs";
|
|
9
|
+
VERCEL_AI_GATEWAY: "vercel_ai_gateway";
|
|
10
|
+
}>;
|
|
11
|
+
export type AiSdk = (typeof AiSdk)[keyof typeof AiSdk];
|
|
12
|
+
export declare const AIProviderName: Readonly<{
|
|
13
|
+
OPENAI: "openai";
|
|
14
|
+
AZURE_OPENAI: "azure";
|
|
15
|
+
ANTHROPIC: "anthropic";
|
|
16
|
+
BEDROCK: "bedrock";
|
|
17
|
+
COHERE: "cohere";
|
|
18
|
+
ELEVENLABS: "elevenlabs";
|
|
19
|
+
MISTRAL: "mistral";
|
|
20
|
+
VERCEL_AI_GATEWAY: "vercel_ai_gateway";
|
|
21
|
+
GEMINI: "gemini";
|
|
22
|
+
VERTEX: "vertex";
|
|
23
|
+
}>;
|
|
24
|
+
export type AIProviderName = (typeof AIProviderName)[keyof typeof AIProviderName];
|
|
25
|
+
interface RegistryEntry {
|
|
26
|
+
package: string;
|
|
27
|
+
requirePath?: string;
|
|
28
|
+
className?: string;
|
|
29
|
+
}
|
|
30
|
+
declare const REGISTRY: Record<string, RegistryEntry>;
|
|
31
|
+
export interface AutoInstrumentOptions extends Partial<SetupOptions> {
|
|
32
|
+
aiSdks: AiSdk | AiSdk[];
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Register an OTel Instrumentor for one or more LLM provider SDKs.
|
|
36
|
+
*
|
|
37
|
+
* Convenience: pass `apiKey` (+ other `setup()` options) here to skip a
|
|
38
|
+
* separate `weflayr.setup()` call. If `apiKey` is omitted, `setup()` must
|
|
39
|
+
* have been called beforehand.
|
|
40
|
+
*/
|
|
41
|
+
export declare function autoInstrument({ aiSdks, ...options }: AutoInstrumentOptions): Promise<void>;
|
|
42
|
+
export { REGISTRY };
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.REGISTRY = exports.AIProviderName = exports.AiSdk = void 0;
|
|
4
|
+
exports.autoInstrument = autoInstrument;
|
|
5
|
+
const instrumentation_1 = require("@opentelemetry/instrumentation");
|
|
6
|
+
const logger_1 = require("./logger");
|
|
7
|
+
const setup_1 = require("./setup");
|
|
8
|
+
exports.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
|
+
// Allowed values for `propagateMetadata({ providerName })`: the actual AI
|
|
18
|
+
// providers a call can be attributed to. Unlike AiSdk this names providers,
|
|
19
|
+
// not SDKs — google-genai is an SDK whose calls are labelled gemini or vertex,
|
|
20
|
+
// and mistral has no Node OTel instrumentor so it is reached through the
|
|
21
|
+
// OpenAI SDK (OpenAI-compatible endpoint) but reported as itself.
|
|
22
|
+
exports.AIProviderName = Object.freeze({
|
|
23
|
+
OPENAI: 'openai',
|
|
24
|
+
AZURE_OPENAI: 'azure',
|
|
25
|
+
ANTHROPIC: 'anthropic',
|
|
26
|
+
BEDROCK: 'bedrock',
|
|
27
|
+
COHERE: 'cohere',
|
|
28
|
+
ELEVENLABS: 'elevenlabs',
|
|
29
|
+
MISTRAL: 'mistral',
|
|
30
|
+
VERCEL_AI_GATEWAY: 'vercel_ai_gateway',
|
|
31
|
+
GEMINI: 'gemini',
|
|
32
|
+
VERTEX: 'vertex',
|
|
33
|
+
});
|
|
34
|
+
// The primary instrumentor for each provider SDK. Most are third-party
|
|
35
|
+
// traceloop packages, loaded by `package` name. Providers with no usable
|
|
36
|
+
// third-party instrumentor (e.g. ElevenLabs) instead carry a `requirePath` +
|
|
37
|
+
// `className` pointing at the instrumentor weflayr ships itself; `package` then
|
|
38
|
+
// names the provider SDK to suggest installing if its import fails.
|
|
39
|
+
const REGISTRY = {
|
|
40
|
+
[exports.AiSdk.OPENAI]: { package: '@traceloop/instrumentation-openai' },
|
|
41
|
+
[exports.AiSdk.ANTHROPIC]: { package: '@traceloop/instrumentation-anthropic' },
|
|
42
|
+
[exports.AiSdk.BEDROCK]: { package: '@traceloop/instrumentation-bedrock' },
|
|
43
|
+
[exports.AiSdk.COHERE]: { package: '@traceloop/instrumentation-cohere' },
|
|
44
|
+
[exports.AiSdk.GOOGLE_GENAI]: { package: '@traceloop/instrumentation-google-generativeai' },
|
|
45
|
+
[exports.AiSdk.ELEVENLABS]: {
|
|
46
|
+
package: '@elevenlabs/elevenlabs-js',
|
|
47
|
+
requirePath: './instrumentation/elevenlabs/full_instrumentation',
|
|
48
|
+
className: 'ElevenLabsInstrumentor',
|
|
49
|
+
},
|
|
50
|
+
[exports.AiSdk.VERCEL_AI_GATEWAY]: {
|
|
51
|
+
package: 'ai',
|
|
52
|
+
requirePath: './instrumentation/vercel/full_instrumentation',
|
|
53
|
+
className: 'VercelAiSdkInstrumentor',
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
exports.REGISTRY = REGISTRY;
|
|
57
|
+
// One complementary instrumentor per provider: a `set_telemetry_attributes`
|
|
58
|
+
// orchestrator under `instrumentation/<provider>/` that wires every weflayr patch
|
|
59
|
+
// the traceloop instrumentor misses (the orchestrator itself groups the per-patch
|
|
60
|
+
// `get_*` files, so a single entry per provider suffices).
|
|
61
|
+
const COMPLEMENTARY_INSTRUMENTOR = {
|
|
62
|
+
[exports.AiSdk.OPENAI]: {
|
|
63
|
+
requirePath: './instrumentation/openai/set_telemetry_attributes',
|
|
64
|
+
className: 'OpenAITelemetryInstrumentor',
|
|
65
|
+
},
|
|
66
|
+
[exports.AiSdk.ANTHROPIC]: {
|
|
67
|
+
requirePath: './instrumentation/anthropic/set_telemetry_attributes',
|
|
68
|
+
className: 'AnthropicTelemetryInstrumentor',
|
|
69
|
+
},
|
|
70
|
+
[exports.AiSdk.BEDROCK]: {
|
|
71
|
+
requirePath: './instrumentation/bedrock/set_telemetry_attributes',
|
|
72
|
+
className: 'BedrockTelemetryInstrumentor',
|
|
73
|
+
},
|
|
74
|
+
[exports.AiSdk.COHERE]: {
|
|
75
|
+
requirePath: './instrumentation/cohere/set_telemetry_attributes',
|
|
76
|
+
className: 'CohereTelemetryInstrumentor',
|
|
77
|
+
},
|
|
78
|
+
[exports.AiSdk.GOOGLE_GENAI]: {
|
|
79
|
+
requirePath: './instrumentation/google/set_telemetry_attributes',
|
|
80
|
+
className: 'GoogleTelemetryInstrumentor',
|
|
81
|
+
},
|
|
82
|
+
};
|
|
83
|
+
const SETUP_OPTION_KEYS = [
|
|
84
|
+
'apiKey',
|
|
85
|
+
'baseUrl',
|
|
86
|
+
'defaultTags',
|
|
87
|
+
'exportMode',
|
|
88
|
+
'mask',
|
|
89
|
+
'captureMessageContent',
|
|
90
|
+
'warnOnExportError',
|
|
91
|
+
];
|
|
92
|
+
function _instantiateInstrumentation(instrumentationPkg) {
|
|
93
|
+
for (const value of Object.values(instrumentationPkg)) {
|
|
94
|
+
if (typeof value === 'function' && /Instrumentation$/.test(value.name)) {
|
|
95
|
+
return new value();
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
if (typeof instrumentationPkg.default === 'function')
|
|
99
|
+
return new instrumentationPkg.default();
|
|
100
|
+
throw new Error('No Instrumentation class found in module exports');
|
|
101
|
+
}
|
|
102
|
+
async function _instrumentAiSdk(aiSdk) {
|
|
103
|
+
if (!(aiSdk in REGISTRY)) {
|
|
104
|
+
throw new Error(`weflayr.autoInstrument: unknown provider "${aiSdk}". Known: ${Object.keys(REGISTRY).join(', ')}`);
|
|
105
|
+
}
|
|
106
|
+
const entry = REGISTRY[aiSdk];
|
|
107
|
+
if (entry.requirePath) {
|
|
108
|
+
// No usable third-party instrumentor — use the hand-written one bundled
|
|
109
|
+
// with weflayr (it covers every endpoint of the provider).
|
|
110
|
+
const Instrumentor = require(entry.requirePath)[entry.className];
|
|
111
|
+
new Instrumentor().instrument();
|
|
112
|
+
(0, logger_1.debug)('autoInstrument: registered aiSdk=%s package=%s', aiSdk, entry.package);
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
let instrumentationPkg;
|
|
116
|
+
try {
|
|
117
|
+
instrumentationPkg = require(entry.package);
|
|
118
|
+
}
|
|
119
|
+
catch (err) {
|
|
120
|
+
throw new Error(`weflayr.autoInstrument("${aiSdk}"): failed to load "${entry.package}". ` +
|
|
121
|
+
`Install it with: npm install ${entry.package}\nUnderlying error: ${err.message}`);
|
|
122
|
+
}
|
|
123
|
+
const instrumentation = _instantiateInstrumentation(instrumentationPkg);
|
|
124
|
+
(0, instrumentation_1.registerInstrumentations)({ instrumentations: [instrumentation] });
|
|
125
|
+
const complementary = COMPLEMENTARY_INSTRUMENTOR[aiSdk];
|
|
126
|
+
if (complementary) {
|
|
127
|
+
const InstrumentorClass = require(complementary.requirePath)[complementary.className];
|
|
128
|
+
new InstrumentorClass().instrument(instrumentation);
|
|
129
|
+
}
|
|
130
|
+
(0, logger_1.debug)('autoInstrument: registered aiSdk=%s package=%s', aiSdk, entry.package);
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Register an OTel Instrumentor for one or more LLM provider SDKs.
|
|
134
|
+
*
|
|
135
|
+
* Convenience: pass `apiKey` (+ other `setup()` options) here to skip a
|
|
136
|
+
* separate `weflayr.setup()` call. If `apiKey` is omitted, `setup()` must
|
|
137
|
+
* have been called beforehand.
|
|
138
|
+
*/
|
|
139
|
+
async function autoInstrument({ aiSdks, ...options }) {
|
|
140
|
+
if (aiSdks === undefined) {
|
|
141
|
+
throw new Error('weflayr.autoInstrument: `aiSdks` is required.');
|
|
142
|
+
}
|
|
143
|
+
if (!setup_1._state.processor) {
|
|
144
|
+
// setup() picks up WEFLAYR_API_KEY from the env if not passed here.
|
|
145
|
+
const setupOptions = {};
|
|
146
|
+
for (const key of SETUP_OPTION_KEYS) {
|
|
147
|
+
if (options[key] !== undefined)
|
|
148
|
+
setupOptions[key] = options[key];
|
|
149
|
+
}
|
|
150
|
+
(0, setup_1.setup)(setupOptions);
|
|
151
|
+
}
|
|
152
|
+
const list = Array.isArray(aiSdks) ? aiSdks : [aiSdks];
|
|
153
|
+
for (const aiSdk of list) {
|
|
154
|
+
await _instrumentAiSdk(aiSdk);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { setup, flush, type SetupOptions } from './setup';
|
|
2
|
+
import { autoInstrument, AiSdk, AIProviderName } from './auto-instrument';
|
|
3
|
+
import { propagateMetadata, type PropagateMetadataOptions } from './otel/propagation';
|
|
4
|
+
import type { Tags, OtelSpanAttributes } from './otel/span-processor';
|
|
5
|
+
import * as api from './api';
|
|
6
|
+
export { setup, flush, autoInstrument, AiSdk, AIProviderName, propagateMetadata, api };
|
|
7
|
+
export type { SetupOptions, PropagateMetadataOptions, Tags, OtelSpanAttributes };
|
|
8
|
+
export declare const client: typeof api.client;
|
|
9
|
+
export type { ApiClientOptions } from './api';
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.client = exports.api = exports.propagateMetadata = exports.AIProviderName = exports.AiSdk = exports.autoInstrument = exports.flush = exports.setup = void 0;
|
|
37
|
+
const setup_1 = require("./setup");
|
|
38
|
+
Object.defineProperty(exports, "setup", { enumerable: true, get: function () { return setup_1.setup; } });
|
|
39
|
+
Object.defineProperty(exports, "flush", { enumerable: true, get: function () { return setup_1.flush; } });
|
|
40
|
+
const auto_instrument_1 = require("./auto-instrument");
|
|
41
|
+
Object.defineProperty(exports, "autoInstrument", { enumerable: true, get: function () { return auto_instrument_1.autoInstrument; } });
|
|
42
|
+
Object.defineProperty(exports, "AiSdk", { enumerable: true, get: function () { return auto_instrument_1.AiSdk; } });
|
|
43
|
+
Object.defineProperty(exports, "AIProviderName", { enumerable: true, get: function () { return auto_instrument_1.AIProviderName; } });
|
|
44
|
+
const propagation_1 = require("./otel/propagation");
|
|
45
|
+
Object.defineProperty(exports, "propagateMetadata", { enumerable: true, get: function () { return propagation_1.propagateMetadata; } });
|
|
46
|
+
// Public-API client (revenue, key metrics, customer tags).
|
|
47
|
+
const api = __importStar(require("./api"));
|
|
48
|
+
exports.api = api;
|
|
49
|
+
exports.client = api.client;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cached-prompt token enrichment complement for the non-streamed Anthropic path.
|
|
3
|
+
*
|
|
4
|
+
* `@traceloop/instrumentation-anthropic` reads the response's
|
|
5
|
+
* `usage.cache_creation_input_tokens` / `cache_read_input_tokens` but never writes
|
|
6
|
+
* them to a `gen_ai.usage.cache_*` span attribute (its semantic conventions define
|
|
7
|
+
* no such key), so cache-hit spans carry no cached-token counts. This stamps the
|
|
8
|
+
* underscored attributes the worker reads. (The Python instrumentor emits them
|
|
9
|
+
* natively, under the dotted `cache_read.input_tokens` form, which the worker also
|
|
10
|
+
* accepts.)
|
|
11
|
+
*
|
|
12
|
+
* It wraps the instrumentor instance's `_endSpan({ span, type, result })`, which
|
|
13
|
+
* finalizes the span after the response resolves, letting us read `result.usage`
|
|
14
|
+
* while the span is still open.
|
|
15
|
+
*/
|
|
16
|
+
export declare class AnthropicPromptCachingInstrumentor {
|
|
17
|
+
private _patched;
|
|
18
|
+
instrument(instrumentation: any): void;
|
|
19
|
+
uninstrument(): void;
|
|
20
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Cached-prompt token enrichment complement for the non-streamed Anthropic path.
|
|
4
|
+
*
|
|
5
|
+
* `@traceloop/instrumentation-anthropic` reads the response's
|
|
6
|
+
* `usage.cache_creation_input_tokens` / `cache_read_input_tokens` but never writes
|
|
7
|
+
* them to a `gen_ai.usage.cache_*` span attribute (its semantic conventions define
|
|
8
|
+
* no such key), so cache-hit spans carry no cached-token counts. This stamps the
|
|
9
|
+
* underscored attributes the worker reads. (The Python instrumentor emits them
|
|
10
|
+
* natively, under the dotted `cache_read.input_tokens` form, which the worker also
|
|
11
|
+
* accepts.)
|
|
12
|
+
*
|
|
13
|
+
* It wraps the instrumentor instance's `_endSpan({ span, type, result })`, which
|
|
14
|
+
* finalizes the span after the response resolves, letting us read `result.usage`
|
|
15
|
+
* while the span is still open.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.AnthropicPromptCachingInstrumentor = void 0;
|
|
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
|
+
// Stamp `usage.cache_creation` verbatim (the written tokens per TTL, billed at
|
|
25
|
+
// different rates); skipped when nothing was written so non-caching calls
|
|
26
|
+
// carry no attribute. The normalizer owns the mapping to TTL tiers.
|
|
27
|
+
function _setCacheCreation(span, cacheCreation) {
|
|
28
|
+
if (!cacheCreation)
|
|
29
|
+
return;
|
|
30
|
+
if (!Object.values(cacheCreation).some(Boolean))
|
|
31
|
+
return;
|
|
32
|
+
span.setAttribute(CACHE_CREATION_ATTR, JSON.stringify(cacheCreation));
|
|
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())
|
|
42
|
+
return;
|
|
43
|
+
if (usage.cache_read_input_tokens) {
|
|
44
|
+
span.setAttribute(CACHE_READ_INPUT_TOKENS_ATTR, usage.cache_read_input_tokens);
|
|
45
|
+
}
|
|
46
|
+
if (usage.cache_creation_input_tokens) {
|
|
47
|
+
span.setAttribute(CACHE_CREATION_INPUT_TOKENS_ATTR, usage.cache_creation_input_tokens);
|
|
48
|
+
}
|
|
49
|
+
_setCacheCreation(span, usage.cache_creation);
|
|
50
|
+
if (typeof usage.input_tokens === 'number') {
|
|
51
|
+
span.setAttribute(INPUT_TOKENS_ATTR, usage.input_tokens);
|
|
52
|
+
}
|
|
53
|
+
const thinking = usage.output_tokens_details && usage.output_tokens_details.thinking_tokens;
|
|
54
|
+
if (thinking) {
|
|
55
|
+
span.setAttribute(THINKING_TOKENS_ATTR, thinking);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
class AnthropicPromptCachingInstrumentor {
|
|
59
|
+
// [instrumentation, methodName, originalFunction] for uninstrument().
|
|
60
|
+
_patched = [];
|
|
61
|
+
// No-op (and never throws) if the instrumentor's internals have changed shape —
|
|
62
|
+
// the worst case is missing cached-token counts, never a crash.
|
|
63
|
+
instrument(instrumentation) {
|
|
64
|
+
if (!instrumentation)
|
|
65
|
+
return;
|
|
66
|
+
// Non-streamed: the instrumentor finalizes via `_endSpan({ span, result })`.
|
|
67
|
+
const endSpanOriginal = instrumentation._endSpan;
|
|
68
|
+
if (typeof endSpanOriginal === 'function') {
|
|
69
|
+
instrumentation._endSpan = function endSpanWithCache(args) {
|
|
70
|
+
try {
|
|
71
|
+
_setUsage(args && args.span, args && args.result && args.result.usage);
|
|
72
|
+
}
|
|
73
|
+
catch {
|
|
74
|
+
// Never break span finalization over an enrichment failure.
|
|
75
|
+
}
|
|
76
|
+
return endSpanOriginal.call(this, args);
|
|
77
|
+
};
|
|
78
|
+
this._patched.push([instrumentation, '_endSpan', endSpanOriginal]);
|
|
79
|
+
}
|
|
80
|
+
// Streamed: cache + raw input arrive in the `message_start` (and `message_delta`)
|
|
81
|
+
// usage events; observe the chunks as they pass through the streaming handler.
|
|
82
|
+
const streamOriginal = instrumentation._streamingWrapPromise;
|
|
83
|
+
if (typeof streamOriginal === 'function') {
|
|
84
|
+
instrumentation._streamingWrapPromise = function streamWithCache(...streamArgs) {
|
|
85
|
+
const opts = streamArgs[streamArgs.length - 1];
|
|
86
|
+
const span = opts && opts.span;
|
|
87
|
+
const result = streamOriginal.apply(this, streamArgs);
|
|
88
|
+
if (!span || !result || typeof result[Symbol.asyncIterator] !== 'function')
|
|
89
|
+
return result;
|
|
90
|
+
return (async function* observeCache() {
|
|
91
|
+
for await (const chunk of result) {
|
|
92
|
+
try {
|
|
93
|
+
const usage = (chunk && chunk.type === 'message_start' && chunk.message && chunk.message.usage) ||
|
|
94
|
+
(chunk && chunk.usage);
|
|
95
|
+
_setUsage(span, usage);
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// Never break the caller's stream over an enrichment failure.
|
|
99
|
+
}
|
|
100
|
+
yield chunk;
|
|
101
|
+
}
|
|
102
|
+
})();
|
|
103
|
+
};
|
|
104
|
+
this._patched.push([instrumentation, '_streamingWrapPromise', streamOriginal]);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
uninstrument() {
|
|
108
|
+
for (const [owner, methodName, original] of this._patched) {
|
|
109
|
+
owner[methodName] = original;
|
|
110
|
+
}
|
|
111
|
+
this._patched = [];
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.AnthropicPromptCachingInstrumentor = AnthropicPromptCachingInstrumentor;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Request-side prompt-caching config capture for Anthropic spans.
|
|
3
|
+
*
|
|
4
|
+
* Anthropic callers opt into caching by placing `cache_control` breakpoints on
|
|
5
|
+
* content blocks (`system` text blocks, message content blocks, tool
|
|
6
|
+
* definitions) or as a top-level request parameter (automatic caching: the
|
|
7
|
+
* provider places the breakpoint on the last cacheable block), each with an
|
|
8
|
+
* optional `ttl` ("5m" default, or "1h"). The traceloop instrumentor never
|
|
9
|
+
* records them, so cache-hit analysis cannot tell what the request asked to
|
|
10
|
+
* 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]`, `tools[i]` or `auto_last_block` (the top-level
|
|
16
|
+
* parameter) and `ttl` is the raw cache_control string, omitted when the
|
|
17
|
+
* breakpoint sets none; the normalizer owns the TTL vocabulary.
|
|
18
|
+
*/
|
|
19
|
+
export interface CacheBreakpoint {
|
|
20
|
+
location: string;
|
|
21
|
+
ttl?: string;
|
|
22
|
+
}
|
|
23
|
+
export declare function extractCacheBreakpoints(params: any): CacheBreakpoint[];
|
|
24
|
+
export declare class AnthropicCacheConfigInstrumentor {
|
|
25
|
+
private _patched;
|
|
26
|
+
instrument(instrumentation: any): void;
|
|
27
|
+
uninstrument(): void;
|
|
28
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Request-side prompt-caching config capture for Anthropic spans.
|
|
4
|
+
*
|
|
5
|
+
* Anthropic callers opt into caching by placing `cache_control` breakpoints on
|
|
6
|
+
* content blocks (`system` text blocks, message content blocks, tool
|
|
7
|
+
* definitions) or as a top-level request parameter (automatic caching: the
|
|
8
|
+
* provider places the breakpoint on the last cacheable block), each with an
|
|
9
|
+
* optional `ttl` ("5m" default, or "1h"). The traceloop instrumentor never
|
|
10
|
+
* records them, so cache-hit analysis cannot tell what the request asked to
|
|
11
|
+
* cache or for how long.
|
|
12
|
+
*
|
|
13
|
+
* Wrap `startSpan({ type, params })` (covering the streamed and non-streamed
|
|
14
|
+
* paths) to stamp every breakpoint found in the request as
|
|
15
|
+
* `weflayr.cache.breakpoints`: a JSON list of `{location, ttl}` where location
|
|
16
|
+
* is `system`, `messages[i]`, `tools[i]` or `auto_last_block` (the top-level
|
|
17
|
+
* parameter) and `ttl` is the raw cache_control string, omitted when the
|
|
18
|
+
* breakpoint sets none; the normalizer owns the TTL vocabulary.
|
|
19
|
+
*/
|
|
20
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
|
+
exports.AnthropicCacheConfigInstrumentor = void 0;
|
|
22
|
+
exports.extractCacheBreakpoints = extractCacheBreakpoints;
|
|
23
|
+
const BREAKPOINTS_ATTR = 'weflayr.cache.breakpoints';
|
|
24
|
+
// A breakpoint as location + the raw cache_control `ttl` string, omitted when
|
|
25
|
+
// the request sets none.
|
|
26
|
+
function _breakpointEntry(location, cacheControl) {
|
|
27
|
+
const ttl = cacheControl && cacheControl.ttl;
|
|
28
|
+
return ttl ? { location, ttl: String(ttl) } : { location };
|
|
29
|
+
}
|
|
30
|
+
function _cacheControlsInBlocks(blocks) {
|
|
31
|
+
if (!Array.isArray(blocks))
|
|
32
|
+
return [];
|
|
33
|
+
return blocks.map((block) => block && block.cache_control).filter(Boolean);
|
|
34
|
+
}
|
|
35
|
+
// Every `cache_control` breakpoint in the request, as location + the raw
|
|
36
|
+
// `ttl` string (omitted when the breakpoint sets none).
|
|
37
|
+
function extractCacheBreakpoints(params) {
|
|
38
|
+
const breakpoints = [];
|
|
39
|
+
for (const cacheControl of _cacheControlsInBlocks(params.system)) {
|
|
40
|
+
breakpoints.push(_breakpointEntry('system', cacheControl));
|
|
41
|
+
}
|
|
42
|
+
(params.messages || []).forEach((message, index) => {
|
|
43
|
+
for (const cacheControl of _cacheControlsInBlocks(message && message.content)) {
|
|
44
|
+
breakpoints.push(_breakpointEntry(`messages[${index}]`, cacheControl));
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
(params.tools || []).forEach((tool, index) => {
|
|
48
|
+
if (tool && tool.cache_control) {
|
|
49
|
+
breakpoints.push(_breakpointEntry(`tools[${index}]`, tool.cache_control));
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
if (params.cache_control) {
|
|
53
|
+
breakpoints.push(_breakpointEntry('auto_last_block', params.cache_control));
|
|
54
|
+
}
|
|
55
|
+
return breakpoints;
|
|
56
|
+
}
|
|
57
|
+
class AnthropicCacheConfigInstrumentor {
|
|
58
|
+
// [instrumentation, methodName, originalFunction] for uninstrument().
|
|
59
|
+
_patched = [];
|
|
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)
|
|
64
|
+
return;
|
|
65
|
+
const startSpanOriginal = instrumentation.startSpan;
|
|
66
|
+
if (typeof startSpanOriginal !== 'function')
|
|
67
|
+
return;
|
|
68
|
+
instrumentation.startSpan = function startSpanWithCacheConfig(request) {
|
|
69
|
+
const span = startSpanOriginal.call(this, request);
|
|
70
|
+
try {
|
|
71
|
+
const breakpoints = extractCacheBreakpoints((request && request.params) || {});
|
|
72
|
+
if (breakpoints.length) {
|
|
73
|
+
span.setAttribute(BREAKPOINTS_ATTR, JSON.stringify(breakpoints));
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
catch {
|
|
77
|
+
// Never break span creation over an enrichment failure.
|
|
78
|
+
}
|
|
79
|
+
return span;
|
|
80
|
+
};
|
|
81
|
+
this._patched.push([instrumentation, 'startSpan', startSpanOriginal]);
|
|
82
|
+
}
|
|
83
|
+
uninstrument() {
|
|
84
|
+
// Restore newest first, so a double instrument() unwinds back to the
|
|
85
|
+
// true original instead of reinstalling the first wrapper.
|
|
86
|
+
for (const [owner, methodName, original] of this._patched.slice().reverse()) {
|
|
87
|
+
owner[methodName] = original;
|
|
88
|
+
}
|
|
89
|
+
this._patched = [];
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
exports.AnthropicCacheConfigInstrumentor = AnthropicCacheConfigInstrumentor;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Streamed-accumulation gap filling for the Anthropic chat span.
|
|
3
|
+
*
|
|
4
|
+
* `@traceloop/instrumentation-anthropic` accumulates a streamed response into a
|
|
5
|
+
* result object but drops two things on the way:
|
|
6
|
+
* - the `message_delta` chunk's `delta.stop_reason`, so streamed spans format
|
|
7
|
+
* their output message with an empty `finish_reason`, and
|
|
8
|
+
* - the `content_block_delta` chunks' `input_json_delta` fragments, so a
|
|
9
|
+
* streamed tool call's `tool_call` part carries no `arguments`.
|
|
10
|
+
*
|
|
11
|
+
* `_streamingWrapPromise(client, moduleExports, { span, type, promise })`
|
|
12
|
+
* returns `new moduleExports.APIPromise(...)` whose parse step wraps the real
|
|
13
|
+
* SDK stream with the instrumentor's accumulating iterator. This complement
|
|
14
|
+
* hands it a patched `moduleExports` whose APIPromise interposes on that parse
|
|
15
|
+
* step, observing the chunks (outside the accumulating iterator, so every chunk
|
|
16
|
+
* is seen before the iterator finishes) to capture both — which are then
|
|
17
|
+
* injected into the accumulated result just before `_endSpan` formats the
|
|
18
|
+
* output message.
|
|
19
|
+
*/
|
|
20
|
+
export declare class AnthropicStreamingAccumulationInstrumentor {
|
|
21
|
+
private _patched;
|
|
22
|
+
private _gapsBySpan;
|
|
23
|
+
instrument(instrumentation: any): void;
|
|
24
|
+
uninstrument(): void;
|
|
25
|
+
}
|