weflayr 0.29.1 → 0.31.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/dist/package.json +9 -9
- package/dist/src/api/generated/facade.gen.d.ts +1436 -10
- package/dist/src/api/generated/facade.gen.js +24 -1
- package/dist/src/api/generated/index.d.ts +2 -2
- package/dist/src/api/generated/index.js +24 -1
- package/dist/src/api/generated/sdk.gen.d.ts +97 -5
- package/dist/src/api/generated/sdk.gen.js +256 -5
- package/dist/src/api/generated/types.gen.d.ts +4527 -741
- package/dist/src/get-data-uri-mime-type.d.ts +8 -0
- package/dist/src/get-data-uri-mime-type.js +18 -0
- package/dist/src/instrumentation/anthropic/get_streaming_accumulation_telemetry.d.ts +6 -4
- package/dist/src/instrumentation/anthropic/get_streaming_accumulation_telemetry.js +22 -5
- package/dist/src/instrumentation/bedrock/{get_cache_telemetry.d.ts → get_cache_and_reasoning_telemetry.d.ts} +7 -0
- package/dist/src/instrumentation/bedrock/{get_cache_telemetry.js → get_cache_and_reasoning_telemetry.js} +25 -2
- package/dist/src/instrumentation/bedrock/get_input_message_content_telemetry.js +23 -16
- package/dist/src/instrumentation/bedrock/get_streaming_output_message_telemetry.d.ts +6 -0
- package/dist/src/instrumentation/bedrock/get_streaming_output_message_telemetry.js +18 -2
- package/dist/src/instrumentation/bedrock/set_telemetry_attributes.js +2 -2
- package/dist/src/instrumentation/cohere/get_input_message_content_telemetry.d.ts +2 -3
- package/dist/src/instrumentation/cohere/get_input_message_content_telemetry.js +6 -10
- package/dist/src/instrumentation/google/get_cache_operations_telemetry.js +7 -3
- package/dist/src/instrumentation/mistral/full_instrumentation.d.ts +10 -4
- package/dist/src/instrumentation/mistral/full_instrumentation.js +47 -14
- package/dist/src/instrumentation/mistral/get_input_message_content_telemetry.d.ts +1 -1
- package/dist/src/instrumentation/mistral/get_input_message_content_telemetry.js +5 -8
- package/dist/src/instrumentation/mistral/get_streamed_reasoning_telemetry.d.ts +38 -0
- package/dist/src/instrumentation/mistral/get_streamed_reasoning_telemetry.js +72 -0
- package/dist/src/instrumentation/openai/get_file_part_mime_type_telemetry.d.ts +5 -4
- package/dist/src/instrumentation/openai/get_file_part_mime_type_telemetry.js +14 -10
- package/dist/src/instrumentation/openai/get_reasoning_effort_telemetry.d.ts +16 -0
- package/dist/src/instrumentation/openai/get_reasoning_effort_telemetry.js +49 -0
- package/dist/src/instrumentation/openai/get_responses_telemetry.d.ts +7 -7
- package/dist/src/instrumentation/openai/get_responses_telemetry.js +11 -11
- package/dist/src/instrumentation/openai/get_streaming_usage.d.ts +5 -2
- package/dist/src/instrumentation/openai/get_streaming_usage.js +10 -2
- package/dist/src/instrumentation/openai/set_telemetry_attributes.d.ts +2 -1
- package/dist/src/instrumentation/openai/set_telemetry_attributes.js +4 -1
- package/dist/src/otel/exporter.d.ts +1 -1
- package/dist/src/otel/span-filter.d.ts +1 -1
- package/dist/src/otel/span-processor.d.ts +1 -1
- package/dist/src/otel/span-processor.js +3 -7
- package/dist/src/propagate-metadata-to-gateway.js +38 -11
- package/dist/src/setup.js +19 -7
- package/package.json +9 -9
- package/dist/src/otel/strip-media-payloads.d.ts +0 -26
- package/dist/src/otel/strip-media-payloads.js +0 -135
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "weflayr",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.0",
|
|
4
4
|
"description": "Weflayr JS/TS SDK — instrument any LLM client",
|
|
5
5
|
"main": "dist/src/index.js",
|
|
6
6
|
"types": "dist/src/index.d.ts",
|
|
@@ -27,15 +27,16 @@
|
|
|
27
27
|
"author": "Weflayr <contact@weflayr.com>",
|
|
28
28
|
"license": "Elastic-2.0",
|
|
29
29
|
"engines": {
|
|
30
|
-
"node": ">=
|
|
30
|
+
"node": ">=22.15.0"
|
|
31
31
|
},
|
|
32
32
|
"dependencies": {
|
|
33
|
-
"@opentelemetry/api": "^1.
|
|
34
|
-
"@opentelemetry/
|
|
35
|
-
"@opentelemetry/
|
|
36
|
-
"@opentelemetry/
|
|
37
|
-
"@opentelemetry/
|
|
38
|
-
"@opentelemetry/
|
|
33
|
+
"@opentelemetry/api": "^1.10.0",
|
|
34
|
+
"@opentelemetry/context-async-hooks": "^3.0.0",
|
|
35
|
+
"@opentelemetry/core": "^3.0.0",
|
|
36
|
+
"@opentelemetry/exporter-trace-otlp-http": "^0.300.0",
|
|
37
|
+
"@opentelemetry/instrumentation": "^0.300.0",
|
|
38
|
+
"@opentelemetry/resources": "^3.0.0",
|
|
39
|
+
"@opentelemetry/sdk-trace": "^3.0.0",
|
|
39
40
|
"async-retry": "^1.3.3"
|
|
40
41
|
},
|
|
41
42
|
"overrides": {
|
|
@@ -43,7 +44,6 @@
|
|
|
43
44
|
},
|
|
44
45
|
"devDependencies": {
|
|
45
46
|
"@hey-api/openapi-ts": "^0.99.0",
|
|
46
|
-
"@opentelemetry/context-async-hooks": "^2.8.0",
|
|
47
47
|
"@types/async-retry": "^1.4.9",
|
|
48
48
|
"@types/node": "^26.1.1",
|
|
49
49
|
"eslint": "^10.8.0",
|
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Remove media payloads (base64 images, audio, documents) from the message
|
|
3
|
-
* content span attributes, right before export.
|
|
4
|
-
*
|
|
5
|
-
* An inline image, audio clip or document reaches the span in one of five shapes,
|
|
6
|
-
* depending on the instrumentor: a `blob` part carrying the base64 bytes in
|
|
7
|
-
* `content` (OpenAI chat completions, Anthropic), a `uri` part whose uri is a
|
|
8
|
-
* `data:` URI holding the same bytes (OpenAI Responses), Anthropic's own content
|
|
9
|
-
* block with the bytes under `source.data` (Bedrock), an OpenAI `file` block
|
|
10
|
-
* with the bytes under `file.file_data`, an OpenAI Responses `input_audio` block
|
|
11
|
-
* kept whole under `content` with the bytes under `content.input_audio.data`. A single
|
|
12
|
-
* image is hundreds of kilobytes, so keeping it would make every event on the
|
|
13
|
-
* queue that much bigger for nothing: the payload is never read back.
|
|
14
|
-
*
|
|
15
|
-
* Each of those becomes `{"type": "blob", "mime_type": "<mime_type>"}`, the same
|
|
16
|
-
* byte-less stub the google, cohere and bedrock instrumentation complements
|
|
17
|
-
* build themselves: the analyses reading these messages still see that the call
|
|
18
|
-
* carried content the stored text does not. A `uri` part pointing at a hosted
|
|
19
|
-
* image is a reference, not a payload, and is kept as is.
|
|
20
|
-
*/
|
|
21
|
-
import type { OtelSpanAttributes } from './span-processor';
|
|
22
|
-
/**
|
|
23
|
-
* Rewrite in place every message content attribute of `attributes` that carries
|
|
24
|
-
* media bytes.
|
|
25
|
-
*/
|
|
26
|
-
export declare function stripMediaPayloads(attributes: OtelSpanAttributes): void;
|
|
@@ -1,135 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Remove media payloads (base64 images, audio, documents) from the message
|
|
4
|
-
* content span attributes, right before export.
|
|
5
|
-
*
|
|
6
|
-
* An inline image, audio clip or document reaches the span in one of five shapes,
|
|
7
|
-
* depending on the instrumentor: a `blob` part carrying the base64 bytes in
|
|
8
|
-
* `content` (OpenAI chat completions, Anthropic), a `uri` part whose uri is a
|
|
9
|
-
* `data:` URI holding the same bytes (OpenAI Responses), Anthropic's own content
|
|
10
|
-
* block with the bytes under `source.data` (Bedrock), an OpenAI `file` block
|
|
11
|
-
* with the bytes under `file.file_data`, an OpenAI Responses `input_audio` block
|
|
12
|
-
* kept whole under `content` with the bytes under `content.input_audio.data`. A single
|
|
13
|
-
* image is hundreds of kilobytes, so keeping it would make every event on the
|
|
14
|
-
* queue that much bigger for nothing: the payload is never read back.
|
|
15
|
-
*
|
|
16
|
-
* Each of those becomes `{"type": "blob", "mime_type": "<mime_type>"}`, the same
|
|
17
|
-
* byte-less stub the google, cohere and bedrock instrumentation complements
|
|
18
|
-
* build themselves: the analyses reading these messages still see that the call
|
|
19
|
-
* carried content the stored text does not. A `uri` part pointing at a hosted
|
|
20
|
-
* image is a reference, not a payload, and is kept as is.
|
|
21
|
-
*/
|
|
22
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
23
|
-
exports.stripMediaPayloads = stripMediaPayloads;
|
|
24
|
-
const get_data_uri_mime_type_1 = require("../get-data-uri-mime-type");
|
|
25
|
-
// The message content attributes whose JSON holds parts: the first two are
|
|
26
|
-
// `[{role, parts}]`, `gen_ai.system_instructions` is a flat parts array.
|
|
27
|
-
const MESSAGE_PARTS_ATTRIBUTES = [
|
|
28
|
-
'gen_ai.input.messages',
|
|
29
|
-
'gen_ai.output.messages',
|
|
30
|
-
'gen_ai.system_instructions',
|
|
31
|
-
];
|
|
32
|
-
function isJsonObject(value) {
|
|
33
|
-
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
34
|
-
}
|
|
35
|
-
function stripPart(part) {
|
|
36
|
-
if (!isJsonObject(part))
|
|
37
|
-
return part;
|
|
38
|
-
if (part.type === 'blob') {
|
|
39
|
-
return { type: 'blob', mime_type: String(part.mime_type ?? '') };
|
|
40
|
-
}
|
|
41
|
-
if (part.type === 'uri') {
|
|
42
|
-
const mimeType = (0, get_data_uri_mime_type_1.getDataUriMimeType)(String(part.uri ?? ''));
|
|
43
|
-
if (mimeType !== null)
|
|
44
|
-
return { type: 'blob', mime_type: mimeType };
|
|
45
|
-
}
|
|
46
|
-
// Anthropic's own content block, which the Bedrock instrumentor copies onto
|
|
47
|
-
// the span as is: the bytes sit under source.data whatever the block's type
|
|
48
|
-
// says ("image", "document", "video", "audio").
|
|
49
|
-
const source = part.source;
|
|
50
|
-
if (isJsonObject(source) && source.data != null) {
|
|
51
|
-
return { type: 'blob', mime_type: String(source.media_type ?? '') };
|
|
52
|
-
}
|
|
53
|
-
// OpenAI's file block (a PDF sent to chat completions). On Node the
|
|
54
|
-
// instrumentor already maps it to a blob part (see the openai complement that
|
|
55
|
-
// repairs its mime type), so this is the guard for the day it stops, and the
|
|
56
|
-
// mirror of the branch the Python SDK needs.
|
|
57
|
-
const fileBlock = part.file;
|
|
58
|
-
if (isJsonObject(fileBlock)) {
|
|
59
|
-
const mimeType = (0, get_data_uri_mime_type_1.getDataUriMimeType)(String(fileBlock.file_data ?? ''));
|
|
60
|
-
if (mimeType !== null)
|
|
61
|
-
return { type: 'blob', mime_type: mimeType };
|
|
62
|
-
}
|
|
63
|
-
// An input block the OpenAI Responses instrumentor does not recognize is
|
|
64
|
-
// recorded as `{"type": "<block type>", "content": <the block itself>}`, so an
|
|
65
|
-
// `input_audio` block puts its base64 clip under `content.input_audio.data`.
|
|
66
|
-
const unrecognizedBlock = part.content;
|
|
67
|
-
const inlineAudio = isJsonObject(unrecognizedBlock) ? unrecognizedBlock.input_audio : null;
|
|
68
|
-
if (isJsonObject(inlineAudio) && inlineAudio.data != null) {
|
|
69
|
-
const audioFormat = inlineAudio.format;
|
|
70
|
-
return {
|
|
71
|
-
type: 'blob',
|
|
72
|
-
mime_type: audioFormat ? `audio/${audioFormat}` : 'audio/unknown',
|
|
73
|
-
};
|
|
74
|
-
}
|
|
75
|
-
// Mistral's document block. Its own tracing names the block by its type and
|
|
76
|
-
// drops the payload, so what arrives is usually `{"type": "document_url"}`
|
|
77
|
-
// already; this is what keeps the bytes off the queue if it stops dropping
|
|
78
|
-
// them.
|
|
79
|
-
const documentMimeType = (0, get_data_uri_mime_type_1.getDataUriMimeType)(String(part.document_url ?? ''));
|
|
80
|
-
if (documentMimeType !== null)
|
|
81
|
-
return { type: 'blob', mime_type: documentMimeType };
|
|
82
|
-
return part;
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* `items` with `stripItem` applied to each of them, or `items` itself when
|
|
86
|
-
* every item came back unchanged - an attribute carrying no media then keeps
|
|
87
|
-
* the instrumentor's exact JSON string.
|
|
88
|
-
*/
|
|
89
|
-
function stripList(items, stripItem) {
|
|
90
|
-
const stripped = items.map(stripItem);
|
|
91
|
-
return stripped.every((item, index) => item === items[index]) ? items : stripped;
|
|
92
|
-
}
|
|
93
|
-
/**
|
|
94
|
-
* One entry of a parts attribute: a message whose `parts` are stripped, or a
|
|
95
|
-
* bare part when the attribute is a flat parts array.
|
|
96
|
-
*/
|
|
97
|
-
function stripPartsEntry(entry) {
|
|
98
|
-
if (isJsonObject(entry) && Array.isArray(entry.parts)) {
|
|
99
|
-
const parts = stripList(entry.parts, stripPart);
|
|
100
|
-
return parts === entry.parts ? entry : { ...entry, parts };
|
|
101
|
-
}
|
|
102
|
-
return stripPart(entry);
|
|
103
|
-
}
|
|
104
|
-
/**
|
|
105
|
-
* The attribute's JSON with the media stripped from each of its entries, or
|
|
106
|
-
* null when there was nothing to strip.
|
|
107
|
-
*/
|
|
108
|
-
function getStrippedAttribute(value) {
|
|
109
|
-
if (typeof value !== 'string')
|
|
110
|
-
return null;
|
|
111
|
-
let entries;
|
|
112
|
-
try {
|
|
113
|
-
entries = JSON.parse(value);
|
|
114
|
-
}
|
|
115
|
-
catch {
|
|
116
|
-
return null;
|
|
117
|
-
}
|
|
118
|
-
if (!Array.isArray(entries))
|
|
119
|
-
return null;
|
|
120
|
-
const stripped = stripList(entries, stripPartsEntry);
|
|
121
|
-
return stripped === entries ? null : JSON.stringify(stripped);
|
|
122
|
-
}
|
|
123
|
-
/**
|
|
124
|
-
* Rewrite in place every message content attribute of `attributes` that carries
|
|
125
|
-
* media bytes.
|
|
126
|
-
*/
|
|
127
|
-
function stripMediaPayloads(attributes) {
|
|
128
|
-
for (const key of MESSAGE_PARTS_ATTRIBUTES) {
|
|
129
|
-
if (key in attributes) {
|
|
130
|
-
const stripped = getStrippedAttribute(attributes[key]);
|
|
131
|
-
if (stripped !== null)
|
|
132
|
-
attributes[key] = stripped;
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
}
|