langsmith 0.3.38 → 0.3.40
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/experimental/otel/constants.cjs +2 -1
- package/dist/experimental/otel/constants.d.ts +1 -0
- package/dist/experimental/otel/constants.js +1 -0
- package/dist/experimental/otel/exporter.cjs +4 -0
- package/dist/experimental/otel/exporter.js +4 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/utils/vercel.cjs +71 -0
- package/dist/utils/vercel.d.ts +7 -0
- package/dist/utils/vercel.js +68 -0
- package/dist/vercel.cjs +30 -30
- package/dist/vercel.js +30 -30
- package/package.json +3 -2
- /package/dist/{vercel.types.cjs → utils/vercel.types.cjs} +0 -0
- /package/dist/{vercel.types.d.ts → utils/vercel.types.d.ts} +0 -0
- /package/dist/{vercel.types.js → utils/vercel.types.js} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.AI_SDK_TOOL_OPERATIONS = exports.AI_SDK_LLM_OPERATIONS = exports.GEN_AI_CHOICE = exports.GEN_AI_ASSISTANT_MESSAGE = exports.GEN_AI_USER_MESSAGE = exports.GEN_AI_SYSTEM_MESSAGE = exports.LANGSMITH_PARENT_RUN_ID = exports.LANGSMITH_DOTTED_ORDER = exports.LANGSMITH_TRACE_ID = exports.LANGSMITH_RUN_ID = exports.LANGSMITH_REQUEST_HEADERS = exports.LANGSMITH_REQUEST_STREAMING = exports.LANGSMITH_RUNTIME = exports.LANGSMITH_TAGS = exports.LANGSMITH_METADATA = exports.LANGSMITH_NAME = exports.LANGSMITH_RUN_TYPE = exports.LANGSMITH_SESSION_NAME = exports.LANGSMITH_SESSION_ID = exports.GEN_AI_USAGE_OUTPUT_TOKEN_DETAILS = exports.GEN_AI_USAGE_INPUT_TOKEN_DETAILS = exports.GEN_AI_RESPONSE_SYSTEM_FINGERPRINT = exports.GEN_AI_RESPONSE_SERVICE_TIER = exports.GEN_AI_RESPONSE_ID = exports.GEN_AI_SERIALIZED_DOC = exports.GEN_AI_SERIALIZED_SIGNATURE = exports.GEN_AI_SERIALIZED_NAME = exports.GEN_AI_REQUEST_EXTRA_BODY = exports.GEN_AI_REQUEST_EXTRA_QUERY = exports.GENAI_COMPLETION = exports.GENAI_PROMPT = exports.GEN_AI_RESPONSE_FINISH_REASONS = exports.GEN_AI_REQUEST_PRESENCE_PENALTY = exports.GEN_AI_REQUEST_FREQUENCY_PENALTY = exports.GEN_AI_REQUEST_TOP_P = exports.GEN_AI_REQUEST_TEMPERATURE = exports.GEN_AI_REQUEST_MAX_TOKENS = exports.GEN_AI_USAGE_TOTAL_TOKENS = exports.GEN_AI_USAGE_OUTPUT_TOKENS = exports.GEN_AI_USAGE_INPUT_TOKENS = exports.GEN_AI_RESPONSE_MODEL = exports.GEN_AI_REQUEST_MODEL = exports.GEN_AI_SYSTEM = exports.GEN_AI_OPERATION_NAME = void 0;
|
|
3
|
+
exports.AI_SDK_TOOL_OPERATIONS = exports.AI_SDK_LLM_OPERATIONS = exports.GEN_AI_CHOICE = exports.GEN_AI_ASSISTANT_MESSAGE = exports.GEN_AI_USER_MESSAGE = exports.GEN_AI_SYSTEM_MESSAGE = exports.LANGSMITH_USAGE_METADATA = exports.LANGSMITH_PARENT_RUN_ID = exports.LANGSMITH_DOTTED_ORDER = exports.LANGSMITH_TRACE_ID = exports.LANGSMITH_RUN_ID = exports.LANGSMITH_REQUEST_HEADERS = exports.LANGSMITH_REQUEST_STREAMING = exports.LANGSMITH_RUNTIME = exports.LANGSMITH_TAGS = exports.LANGSMITH_METADATA = exports.LANGSMITH_NAME = exports.LANGSMITH_RUN_TYPE = exports.LANGSMITH_SESSION_NAME = exports.LANGSMITH_SESSION_ID = exports.GEN_AI_USAGE_OUTPUT_TOKEN_DETAILS = exports.GEN_AI_USAGE_INPUT_TOKEN_DETAILS = exports.GEN_AI_RESPONSE_SYSTEM_FINGERPRINT = exports.GEN_AI_RESPONSE_SERVICE_TIER = exports.GEN_AI_RESPONSE_ID = exports.GEN_AI_SERIALIZED_DOC = exports.GEN_AI_SERIALIZED_SIGNATURE = exports.GEN_AI_SERIALIZED_NAME = exports.GEN_AI_REQUEST_EXTRA_BODY = exports.GEN_AI_REQUEST_EXTRA_QUERY = exports.GENAI_COMPLETION = exports.GENAI_PROMPT = exports.GEN_AI_RESPONSE_FINISH_REASONS = exports.GEN_AI_REQUEST_PRESENCE_PENALTY = exports.GEN_AI_REQUEST_FREQUENCY_PENALTY = exports.GEN_AI_REQUEST_TOP_P = exports.GEN_AI_REQUEST_TEMPERATURE = exports.GEN_AI_REQUEST_MAX_TOKENS = exports.GEN_AI_USAGE_TOTAL_TOKENS = exports.GEN_AI_USAGE_OUTPUT_TOKENS = exports.GEN_AI_USAGE_INPUT_TOKENS = exports.GEN_AI_RESPONSE_MODEL = exports.GEN_AI_REQUEST_MODEL = exports.GEN_AI_SYSTEM = exports.GEN_AI_OPERATION_NAME = void 0;
|
|
4
4
|
// OpenTelemetry GenAI semantic convention attribute names
|
|
5
5
|
exports.GEN_AI_OPERATION_NAME = "gen_ai.operation.name";
|
|
6
6
|
exports.GEN_AI_SYSTEM = "gen_ai.system";
|
|
@@ -41,6 +41,7 @@ exports.LANGSMITH_RUN_ID = "langsmith.span.id";
|
|
|
41
41
|
exports.LANGSMITH_TRACE_ID = "langsmith.trace.id";
|
|
42
42
|
exports.LANGSMITH_DOTTED_ORDER = "langsmith.span.dotted_order";
|
|
43
43
|
exports.LANGSMITH_PARENT_RUN_ID = "langsmith.span.parent_id";
|
|
44
|
+
exports.LANGSMITH_USAGE_METADATA = "langsmith.usage_metadata";
|
|
44
45
|
// GenAI event names
|
|
45
46
|
exports.GEN_AI_SYSTEM_MESSAGE = "gen_ai.system.message";
|
|
46
47
|
exports.GEN_AI_USER_MESSAGE = "gen_ai.user.message";
|
|
@@ -36,6 +36,7 @@ export declare const LANGSMITH_RUN_ID = "langsmith.span.id";
|
|
|
36
36
|
export declare const LANGSMITH_TRACE_ID = "langsmith.trace.id";
|
|
37
37
|
export declare const LANGSMITH_DOTTED_ORDER = "langsmith.span.dotted_order";
|
|
38
38
|
export declare const LANGSMITH_PARENT_RUN_ID = "langsmith.span.parent_id";
|
|
39
|
+
export declare const LANGSMITH_USAGE_METADATA = "langsmith.usage_metadata";
|
|
39
40
|
export declare const GEN_AI_SYSTEM_MESSAGE = "gen_ai.system.message";
|
|
40
41
|
export declare const GEN_AI_USER_MESSAGE = "gen_ai.user.message";
|
|
41
42
|
export declare const GEN_AI_ASSISTANT_MESSAGE = "gen_ai.assistant.message";
|
|
@@ -38,6 +38,7 @@ export const LANGSMITH_RUN_ID = "langsmith.span.id";
|
|
|
38
38
|
export const LANGSMITH_TRACE_ID = "langsmith.trace.id";
|
|
39
39
|
export const LANGSMITH_DOTTED_ORDER = "langsmith.span.dotted_order";
|
|
40
40
|
export const LANGSMITH_PARENT_RUN_ID = "langsmith.span.parent_id";
|
|
41
|
+
export const LANGSMITH_USAGE_METADATA = "langsmith.usage_metadata";
|
|
41
42
|
// GenAI event names
|
|
42
43
|
export const GEN_AI_SYSTEM_MESSAGE = "gen_ai.system.message";
|
|
43
44
|
export const GEN_AI_USER_MESSAGE = "gen_ai.user.message";
|
|
@@ -38,6 +38,7 @@ const exporter_trace_otlp_proto_1 = require("@opentelemetry/exporter-trace-otlp-
|
|
|
38
38
|
const constants = __importStar(require("./constants.cjs"));
|
|
39
39
|
const env_js_1 = require("../../env.cjs");
|
|
40
40
|
const env_js_2 = require("../../utils/env.cjs");
|
|
41
|
+
const vercel_js_1 = require("../../utils/vercel.cjs");
|
|
41
42
|
/**
|
|
42
43
|
* Convert headers string in format "name=value,name2=value2" to object
|
|
43
44
|
*/
|
|
@@ -168,6 +169,9 @@ class LangSmithOTLPTraceExporter extends exporter_trace_otlp_proto_1.OTLPTraceEx
|
|
|
168
169
|
if (typeof span.attributes["ai.operationId"] === "string" &&
|
|
169
170
|
constants.AI_SDK_LLM_OPERATIONS.includes(span.attributes["ai.operationId"])) {
|
|
170
171
|
span.attributes[constants.LANGSMITH_RUN_TYPE] = "llm";
|
|
172
|
+
const usageMetadata = (0, vercel_js_1.extractUsageMetadata)(span);
|
|
173
|
+
span.attributes[constants.LANGSMITH_USAGE_METADATA] =
|
|
174
|
+
JSON.stringify(usageMetadata);
|
|
171
175
|
}
|
|
172
176
|
else if (typeof span.attributes["ai.operationId"] === "string" &&
|
|
173
177
|
constants.AI_SDK_TOOL_OPERATIONS.includes(span.attributes["ai.operationId"])) {
|
|
@@ -2,6 +2,7 @@ import { OTLPTraceExporter } from "@opentelemetry/exporter-trace-otlp-proto";
|
|
|
2
2
|
import * as constants from "./constants.js";
|
|
3
3
|
import { isTracingEnabled } from "../../env.js";
|
|
4
4
|
import { getEnvironmentVariable, getLangSmithEnvironmentVariable, } from "../../utils/env.js";
|
|
5
|
+
import { extractUsageMetadata } from "../../utils/vercel.js";
|
|
5
6
|
/**
|
|
6
7
|
* Convert headers string in format "name=value,name2=value2" to object
|
|
7
8
|
*/
|
|
@@ -132,6 +133,9 @@ export class LangSmithOTLPTraceExporter extends OTLPTraceExporter {
|
|
|
132
133
|
if (typeof span.attributes["ai.operationId"] === "string" &&
|
|
133
134
|
constants.AI_SDK_LLM_OPERATIONS.includes(span.attributes["ai.operationId"])) {
|
|
134
135
|
span.attributes[constants.LANGSMITH_RUN_TYPE] = "llm";
|
|
136
|
+
const usageMetadata = extractUsageMetadata(span);
|
|
137
|
+
span.attributes[constants.LANGSMITH_USAGE_METADATA] =
|
|
138
|
+
JSON.stringify(usageMetadata);
|
|
135
139
|
}
|
|
136
140
|
else if (typeof span.attributes["ai.operationId"] === "string" &&
|
|
137
141
|
constants.AI_SDK_TOOL_OPERATIONS.includes(span.attributes["ai.operationId"])) {
|
package/dist/index.cjs
CHANGED
|
@@ -10,4 +10,4 @@ Object.defineProperty(exports, "overrideFetchImplementation", { enumerable: true
|
|
|
10
10
|
var project_js_1 = require("./utils/project.cjs");
|
|
11
11
|
Object.defineProperty(exports, "getDefaultProjectName", { enumerable: true, get: function () { return project_js_1.getDefaultProjectName; } });
|
|
12
12
|
// Update using yarn bump-version
|
|
13
|
-
exports.__version__ = "0.3.
|
|
13
|
+
exports.__version__ = "0.3.40";
|
package/dist/index.d.ts
CHANGED
|
@@ -3,4 +3,4 @@ export type { Dataset, Example, TracerSession, Run, Feedback, RetrieverOutput, }
|
|
|
3
3
|
export { RunTree, type RunTreeConfig } from "./run_trees.js";
|
|
4
4
|
export { overrideFetchImplementation } from "./singletons/fetch.js";
|
|
5
5
|
export { getDefaultProjectName } from "./utils/project.js";
|
|
6
|
-
export declare const __version__ = "0.3.
|
|
6
|
+
export declare const __version__ = "0.3.40";
|
package/dist/index.js
CHANGED
|
@@ -3,4 +3,4 @@ export { RunTree } from "./run_trees.js";
|
|
|
3
3
|
export { overrideFetchImplementation } from "./singletons/fetch.js";
|
|
4
4
|
export { getDefaultProjectName } from "./utils/project.js";
|
|
5
5
|
// Update using yarn bump-version
|
|
6
|
-
export const __version__ = "0.3.
|
|
6
|
+
export const __version__ = "0.3.40";
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.extractUsageMetadata = extractUsageMetadata;
|
|
4
|
+
function extractInputTokenDetails(providerMetadata) {
|
|
5
|
+
const inputTokenDetails = {};
|
|
6
|
+
if (providerMetadata.anthropic != null &&
|
|
7
|
+
typeof providerMetadata.anthropic === "object") {
|
|
8
|
+
const anthropic = providerMetadata.anthropic;
|
|
9
|
+
if (anthropic.cacheReadInputTokens != null &&
|
|
10
|
+
typeof anthropic.cacheReadInputTokens === "number") {
|
|
11
|
+
inputTokenDetails.cache_read = anthropic.cacheReadInputTokens;
|
|
12
|
+
}
|
|
13
|
+
if (anthropic.cacheCreationInputTokens != null &&
|
|
14
|
+
typeof anthropic.cacheCreationInputTokens === "number") {
|
|
15
|
+
inputTokenDetails.ephemeral_5m_input_tokens =
|
|
16
|
+
anthropic.cacheCreationInputTokens;
|
|
17
|
+
}
|
|
18
|
+
return inputTokenDetails;
|
|
19
|
+
}
|
|
20
|
+
else if (providerMetadata.openai != null &&
|
|
21
|
+
typeof providerMetadata.openai === "object") {
|
|
22
|
+
const openai = providerMetadata.openai;
|
|
23
|
+
if (openai.cachedPromptTokens != null &&
|
|
24
|
+
typeof openai.cachedPromptTokens === "number") {
|
|
25
|
+
inputTokenDetails.cache_read = openai.cachedPromptTokens;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
return inputTokenDetails;
|
|
29
|
+
}
|
|
30
|
+
function extractUsageMetadata(span) {
|
|
31
|
+
const isError = span?.status?.code === 2;
|
|
32
|
+
if (isError || !span || !span.attributes) {
|
|
33
|
+
return {
|
|
34
|
+
input_tokens: 0,
|
|
35
|
+
output_tokens: 0,
|
|
36
|
+
total_tokens: 0,
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
const usageMetadata = {
|
|
40
|
+
input_tokens: 0,
|
|
41
|
+
output_tokens: 0,
|
|
42
|
+
total_tokens: 0,
|
|
43
|
+
};
|
|
44
|
+
if (typeof span.attributes["ai.usage.promptTokens"] === "number") {
|
|
45
|
+
usageMetadata.input_tokens = span.attributes["ai.usage.promptTokens"];
|
|
46
|
+
}
|
|
47
|
+
if (typeof span.attributes["ai.usage.completionTokens"] === "number") {
|
|
48
|
+
usageMetadata.output_tokens = span.attributes["ai.usage.completionTokens"];
|
|
49
|
+
}
|
|
50
|
+
if (typeof span.attributes["ai.response.providerMetadata"] === "string") {
|
|
51
|
+
try {
|
|
52
|
+
const providerMetadata = JSON.parse(span.attributes["ai.response.providerMetadata"]);
|
|
53
|
+
usageMetadata.input_token_details =
|
|
54
|
+
extractInputTokenDetails(providerMetadata);
|
|
55
|
+
if (providerMetadata.anthropic != null &&
|
|
56
|
+
typeof providerMetadata.anthropic === "object") {
|
|
57
|
+
// AI SDK does not include Anthropic cache tokens in their stated input token
|
|
58
|
+
// numbers, so we need to add them manually
|
|
59
|
+
for (const key in usageMetadata.input_token_details) {
|
|
60
|
+
usageMetadata.input_tokens += usageMetadata.input_token_details[key];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
// pass
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
usageMetadata.total_tokens =
|
|
69
|
+
usageMetadata.input_tokens + usageMetadata.output_tokens;
|
|
70
|
+
return usageMetadata;
|
|
71
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
function extractInputTokenDetails(providerMetadata) {
|
|
2
|
+
const inputTokenDetails = {};
|
|
3
|
+
if (providerMetadata.anthropic != null &&
|
|
4
|
+
typeof providerMetadata.anthropic === "object") {
|
|
5
|
+
const anthropic = providerMetadata.anthropic;
|
|
6
|
+
if (anthropic.cacheReadInputTokens != null &&
|
|
7
|
+
typeof anthropic.cacheReadInputTokens === "number") {
|
|
8
|
+
inputTokenDetails.cache_read = anthropic.cacheReadInputTokens;
|
|
9
|
+
}
|
|
10
|
+
if (anthropic.cacheCreationInputTokens != null &&
|
|
11
|
+
typeof anthropic.cacheCreationInputTokens === "number") {
|
|
12
|
+
inputTokenDetails.ephemeral_5m_input_tokens =
|
|
13
|
+
anthropic.cacheCreationInputTokens;
|
|
14
|
+
}
|
|
15
|
+
return inputTokenDetails;
|
|
16
|
+
}
|
|
17
|
+
else if (providerMetadata.openai != null &&
|
|
18
|
+
typeof providerMetadata.openai === "object") {
|
|
19
|
+
const openai = providerMetadata.openai;
|
|
20
|
+
if (openai.cachedPromptTokens != null &&
|
|
21
|
+
typeof openai.cachedPromptTokens === "number") {
|
|
22
|
+
inputTokenDetails.cache_read = openai.cachedPromptTokens;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
return inputTokenDetails;
|
|
26
|
+
}
|
|
27
|
+
export function extractUsageMetadata(span) {
|
|
28
|
+
const isError = span?.status?.code === 2;
|
|
29
|
+
if (isError || !span || !span.attributes) {
|
|
30
|
+
return {
|
|
31
|
+
input_tokens: 0,
|
|
32
|
+
output_tokens: 0,
|
|
33
|
+
total_tokens: 0,
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
const usageMetadata = {
|
|
37
|
+
input_tokens: 0,
|
|
38
|
+
output_tokens: 0,
|
|
39
|
+
total_tokens: 0,
|
|
40
|
+
};
|
|
41
|
+
if (typeof span.attributes["ai.usage.promptTokens"] === "number") {
|
|
42
|
+
usageMetadata.input_tokens = span.attributes["ai.usage.promptTokens"];
|
|
43
|
+
}
|
|
44
|
+
if (typeof span.attributes["ai.usage.completionTokens"] === "number") {
|
|
45
|
+
usageMetadata.output_tokens = span.attributes["ai.usage.completionTokens"];
|
|
46
|
+
}
|
|
47
|
+
if (typeof span.attributes["ai.response.providerMetadata"] === "string") {
|
|
48
|
+
try {
|
|
49
|
+
const providerMetadata = JSON.parse(span.attributes["ai.response.providerMetadata"]);
|
|
50
|
+
usageMetadata.input_token_details =
|
|
51
|
+
extractInputTokenDetails(providerMetadata);
|
|
52
|
+
if (providerMetadata.anthropic != null &&
|
|
53
|
+
typeof providerMetadata.anthropic === "object") {
|
|
54
|
+
// AI SDK does not include Anthropic cache tokens in their stated input token
|
|
55
|
+
// numbers, so we need to add them manually
|
|
56
|
+
for (const key in usageMetadata.input_token_details) {
|
|
57
|
+
usageMetadata.input_tokens += usageMetadata.input_token_details[key];
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// pass
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
usageMetadata.total_tokens =
|
|
66
|
+
usageMetadata.input_tokens + usageMetadata.output_tokens;
|
|
67
|
+
return usageMetadata;
|
|
68
|
+
}
|
package/dist/vercel.cjs
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.AISDKExporter = void 0;
|
|
4
|
+
const vercel_js_1 = require("./utils/vercel.cjs");
|
|
4
5
|
const index_js_1 = require("./index.cjs");
|
|
5
6
|
const uuid_1 = require("uuid");
|
|
6
7
|
const traceable_js_1 = require("./singletons/traceable.cjs");
|
|
@@ -473,20 +474,6 @@ class AISDKExporter {
|
|
|
473
474
|
}),
|
|
474
475
|
};
|
|
475
476
|
}
|
|
476
|
-
if (span.attributes["ai.usage.completionTokens"]) {
|
|
477
|
-
result ??= {};
|
|
478
|
-
result.llm_output ??= {};
|
|
479
|
-
result.llm_output.token_usage ??= {};
|
|
480
|
-
result.llm_output.token_usage["completion_tokens"] =
|
|
481
|
-
span.attributes["ai.usage.completionTokens"];
|
|
482
|
-
}
|
|
483
|
-
if (span.attributes["ai.usage.promptTokens"]) {
|
|
484
|
-
result ??= {};
|
|
485
|
-
result.llm_output ??= {};
|
|
486
|
-
result.llm_output.token_usage ??= {};
|
|
487
|
-
result.llm_output.token_usage["prompt_tokens"] =
|
|
488
|
-
span.attributes["ai.usage.promptTokens"];
|
|
489
|
-
}
|
|
490
477
|
return result;
|
|
491
478
|
})();
|
|
492
479
|
const invocationParams = (() => {
|
|
@@ -513,10 +500,16 @@ class AISDKExporter {
|
|
|
513
500
|
time: convertToTimestamp(firstChunkEvent.time),
|
|
514
501
|
});
|
|
515
502
|
}
|
|
503
|
+
const runType = span.name === "ai.generateText" || span.name === "ai.streamText"
|
|
504
|
+
? "chain"
|
|
505
|
+
: "llm";
|
|
506
|
+
const error = span.status?.code === 2 ? span.status.message : undefined;
|
|
507
|
+
const usageMetadata = (0, vercel_js_1.extractUsageMetadata)(span);
|
|
516
508
|
// TODO: add first_token_time
|
|
517
509
|
return asRunCreate({
|
|
518
|
-
run_type:
|
|
510
|
+
run_type: runType,
|
|
519
511
|
name: span.attributes["ai.model.provider"],
|
|
512
|
+
error,
|
|
520
513
|
inputs,
|
|
521
514
|
outputs,
|
|
522
515
|
events,
|
|
@@ -524,6 +517,7 @@ class AISDKExporter {
|
|
|
524
517
|
invocation_params: invocationParams,
|
|
525
518
|
batch_size: 1,
|
|
526
519
|
metadata: {
|
|
520
|
+
usage_metadata: usageMetadata,
|
|
527
521
|
ls_provider: span.attributes["ai.model.provider"]
|
|
528
522
|
.split(".")
|
|
529
523
|
.at(0),
|
|
@@ -546,9 +540,22 @@ class AISDKExporter {
|
|
|
546
540
|
if (typeof output === "object" && output != null) {
|
|
547
541
|
outputs = output;
|
|
548
542
|
}
|
|
543
|
+
const error = span.status?.code === 2 ? span.status.message : undefined;
|
|
549
544
|
return asRunCreate({
|
|
550
545
|
run_type: "tool",
|
|
551
546
|
name: span.attributes["ai.toolCall.name"],
|
|
547
|
+
error,
|
|
548
|
+
extra: error
|
|
549
|
+
? {
|
|
550
|
+
metadata: {
|
|
551
|
+
usage_metadata: {
|
|
552
|
+
input_tokens: 0,
|
|
553
|
+
output_tokens: 0,
|
|
554
|
+
total_tokens: 0,
|
|
555
|
+
},
|
|
556
|
+
},
|
|
557
|
+
}
|
|
558
|
+
: undefined,
|
|
552
559
|
inputs,
|
|
553
560
|
outputs,
|
|
554
561
|
});
|
|
@@ -575,20 +582,6 @@ class AISDKExporter {
|
|
|
575
582
|
output: tryJson(span.attributes["ai.response.object"]),
|
|
576
583
|
};
|
|
577
584
|
}
|
|
578
|
-
if (span.attributes["ai.usage.completionTokens"]) {
|
|
579
|
-
result ??= {};
|
|
580
|
-
result.llm_output ??= {};
|
|
581
|
-
result.llm_output.token_usage ??= {};
|
|
582
|
-
result.llm_output.token_usage["completion_tokens"] =
|
|
583
|
-
span.attributes["ai.usage.completionTokens"];
|
|
584
|
-
}
|
|
585
|
-
if (span.attributes["ai.usage.promptTokens"]) {
|
|
586
|
-
result ??= {};
|
|
587
|
-
result.llm_output ??= {};
|
|
588
|
-
result.llm_output.token_usage ??= {};
|
|
589
|
-
result.llm_output.token_usage["prompt_tokens"] =
|
|
590
|
-
+span.attributes["ai.usage.promptTokens"];
|
|
591
|
-
}
|
|
592
585
|
return result;
|
|
593
586
|
})();
|
|
594
587
|
const events = [];
|
|
@@ -599,15 +592,22 @@ class AISDKExporter {
|
|
|
599
592
|
time: convertToTimestamp(firstChunkEvent.time),
|
|
600
593
|
});
|
|
601
594
|
}
|
|
595
|
+
const runType = span.name === "ai.generateObject" || span.name === "ai.streamObject"
|
|
596
|
+
? "chain"
|
|
597
|
+
: "llm";
|
|
598
|
+
const error = span.status?.code === 2 ? span.status.message : undefined;
|
|
599
|
+
const usageMetadata = (0, vercel_js_1.extractUsageMetadata)(span);
|
|
602
600
|
return asRunCreate({
|
|
603
|
-
run_type:
|
|
601
|
+
run_type: runType,
|
|
604
602
|
name: span.attributes["ai.model.provider"],
|
|
603
|
+
error,
|
|
605
604
|
inputs,
|
|
606
605
|
outputs,
|
|
607
606
|
events,
|
|
608
607
|
extra: {
|
|
609
608
|
batch_size: 1,
|
|
610
609
|
metadata: {
|
|
610
|
+
usage_metadata: usageMetadata,
|
|
611
611
|
ls_provider: span.attributes["ai.model.provider"]
|
|
612
612
|
.split(".")
|
|
613
613
|
.at(0),
|
package/dist/vercel.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { extractUsageMetadata } from "./utils/vercel.js";
|
|
1
2
|
import { Client, RunTree } from "./index.js";
|
|
2
3
|
import { v5 as uuid5 } from "uuid";
|
|
3
4
|
import { getCurrentRunTree } from "./singletons/traceable.js";
|
|
@@ -470,20 +471,6 @@ export class AISDKExporter {
|
|
|
470
471
|
}),
|
|
471
472
|
};
|
|
472
473
|
}
|
|
473
|
-
if (span.attributes["ai.usage.completionTokens"]) {
|
|
474
|
-
result ??= {};
|
|
475
|
-
result.llm_output ??= {};
|
|
476
|
-
result.llm_output.token_usage ??= {};
|
|
477
|
-
result.llm_output.token_usage["completion_tokens"] =
|
|
478
|
-
span.attributes["ai.usage.completionTokens"];
|
|
479
|
-
}
|
|
480
|
-
if (span.attributes["ai.usage.promptTokens"]) {
|
|
481
|
-
result ??= {};
|
|
482
|
-
result.llm_output ??= {};
|
|
483
|
-
result.llm_output.token_usage ??= {};
|
|
484
|
-
result.llm_output.token_usage["prompt_tokens"] =
|
|
485
|
-
span.attributes["ai.usage.promptTokens"];
|
|
486
|
-
}
|
|
487
474
|
return result;
|
|
488
475
|
})();
|
|
489
476
|
const invocationParams = (() => {
|
|
@@ -510,10 +497,16 @@ export class AISDKExporter {
|
|
|
510
497
|
time: convertToTimestamp(firstChunkEvent.time),
|
|
511
498
|
});
|
|
512
499
|
}
|
|
500
|
+
const runType = span.name === "ai.generateText" || span.name === "ai.streamText"
|
|
501
|
+
? "chain"
|
|
502
|
+
: "llm";
|
|
503
|
+
const error = span.status?.code === 2 ? span.status.message : undefined;
|
|
504
|
+
const usageMetadata = extractUsageMetadata(span);
|
|
513
505
|
// TODO: add first_token_time
|
|
514
506
|
return asRunCreate({
|
|
515
|
-
run_type:
|
|
507
|
+
run_type: runType,
|
|
516
508
|
name: span.attributes["ai.model.provider"],
|
|
509
|
+
error,
|
|
517
510
|
inputs,
|
|
518
511
|
outputs,
|
|
519
512
|
events,
|
|
@@ -521,6 +514,7 @@ export class AISDKExporter {
|
|
|
521
514
|
invocation_params: invocationParams,
|
|
522
515
|
batch_size: 1,
|
|
523
516
|
metadata: {
|
|
517
|
+
usage_metadata: usageMetadata,
|
|
524
518
|
ls_provider: span.attributes["ai.model.provider"]
|
|
525
519
|
.split(".")
|
|
526
520
|
.at(0),
|
|
@@ -543,9 +537,22 @@ export class AISDKExporter {
|
|
|
543
537
|
if (typeof output === "object" && output != null) {
|
|
544
538
|
outputs = output;
|
|
545
539
|
}
|
|
540
|
+
const error = span.status?.code === 2 ? span.status.message : undefined;
|
|
546
541
|
return asRunCreate({
|
|
547
542
|
run_type: "tool",
|
|
548
543
|
name: span.attributes["ai.toolCall.name"],
|
|
544
|
+
error,
|
|
545
|
+
extra: error
|
|
546
|
+
? {
|
|
547
|
+
metadata: {
|
|
548
|
+
usage_metadata: {
|
|
549
|
+
input_tokens: 0,
|
|
550
|
+
output_tokens: 0,
|
|
551
|
+
total_tokens: 0,
|
|
552
|
+
},
|
|
553
|
+
},
|
|
554
|
+
}
|
|
555
|
+
: undefined,
|
|
549
556
|
inputs,
|
|
550
557
|
outputs,
|
|
551
558
|
});
|
|
@@ -572,20 +579,6 @@ export class AISDKExporter {
|
|
|
572
579
|
output: tryJson(span.attributes["ai.response.object"]),
|
|
573
580
|
};
|
|
574
581
|
}
|
|
575
|
-
if (span.attributes["ai.usage.completionTokens"]) {
|
|
576
|
-
result ??= {};
|
|
577
|
-
result.llm_output ??= {};
|
|
578
|
-
result.llm_output.token_usage ??= {};
|
|
579
|
-
result.llm_output.token_usage["completion_tokens"] =
|
|
580
|
-
span.attributes["ai.usage.completionTokens"];
|
|
581
|
-
}
|
|
582
|
-
if (span.attributes["ai.usage.promptTokens"]) {
|
|
583
|
-
result ??= {};
|
|
584
|
-
result.llm_output ??= {};
|
|
585
|
-
result.llm_output.token_usage ??= {};
|
|
586
|
-
result.llm_output.token_usage["prompt_tokens"] =
|
|
587
|
-
+span.attributes["ai.usage.promptTokens"];
|
|
588
|
-
}
|
|
589
582
|
return result;
|
|
590
583
|
})();
|
|
591
584
|
const events = [];
|
|
@@ -596,15 +589,22 @@ export class AISDKExporter {
|
|
|
596
589
|
time: convertToTimestamp(firstChunkEvent.time),
|
|
597
590
|
});
|
|
598
591
|
}
|
|
592
|
+
const runType = span.name === "ai.generateObject" || span.name === "ai.streamObject"
|
|
593
|
+
? "chain"
|
|
594
|
+
: "llm";
|
|
595
|
+
const error = span.status?.code === 2 ? span.status.message : undefined;
|
|
596
|
+
const usageMetadata = extractUsageMetadata(span);
|
|
599
597
|
return asRunCreate({
|
|
600
|
-
run_type:
|
|
598
|
+
run_type: runType,
|
|
601
599
|
name: span.attributes["ai.model.provider"],
|
|
600
|
+
error,
|
|
602
601
|
inputs,
|
|
603
602
|
outputs,
|
|
604
603
|
events,
|
|
605
604
|
extra: {
|
|
606
605
|
batch_size: 1,
|
|
607
606
|
metadata: {
|
|
607
|
+
usage_metadata: usageMetadata,
|
|
608
608
|
ls_provider: span.attributes["ai.model.provider"]
|
|
609
609
|
.split(".")
|
|
610
610
|
.at(0),
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "langsmith",
|
|
3
|
-
"version": "0.3.
|
|
3
|
+
"version": "0.3.40",
|
|
4
4
|
"description": "Client library to connect to the LangSmith LLM Tracing and Evaluation Platform.",
|
|
5
5
|
"packageManager": "yarn@1.22.19",
|
|
6
6
|
"files": [
|
|
@@ -140,6 +140,7 @@
|
|
|
140
140
|
"uuid": "^10.0.0"
|
|
141
141
|
},
|
|
142
142
|
"devDependencies": {
|
|
143
|
+
"@ai-sdk/anthropic": "^1.2.12",
|
|
143
144
|
"@ai-sdk/openai": "^1.3.20",
|
|
144
145
|
"@babel/preset-env": "^7.22.4",
|
|
145
146
|
"@faker-js/faker": "^8.4.1",
|
|
@@ -158,7 +159,7 @@
|
|
|
158
159
|
"@types/node-fetch": "^2.6.12",
|
|
159
160
|
"@typescript-eslint/eslint-plugin": "^5.59.8",
|
|
160
161
|
"@typescript-eslint/parser": "^5.59.8",
|
|
161
|
-
"ai": "^4.3.
|
|
162
|
+
"ai": "^4.3.17",
|
|
162
163
|
"babel-jest": "^29.5.0",
|
|
163
164
|
"cross-env": "^7.0.3",
|
|
164
165
|
"dotenv": "^16.1.3",
|
|
File without changes
|
|
File without changes
|
|
File without changes
|