@jini-ai/provider-plugins 0.0.0-stage → 0.6.15-rc.2
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/CHANGELOG.md +23 -0
- package/LICENSE +201 -0
- package/README.md +58 -2
- package/catalog.json +32 -0
- package/package.json +61 -3
- package/plugins/ai-trace-langfuse/0.6.15-rc.2/jini.plugin.json +75 -0
- package/plugins/ai-trace-langfuse/0.6.15-rc.2/licenses/_jini-ai_provider-plugins/LICENSE +201 -0
- package/plugins/ai-trace-langfuse/0.6.15-rc.2/licenses/_jini-ai_provider-plugins/package-license.json +5 -0
- package/plugins/ai-trace-langfuse/0.6.15-rc.2/licenses/langfuse/LICENSE +21 -0
- package/plugins/ai-trace-langfuse/0.6.15-rc.2/licenses/langfuse/LICENSE-SOURCE +1 -0
- package/plugins/ai-trace-langfuse/0.6.15-rc.2/licenses/langfuse/SOURCE +1 -0
- package/plugins/ai-trace-langfuse/0.6.15-rc.2/licenses/langfuse/package-license.json +5 -0
- package/plugins/ai-trace-langfuse/0.6.15-rc.2/licenses/langfuse-core/LICENSE +21 -0
- package/plugins/ai-trace-langfuse/0.6.15-rc.2/licenses/langfuse-core/LICENSE-SOURCE +1 -0
- package/plugins/ai-trace-langfuse/0.6.15-rc.2/licenses/langfuse-core/SOURCE +1 -0
- package/plugins/ai-trace-langfuse/0.6.15-rc.2/licenses/langfuse-core/package-license.json +5 -0
- package/plugins/ai-trace-langfuse/0.6.15-rc.2/licenses/mustache/LICENSE +11 -0
- package/plugins/ai-trace-langfuse/0.6.15-rc.2/licenses/mustache/package-license.json +5 -0
- package/plugins/ai-trace-langfuse/0.6.15-rc.2/server/index.mjs +4172 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/jini.plugin.json +111 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/licenses/_jini-ai_cookie-consent/LICENSE +201 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/licenses/_jini-ai_cookie-consent/LICENSE-SOURCE +1 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/licenses/_jini-ai_cookie-consent/package-license.json +5 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/licenses/_jini-ai_core/LICENSE +201 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/licenses/_jini-ai_core/package-license.json +5 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/licenses/_jini-ai_diagnostics/LICENSE +201 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/licenses/_jini-ai_diagnostics/package-license.json +5 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/licenses/_jini-ai_provider-plugins/LICENSE +201 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/licenses/_jini-ai_provider-plugins/package-license.json +5 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/licenses/_posthog_core/LICENSE +417 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/licenses/_posthog_core/package-license.json +5 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/licenses/js-tokens/LICENSE +21 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/licenses/js-tokens/package-license.json +5 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/licenses/posthog-js/LICENSE +245 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/licenses/posthog-js/package-license.json +5 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/licenses/posthog-node/LICENSE +417 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/licenses/posthog-node/package-license.json +5 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/server/consent-adapter.mjs +1 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/server/index.mjs +9551 -0
- package/plugins/analytics-posthog/0.6.15-rc.2/server/posthog-browser.js +2 -0
- package/plugins/fixture-provider/0.6.15-rc.2/jini.plugin.json +35 -0
- package/plugins/fixture-provider/0.6.15-rc.2/licenses/_jini-ai_provider-plugins/LICENSE +201 -0
- package/plugins/fixture-provider/0.6.15-rc.2/licenses/_jini-ai_provider-plugins/package-license.json +5 -0
- package/plugins/fixture-provider/0.6.15-rc.2/server/index.mjs +26 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/jini.plugin.json +160 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_jini-ai_analytics/LICENSE +201 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_jini-ai_analytics/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_jini-ai_core/LICENSE +201 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_jini-ai_core/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_jini-ai_diagnostics/LICENSE +201 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_jini-ai_diagnostics/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_jini-ai_plugins/LICENSE +201 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_jini-ai_plugins/LICENSE-SOURCE +1 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_jini-ai_plugins/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_jini-ai_provider-plugins/LICENSE +201 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_jini-ai_provider-plugins/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_api/LICENSE +201 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_api/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_api-logs/LICENSE +201 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_api-logs/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_context-async-hooks/LICENSE +201 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_context-async-hooks/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_core/LICENSE +201 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_core/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_otlp-exporter-base/LICENSE +201 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_otlp-exporter-base/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_otlp-transformer/LICENSE +201 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_otlp-transformer/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_resources/LICENSE +201 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_resources/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_sdk-metrics/LICENSE +201 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_sdk-metrics/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_sdk-trace/LICENSE +201 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_sdk-trace/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_sdk-trace-base/LICENSE +201 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_sdk-trace-base/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_sdk-trace-node/LICENSE +201 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_sdk-trace-node/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_semantic-conventions/LICENSE +201 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/_opentelemetry_semantic-conventions/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/js-tokens/LICENSE +21 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/js-tokens/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/semver/LICENSE +15 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/licenses/semver/package-license.json +5 -0
- package/plugins/observability-opentelemetry/0.6.15-rc.2/server/index.mjs +20101 -0
- package/plugins/observability-sentry/0.6.15-rc.2/jini.plugin.json +71 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_jini-ai_core/LICENSE +201 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_jini-ai_core/package-license.json +5 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_jini-ai_diagnostics/LICENSE +201 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_jini-ai_diagnostics/package-license.json +5 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_jini-ai_provider-plugins/LICENSE +201 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_jini-ai_provider-plugins/package-license.json +5 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_opentelemetry_api/LICENSE +201 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_opentelemetry_api/package-license.json +5 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_sentry_conventions/LICENSE +21 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_sentry_conventions/package-license.json +5 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_sentry_core/LICENSE +21 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_sentry_core/package-license.json +5 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_sentry_node/LICENSE +21 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_sentry_node/package-license.json +5 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_sentry_opentelemetry/LICENSE +21 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_sentry_opentelemetry/package-license.json +5 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_sentry_server-runtime-injection/LICENSE +21 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_sentry_server-runtime-injection/LICENSE-SOURCE +1 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_sentry_server-runtime-injection/package-license.json +5 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_sentry_server-utils/LICENSE +21 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_sentry_server-utils/LICENSE-SOURCE +1 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/_sentry_server-utils/package-license.json +5 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/js-tokens/LICENSE +21 -0
- package/plugins/observability-sentry/0.6.15-rc.2/licenses/js-tokens/package-license.json +5 -0
- package/plugins/observability-sentry/0.6.15-rc.2/server/index.mjs +13093 -0
- package/plugins/payments-stripe/0.6.15-rc.2/jini.plugin.json +35 -0
- package/plugins/payments-stripe/0.6.15-rc.2/licenses/_jini-ai_provider-plugins/LICENSE +201 -0
- package/plugins/payments-stripe/0.6.15-rc.2/licenses/_jini-ai_provider-plugins/package-license.json +5 -0
- package/plugins/payments-stripe/0.6.15-rc.2/server/index.mjs +153 -0
|
@@ -0,0 +1,4172 @@
|
|
|
1
|
+
import { createRequire as __jiniCreateRequire } from "node:module"; const require = __jiniCreateRequire(import.meta.url);
|
|
2
|
+
|
|
3
|
+
// ../../node_modules/.pnpm/mustache@4.2.0/node_modules/mustache/mustache.mjs
|
|
4
|
+
/*!
|
|
5
|
+
* mustache.js - Logic-less {{mustache}} templates with JavaScript
|
|
6
|
+
* http://github.com/janl/mustache.js
|
|
7
|
+
*/
|
|
8
|
+
var objectToString = Object.prototype.toString;
|
|
9
|
+
var isArray = Array.isArray || function isArrayPolyfill(object) {
|
|
10
|
+
return objectToString.call(object) === "[object Array]";
|
|
11
|
+
};
|
|
12
|
+
function isFunction(object) {
|
|
13
|
+
return typeof object === "function";
|
|
14
|
+
}
|
|
15
|
+
function typeStr(obj) {
|
|
16
|
+
return isArray(obj) ? "array" : typeof obj;
|
|
17
|
+
}
|
|
18
|
+
function escapeRegExp(string) {
|
|
19
|
+
return string.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
|
|
20
|
+
}
|
|
21
|
+
function hasProperty(obj, propName) {
|
|
22
|
+
return obj != null && typeof obj === "object" && propName in obj;
|
|
23
|
+
}
|
|
24
|
+
function primitiveHasOwnProperty(primitive, propName) {
|
|
25
|
+
return primitive != null && typeof primitive !== "object" && primitive.hasOwnProperty && primitive.hasOwnProperty(propName);
|
|
26
|
+
}
|
|
27
|
+
var regExpTest = RegExp.prototype.test;
|
|
28
|
+
function testRegExp(re, string) {
|
|
29
|
+
return regExpTest.call(re, string);
|
|
30
|
+
}
|
|
31
|
+
var nonSpaceRe = /\S/;
|
|
32
|
+
function isWhitespace(string) {
|
|
33
|
+
return !testRegExp(nonSpaceRe, string);
|
|
34
|
+
}
|
|
35
|
+
var entityMap = {
|
|
36
|
+
"&": "&",
|
|
37
|
+
"<": "<",
|
|
38
|
+
">": ">",
|
|
39
|
+
'"': """,
|
|
40
|
+
"'": "'",
|
|
41
|
+
"/": "/",
|
|
42
|
+
"`": "`",
|
|
43
|
+
"=": "="
|
|
44
|
+
};
|
|
45
|
+
function escapeHtml(string) {
|
|
46
|
+
return String(string).replace(/[&<>"'`=\/]/g, function fromEntityMap(s) {
|
|
47
|
+
return entityMap[s];
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
var whiteRe = /\s*/;
|
|
51
|
+
var spaceRe = /\s+/;
|
|
52
|
+
var equalsRe = /\s*=/;
|
|
53
|
+
var curlyRe = /\s*\}/;
|
|
54
|
+
var tagRe = /#|\^|\/|>|\{|&|=|!/;
|
|
55
|
+
function parseTemplate(template, tags) {
|
|
56
|
+
if (!template)
|
|
57
|
+
return [];
|
|
58
|
+
var lineHasNonSpace = false;
|
|
59
|
+
var sections = [];
|
|
60
|
+
var tokens = [];
|
|
61
|
+
var spaces = [];
|
|
62
|
+
var hasTag = false;
|
|
63
|
+
var nonSpace = false;
|
|
64
|
+
var indentation = "";
|
|
65
|
+
var tagIndex = 0;
|
|
66
|
+
function stripSpace() {
|
|
67
|
+
if (hasTag && !nonSpace) {
|
|
68
|
+
while (spaces.length)
|
|
69
|
+
delete tokens[spaces.pop()];
|
|
70
|
+
} else {
|
|
71
|
+
spaces = [];
|
|
72
|
+
}
|
|
73
|
+
hasTag = false;
|
|
74
|
+
nonSpace = false;
|
|
75
|
+
}
|
|
76
|
+
var openingTagRe, closingTagRe, closingCurlyRe;
|
|
77
|
+
function compileTags(tagsToCompile) {
|
|
78
|
+
if (typeof tagsToCompile === "string")
|
|
79
|
+
tagsToCompile = tagsToCompile.split(spaceRe, 2);
|
|
80
|
+
if (!isArray(tagsToCompile) || tagsToCompile.length !== 2)
|
|
81
|
+
throw new Error("Invalid tags: " + tagsToCompile);
|
|
82
|
+
openingTagRe = new RegExp(escapeRegExp(tagsToCompile[0]) + "\\s*");
|
|
83
|
+
closingTagRe = new RegExp("\\s*" + escapeRegExp(tagsToCompile[1]));
|
|
84
|
+
closingCurlyRe = new RegExp("\\s*" + escapeRegExp("}" + tagsToCompile[1]));
|
|
85
|
+
}
|
|
86
|
+
compileTags(tags || mustache.tags);
|
|
87
|
+
var scanner = new Scanner(template);
|
|
88
|
+
var start, type, value, chr, token, openSection;
|
|
89
|
+
while (!scanner.eos()) {
|
|
90
|
+
start = scanner.pos;
|
|
91
|
+
value = scanner.scanUntil(openingTagRe);
|
|
92
|
+
if (value) {
|
|
93
|
+
for (var i = 0, valueLength = value.length; i < valueLength; ++i) {
|
|
94
|
+
chr = value.charAt(i);
|
|
95
|
+
if (isWhitespace(chr)) {
|
|
96
|
+
spaces.push(tokens.length);
|
|
97
|
+
indentation += chr;
|
|
98
|
+
} else {
|
|
99
|
+
nonSpace = true;
|
|
100
|
+
lineHasNonSpace = true;
|
|
101
|
+
indentation += " ";
|
|
102
|
+
}
|
|
103
|
+
tokens.push(["text", chr, start, start + 1]);
|
|
104
|
+
start += 1;
|
|
105
|
+
if (chr === "\n") {
|
|
106
|
+
stripSpace();
|
|
107
|
+
indentation = "";
|
|
108
|
+
tagIndex = 0;
|
|
109
|
+
lineHasNonSpace = false;
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (!scanner.scan(openingTagRe))
|
|
114
|
+
break;
|
|
115
|
+
hasTag = true;
|
|
116
|
+
type = scanner.scan(tagRe) || "name";
|
|
117
|
+
scanner.scan(whiteRe);
|
|
118
|
+
if (type === "=") {
|
|
119
|
+
value = scanner.scanUntil(equalsRe);
|
|
120
|
+
scanner.scan(equalsRe);
|
|
121
|
+
scanner.scanUntil(closingTagRe);
|
|
122
|
+
} else if (type === "{") {
|
|
123
|
+
value = scanner.scanUntil(closingCurlyRe);
|
|
124
|
+
scanner.scan(curlyRe);
|
|
125
|
+
scanner.scanUntil(closingTagRe);
|
|
126
|
+
type = "&";
|
|
127
|
+
} else {
|
|
128
|
+
value = scanner.scanUntil(closingTagRe);
|
|
129
|
+
}
|
|
130
|
+
if (!scanner.scan(closingTagRe))
|
|
131
|
+
throw new Error("Unclosed tag at " + scanner.pos);
|
|
132
|
+
if (type == ">") {
|
|
133
|
+
token = [type, value, start, scanner.pos, indentation, tagIndex, lineHasNonSpace];
|
|
134
|
+
} else {
|
|
135
|
+
token = [type, value, start, scanner.pos];
|
|
136
|
+
}
|
|
137
|
+
tagIndex++;
|
|
138
|
+
tokens.push(token);
|
|
139
|
+
if (type === "#" || type === "^") {
|
|
140
|
+
sections.push(token);
|
|
141
|
+
} else if (type === "/") {
|
|
142
|
+
openSection = sections.pop();
|
|
143
|
+
if (!openSection)
|
|
144
|
+
throw new Error('Unopened section "' + value + '" at ' + start);
|
|
145
|
+
if (openSection[1] !== value)
|
|
146
|
+
throw new Error('Unclosed section "' + openSection[1] + '" at ' + start);
|
|
147
|
+
} else if (type === "name" || type === "{" || type === "&") {
|
|
148
|
+
nonSpace = true;
|
|
149
|
+
} else if (type === "=") {
|
|
150
|
+
compileTags(value);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
stripSpace();
|
|
154
|
+
openSection = sections.pop();
|
|
155
|
+
if (openSection)
|
|
156
|
+
throw new Error('Unclosed section "' + openSection[1] + '" at ' + scanner.pos);
|
|
157
|
+
return nestTokens(squashTokens(tokens));
|
|
158
|
+
}
|
|
159
|
+
function squashTokens(tokens) {
|
|
160
|
+
var squashedTokens = [];
|
|
161
|
+
var token, lastToken;
|
|
162
|
+
for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {
|
|
163
|
+
token = tokens[i];
|
|
164
|
+
if (token) {
|
|
165
|
+
if (token[0] === "text" && lastToken && lastToken[0] === "text") {
|
|
166
|
+
lastToken[1] += token[1];
|
|
167
|
+
lastToken[3] = token[3];
|
|
168
|
+
} else {
|
|
169
|
+
squashedTokens.push(token);
|
|
170
|
+
lastToken = token;
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
return squashedTokens;
|
|
175
|
+
}
|
|
176
|
+
function nestTokens(tokens) {
|
|
177
|
+
var nestedTokens = [];
|
|
178
|
+
var collector = nestedTokens;
|
|
179
|
+
var sections = [];
|
|
180
|
+
var token, section;
|
|
181
|
+
for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {
|
|
182
|
+
token = tokens[i];
|
|
183
|
+
switch (token[0]) {
|
|
184
|
+
case "#":
|
|
185
|
+
case "^":
|
|
186
|
+
collector.push(token);
|
|
187
|
+
sections.push(token);
|
|
188
|
+
collector = token[4] = [];
|
|
189
|
+
break;
|
|
190
|
+
case "/":
|
|
191
|
+
section = sections.pop();
|
|
192
|
+
section[5] = token[2];
|
|
193
|
+
collector = sections.length > 0 ? sections[sections.length - 1][4] : nestedTokens;
|
|
194
|
+
break;
|
|
195
|
+
default:
|
|
196
|
+
collector.push(token);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return nestedTokens;
|
|
200
|
+
}
|
|
201
|
+
function Scanner(string) {
|
|
202
|
+
this.string = string;
|
|
203
|
+
this.tail = string;
|
|
204
|
+
this.pos = 0;
|
|
205
|
+
}
|
|
206
|
+
Scanner.prototype.eos = function eos() {
|
|
207
|
+
return this.tail === "";
|
|
208
|
+
};
|
|
209
|
+
Scanner.prototype.scan = function scan(re) {
|
|
210
|
+
var match = this.tail.match(re);
|
|
211
|
+
if (!match || match.index !== 0)
|
|
212
|
+
return "";
|
|
213
|
+
var string = match[0];
|
|
214
|
+
this.tail = this.tail.substring(string.length);
|
|
215
|
+
this.pos += string.length;
|
|
216
|
+
return string;
|
|
217
|
+
};
|
|
218
|
+
Scanner.prototype.scanUntil = function scanUntil(re) {
|
|
219
|
+
var index = this.tail.search(re), match;
|
|
220
|
+
switch (index) {
|
|
221
|
+
case -1:
|
|
222
|
+
match = this.tail;
|
|
223
|
+
this.tail = "";
|
|
224
|
+
break;
|
|
225
|
+
case 0:
|
|
226
|
+
match = "";
|
|
227
|
+
break;
|
|
228
|
+
default:
|
|
229
|
+
match = this.tail.substring(0, index);
|
|
230
|
+
this.tail = this.tail.substring(index);
|
|
231
|
+
}
|
|
232
|
+
this.pos += match.length;
|
|
233
|
+
return match;
|
|
234
|
+
};
|
|
235
|
+
function Context(view, parentContext) {
|
|
236
|
+
this.view = view;
|
|
237
|
+
this.cache = { ".": this.view };
|
|
238
|
+
this.parent = parentContext;
|
|
239
|
+
}
|
|
240
|
+
Context.prototype.push = function push(view) {
|
|
241
|
+
return new Context(view, this);
|
|
242
|
+
};
|
|
243
|
+
Context.prototype.lookup = function lookup(name) {
|
|
244
|
+
var cache = this.cache;
|
|
245
|
+
var value;
|
|
246
|
+
if (cache.hasOwnProperty(name)) {
|
|
247
|
+
value = cache[name];
|
|
248
|
+
} else {
|
|
249
|
+
var context = this, intermediateValue, names, index, lookupHit = false;
|
|
250
|
+
while (context) {
|
|
251
|
+
if (name.indexOf(".") > 0) {
|
|
252
|
+
intermediateValue = context.view;
|
|
253
|
+
names = name.split(".");
|
|
254
|
+
index = 0;
|
|
255
|
+
while (intermediateValue != null && index < names.length) {
|
|
256
|
+
if (index === names.length - 1)
|
|
257
|
+
lookupHit = hasProperty(intermediateValue, names[index]) || primitiveHasOwnProperty(intermediateValue, names[index]);
|
|
258
|
+
intermediateValue = intermediateValue[names[index++]];
|
|
259
|
+
}
|
|
260
|
+
} else {
|
|
261
|
+
intermediateValue = context.view[name];
|
|
262
|
+
lookupHit = hasProperty(context.view, name);
|
|
263
|
+
}
|
|
264
|
+
if (lookupHit) {
|
|
265
|
+
value = intermediateValue;
|
|
266
|
+
break;
|
|
267
|
+
}
|
|
268
|
+
context = context.parent;
|
|
269
|
+
}
|
|
270
|
+
cache[name] = value;
|
|
271
|
+
}
|
|
272
|
+
if (isFunction(value))
|
|
273
|
+
value = value.call(this.view);
|
|
274
|
+
return value;
|
|
275
|
+
};
|
|
276
|
+
function Writer() {
|
|
277
|
+
this.templateCache = {
|
|
278
|
+
_cache: {},
|
|
279
|
+
set: function set(key, value) {
|
|
280
|
+
this._cache[key] = value;
|
|
281
|
+
},
|
|
282
|
+
get: function get(key) {
|
|
283
|
+
return this._cache[key];
|
|
284
|
+
},
|
|
285
|
+
clear: function clear() {
|
|
286
|
+
this._cache = {};
|
|
287
|
+
}
|
|
288
|
+
};
|
|
289
|
+
}
|
|
290
|
+
Writer.prototype.clearCache = function clearCache() {
|
|
291
|
+
if (typeof this.templateCache !== "undefined") {
|
|
292
|
+
this.templateCache.clear();
|
|
293
|
+
}
|
|
294
|
+
};
|
|
295
|
+
Writer.prototype.parse = function parse(template, tags) {
|
|
296
|
+
var cache = this.templateCache;
|
|
297
|
+
var cacheKey = template + ":" + (tags || mustache.tags).join(":");
|
|
298
|
+
var isCacheEnabled = typeof cache !== "undefined";
|
|
299
|
+
var tokens = isCacheEnabled ? cache.get(cacheKey) : void 0;
|
|
300
|
+
if (tokens == void 0) {
|
|
301
|
+
tokens = parseTemplate(template, tags);
|
|
302
|
+
isCacheEnabled && cache.set(cacheKey, tokens);
|
|
303
|
+
}
|
|
304
|
+
return tokens;
|
|
305
|
+
};
|
|
306
|
+
Writer.prototype.render = function render(template, view, partials, config) {
|
|
307
|
+
var tags = this.getConfigTags(config);
|
|
308
|
+
var tokens = this.parse(template, tags);
|
|
309
|
+
var context = view instanceof Context ? view : new Context(view, void 0);
|
|
310
|
+
return this.renderTokens(tokens, context, partials, template, config);
|
|
311
|
+
};
|
|
312
|
+
Writer.prototype.renderTokens = function renderTokens(tokens, context, partials, originalTemplate, config) {
|
|
313
|
+
var buffer = "";
|
|
314
|
+
var token, symbol, value;
|
|
315
|
+
for (var i = 0, numTokens = tokens.length; i < numTokens; ++i) {
|
|
316
|
+
value = void 0;
|
|
317
|
+
token = tokens[i];
|
|
318
|
+
symbol = token[0];
|
|
319
|
+
if (symbol === "#") value = this.renderSection(token, context, partials, originalTemplate, config);
|
|
320
|
+
else if (symbol === "^") value = this.renderInverted(token, context, partials, originalTemplate, config);
|
|
321
|
+
else if (symbol === ">") value = this.renderPartial(token, context, partials, config);
|
|
322
|
+
else if (symbol === "&") value = this.unescapedValue(token, context);
|
|
323
|
+
else if (symbol === "name") value = this.escapedValue(token, context, config);
|
|
324
|
+
else if (symbol === "text") value = this.rawValue(token);
|
|
325
|
+
if (value !== void 0)
|
|
326
|
+
buffer += value;
|
|
327
|
+
}
|
|
328
|
+
return buffer;
|
|
329
|
+
};
|
|
330
|
+
Writer.prototype.renderSection = function renderSection(token, context, partials, originalTemplate, config) {
|
|
331
|
+
var self = this;
|
|
332
|
+
var buffer = "";
|
|
333
|
+
var value = context.lookup(token[1]);
|
|
334
|
+
function subRender(template) {
|
|
335
|
+
return self.render(template, context, partials, config);
|
|
336
|
+
}
|
|
337
|
+
if (!value) return;
|
|
338
|
+
if (isArray(value)) {
|
|
339
|
+
for (var j = 0, valueLength = value.length; j < valueLength; ++j) {
|
|
340
|
+
buffer += this.renderTokens(token[4], context.push(value[j]), partials, originalTemplate, config);
|
|
341
|
+
}
|
|
342
|
+
} else if (typeof value === "object" || typeof value === "string" || typeof value === "number") {
|
|
343
|
+
buffer += this.renderTokens(token[4], context.push(value), partials, originalTemplate, config);
|
|
344
|
+
} else if (isFunction(value)) {
|
|
345
|
+
if (typeof originalTemplate !== "string")
|
|
346
|
+
throw new Error("Cannot use higher-order sections without the original template");
|
|
347
|
+
value = value.call(context.view, originalTemplate.slice(token[3], token[5]), subRender);
|
|
348
|
+
if (value != null)
|
|
349
|
+
buffer += value;
|
|
350
|
+
} else {
|
|
351
|
+
buffer += this.renderTokens(token[4], context, partials, originalTemplate, config);
|
|
352
|
+
}
|
|
353
|
+
return buffer;
|
|
354
|
+
};
|
|
355
|
+
Writer.prototype.renderInverted = function renderInverted(token, context, partials, originalTemplate, config) {
|
|
356
|
+
var value = context.lookup(token[1]);
|
|
357
|
+
if (!value || isArray(value) && value.length === 0)
|
|
358
|
+
return this.renderTokens(token[4], context, partials, originalTemplate, config);
|
|
359
|
+
};
|
|
360
|
+
Writer.prototype.indentPartial = function indentPartial(partial, indentation, lineHasNonSpace) {
|
|
361
|
+
var filteredIndentation = indentation.replace(/[^ \t]/g, "");
|
|
362
|
+
var partialByNl = partial.split("\n");
|
|
363
|
+
for (var i = 0; i < partialByNl.length; i++) {
|
|
364
|
+
if (partialByNl[i].length && (i > 0 || !lineHasNonSpace)) {
|
|
365
|
+
partialByNl[i] = filteredIndentation + partialByNl[i];
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
return partialByNl.join("\n");
|
|
369
|
+
};
|
|
370
|
+
Writer.prototype.renderPartial = function renderPartial(token, context, partials, config) {
|
|
371
|
+
if (!partials) return;
|
|
372
|
+
var tags = this.getConfigTags(config);
|
|
373
|
+
var value = isFunction(partials) ? partials(token[1]) : partials[token[1]];
|
|
374
|
+
if (value != null) {
|
|
375
|
+
var lineHasNonSpace = token[6];
|
|
376
|
+
var tagIndex = token[5];
|
|
377
|
+
var indentation = token[4];
|
|
378
|
+
var indentedValue = value;
|
|
379
|
+
if (tagIndex == 0 && indentation) {
|
|
380
|
+
indentedValue = this.indentPartial(value, indentation, lineHasNonSpace);
|
|
381
|
+
}
|
|
382
|
+
var tokens = this.parse(indentedValue, tags);
|
|
383
|
+
return this.renderTokens(tokens, context, partials, indentedValue, config);
|
|
384
|
+
}
|
|
385
|
+
};
|
|
386
|
+
Writer.prototype.unescapedValue = function unescapedValue(token, context) {
|
|
387
|
+
var value = context.lookup(token[1]);
|
|
388
|
+
if (value != null)
|
|
389
|
+
return value;
|
|
390
|
+
};
|
|
391
|
+
Writer.prototype.escapedValue = function escapedValue(token, context, config) {
|
|
392
|
+
var escape = this.getConfigEscape(config) || mustache.escape;
|
|
393
|
+
var value = context.lookup(token[1]);
|
|
394
|
+
if (value != null)
|
|
395
|
+
return typeof value === "number" && escape === mustache.escape ? String(value) : escape(value);
|
|
396
|
+
};
|
|
397
|
+
Writer.prototype.rawValue = function rawValue(token) {
|
|
398
|
+
return token[1];
|
|
399
|
+
};
|
|
400
|
+
Writer.prototype.getConfigTags = function getConfigTags(config) {
|
|
401
|
+
if (isArray(config)) {
|
|
402
|
+
return config;
|
|
403
|
+
} else if (config && typeof config === "object") {
|
|
404
|
+
return config.tags;
|
|
405
|
+
} else {
|
|
406
|
+
return void 0;
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
Writer.prototype.getConfigEscape = function getConfigEscape(config) {
|
|
410
|
+
if (config && typeof config === "object" && !isArray(config)) {
|
|
411
|
+
return config.escape;
|
|
412
|
+
} else {
|
|
413
|
+
return void 0;
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
var mustache = {
|
|
417
|
+
name: "mustache.js",
|
|
418
|
+
version: "4.2.0",
|
|
419
|
+
tags: ["{{", "}}"],
|
|
420
|
+
clearCache: void 0,
|
|
421
|
+
escape: void 0,
|
|
422
|
+
parse: void 0,
|
|
423
|
+
render: void 0,
|
|
424
|
+
Scanner: void 0,
|
|
425
|
+
Context: void 0,
|
|
426
|
+
Writer: void 0,
|
|
427
|
+
/**
|
|
428
|
+
* Allows a user to override the default caching strategy, by providing an
|
|
429
|
+
* object with set, get and clear methods. This can also be used to disable
|
|
430
|
+
* the cache by setting it to the literal `undefined`.
|
|
431
|
+
*/
|
|
432
|
+
set templateCache(cache) {
|
|
433
|
+
defaultWriter.templateCache = cache;
|
|
434
|
+
},
|
|
435
|
+
/**
|
|
436
|
+
* Gets the default or overridden caching object from the default writer.
|
|
437
|
+
*/
|
|
438
|
+
get templateCache() {
|
|
439
|
+
return defaultWriter.templateCache;
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
var defaultWriter = new Writer();
|
|
443
|
+
mustache.clearCache = function clearCache2() {
|
|
444
|
+
return defaultWriter.clearCache();
|
|
445
|
+
};
|
|
446
|
+
mustache.parse = function parse2(template, tags) {
|
|
447
|
+
return defaultWriter.parse(template, tags);
|
|
448
|
+
};
|
|
449
|
+
mustache.render = function render2(template, view, partials, config) {
|
|
450
|
+
if (typeof template !== "string") {
|
|
451
|
+
throw new TypeError('Invalid template! Template should be a "string" but "' + typeStr(template) + '" was given as the first argument for mustache#render(template, view, partials)');
|
|
452
|
+
}
|
|
453
|
+
return defaultWriter.render(template, view, partials, config);
|
|
454
|
+
};
|
|
455
|
+
mustache.escape = escapeHtml;
|
|
456
|
+
mustache.Scanner = Scanner;
|
|
457
|
+
mustache.Context = Context;
|
|
458
|
+
mustache.Writer = Writer;
|
|
459
|
+
var mustache_default = mustache;
|
|
460
|
+
|
|
461
|
+
// ../../node_modules/.pnpm/langfuse-core@3.39.2/node_modules/langfuse-core/lib/index.mjs
|
|
462
|
+
var SimpleEventEmitter = class {
|
|
463
|
+
constructor() {
|
|
464
|
+
this.events = {};
|
|
465
|
+
this.events = {};
|
|
466
|
+
}
|
|
467
|
+
on(event, listener) {
|
|
468
|
+
if (!this.events[event]) {
|
|
469
|
+
this.events[event] = [];
|
|
470
|
+
}
|
|
471
|
+
this.events[event].push(listener);
|
|
472
|
+
return () => {
|
|
473
|
+
this.events[event] = this.events[event].filter((x) => x !== listener);
|
|
474
|
+
};
|
|
475
|
+
}
|
|
476
|
+
emit(event, payload) {
|
|
477
|
+
for (const listener of this.events[event] || []) {
|
|
478
|
+
listener(payload);
|
|
479
|
+
}
|
|
480
|
+
for (const listener of this.events["*"] || []) {
|
|
481
|
+
listener(event, payload);
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
};
|
|
485
|
+
var DEFAULT_PROMPT_CACHE_TTL_SECONDS = 60;
|
|
486
|
+
var LangfusePromptCacheItem = class {
|
|
487
|
+
constructor(value, ttlSeconds) {
|
|
488
|
+
this.value = value;
|
|
489
|
+
this._expiry = Date.now() + ttlSeconds * 1e3;
|
|
490
|
+
}
|
|
491
|
+
get isExpired() {
|
|
492
|
+
return Date.now() > this._expiry;
|
|
493
|
+
}
|
|
494
|
+
};
|
|
495
|
+
var LangfusePromptCache = class {
|
|
496
|
+
constructor() {
|
|
497
|
+
this._cache = /* @__PURE__ */ new Map();
|
|
498
|
+
this._defaultTtlSeconds = DEFAULT_PROMPT_CACHE_TTL_SECONDS;
|
|
499
|
+
this._refreshingKeys = /* @__PURE__ */ new Map();
|
|
500
|
+
}
|
|
501
|
+
getIncludingExpired(key) {
|
|
502
|
+
return this._cache.get(key) ?? null;
|
|
503
|
+
}
|
|
504
|
+
set(key, value, ttlSeconds) {
|
|
505
|
+
const effectiveTtlSeconds = ttlSeconds ?? this._defaultTtlSeconds;
|
|
506
|
+
this._cache.set(key, new LangfusePromptCacheItem(value, effectiveTtlSeconds));
|
|
507
|
+
}
|
|
508
|
+
addRefreshingPromise(key, promise) {
|
|
509
|
+
this._refreshingKeys.set(key, promise);
|
|
510
|
+
promise.then(() => {
|
|
511
|
+
this._refreshingKeys.delete(key);
|
|
512
|
+
}).catch(() => {
|
|
513
|
+
this._refreshingKeys.delete(key);
|
|
514
|
+
});
|
|
515
|
+
}
|
|
516
|
+
isRefreshing(key) {
|
|
517
|
+
return this._refreshingKeys.has(key);
|
|
518
|
+
}
|
|
519
|
+
invalidate(promptName) {
|
|
520
|
+
console.log("invalidating", promptName, this._cache.keys());
|
|
521
|
+
for (const key of this._cache.keys()) {
|
|
522
|
+
if (key.startsWith(promptName)) {
|
|
523
|
+
this._cache.delete(key);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
};
|
|
528
|
+
var LangfusePersistedProperty;
|
|
529
|
+
(function(LangfusePersistedProperty2) {
|
|
530
|
+
LangfusePersistedProperty2["Props"] = "props";
|
|
531
|
+
LangfusePersistedProperty2["Queue"] = "queue";
|
|
532
|
+
LangfusePersistedProperty2["OptedOut"] = "opted_out";
|
|
533
|
+
})(LangfusePersistedProperty || (LangfusePersistedProperty = {}));
|
|
534
|
+
var ChatMessageType;
|
|
535
|
+
(function(ChatMessageType2) {
|
|
536
|
+
ChatMessageType2["ChatMessage"] = "chatmessage";
|
|
537
|
+
ChatMessageType2["Placeholder"] = "placeholder";
|
|
538
|
+
})(ChatMessageType || (ChatMessageType = {}));
|
|
539
|
+
mustache_default.escape = function(text) {
|
|
540
|
+
return text;
|
|
541
|
+
};
|
|
542
|
+
var BasePromptClient = class {
|
|
543
|
+
constructor(prompt, isFallback = false, type) {
|
|
544
|
+
this.name = prompt.name;
|
|
545
|
+
this.version = prompt.version;
|
|
546
|
+
this.config = prompt.config;
|
|
547
|
+
this.labels = prompt.labels;
|
|
548
|
+
this.tags = prompt.tags;
|
|
549
|
+
this.isFallback = isFallback;
|
|
550
|
+
this.type = type;
|
|
551
|
+
this.commitMessage = prompt.commitMessage;
|
|
552
|
+
}
|
|
553
|
+
_transformToLangchainVariables(content2) {
|
|
554
|
+
const jsonEscapedContent = this.escapeJsonForLangchain(content2);
|
|
555
|
+
return jsonEscapedContent.replace(/\{\{(\w+)\}\}/g, "{$1}");
|
|
556
|
+
}
|
|
557
|
+
/**
|
|
558
|
+
* Escapes every curly brace that is part of a JSON object by doubling it.
|
|
559
|
+
*
|
|
560
|
+
* A curly brace is considered “JSON-related” when, after skipping any immediate
|
|
561
|
+
* whitespace, the next non-whitespace character is a single (') or double (") quote.
|
|
562
|
+
*
|
|
563
|
+
* Braces that are already doubled (e.g. `{{variable}}` placeholders) are left untouched.
|
|
564
|
+
*
|
|
565
|
+
* @param text - Input string that may contain JSON snippets.
|
|
566
|
+
* @returns The string with JSON-related braces doubled.
|
|
567
|
+
*/
|
|
568
|
+
escapeJsonForLangchain(text) {
|
|
569
|
+
const out = [];
|
|
570
|
+
const stack = [];
|
|
571
|
+
let i = 0;
|
|
572
|
+
const n = text.length;
|
|
573
|
+
while (i < n) {
|
|
574
|
+
const ch = text[i];
|
|
575
|
+
if (ch === "{") {
|
|
576
|
+
if (i + 1 < n && text[i + 1] === "{") {
|
|
577
|
+
out.push("{{");
|
|
578
|
+
i += 2;
|
|
579
|
+
continue;
|
|
580
|
+
}
|
|
581
|
+
let j = i + 1;
|
|
582
|
+
while (j < n && /\s/.test(text[j])) {
|
|
583
|
+
j++;
|
|
584
|
+
}
|
|
585
|
+
const isJson = j < n && (text[j] === "'" || text[j] === '"');
|
|
586
|
+
out.push(isJson ? "{{" : "{");
|
|
587
|
+
stack.push(isJson);
|
|
588
|
+
i += 1;
|
|
589
|
+
continue;
|
|
590
|
+
}
|
|
591
|
+
if (ch === "}") {
|
|
592
|
+
if (i + 1 < n && text[i + 1] === "}") {
|
|
593
|
+
out.push("}}");
|
|
594
|
+
i += 2;
|
|
595
|
+
continue;
|
|
596
|
+
}
|
|
597
|
+
const isJson = stack.pop() ?? false;
|
|
598
|
+
out.push(isJson ? "}}" : "}");
|
|
599
|
+
i += 1;
|
|
600
|
+
continue;
|
|
601
|
+
}
|
|
602
|
+
out.push(ch);
|
|
603
|
+
i += 1;
|
|
604
|
+
}
|
|
605
|
+
return out.join("");
|
|
606
|
+
}
|
|
607
|
+
};
|
|
608
|
+
var TextPromptClient = class extends BasePromptClient {
|
|
609
|
+
constructor(prompt, isFallback = false) {
|
|
610
|
+
super(prompt, isFallback, "text");
|
|
611
|
+
this.promptResponse = prompt;
|
|
612
|
+
this.prompt = prompt.prompt;
|
|
613
|
+
}
|
|
614
|
+
compile(variables, _placeholders) {
|
|
615
|
+
return mustache_default.render(this.promptResponse.prompt, variables ?? {});
|
|
616
|
+
}
|
|
617
|
+
getLangchainPrompt(_options) {
|
|
618
|
+
return this._transformToLangchainVariables(this.prompt);
|
|
619
|
+
}
|
|
620
|
+
toJSON() {
|
|
621
|
+
return JSON.stringify({
|
|
622
|
+
name: this.name,
|
|
623
|
+
prompt: this.prompt,
|
|
624
|
+
version: this.version,
|
|
625
|
+
isFallback: this.isFallback,
|
|
626
|
+
tags: this.tags,
|
|
627
|
+
labels: this.labels,
|
|
628
|
+
type: this.type,
|
|
629
|
+
config: this.config
|
|
630
|
+
});
|
|
631
|
+
}
|
|
632
|
+
};
|
|
633
|
+
var ChatPromptClient = class _ChatPromptClient extends BasePromptClient {
|
|
634
|
+
constructor(prompt, isFallback = false) {
|
|
635
|
+
const normalizedPrompt = _ChatPromptClient.normalizePrompt(prompt.prompt);
|
|
636
|
+
const typedPrompt = {
|
|
637
|
+
...prompt,
|
|
638
|
+
prompt: normalizedPrompt
|
|
639
|
+
};
|
|
640
|
+
super(typedPrompt, isFallback, "chat");
|
|
641
|
+
this.promptResponse = typedPrompt;
|
|
642
|
+
this.prompt = normalizedPrompt;
|
|
643
|
+
}
|
|
644
|
+
static normalizePrompt(prompt) {
|
|
645
|
+
return prompt.map((item) => {
|
|
646
|
+
if ("type" in item) {
|
|
647
|
+
return item;
|
|
648
|
+
} else {
|
|
649
|
+
return {
|
|
650
|
+
type: ChatMessageType.ChatMessage,
|
|
651
|
+
...item
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
});
|
|
655
|
+
}
|
|
656
|
+
compile(variables, placeholders) {
|
|
657
|
+
const messagesWithPlaceholdersReplaced = [];
|
|
658
|
+
const placeholderValues = placeholders ?? {};
|
|
659
|
+
for (const item of this.prompt) {
|
|
660
|
+
if ("type" in item && item.type === ChatMessageType.Placeholder) {
|
|
661
|
+
const placeholderValue = placeholderValues[item.name];
|
|
662
|
+
if (Array.isArray(placeholderValue) && placeholderValue.length > 0 && placeholderValue.every((msg) => typeof msg === "object" && "role" in msg && "content" in msg)) {
|
|
663
|
+
messagesWithPlaceholdersReplaced.push(...placeholderValue);
|
|
664
|
+
} else if (Array.isArray(placeholderValue) && placeholderValue.length === 0) ;
|
|
665
|
+
else if (placeholderValue !== void 0) {
|
|
666
|
+
messagesWithPlaceholdersReplaced.push(JSON.stringify(placeholderValue));
|
|
667
|
+
} else {
|
|
668
|
+
messagesWithPlaceholdersReplaced.push(item);
|
|
669
|
+
}
|
|
670
|
+
} else if ("role" in item && "content" in item && item.type === ChatMessageType.ChatMessage) {
|
|
671
|
+
messagesWithPlaceholdersReplaced.push({
|
|
672
|
+
role: item.role,
|
|
673
|
+
content: item.content
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
return messagesWithPlaceholdersReplaced.map((item) => {
|
|
678
|
+
if (typeof item === "object" && item !== null && "role" in item && "content" in item) {
|
|
679
|
+
return {
|
|
680
|
+
...item,
|
|
681
|
+
content: mustache_default.render(item.content, variables ?? {})
|
|
682
|
+
};
|
|
683
|
+
} else {
|
|
684
|
+
return item;
|
|
685
|
+
}
|
|
686
|
+
});
|
|
687
|
+
}
|
|
688
|
+
getLangchainPrompt(options) {
|
|
689
|
+
const messagesWithPlaceholdersReplaced = [];
|
|
690
|
+
const placeholderValues = options?.placeholders ?? {};
|
|
691
|
+
for (const item of this.prompt) {
|
|
692
|
+
if ("type" in item && item.type === ChatMessageType.Placeholder) {
|
|
693
|
+
const placeholderValue = placeholderValues[item.name];
|
|
694
|
+
if (Array.isArray(placeholderValue) && placeholderValue.length > 0 && placeholderValue.every((msg) => typeof msg === "object" && "role" in msg && "content" in msg)) {
|
|
695
|
+
messagesWithPlaceholdersReplaced.push(...placeholderValue.map((msg) => {
|
|
696
|
+
return {
|
|
697
|
+
role: msg.role,
|
|
698
|
+
content: this._transformToLangchainVariables(msg.content)
|
|
699
|
+
};
|
|
700
|
+
}));
|
|
701
|
+
} else if (Array.isArray(placeholderValue) && placeholderValue.length === 0) ;
|
|
702
|
+
else if (placeholderValue !== void 0) {
|
|
703
|
+
messagesWithPlaceholdersReplaced.push(JSON.stringify(placeholderValue));
|
|
704
|
+
} else {
|
|
705
|
+
messagesWithPlaceholdersReplaced.push({
|
|
706
|
+
variableName: item.name,
|
|
707
|
+
optional: false
|
|
708
|
+
});
|
|
709
|
+
}
|
|
710
|
+
} else if ("role" in item && "content" in item && item.type === ChatMessageType.ChatMessage) {
|
|
711
|
+
messagesWithPlaceholdersReplaced.push({
|
|
712
|
+
role: item.role,
|
|
713
|
+
content: this._transformToLangchainVariables(item.content)
|
|
714
|
+
});
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
return messagesWithPlaceholdersReplaced;
|
|
718
|
+
}
|
|
719
|
+
toJSON() {
|
|
720
|
+
return JSON.stringify({
|
|
721
|
+
name: this.name,
|
|
722
|
+
prompt: this.promptResponse.prompt.map((item) => {
|
|
723
|
+
if ("type" in item && item.type === ChatMessageType.ChatMessage) {
|
|
724
|
+
const {
|
|
725
|
+
type: _,
|
|
726
|
+
...messageWithoutType
|
|
727
|
+
} = item;
|
|
728
|
+
return messageWithoutType;
|
|
729
|
+
}
|
|
730
|
+
return item;
|
|
731
|
+
}),
|
|
732
|
+
version: this.version,
|
|
733
|
+
isFallback: this.isFallback,
|
|
734
|
+
tags: this.tags,
|
|
735
|
+
labels: this.labels,
|
|
736
|
+
type: this.type,
|
|
737
|
+
config: this.config
|
|
738
|
+
});
|
|
739
|
+
}
|
|
740
|
+
};
|
|
741
|
+
function assert(truthyValue, message) {
|
|
742
|
+
if (!truthyValue) {
|
|
743
|
+
throw new Error(message);
|
|
744
|
+
}
|
|
745
|
+
}
|
|
746
|
+
function removeTrailingSlash(url) {
|
|
747
|
+
return url?.replace(/\/+$/, "");
|
|
748
|
+
}
|
|
749
|
+
async function retriable(fn, props = {}, log) {
|
|
750
|
+
const {
|
|
751
|
+
retryCount = 3,
|
|
752
|
+
retryDelay = 5e3,
|
|
753
|
+
retryCheck = () => true
|
|
754
|
+
} = props;
|
|
755
|
+
let lastError = null;
|
|
756
|
+
for (let i = 0; i < retryCount + 1; i++) {
|
|
757
|
+
if (i > 0) {
|
|
758
|
+
await new Promise((resolve) => setTimeout(resolve, retryDelay));
|
|
759
|
+
log(`Retrying ${i + 1} of ${retryCount + 1}`);
|
|
760
|
+
}
|
|
761
|
+
try {
|
|
762
|
+
const res = await fn();
|
|
763
|
+
return res;
|
|
764
|
+
} catch (e) {
|
|
765
|
+
lastError = e;
|
|
766
|
+
if (!retryCheck(e)) {
|
|
767
|
+
throw e;
|
|
768
|
+
}
|
|
769
|
+
log(`Retriable error: ${JSON.stringify(e)}`);
|
|
770
|
+
}
|
|
771
|
+
}
|
|
772
|
+
throw lastError;
|
|
773
|
+
}
|
|
774
|
+
function generateUUID(globalThis2) {
|
|
775
|
+
let d = (/* @__PURE__ */ new Date()).getTime();
|
|
776
|
+
let d2 = globalThis2 && globalThis2.performance && globalThis2.performance.now && globalThis2.performance.now() * 1e3 || 0;
|
|
777
|
+
return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(c) {
|
|
778
|
+
let r = Math.random() * 16;
|
|
779
|
+
if (d > 0) {
|
|
780
|
+
r = (d + r) % 16 | 0;
|
|
781
|
+
d = Math.floor(d / 16);
|
|
782
|
+
} else {
|
|
783
|
+
r = (d2 + r) % 16 | 0;
|
|
784
|
+
d2 = Math.floor(d2 / 16);
|
|
785
|
+
}
|
|
786
|
+
return (c === "x" ? r : r & 3 | 8).toString(16);
|
|
787
|
+
});
|
|
788
|
+
}
|
|
789
|
+
function currentTimestamp() {
|
|
790
|
+
return (/* @__PURE__ */ new Date()).getTime();
|
|
791
|
+
}
|
|
792
|
+
function currentISOTime() {
|
|
793
|
+
return (/* @__PURE__ */ new Date()).toISOString();
|
|
794
|
+
}
|
|
795
|
+
function safeSetTimeout(fn, timeout) {
|
|
796
|
+
const t = setTimeout(fn, timeout);
|
|
797
|
+
t?.unref && t?.unref();
|
|
798
|
+
return t;
|
|
799
|
+
}
|
|
800
|
+
function getEnv(key) {
|
|
801
|
+
if (typeof process !== "undefined" && process.env[key]) {
|
|
802
|
+
return process.env[key];
|
|
803
|
+
} else if (typeof globalThis !== "undefined") {
|
|
804
|
+
return globalThis[key];
|
|
805
|
+
}
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
808
|
+
function configLangfuseSDK(params, secretRequired = true) {
|
|
809
|
+
const {
|
|
810
|
+
publicKey,
|
|
811
|
+
secretKey,
|
|
812
|
+
...coreOptions
|
|
813
|
+
} = params ?? {};
|
|
814
|
+
const finalPublicKey = publicKey ?? getEnv("LANGFUSE_PUBLIC_KEY");
|
|
815
|
+
const finalSecretKey = secretRequired ? secretKey ?? getEnv("LANGFUSE_SECRET_KEY") : void 0;
|
|
816
|
+
const finalBaseUrl = coreOptions.baseUrl ?? getEnv("LANGFUSE_BASEURL");
|
|
817
|
+
const finalCoreOptions = {
|
|
818
|
+
...coreOptions,
|
|
819
|
+
baseUrl: finalBaseUrl
|
|
820
|
+
};
|
|
821
|
+
return {
|
|
822
|
+
publicKey: finalPublicKey,
|
|
823
|
+
...secretRequired ? {
|
|
824
|
+
secretKey: finalSecretKey
|
|
825
|
+
} : void 0,
|
|
826
|
+
...finalCoreOptions
|
|
827
|
+
};
|
|
828
|
+
}
|
|
829
|
+
var encodeQueryParams = (params) => {
|
|
830
|
+
const queryParams = new URLSearchParams();
|
|
831
|
+
Object.entries(params ?? {}).forEach(([key, value]) => {
|
|
832
|
+
if (value !== void 0 && value !== null) {
|
|
833
|
+
if (value instanceof Date) {
|
|
834
|
+
queryParams.append(key, value.toISOString());
|
|
835
|
+
} else {
|
|
836
|
+
queryParams.append(key, value.toString());
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
});
|
|
840
|
+
return queryParams.toString();
|
|
841
|
+
};
|
|
842
|
+
var utils = /* @__PURE__ */ Object.freeze({
|
|
843
|
+
__proto__: null,
|
|
844
|
+
assert,
|
|
845
|
+
configLangfuseSDK,
|
|
846
|
+
currentISOTime,
|
|
847
|
+
currentTimestamp,
|
|
848
|
+
encodeQueryParams,
|
|
849
|
+
generateUUID,
|
|
850
|
+
getEnv,
|
|
851
|
+
removeTrailingSlash,
|
|
852
|
+
retriable,
|
|
853
|
+
safeSetTimeout
|
|
854
|
+
});
|
|
855
|
+
var common_release_envs = [
|
|
856
|
+
// Vercel
|
|
857
|
+
"VERCEL_GIT_COMMIT_SHA",
|
|
858
|
+
"NEXT_PUBLIC_VERCEL_GIT_COMMIT_SHA",
|
|
859
|
+
// Netlify
|
|
860
|
+
"COMMIT_REF",
|
|
861
|
+
// Render
|
|
862
|
+
"RENDER_GIT_COMMIT",
|
|
863
|
+
// GitLab CI
|
|
864
|
+
"CI_COMMIT_SHA",
|
|
865
|
+
// CicleCI
|
|
866
|
+
"CIRCLE_SHA1",
|
|
867
|
+
// Cloudflare pages
|
|
868
|
+
"CF_PAGES_COMMIT_SHA",
|
|
869
|
+
// AWS Amplify
|
|
870
|
+
"REACT_APP_GIT_SHA",
|
|
871
|
+
// Heroku
|
|
872
|
+
"SOURCE_VERSION",
|
|
873
|
+
// Trigger.dev
|
|
874
|
+
"TRIGGER_DEPLOYMENT_ID"
|
|
875
|
+
];
|
|
876
|
+
function getCommonReleaseEnvs() {
|
|
877
|
+
for (const key of common_release_envs) {
|
|
878
|
+
const value = getEnv(key);
|
|
879
|
+
if (value) {
|
|
880
|
+
return value;
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
return void 0;
|
|
884
|
+
}
|
|
885
|
+
var fs = null;
|
|
886
|
+
var cryptoModule = null;
|
|
887
|
+
var dynamicImport = (module) => {
|
|
888
|
+
return import(
|
|
889
|
+
/* webpackIgnore: true */
|
|
890
|
+
module
|
|
891
|
+
);
|
|
892
|
+
};
|
|
893
|
+
if (typeof globalThis.Deno !== "undefined") {
|
|
894
|
+
Promise.all([dynamicImport("node:fs"), dynamicImport("node:crypto")]).then(([importedFs, importedCrypto]) => {
|
|
895
|
+
fs = importedFs;
|
|
896
|
+
cryptoModule = importedCrypto;
|
|
897
|
+
}).catch();
|
|
898
|
+
} else if (typeof process !== "undefined" && process.versions?.node) {
|
|
899
|
+
Promise.all([dynamicImport("fs"), dynamicImport("crypto")]).then(([importedFs, importedCrypto]) => {
|
|
900
|
+
fs = importedFs;
|
|
901
|
+
cryptoModule = importedCrypto;
|
|
902
|
+
}).catch();
|
|
903
|
+
} else if (typeof crypto !== "undefined") {
|
|
904
|
+
cryptoModule = crypto;
|
|
905
|
+
}
|
|
906
|
+
var LangfuseMedia = class _LangfuseMedia {
|
|
907
|
+
constructor(params) {
|
|
908
|
+
const {
|
|
909
|
+
obj,
|
|
910
|
+
base64DataUri,
|
|
911
|
+
contentType,
|
|
912
|
+
contentBytes,
|
|
913
|
+
filePath
|
|
914
|
+
} = params;
|
|
915
|
+
this.obj = obj;
|
|
916
|
+
this._mediaId = void 0;
|
|
917
|
+
if (base64DataUri) {
|
|
918
|
+
const [contentBytesParsed, contentTypeParsed] = this.parseBase64DataUri(base64DataUri);
|
|
919
|
+
this._contentBytes = contentBytesParsed;
|
|
920
|
+
this._contentType = contentTypeParsed;
|
|
921
|
+
this._source = "base64_data_uri";
|
|
922
|
+
} else if (contentBytes && contentType) {
|
|
923
|
+
this._contentBytes = contentBytes;
|
|
924
|
+
this._contentType = contentType;
|
|
925
|
+
this._source = "bytes";
|
|
926
|
+
} else if (filePath && contentType) {
|
|
927
|
+
if (!fs) {
|
|
928
|
+
throw new Error("File system support is not available in this environment");
|
|
929
|
+
}
|
|
930
|
+
if (!fs.existsSync(filePath)) {
|
|
931
|
+
throw new Error(`File at path ${filePath} does not exist`);
|
|
932
|
+
}
|
|
933
|
+
this._contentBytes = this.readFile(filePath);
|
|
934
|
+
this._contentType = this._contentBytes ? contentType : void 0;
|
|
935
|
+
this._source = this._contentBytes ? "file" : void 0;
|
|
936
|
+
} else {
|
|
937
|
+
console.error("base64DataUri, or contentBytes and contentType, or filePath must be provided to LangfuseMedia");
|
|
938
|
+
}
|
|
939
|
+
}
|
|
940
|
+
readFile(filePath) {
|
|
941
|
+
try {
|
|
942
|
+
if (!fs) {
|
|
943
|
+
throw new Error("File system support is not available in this environment");
|
|
944
|
+
}
|
|
945
|
+
return fs.readFileSync(filePath);
|
|
946
|
+
} catch (error) {
|
|
947
|
+
console.error(`Error reading file at path ${filePath}`, error);
|
|
948
|
+
return void 0;
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
parseBase64DataUri(data) {
|
|
952
|
+
try {
|
|
953
|
+
if (!data || typeof data !== "string") {
|
|
954
|
+
throw new Error("Data URI is not a string");
|
|
955
|
+
}
|
|
956
|
+
if (!data.startsWith("data:")) {
|
|
957
|
+
throw new Error("Data URI does not start with 'data:'");
|
|
958
|
+
}
|
|
959
|
+
const [header, actualData] = data.slice(5).split(",", 2);
|
|
960
|
+
if (!header || !actualData) {
|
|
961
|
+
throw new Error("Invalid URI");
|
|
962
|
+
}
|
|
963
|
+
const headerParts = header.split(";");
|
|
964
|
+
if (!headerParts.includes("base64")) {
|
|
965
|
+
throw new Error("Data is not base64 encoded");
|
|
966
|
+
}
|
|
967
|
+
const contentType = headerParts[0];
|
|
968
|
+
if (!contentType) {
|
|
969
|
+
throw new Error("Content type is empty");
|
|
970
|
+
}
|
|
971
|
+
return [Buffer.from(actualData, "base64"), contentType];
|
|
972
|
+
} catch (error) {
|
|
973
|
+
console.error("Error parsing base64 data URI", error);
|
|
974
|
+
return [void 0, void 0];
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
get contentLength() {
|
|
978
|
+
return this._contentBytes?.length;
|
|
979
|
+
}
|
|
980
|
+
get contentSha256Hash() {
|
|
981
|
+
if (!this._contentBytes) {
|
|
982
|
+
return void 0;
|
|
983
|
+
}
|
|
984
|
+
if (!cryptoModule) {
|
|
985
|
+
console.error("Crypto support is not available in this environment");
|
|
986
|
+
return void 0;
|
|
987
|
+
}
|
|
988
|
+
const sha256Hash = cryptoModule.createHash("sha256").update(this._contentBytes).digest("base64");
|
|
989
|
+
return sha256Hash;
|
|
990
|
+
}
|
|
991
|
+
toJSON() {
|
|
992
|
+
if (!this._contentType || !this._source || !this._mediaId) {
|
|
993
|
+
return `<Upload handling failed for LangfuseMedia of type ${this._contentType}>`;
|
|
994
|
+
}
|
|
995
|
+
return `@@@langfuseMedia:type=${this._contentType}|id=${this._mediaId}|source=${this._source}@@@`;
|
|
996
|
+
}
|
|
997
|
+
/**
|
|
998
|
+
* Parses a media reference string into a ParsedMediaReference.
|
|
999
|
+
*
|
|
1000
|
+
* Example reference string:
|
|
1001
|
+
* "@@@langfuseMedia:type=image/jpeg|id=some-uuid|source=base64DataUri@@@"
|
|
1002
|
+
*
|
|
1003
|
+
* @param referenceString - The reference string to parse.
|
|
1004
|
+
* @returns An object with the mediaId, source, and contentType.
|
|
1005
|
+
*
|
|
1006
|
+
* @throws Error if the reference string is invalid or missing required fields.
|
|
1007
|
+
*/
|
|
1008
|
+
static parseReferenceString(referenceString) {
|
|
1009
|
+
const prefix = "@@@langfuseMedia:";
|
|
1010
|
+
const suffix = "@@@";
|
|
1011
|
+
if (!referenceString.startsWith(prefix)) {
|
|
1012
|
+
throw new Error("Reference string does not start with '@@@langfuseMedia:type='");
|
|
1013
|
+
}
|
|
1014
|
+
if (!referenceString.endsWith(suffix)) {
|
|
1015
|
+
throw new Error("Reference string does not end with '@@@'");
|
|
1016
|
+
}
|
|
1017
|
+
const content2 = referenceString.slice(prefix.length, -suffix.length);
|
|
1018
|
+
const pairs = content2.split("|");
|
|
1019
|
+
const parsedData = {};
|
|
1020
|
+
for (const pair of pairs) {
|
|
1021
|
+
const [key, value] = pair.split("=", 2);
|
|
1022
|
+
parsedData[key] = value;
|
|
1023
|
+
}
|
|
1024
|
+
if (!("type" in parsedData && "id" in parsedData && "source" in parsedData)) {
|
|
1025
|
+
throw new Error("Missing required fields in reference string");
|
|
1026
|
+
}
|
|
1027
|
+
return {
|
|
1028
|
+
mediaId: parsedData["id"],
|
|
1029
|
+
source: parsedData["source"],
|
|
1030
|
+
contentType: parsedData["type"]
|
|
1031
|
+
};
|
|
1032
|
+
}
|
|
1033
|
+
/**
|
|
1034
|
+
* Replaces the media reference strings in an object with base64 data URIs for the media content.
|
|
1035
|
+
*
|
|
1036
|
+
* This method recursively traverses an object (up to a maximum depth of 10) looking for media reference strings
|
|
1037
|
+
* in the format "@@@langfuseMedia:...@@@". When found, it fetches the actual media content using the provided
|
|
1038
|
+
* Langfuse client and replaces the reference string with a base64 data URI.
|
|
1039
|
+
*
|
|
1040
|
+
* If fetching media content fails for a reference string, a warning is logged and the reference string is left unchanged.
|
|
1041
|
+
*
|
|
1042
|
+
* @param params - Configuration object
|
|
1043
|
+
* @param params.obj - The object to process. Can be a primitive value, array, or nested object
|
|
1044
|
+
* @param params.langfuseClient - Langfuse client instance used to fetch media content
|
|
1045
|
+
* @param params.resolveWith - The representation of the media content to replace the media reference string with. Currently only "base64DataUri" is supported.
|
|
1046
|
+
* @param params.maxDepth - Optional. Default is 10. The maximum depth to traverse the object.
|
|
1047
|
+
*
|
|
1048
|
+
* @returns A deep copy of the input object with all media references replaced with base64 data URIs where possible
|
|
1049
|
+
*
|
|
1050
|
+
* @example
|
|
1051
|
+
* ```typescript
|
|
1052
|
+
* const obj = {
|
|
1053
|
+
* image: "@@@langfuseMedia:type=image/jpeg|id=123|source=bytes@@@",
|
|
1054
|
+
* nested: {
|
|
1055
|
+
* pdf: "@@@langfuseMedia:type=application/pdf|id=456|source=bytes@@@"
|
|
1056
|
+
* }
|
|
1057
|
+
* };
|
|
1058
|
+
*
|
|
1059
|
+
* const result = await LangfuseMedia.resolveMediaReferences({
|
|
1060
|
+
* obj,
|
|
1061
|
+
* langfuseClient
|
|
1062
|
+
* });
|
|
1063
|
+
*
|
|
1064
|
+
* // Result:
|
|
1065
|
+
* // {
|
|
1066
|
+
* // image: "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
|
|
1067
|
+
* // nested: {
|
|
1068
|
+
* // pdf: "data:application/pdf;base64,JVBERi0xLjcK..."
|
|
1069
|
+
* // }
|
|
1070
|
+
* // }
|
|
1071
|
+
* ```
|
|
1072
|
+
*/
|
|
1073
|
+
static async resolveMediaReferences(params) {
|
|
1074
|
+
const {
|
|
1075
|
+
obj,
|
|
1076
|
+
langfuseClient,
|
|
1077
|
+
maxDepth = 10
|
|
1078
|
+
} = params;
|
|
1079
|
+
async function traverse(obj2, depth) {
|
|
1080
|
+
if (depth > maxDepth) {
|
|
1081
|
+
return obj2;
|
|
1082
|
+
}
|
|
1083
|
+
if (typeof obj2 === "string") {
|
|
1084
|
+
const regex = /@@@langfuseMedia:.+?@@@/g;
|
|
1085
|
+
const referenceStringMatches = obj2.match(regex);
|
|
1086
|
+
if (!referenceStringMatches) {
|
|
1087
|
+
return obj2;
|
|
1088
|
+
}
|
|
1089
|
+
let result = obj2;
|
|
1090
|
+
const referenceStringToMediaContentMap = /* @__PURE__ */ new Map();
|
|
1091
|
+
await Promise.all(referenceStringMatches.map(async (referenceString) => {
|
|
1092
|
+
try {
|
|
1093
|
+
const parsedMediaReference = _LangfuseMedia.parseReferenceString(referenceString);
|
|
1094
|
+
const mediaData = await langfuseClient.fetchMedia(parsedMediaReference.mediaId);
|
|
1095
|
+
const mediaContent = await langfuseClient.fetch(mediaData.url, {
|
|
1096
|
+
method: "GET",
|
|
1097
|
+
headers: {}
|
|
1098
|
+
});
|
|
1099
|
+
if (mediaContent.status !== 200) {
|
|
1100
|
+
throw new Error("Failed to fetch media content");
|
|
1101
|
+
}
|
|
1102
|
+
const base64MediaContent = Buffer.from(await mediaContent.arrayBuffer()).toString("base64");
|
|
1103
|
+
const base64DataUri = `data:${mediaData.contentType};base64,${base64MediaContent}`;
|
|
1104
|
+
referenceStringToMediaContentMap.set(referenceString, base64DataUri);
|
|
1105
|
+
} catch (error) {
|
|
1106
|
+
console.warn("Error fetching media content for reference string", referenceString, error);
|
|
1107
|
+
}
|
|
1108
|
+
}));
|
|
1109
|
+
for (const [referenceString, base64MediaContent] of referenceStringToMediaContentMap.entries()) {
|
|
1110
|
+
result = result.replaceAll(referenceString, base64MediaContent);
|
|
1111
|
+
}
|
|
1112
|
+
return result;
|
|
1113
|
+
}
|
|
1114
|
+
if (Array.isArray(obj2)) {
|
|
1115
|
+
return Promise.all(obj2.map(async (item) => await traverse(item, depth + 1)));
|
|
1116
|
+
}
|
|
1117
|
+
if (typeof obj2 === "object" && obj2 !== null) {
|
|
1118
|
+
return Object.fromEntries(await Promise.all(Object.entries(obj2).map(async ([key, value]) => [key, await traverse(value, depth + 1)])));
|
|
1119
|
+
}
|
|
1120
|
+
return obj2;
|
|
1121
|
+
}
|
|
1122
|
+
return traverse(obj, 0);
|
|
1123
|
+
}
|
|
1124
|
+
};
|
|
1125
|
+
function isInSample(input, sampleRate) {
|
|
1126
|
+
if (sampleRate === void 0) {
|
|
1127
|
+
return true;
|
|
1128
|
+
} else if (sampleRate === 0) {
|
|
1129
|
+
return false;
|
|
1130
|
+
}
|
|
1131
|
+
if (sampleRate < 0 || sampleRate > 1 || isNaN(sampleRate)) {
|
|
1132
|
+
console.warn("Sample rate must be between 0 and 1. Ignoring setting.");
|
|
1133
|
+
return true;
|
|
1134
|
+
}
|
|
1135
|
+
return simpleHash(input) < sampleRate;
|
|
1136
|
+
}
|
|
1137
|
+
function simpleHash(str) {
|
|
1138
|
+
let hash = 0;
|
|
1139
|
+
const prime = 31;
|
|
1140
|
+
for (let i = 0; i < str.length; i++) {
|
|
1141
|
+
hash = hash * prime + str.charCodeAt(i) >>> 0;
|
|
1142
|
+
}
|
|
1143
|
+
hash = (hash >>> 16 ^ hash) * 73244475;
|
|
1144
|
+
hash = (hash >>> 16 ^ hash) * 73244475;
|
|
1145
|
+
hash = hash >>> 16 ^ hash;
|
|
1146
|
+
return Math.abs(hash) / 2147483647;
|
|
1147
|
+
}
|
|
1148
|
+
var MAX_EVENT_SIZE_BYTES = getEnv("LANGFUSE_MAX_EVENT_SIZE_BYTES") ? Number(getEnv("LANGFUSE_MAX_EVENT_SIZE_BYTES")) : 1e6;
|
|
1149
|
+
var MAX_BATCH_SIZE_BYTES = getEnv("LANGFUSE_MAX_BATCH_SIZE_BYTES") ? Number(getEnv("LANGFUSE_MAX_BATCH_SIZE_BYTES")) : 25e5;
|
|
1150
|
+
var ENVIRONMENT_PATTERN = /^(?!langfuse)[a-z0-9_-]+$/;
|
|
1151
|
+
var WHITELISTED_LANGFUSE_INTERNAL_ENVIRONMENTS = ["langfuse-prompt-experiment"];
|
|
1152
|
+
var LangfuseFetchHttpError = class extends Error {
|
|
1153
|
+
constructor(response, body) {
|
|
1154
|
+
super("HTTP error while fetching Langfuse: " + response.status + " and body: " + body);
|
|
1155
|
+
this.response = response;
|
|
1156
|
+
this.name = "LangfuseFetchHttpError";
|
|
1157
|
+
}
|
|
1158
|
+
};
|
|
1159
|
+
var LangfuseFetchNetworkError = class extends Error {
|
|
1160
|
+
constructor(error) {
|
|
1161
|
+
super("Network error while fetching Langfuse", error instanceof Error ? {
|
|
1162
|
+
cause: error
|
|
1163
|
+
} : {});
|
|
1164
|
+
this.error = error;
|
|
1165
|
+
this.name = "LangfuseFetchNetworkError";
|
|
1166
|
+
}
|
|
1167
|
+
};
|
|
1168
|
+
function isLangfuseFetchHttpError(error) {
|
|
1169
|
+
return typeof error === "object" && error.name === "LangfuseFetchHttpError";
|
|
1170
|
+
}
|
|
1171
|
+
function isLangfuseFetchNetworkError(error) {
|
|
1172
|
+
return typeof error === "object" && error.name === "LangfuseFetchNetworkError";
|
|
1173
|
+
}
|
|
1174
|
+
function isLangfuseFetchError(err) {
|
|
1175
|
+
return isLangfuseFetchHttpError(err) || isLangfuseFetchNetworkError(err);
|
|
1176
|
+
}
|
|
1177
|
+
var SUPPORT_URL = "https://langfuse.com/support";
|
|
1178
|
+
var API_DOCS_URL = "https://api.reference.langfuse.com";
|
|
1179
|
+
var RBAC_DOCS_URL = "https://langfuse.com/docs/rbac";
|
|
1180
|
+
var INSTALLATION_DOCS_URL = "https://langfuse.com/docs/sdk/typescript/guide";
|
|
1181
|
+
var RATE_LIMITS_URL = "https://langfuse.com/faq/all/api-limits";
|
|
1182
|
+
var NPM_PACKAGE_URL = "https://www.npmjs.com/package/langfuse";
|
|
1183
|
+
var updatePromptResponse = `Make sure to keep your SDK updated, refer to ${NPM_PACKAGE_URL} for details.`;
|
|
1184
|
+
var defaultServerErrorPrompt = `This is an unusual occurrence and we are monitoring it closely. For help, please contact support: ${SUPPORT_URL}.`;
|
|
1185
|
+
var defaultErrorResponse = `Unexpected error occurred. Please check your request and contact support: ${SUPPORT_URL}.`;
|
|
1186
|
+
var errorResponseByCode = /* @__PURE__ */ new Map([
|
|
1187
|
+
// Internal error category: 5xx errors, 404 error
|
|
1188
|
+
[500, `Internal server error occurred. For help, please contact support: ${SUPPORT_URL}`],
|
|
1189
|
+
[501, `Not implemented. Please check your request and contact support for help: ${SUPPORT_URL}.`],
|
|
1190
|
+
[502, `Bad gateway. ${defaultServerErrorPrompt}`],
|
|
1191
|
+
[503, `Service unavailable. ${defaultServerErrorPrompt}`],
|
|
1192
|
+
[504, `Gateway timeout. ${defaultServerErrorPrompt}`],
|
|
1193
|
+
[404, `Internal error occurred. ${defaultServerErrorPrompt}`],
|
|
1194
|
+
// Client error category: 4xx errors, excluding 404
|
|
1195
|
+
[400, `Bad request. Please check your request for any missing or incorrect parameters. Refer to our API docs: ${API_DOCS_URL} for details.`],
|
|
1196
|
+
[401, `Unauthorized. Please check your public/private host settings. Refer to our installation and setup guide: ${INSTALLATION_DOCS_URL} for details on SDK configuration.`],
|
|
1197
|
+
[403, `Forbidden. Please check your access control settings. Refer to our RBAC docs: ${RBAC_DOCS_URL} for details.`],
|
|
1198
|
+
[429, `Rate limit exceeded. For more information on rate limits please see: ${RATE_LIMITS_URL}`]
|
|
1199
|
+
]);
|
|
1200
|
+
function getErrorResponseByCode(code) {
|
|
1201
|
+
if (!code) {
|
|
1202
|
+
return `${defaultErrorResponse} ${updatePromptResponse}`;
|
|
1203
|
+
}
|
|
1204
|
+
const errorResponse = errorResponseByCode.get(code) || defaultErrorResponse;
|
|
1205
|
+
return `${code}: ${errorResponse} ${updatePromptResponse}`;
|
|
1206
|
+
}
|
|
1207
|
+
function logIngestionError(error) {
|
|
1208
|
+
if (isLangfuseFetchHttpError(error)) {
|
|
1209
|
+
const code = error.response.status;
|
|
1210
|
+
const errorResponse = getErrorResponseByCode(code);
|
|
1211
|
+
console.error("[Langfuse SDK]", errorResponse, `Error details: ${error}`);
|
|
1212
|
+
} else if (isLangfuseFetchNetworkError(error)) {
|
|
1213
|
+
console.error("[Langfuse SDK] Network error: ", error);
|
|
1214
|
+
} else {
|
|
1215
|
+
console.error("[Langfuse SDK] Unknown error:", error);
|
|
1216
|
+
}
|
|
1217
|
+
}
|
|
1218
|
+
var LangfuseCoreStateless = class {
|
|
1219
|
+
constructor(params) {
|
|
1220
|
+
this.additionalHeaders = {};
|
|
1221
|
+
this.debugMode = false;
|
|
1222
|
+
this.pendingEventProcessingPromises = {};
|
|
1223
|
+
this.pendingIngestionPromises = {};
|
|
1224
|
+
this.localEventExportMap = /* @__PURE__ */ new Map();
|
|
1225
|
+
this._events = new SimpleEventEmitter();
|
|
1226
|
+
const {
|
|
1227
|
+
publicKey,
|
|
1228
|
+
secretKey,
|
|
1229
|
+
enabled,
|
|
1230
|
+
_projectId,
|
|
1231
|
+
_isLocalEventExportEnabled,
|
|
1232
|
+
...options
|
|
1233
|
+
} = params;
|
|
1234
|
+
this._events.on("error", (payload) => {
|
|
1235
|
+
console.error(`[Langfuse SDK] ${typeof payload === "string" ? payload : JSON.stringify(payload)}`);
|
|
1236
|
+
});
|
|
1237
|
+
this.enabled = enabled === false ? false : true;
|
|
1238
|
+
this.publicKey = publicKey ?? "";
|
|
1239
|
+
this.secretKey = secretKey;
|
|
1240
|
+
this.baseUrl = removeTrailingSlash(options?.baseUrl || "https://cloud.langfuse.com");
|
|
1241
|
+
this.additionalHeaders = options?.additionalHeaders || {};
|
|
1242
|
+
this.flushAt = options?.flushAt ? Math.max(options?.flushAt, 1) : 15;
|
|
1243
|
+
this.flushInterval = options?.flushInterval ?? 1e4;
|
|
1244
|
+
this.release = options?.release ?? getEnv("LANGFUSE_RELEASE") ?? getCommonReleaseEnvs() ?? void 0;
|
|
1245
|
+
this.mask = options?.mask;
|
|
1246
|
+
this.sampleRate = options?.sampleRate ?? (getEnv("LANGFUSE_SAMPLE_RATE") ? Number(getEnv("LANGFUSE_SAMPLE_RATE")) : void 0);
|
|
1247
|
+
if (this.sampleRate) {
|
|
1248
|
+
this._events.emit("debug", `Langfuse trace sampling enabled with sampleRate ${this.sampleRate}.`);
|
|
1249
|
+
}
|
|
1250
|
+
this.environment = options?.environment ?? getEnv("LANGFUSE_TRACING_ENVIRONMENT");
|
|
1251
|
+
if (this.environment && !(ENVIRONMENT_PATTERN.test(this.environment) || WHITELISTED_LANGFUSE_INTERNAL_ENVIRONMENTS.includes(this.environment)) && !_isLocalEventExportEnabled) {
|
|
1252
|
+
this._events.emit("error", `Invalid tracing environment set: ${this.environment} . Environment must match regex ${ENVIRONMENT_PATTERN}. Events will be rejected by Langfuse server.`);
|
|
1253
|
+
}
|
|
1254
|
+
this._retryOptions = {
|
|
1255
|
+
retryCount: options?.fetchRetryCount ?? 3,
|
|
1256
|
+
retryDelay: options?.fetchRetryDelay ?? 3e3,
|
|
1257
|
+
retryCheck: isLangfuseFetchError
|
|
1258
|
+
};
|
|
1259
|
+
this.requestTimeout = options?.requestTimeout ?? 5e3;
|
|
1260
|
+
this.sdkIntegration = options?.sdkIntegration ?? "DEFAULT";
|
|
1261
|
+
this.isLocalEventExportEnabled = _isLocalEventExportEnabled ?? false;
|
|
1262
|
+
if (this.isLocalEventExportEnabled && !_projectId) {
|
|
1263
|
+
this._events.emit("error", "Local event export is enabled, but no project ID was provided. Disabling local export.");
|
|
1264
|
+
this.isLocalEventExportEnabled = false;
|
|
1265
|
+
return;
|
|
1266
|
+
} else if (!this.isLocalEventExportEnabled && _projectId) {
|
|
1267
|
+
this._events.emit("error", "Local event export is disabled, but a project ID was provided. Disabling local export.");
|
|
1268
|
+
this.isLocalEventExportEnabled = false;
|
|
1269
|
+
return;
|
|
1270
|
+
} else {
|
|
1271
|
+
this.projectId = _projectId;
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
1274
|
+
getSdkIntegration() {
|
|
1275
|
+
return this.sdkIntegration;
|
|
1276
|
+
}
|
|
1277
|
+
getCommonEventProperties() {
|
|
1278
|
+
return {
|
|
1279
|
+
$lib: this.getLibraryId(),
|
|
1280
|
+
$lib_version: this.getLibraryVersion()
|
|
1281
|
+
};
|
|
1282
|
+
}
|
|
1283
|
+
on(event, cb) {
|
|
1284
|
+
return this._events.on(event, cb);
|
|
1285
|
+
}
|
|
1286
|
+
debug(enabled = true) {
|
|
1287
|
+
this.removeDebugCallback?.();
|
|
1288
|
+
this.debugMode = enabled;
|
|
1289
|
+
if (enabled) {
|
|
1290
|
+
this.removeDebugCallback = this.on("*", (event, payload) => {
|
|
1291
|
+
if (event === "error") {
|
|
1292
|
+
return;
|
|
1293
|
+
}
|
|
1294
|
+
console.log("[Langfuse Debug]", event, JSON.stringify(payload));
|
|
1295
|
+
});
|
|
1296
|
+
}
|
|
1297
|
+
}
|
|
1298
|
+
/***
|
|
1299
|
+
*** Handlers for each object type
|
|
1300
|
+
***/
|
|
1301
|
+
traceStateless(body) {
|
|
1302
|
+
const {
|
|
1303
|
+
id: bodyId,
|
|
1304
|
+
timestamp: bodyTimestamp,
|
|
1305
|
+
release: bodyRelease,
|
|
1306
|
+
...rest
|
|
1307
|
+
} = body;
|
|
1308
|
+
const id = bodyId ?? generateUUID();
|
|
1309
|
+
const release = bodyRelease ?? this.release;
|
|
1310
|
+
const parsedBody = {
|
|
1311
|
+
id,
|
|
1312
|
+
release,
|
|
1313
|
+
timestamp: bodyTimestamp ?? /* @__PURE__ */ new Date(),
|
|
1314
|
+
environment: this.environment,
|
|
1315
|
+
...rest
|
|
1316
|
+
};
|
|
1317
|
+
this.enqueue("trace-create", parsedBody);
|
|
1318
|
+
return id;
|
|
1319
|
+
}
|
|
1320
|
+
eventStateless(body) {
|
|
1321
|
+
const {
|
|
1322
|
+
id: bodyId,
|
|
1323
|
+
startTime: bodyStartTime,
|
|
1324
|
+
...rest
|
|
1325
|
+
} = body;
|
|
1326
|
+
const id = bodyId ?? generateUUID();
|
|
1327
|
+
const parsedBody = {
|
|
1328
|
+
id,
|
|
1329
|
+
startTime: bodyStartTime ?? /* @__PURE__ */ new Date(),
|
|
1330
|
+
environment: this.environment,
|
|
1331
|
+
...rest
|
|
1332
|
+
};
|
|
1333
|
+
this.enqueue("event-create", parsedBody);
|
|
1334
|
+
return id;
|
|
1335
|
+
}
|
|
1336
|
+
spanStateless(body) {
|
|
1337
|
+
const {
|
|
1338
|
+
id: bodyId,
|
|
1339
|
+
startTime: bodyStartTime,
|
|
1340
|
+
...rest
|
|
1341
|
+
} = body;
|
|
1342
|
+
const id = bodyId || generateUUID();
|
|
1343
|
+
const parsedBody = {
|
|
1344
|
+
id,
|
|
1345
|
+
startTime: bodyStartTime ?? /* @__PURE__ */ new Date(),
|
|
1346
|
+
environment: this.environment,
|
|
1347
|
+
...rest
|
|
1348
|
+
};
|
|
1349
|
+
this.enqueue("span-create", parsedBody);
|
|
1350
|
+
return id;
|
|
1351
|
+
}
|
|
1352
|
+
generationStateless(body) {
|
|
1353
|
+
const {
|
|
1354
|
+
id: bodyId,
|
|
1355
|
+
startTime: bodyStartTime,
|
|
1356
|
+
prompt,
|
|
1357
|
+
...rest
|
|
1358
|
+
} = body;
|
|
1359
|
+
const promptDetails = prompt && !prompt.isFallback ? {
|
|
1360
|
+
promptName: prompt.name,
|
|
1361
|
+
promptVersion: prompt.version
|
|
1362
|
+
} : {};
|
|
1363
|
+
const id = bodyId || generateUUID();
|
|
1364
|
+
const parsedBody = {
|
|
1365
|
+
id,
|
|
1366
|
+
startTime: bodyStartTime ?? /* @__PURE__ */ new Date(),
|
|
1367
|
+
environment: this.environment,
|
|
1368
|
+
...promptDetails,
|
|
1369
|
+
...rest
|
|
1370
|
+
};
|
|
1371
|
+
this.enqueue("generation-create", parsedBody);
|
|
1372
|
+
return id;
|
|
1373
|
+
}
|
|
1374
|
+
scoreStateless(body) {
|
|
1375
|
+
const {
|
|
1376
|
+
id: bodyId,
|
|
1377
|
+
...rest
|
|
1378
|
+
} = body;
|
|
1379
|
+
const id = bodyId || generateUUID();
|
|
1380
|
+
const parsedBody = {
|
|
1381
|
+
id,
|
|
1382
|
+
environment: this.environment,
|
|
1383
|
+
...rest
|
|
1384
|
+
};
|
|
1385
|
+
this.enqueue("score-create", parsedBody);
|
|
1386
|
+
return id;
|
|
1387
|
+
}
|
|
1388
|
+
updateSpanStateless(body) {
|
|
1389
|
+
this.enqueue("span-update", body);
|
|
1390
|
+
return body.id;
|
|
1391
|
+
}
|
|
1392
|
+
updateGenerationStateless(body) {
|
|
1393
|
+
const {
|
|
1394
|
+
prompt,
|
|
1395
|
+
...rest
|
|
1396
|
+
} = body;
|
|
1397
|
+
const promptDetails = prompt && !prompt.isFallback ? {
|
|
1398
|
+
promptName: prompt.name,
|
|
1399
|
+
promptVersion: prompt.version
|
|
1400
|
+
} : {};
|
|
1401
|
+
const parsedBody = {
|
|
1402
|
+
...promptDetails,
|
|
1403
|
+
...rest
|
|
1404
|
+
};
|
|
1405
|
+
this.enqueue("generation-update", parsedBody);
|
|
1406
|
+
return body.id;
|
|
1407
|
+
}
|
|
1408
|
+
async _getDataset(name) {
|
|
1409
|
+
const encodedName = encodeURIComponent(name);
|
|
1410
|
+
return this.fetchAndLogErrors(`${this.baseUrl}/api/public/v2/datasets/${encodedName}`, this._getFetchOptions({
|
|
1411
|
+
method: "GET"
|
|
1412
|
+
}));
|
|
1413
|
+
}
|
|
1414
|
+
async _getDatasetItems(query) {
|
|
1415
|
+
const params = new URLSearchParams();
|
|
1416
|
+
Object.entries(query ?? {}).forEach(([key, value]) => {
|
|
1417
|
+
if (value !== void 0 && value !== null) {
|
|
1418
|
+
params.append(key, value.toString());
|
|
1419
|
+
}
|
|
1420
|
+
});
|
|
1421
|
+
return this.fetchAndLogErrors(`${this.baseUrl}/api/public/dataset-items?${params}`, this._getFetchOptions({
|
|
1422
|
+
method: "GET"
|
|
1423
|
+
}));
|
|
1424
|
+
}
|
|
1425
|
+
async _fetchMedia(id) {
|
|
1426
|
+
return this.fetchAndLogErrors(`${this.baseUrl}/api/public/media/${id}`, this._getFetchOptions({
|
|
1427
|
+
method: "GET"
|
|
1428
|
+
}));
|
|
1429
|
+
}
|
|
1430
|
+
async fetchTraces(query) {
|
|
1431
|
+
const {
|
|
1432
|
+
data,
|
|
1433
|
+
meta
|
|
1434
|
+
} = await this.fetchAndLogErrors(`${this.baseUrl}/api/public/traces?${encodeQueryParams(query)}`, this._getFetchOptions({
|
|
1435
|
+
method: "GET"
|
|
1436
|
+
}));
|
|
1437
|
+
return {
|
|
1438
|
+
data,
|
|
1439
|
+
meta
|
|
1440
|
+
};
|
|
1441
|
+
}
|
|
1442
|
+
async fetchTrace(traceId) {
|
|
1443
|
+
const res = await this.fetchAndLogErrors(`${this.baseUrl}/api/public/traces/${traceId}`, this._getFetchOptions({
|
|
1444
|
+
method: "GET"
|
|
1445
|
+
}));
|
|
1446
|
+
return {
|
|
1447
|
+
data: res
|
|
1448
|
+
};
|
|
1449
|
+
}
|
|
1450
|
+
async fetchObservations(query) {
|
|
1451
|
+
const {
|
|
1452
|
+
data,
|
|
1453
|
+
meta
|
|
1454
|
+
} = await this.fetchAndLogErrors(`${this.baseUrl}/api/public/observations?${encodeQueryParams(query)}`, this._getFetchOptions({
|
|
1455
|
+
method: "GET"
|
|
1456
|
+
}));
|
|
1457
|
+
return {
|
|
1458
|
+
data,
|
|
1459
|
+
meta
|
|
1460
|
+
};
|
|
1461
|
+
}
|
|
1462
|
+
async fetchObservation(observationId) {
|
|
1463
|
+
const res = await this.fetchAndLogErrors(`${this.baseUrl}/api/public/observations/${observationId}`, this._getFetchOptions({
|
|
1464
|
+
method: "GET"
|
|
1465
|
+
}));
|
|
1466
|
+
return {
|
|
1467
|
+
data: res
|
|
1468
|
+
};
|
|
1469
|
+
}
|
|
1470
|
+
async fetchSessions(query) {
|
|
1471
|
+
const {
|
|
1472
|
+
data,
|
|
1473
|
+
meta
|
|
1474
|
+
} = await this.fetchAndLogErrors(`${this.baseUrl}/api/public/sessions?${encodeQueryParams(query)}`, this._getFetchOptions({
|
|
1475
|
+
method: "GET"
|
|
1476
|
+
}));
|
|
1477
|
+
return {
|
|
1478
|
+
data,
|
|
1479
|
+
meta
|
|
1480
|
+
};
|
|
1481
|
+
}
|
|
1482
|
+
async getDatasetRun(params) {
|
|
1483
|
+
const encodedDatasetName = encodeURIComponent(params.datasetName);
|
|
1484
|
+
const encodedRunName = encodeURIComponent(params.runName);
|
|
1485
|
+
return this.fetchAndLogErrors(`${this.baseUrl}/api/public/datasets/${encodedDatasetName}/runs/${encodedRunName}`, this._getFetchOptions({
|
|
1486
|
+
method: "GET"
|
|
1487
|
+
}));
|
|
1488
|
+
}
|
|
1489
|
+
async getDatasetRuns(datasetName, query) {
|
|
1490
|
+
return this.fetchAndLogErrors(`${this.baseUrl}/api/public/datasets/${encodeURIComponent(datasetName)}/runs?${encodeQueryParams(query)}`, this._getFetchOptions({
|
|
1491
|
+
method: "GET"
|
|
1492
|
+
}));
|
|
1493
|
+
}
|
|
1494
|
+
async createDatasetRunItem(body) {
|
|
1495
|
+
return this.fetchAndLogErrors(`${this.baseUrl}/api/public/dataset-run-items`, this._getFetchOptions({
|
|
1496
|
+
method: "POST",
|
|
1497
|
+
body: JSON.stringify(body)
|
|
1498
|
+
}));
|
|
1499
|
+
}
|
|
1500
|
+
/**
|
|
1501
|
+
* Creates a dataset. Upserts the dataset if it already exists.
|
|
1502
|
+
*
|
|
1503
|
+
* @param dataset Can be either a string (name) or an object with name, description and metadata
|
|
1504
|
+
* @returns A promise that resolves to the response of the create operation.
|
|
1505
|
+
*/
|
|
1506
|
+
async createDataset(dataset) {
|
|
1507
|
+
const body = typeof dataset === "string" ? {
|
|
1508
|
+
name: dataset
|
|
1509
|
+
} : dataset;
|
|
1510
|
+
return this.fetchAndLogErrors(`${this.baseUrl}/api/public/datasets`, this._getFetchOptions({
|
|
1511
|
+
method: "POST",
|
|
1512
|
+
body: JSON.stringify(body)
|
|
1513
|
+
}));
|
|
1514
|
+
}
|
|
1515
|
+
/**
|
|
1516
|
+
* Creates a dataset item. Upserts the item if it already exists.
|
|
1517
|
+
* @param body The body of the dataset item to be created.
|
|
1518
|
+
* @returns A promise that resolves to the response of the create operation.
|
|
1519
|
+
*/
|
|
1520
|
+
async createDatasetItem(body) {
|
|
1521
|
+
return this.fetchAndLogErrors(`${this.baseUrl}/api/public/dataset-items`, this._getFetchOptions({
|
|
1522
|
+
method: "POST",
|
|
1523
|
+
body: JSON.stringify(body)
|
|
1524
|
+
}));
|
|
1525
|
+
}
|
|
1526
|
+
async getDatasetItem(id) {
|
|
1527
|
+
return this.fetchAndLogErrors(`${this.baseUrl}/api/public/dataset-items/${id}`, this._getFetchOptions({
|
|
1528
|
+
method: "GET"
|
|
1529
|
+
}));
|
|
1530
|
+
}
|
|
1531
|
+
_parsePayload(response) {
|
|
1532
|
+
try {
|
|
1533
|
+
return JSON.parse(response);
|
|
1534
|
+
} catch {
|
|
1535
|
+
return response;
|
|
1536
|
+
}
|
|
1537
|
+
}
|
|
1538
|
+
async createPromptStateless(body) {
|
|
1539
|
+
return this.fetchAndLogErrors(`${this.baseUrl}/api/public/v2/prompts`, this._getFetchOptions({
|
|
1540
|
+
method: "POST",
|
|
1541
|
+
body: JSON.stringify(body)
|
|
1542
|
+
}));
|
|
1543
|
+
}
|
|
1544
|
+
async updatePromptStateless(body) {
|
|
1545
|
+
return this.fetchAndLogErrors(`${this.baseUrl}/api/public/v2/prompts/${encodeURIComponent(body.name)}/versions/${encodeURIComponent(body.version)}`, this._getFetchOptions({
|
|
1546
|
+
method: "PATCH",
|
|
1547
|
+
body: JSON.stringify(body)
|
|
1548
|
+
}));
|
|
1549
|
+
}
|
|
1550
|
+
async getPromptStateless(name, version2, label, maxRetries, requestTimeout) {
|
|
1551
|
+
const encodedName = encodeURIComponent(name);
|
|
1552
|
+
const params = new URLSearchParams();
|
|
1553
|
+
if (version2 && label) {
|
|
1554
|
+
throw new Error("Provide either version or label, not both.");
|
|
1555
|
+
}
|
|
1556
|
+
if (version2) {
|
|
1557
|
+
params.append("version", version2.toString());
|
|
1558
|
+
}
|
|
1559
|
+
if (label) {
|
|
1560
|
+
params.append("label", label);
|
|
1561
|
+
}
|
|
1562
|
+
const url = `${this.baseUrl}/api/public/v2/prompts/${encodedName}${params.size ? "?" + params : ""}`;
|
|
1563
|
+
const boundedMaxRetries = this._getBoundedMaxRetries({
|
|
1564
|
+
maxRetries,
|
|
1565
|
+
defaultMaxRetries: 2,
|
|
1566
|
+
maxRetriesUpperBound: 4
|
|
1567
|
+
});
|
|
1568
|
+
const retryOptions = {
|
|
1569
|
+
...this._retryOptions,
|
|
1570
|
+
retryCount: boundedMaxRetries,
|
|
1571
|
+
retryDelay: 500
|
|
1572
|
+
};
|
|
1573
|
+
const retryLogger = (string) => this._events.emit("retry", string + ", " + url + ", " + JSON.stringify(retryOptions));
|
|
1574
|
+
return retriable(async () => {
|
|
1575
|
+
const res = await this.fetch(url, this._getFetchOptions({
|
|
1576
|
+
method: "GET",
|
|
1577
|
+
fetchTimeout: requestTimeout ?? this.requestTimeout
|
|
1578
|
+
})).catch((e) => {
|
|
1579
|
+
if (e.name === "AbortError") {
|
|
1580
|
+
throw new LangfuseFetchNetworkError("Fetch request timed out");
|
|
1581
|
+
}
|
|
1582
|
+
throw new LangfuseFetchNetworkError(e);
|
|
1583
|
+
});
|
|
1584
|
+
if (res.status >= 500) {
|
|
1585
|
+
throw new LangfuseFetchHttpError(res, await res.text());
|
|
1586
|
+
}
|
|
1587
|
+
const data = await res.json();
|
|
1588
|
+
return {
|
|
1589
|
+
fetchResult: res.status === 200 ? "success" : "failure",
|
|
1590
|
+
data
|
|
1591
|
+
};
|
|
1592
|
+
}, retryOptions, retryLogger);
|
|
1593
|
+
}
|
|
1594
|
+
_getBoundedMaxRetries(params) {
|
|
1595
|
+
const defaultMaxRetries = Math.max(params.defaultMaxRetries ?? 2, 0);
|
|
1596
|
+
const maxRetriesUpperBound = Math.max(params.maxRetriesUpperBound ?? 4, 0);
|
|
1597
|
+
if (params.maxRetries === void 0) {
|
|
1598
|
+
return defaultMaxRetries;
|
|
1599
|
+
}
|
|
1600
|
+
return Math.min(Math.max(params.maxRetries, 0), maxRetriesUpperBound);
|
|
1601
|
+
}
|
|
1602
|
+
/***
|
|
1603
|
+
*** QUEUEING AND FLUSHING
|
|
1604
|
+
***/
|
|
1605
|
+
enqueue(type, body) {
|
|
1606
|
+
if (!this.enabled) {
|
|
1607
|
+
return;
|
|
1608
|
+
}
|
|
1609
|
+
const traceId = this.parseTraceId(type, body);
|
|
1610
|
+
if (!traceId) {
|
|
1611
|
+
this._events.emit("warning", "Failed to parse traceID for sampling. Please open a Github issue in https://github.com/langfuse/langfuse/issues/new/choose");
|
|
1612
|
+
} else if (!isInSample(traceId, this.sampleRate)) {
|
|
1613
|
+
this._events.emit("debug", `Event with trace ID ${traceId} is out of sample. Skipping.`);
|
|
1614
|
+
return;
|
|
1615
|
+
}
|
|
1616
|
+
const promise = this.processEnqueueEvent(type, body);
|
|
1617
|
+
const promiseId = generateUUID();
|
|
1618
|
+
this.pendingEventProcessingPromises[promiseId] = promise;
|
|
1619
|
+
promise.catch((e) => {
|
|
1620
|
+
this._events.emit("error", e);
|
|
1621
|
+
}).finally(() => {
|
|
1622
|
+
delete this.pendingEventProcessingPromises[promiseId];
|
|
1623
|
+
});
|
|
1624
|
+
}
|
|
1625
|
+
async processEnqueueEvent(type, body) {
|
|
1626
|
+
this.maskEventBodyInPlace(body);
|
|
1627
|
+
await this.processMediaInEvent(type, body);
|
|
1628
|
+
const finalEventBody = this.truncateEventBody(body, MAX_EVENT_SIZE_BYTES);
|
|
1629
|
+
try {
|
|
1630
|
+
JSON.stringify(finalEventBody);
|
|
1631
|
+
} catch (e) {
|
|
1632
|
+
this._events.emit("error", `Event Body for ${type} is not JSON-serializable: ${e}`);
|
|
1633
|
+
return;
|
|
1634
|
+
}
|
|
1635
|
+
const queue = this.getPersistedProperty(LangfusePersistedProperty.Queue) || [];
|
|
1636
|
+
queue.push({
|
|
1637
|
+
id: generateUUID(),
|
|
1638
|
+
type,
|
|
1639
|
+
timestamp: currentISOTime(),
|
|
1640
|
+
body: finalEventBody,
|
|
1641
|
+
// TODO: fix typecast. EventBody is not correctly narrowed to the correct type dictated by the 'type' property. This should be part of a larger type cleanup.
|
|
1642
|
+
metadata: void 0
|
|
1643
|
+
});
|
|
1644
|
+
this.setPersistedProperty(LangfusePersistedProperty.Queue, queue);
|
|
1645
|
+
this._events.emit(type, finalEventBody);
|
|
1646
|
+
if (queue.length >= this.flushAt) {
|
|
1647
|
+
this.flush();
|
|
1648
|
+
}
|
|
1649
|
+
if (this.flushInterval && !this._flushTimer) {
|
|
1650
|
+
this._flushTimer = safeSetTimeout(() => this.flush(), this.flushInterval);
|
|
1651
|
+
}
|
|
1652
|
+
}
|
|
1653
|
+
maskEventBodyInPlace(body) {
|
|
1654
|
+
if (!this.mask) {
|
|
1655
|
+
return;
|
|
1656
|
+
}
|
|
1657
|
+
const maskableKeys = ["input", "output"];
|
|
1658
|
+
for (const key of maskableKeys) {
|
|
1659
|
+
if (key in body) {
|
|
1660
|
+
try {
|
|
1661
|
+
body[key] = this.mask({
|
|
1662
|
+
data: body[key]
|
|
1663
|
+
});
|
|
1664
|
+
} catch (e) {
|
|
1665
|
+
this._events.emit("error", `Error masking ${key}: ${e}`);
|
|
1666
|
+
body[key] = "<fully masked due to failed mask function>";
|
|
1667
|
+
}
|
|
1668
|
+
}
|
|
1669
|
+
}
|
|
1670
|
+
}
|
|
1671
|
+
/**
|
|
1672
|
+
* Truncates the event body if its byte size exceeds the specified maximum byte size.
|
|
1673
|
+
* Emits a warning event if truncation occurs.
|
|
1674
|
+
* The fields that may be truncated are: "input", "output", and "metadata".
|
|
1675
|
+
* The fields are truncated in the order of their size, from largest to smallest until the total byte size is within the limit.
|
|
1676
|
+
*/
|
|
1677
|
+
truncateEventBody(body, maxByteSize) {
|
|
1678
|
+
const bodySize = this.getByteSize(body);
|
|
1679
|
+
if (bodySize <= maxByteSize) {
|
|
1680
|
+
return body;
|
|
1681
|
+
}
|
|
1682
|
+
this._events.emit("warning", `Event Body is too large (${bodySize} bytes) and will be truncated`);
|
|
1683
|
+
const keysToCheck = ["input", "output", "metadata"];
|
|
1684
|
+
const keySizes = keysToCheck.map((key) => ({
|
|
1685
|
+
key,
|
|
1686
|
+
size: key in body ? this.getByteSize(body[key]) : 0
|
|
1687
|
+
})).sort((a, b) => b.size - a.size);
|
|
1688
|
+
let result = {
|
|
1689
|
+
...body
|
|
1690
|
+
};
|
|
1691
|
+
let currentSize = bodySize;
|
|
1692
|
+
for (const {
|
|
1693
|
+
key,
|
|
1694
|
+
size
|
|
1695
|
+
} of keySizes) {
|
|
1696
|
+
if (currentSize > maxByteSize && Object.prototype.hasOwnProperty.call(result, key)) {
|
|
1697
|
+
result = {
|
|
1698
|
+
...result,
|
|
1699
|
+
[key]: "<truncated due to size exceeding limit>"
|
|
1700
|
+
};
|
|
1701
|
+
this._events.emit("warning", `Truncated ${key} due to total size exceeding limit`);
|
|
1702
|
+
currentSize -= size;
|
|
1703
|
+
}
|
|
1704
|
+
}
|
|
1705
|
+
return result;
|
|
1706
|
+
}
|
|
1707
|
+
getByteSize(obj) {
|
|
1708
|
+
const serialized = JSON.stringify(obj);
|
|
1709
|
+
if (typeof TextEncoder !== "undefined") {
|
|
1710
|
+
return new TextEncoder().encode(serialized).length;
|
|
1711
|
+
} else {
|
|
1712
|
+
return encodeURIComponent(serialized).replace(/%[A-F\d]{2}/g, "U").length;
|
|
1713
|
+
}
|
|
1714
|
+
}
|
|
1715
|
+
async processMediaInEvent(type, body) {
|
|
1716
|
+
if (!body) {
|
|
1717
|
+
return;
|
|
1718
|
+
}
|
|
1719
|
+
const traceId = this.parseTraceId(type, body);
|
|
1720
|
+
if (!traceId) {
|
|
1721
|
+
this._events.emit("warning", "traceId is required for media upload");
|
|
1722
|
+
return;
|
|
1723
|
+
}
|
|
1724
|
+
const observationId = (type.includes("generation") || type.includes("span")) && body.id ? body.id : void 0;
|
|
1725
|
+
await Promise.all(["input", "output", "metadata"].map(async (field) => {
|
|
1726
|
+
if (body[field]) {
|
|
1727
|
+
body[field] = await this.findAndProcessMedia({
|
|
1728
|
+
data: body[field],
|
|
1729
|
+
traceId,
|
|
1730
|
+
observationId,
|
|
1731
|
+
field
|
|
1732
|
+
}).catch((e) => {
|
|
1733
|
+
this._events.emit("error", `Error processing multimodal event: ${e}`);
|
|
1734
|
+
}) ?? body[field];
|
|
1735
|
+
}
|
|
1736
|
+
}));
|
|
1737
|
+
}
|
|
1738
|
+
parseTraceId(type, body) {
|
|
1739
|
+
return "traceId" in body ? body.traceId : type.includes("trace") ? body.id : void 0;
|
|
1740
|
+
}
|
|
1741
|
+
async findAndProcessMedia({
|
|
1742
|
+
data,
|
|
1743
|
+
traceId,
|
|
1744
|
+
observationId,
|
|
1745
|
+
field
|
|
1746
|
+
}) {
|
|
1747
|
+
const seenObjects = /* @__PURE__ */ new WeakMap();
|
|
1748
|
+
const maxLevels = 10;
|
|
1749
|
+
const processRecursively = async (data2, level) => {
|
|
1750
|
+
if (typeof data2 === "string" && data2.startsWith("data:")) {
|
|
1751
|
+
const media = new LangfuseMedia({
|
|
1752
|
+
base64DataUri: data2
|
|
1753
|
+
});
|
|
1754
|
+
await this.processMediaItem({
|
|
1755
|
+
media,
|
|
1756
|
+
traceId,
|
|
1757
|
+
observationId,
|
|
1758
|
+
field
|
|
1759
|
+
});
|
|
1760
|
+
return media;
|
|
1761
|
+
}
|
|
1762
|
+
if (typeof data2 !== "object" || data2 === null) {
|
|
1763
|
+
return data2;
|
|
1764
|
+
}
|
|
1765
|
+
if (seenObjects.has(data2) || level > maxLevels) {
|
|
1766
|
+
return data2;
|
|
1767
|
+
}
|
|
1768
|
+
seenObjects.set(data2, true);
|
|
1769
|
+
if (data2 instanceof LangfuseMedia || Object.prototype.toString.call(data2) === "[object LangfuseMedia]") {
|
|
1770
|
+
await this.processMediaItem({
|
|
1771
|
+
media: data2,
|
|
1772
|
+
traceId,
|
|
1773
|
+
observationId,
|
|
1774
|
+
field
|
|
1775
|
+
});
|
|
1776
|
+
return data2;
|
|
1777
|
+
}
|
|
1778
|
+
if (Array.isArray(data2)) {
|
|
1779
|
+
return await Promise.all(data2.map((item) => processRecursively(item, level + 1)));
|
|
1780
|
+
}
|
|
1781
|
+
if (typeof data2 === "object" && data2 !== null) {
|
|
1782
|
+
if ("input_audio" in data2 && typeof data2["input_audio"] === "object" && "data" in data2.input_audio) {
|
|
1783
|
+
const media = new LangfuseMedia({
|
|
1784
|
+
base64DataUri: `data:audio/${data2.input_audio["format"] || "wav"};base64,${data2.input_audio.data}`
|
|
1785
|
+
});
|
|
1786
|
+
await this.processMediaItem({
|
|
1787
|
+
media,
|
|
1788
|
+
traceId,
|
|
1789
|
+
observationId,
|
|
1790
|
+
field
|
|
1791
|
+
});
|
|
1792
|
+
return {
|
|
1793
|
+
...data2,
|
|
1794
|
+
input_audio: {
|
|
1795
|
+
...data2.input_audio,
|
|
1796
|
+
data: media
|
|
1797
|
+
}
|
|
1798
|
+
};
|
|
1799
|
+
}
|
|
1800
|
+
if ("audio" in data2 && typeof data2["audio"] === "object" && "data" in data2.audio) {
|
|
1801
|
+
const media = new LangfuseMedia({
|
|
1802
|
+
base64DataUri: `data:audio/${data2.audio["format"] || "wav"};base64,${data2.audio.data}`
|
|
1803
|
+
});
|
|
1804
|
+
await this.processMediaItem({
|
|
1805
|
+
media,
|
|
1806
|
+
traceId,
|
|
1807
|
+
observationId,
|
|
1808
|
+
field
|
|
1809
|
+
});
|
|
1810
|
+
return {
|
|
1811
|
+
...data2,
|
|
1812
|
+
audio: {
|
|
1813
|
+
...data2.audio,
|
|
1814
|
+
data: media
|
|
1815
|
+
}
|
|
1816
|
+
};
|
|
1817
|
+
}
|
|
1818
|
+
return Object.fromEntries(await Promise.all(Object.entries(data2).map(async ([key, value]) => [key, await processRecursively(value, level + 1)])));
|
|
1819
|
+
}
|
|
1820
|
+
return data2;
|
|
1821
|
+
};
|
|
1822
|
+
return await processRecursively(data, 1);
|
|
1823
|
+
}
|
|
1824
|
+
async processMediaItem({
|
|
1825
|
+
media,
|
|
1826
|
+
traceId,
|
|
1827
|
+
observationId,
|
|
1828
|
+
field
|
|
1829
|
+
}) {
|
|
1830
|
+
try {
|
|
1831
|
+
if (!media.contentLength || !media._contentType || !media.contentSha256Hash || !media._contentBytes) {
|
|
1832
|
+
return;
|
|
1833
|
+
}
|
|
1834
|
+
const getUploadUrlBody = {
|
|
1835
|
+
contentLength: media.contentLength,
|
|
1836
|
+
traceId,
|
|
1837
|
+
observationId,
|
|
1838
|
+
field,
|
|
1839
|
+
contentType: media._contentType,
|
|
1840
|
+
sha256Hash: media.contentSha256Hash
|
|
1841
|
+
};
|
|
1842
|
+
const fetchResponse = await this.fetch(`${this.baseUrl}/api/public/media`, this._getFetchOptions({
|
|
1843
|
+
method: "POST",
|
|
1844
|
+
body: JSON.stringify(getUploadUrlBody)
|
|
1845
|
+
}));
|
|
1846
|
+
const uploadUrlResponse = await fetchResponse.json();
|
|
1847
|
+
const {
|
|
1848
|
+
uploadUrl,
|
|
1849
|
+
mediaId
|
|
1850
|
+
} = uploadUrlResponse;
|
|
1851
|
+
media._mediaId = mediaId;
|
|
1852
|
+
if (uploadUrl) {
|
|
1853
|
+
this._events.emit("debug", `Uploading media ${mediaId}`);
|
|
1854
|
+
const startTime = Date.now();
|
|
1855
|
+
const uploadResponse = await this.uploadMediaWithBackoff({
|
|
1856
|
+
uploadUrl,
|
|
1857
|
+
contentBytes: media._contentBytes,
|
|
1858
|
+
contentType: media._contentType,
|
|
1859
|
+
contentSha256Hash: media.contentSha256Hash,
|
|
1860
|
+
maxRetries: 3,
|
|
1861
|
+
baseDelay: 1e3
|
|
1862
|
+
});
|
|
1863
|
+
if (!uploadResponse) {
|
|
1864
|
+
throw Error("Media upload process failed");
|
|
1865
|
+
}
|
|
1866
|
+
const patchMediaBody = {
|
|
1867
|
+
uploadedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1868
|
+
uploadHttpStatus: uploadResponse.status,
|
|
1869
|
+
uploadHttpError: await uploadResponse.text(),
|
|
1870
|
+
uploadTimeMs: Date.now() - startTime
|
|
1871
|
+
};
|
|
1872
|
+
await this.fetch(`${this.baseUrl}/api/public/media/${mediaId}`, this._getFetchOptions({
|
|
1873
|
+
method: "PATCH",
|
|
1874
|
+
body: JSON.stringify(patchMediaBody)
|
|
1875
|
+
}));
|
|
1876
|
+
this._events.emit("debug", `Media upload status reported for ${mediaId}`);
|
|
1877
|
+
} else {
|
|
1878
|
+
this._events.emit("debug", `Media ${mediaId} already uploaded`);
|
|
1879
|
+
}
|
|
1880
|
+
} catch (err) {
|
|
1881
|
+
this._events.emit("error", `Error processing media item: ${err}`);
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
async uploadMediaWithBackoff(params) {
|
|
1885
|
+
const {
|
|
1886
|
+
uploadUrl,
|
|
1887
|
+
contentType,
|
|
1888
|
+
contentSha256Hash,
|
|
1889
|
+
contentBytes,
|
|
1890
|
+
maxRetries,
|
|
1891
|
+
baseDelay
|
|
1892
|
+
} = params;
|
|
1893
|
+
for (let attempt = 0; attempt <= maxRetries; attempt++) {
|
|
1894
|
+
try {
|
|
1895
|
+
const uploadResponse = await this.fetch(uploadUrl, {
|
|
1896
|
+
method: "PUT",
|
|
1897
|
+
body: contentBytes,
|
|
1898
|
+
headers: {
|
|
1899
|
+
"Content-Type": contentType,
|
|
1900
|
+
"x-amz-checksum-sha256": contentSha256Hash,
|
|
1901
|
+
"x-ms-blob-type": "BlockBlob"
|
|
1902
|
+
}
|
|
1903
|
+
});
|
|
1904
|
+
if (attempt < maxRetries && uploadResponse.status !== 200 && uploadResponse.status !== 201) {
|
|
1905
|
+
throw new Error(`Upload failed with status ${uploadResponse.status}`);
|
|
1906
|
+
}
|
|
1907
|
+
return uploadResponse;
|
|
1908
|
+
} catch (e) {
|
|
1909
|
+
if (attempt === maxRetries) {
|
|
1910
|
+
throw e;
|
|
1911
|
+
}
|
|
1912
|
+
const delay = baseDelay * Math.pow(2, attempt);
|
|
1913
|
+
const jitter = Math.random() * 1e3;
|
|
1914
|
+
await new Promise((resolve) => setTimeout(resolve, delay + jitter));
|
|
1915
|
+
}
|
|
1916
|
+
}
|
|
1917
|
+
}
|
|
1918
|
+
/**
|
|
1919
|
+
* Asynchronously flushes all events that are not yet sent to the server.
|
|
1920
|
+
* This function always resolves, even if there were errors when flushing.
|
|
1921
|
+
* Errors are emitted as "error" events and the promise resolves.
|
|
1922
|
+
*
|
|
1923
|
+
* @returns {Promise<void>} A promise that resolves when the flushing is completed.
|
|
1924
|
+
*/
|
|
1925
|
+
async flushAsync() {
|
|
1926
|
+
await Promise.all(Object.values(this.pendingEventProcessingPromises)).catch((e) => {
|
|
1927
|
+
logIngestionError(e);
|
|
1928
|
+
});
|
|
1929
|
+
return new Promise((resolve, _reject) => {
|
|
1930
|
+
try {
|
|
1931
|
+
this.flush((err, data) => {
|
|
1932
|
+
if (err) {
|
|
1933
|
+
logIngestionError(err);
|
|
1934
|
+
resolve();
|
|
1935
|
+
} else {
|
|
1936
|
+
resolve(data);
|
|
1937
|
+
}
|
|
1938
|
+
});
|
|
1939
|
+
} catch (e) {
|
|
1940
|
+
console.error("[Langfuse SDK] Error while flushing Langfuse", e);
|
|
1941
|
+
}
|
|
1942
|
+
});
|
|
1943
|
+
}
|
|
1944
|
+
// Flushes all events that are not yet sent to the server
|
|
1945
|
+
flush(callback) {
|
|
1946
|
+
if (this._flushTimer) {
|
|
1947
|
+
clearTimeout(this._flushTimer);
|
|
1948
|
+
this._flushTimer = null;
|
|
1949
|
+
}
|
|
1950
|
+
const queue = this.getPersistedProperty(LangfusePersistedProperty.Queue) || [];
|
|
1951
|
+
if (!queue.length) {
|
|
1952
|
+
return callback?.();
|
|
1953
|
+
}
|
|
1954
|
+
const items = queue.splice(0, this.flushAt);
|
|
1955
|
+
const {
|
|
1956
|
+
processedItems,
|
|
1957
|
+
remainingItems
|
|
1958
|
+
} = this.processQueueItems(items, MAX_EVENT_SIZE_BYTES, MAX_BATCH_SIZE_BYTES);
|
|
1959
|
+
this.setPersistedProperty(LangfusePersistedProperty.Queue, [...remainingItems, ...queue]);
|
|
1960
|
+
const promiseUUID = generateUUID();
|
|
1961
|
+
const done = (err) => {
|
|
1962
|
+
if (err) {
|
|
1963
|
+
this._events.emit("warning", err);
|
|
1964
|
+
}
|
|
1965
|
+
callback?.(err, items);
|
|
1966
|
+
this._events.emit("flush", items);
|
|
1967
|
+
};
|
|
1968
|
+
if (this.isLocalEventExportEnabled && this.projectId) {
|
|
1969
|
+
if (!this.localEventExportMap.has(this.projectId)) {
|
|
1970
|
+
this.localEventExportMap.set(this.projectId, [...items]);
|
|
1971
|
+
} else {
|
|
1972
|
+
this.localEventExportMap.get(this.projectId)?.push(...items);
|
|
1973
|
+
}
|
|
1974
|
+
done();
|
|
1975
|
+
return;
|
|
1976
|
+
}
|
|
1977
|
+
const payload = JSON.stringify({
|
|
1978
|
+
batch: processedItems,
|
|
1979
|
+
metadata: {
|
|
1980
|
+
batch_size: processedItems.length,
|
|
1981
|
+
sdk_integration: this.sdkIntegration,
|
|
1982
|
+
sdk_version: this.getLibraryVersion(),
|
|
1983
|
+
sdk_variant: this.getLibraryId(),
|
|
1984
|
+
public_key: this.publicKey,
|
|
1985
|
+
sdk_name: "langfuse-js"
|
|
1986
|
+
}
|
|
1987
|
+
});
|
|
1988
|
+
const url = `${this.baseUrl}/api/public/ingestion`;
|
|
1989
|
+
const fetchOptions = this._getFetchOptions({
|
|
1990
|
+
method: "POST",
|
|
1991
|
+
body: payload
|
|
1992
|
+
});
|
|
1993
|
+
const requestPromise = this.fetchWithRetry(url, fetchOptions).then(() => done()).catch((err) => {
|
|
1994
|
+
done(err);
|
|
1995
|
+
});
|
|
1996
|
+
this.pendingIngestionPromises[promiseUUID] = requestPromise;
|
|
1997
|
+
requestPromise.finally(() => {
|
|
1998
|
+
delete this.pendingIngestionPromises[promiseUUID];
|
|
1999
|
+
});
|
|
2000
|
+
}
|
|
2001
|
+
processQueueItems(queue, MAX_MSG_SIZE, BATCH_SIZE_LIMIT) {
|
|
2002
|
+
let totalSize = 0;
|
|
2003
|
+
const processedItems = [];
|
|
2004
|
+
const remainingItems = [];
|
|
2005
|
+
for (let i = 0; i < queue.length; i++) {
|
|
2006
|
+
try {
|
|
2007
|
+
const itemSize = new Blob([JSON.stringify(queue[i])]).size;
|
|
2008
|
+
if (itemSize > MAX_MSG_SIZE) {
|
|
2009
|
+
console.warn(`Item exceeds size limit (size: ${itemSize}), dropping item.`);
|
|
2010
|
+
continue;
|
|
2011
|
+
}
|
|
2012
|
+
if (totalSize + itemSize >= BATCH_SIZE_LIMIT) {
|
|
2013
|
+
console.debug(`hit batch size limit (size: ${totalSize + itemSize})`);
|
|
2014
|
+
remainingItems.push(...queue.slice(i));
|
|
2015
|
+
console.log(`Remaining items: ${remainingItems.length}`);
|
|
2016
|
+
console.log(`processes items: ${processedItems.length}`);
|
|
2017
|
+
break;
|
|
2018
|
+
}
|
|
2019
|
+
totalSize += itemSize;
|
|
2020
|
+
processedItems.push(queue[i]);
|
|
2021
|
+
} catch (error) {
|
|
2022
|
+
this._events.emit("error", error);
|
|
2023
|
+
remainingItems.push(...queue.slice(i));
|
|
2024
|
+
break;
|
|
2025
|
+
}
|
|
2026
|
+
}
|
|
2027
|
+
return {
|
|
2028
|
+
processedItems,
|
|
2029
|
+
remainingItems
|
|
2030
|
+
};
|
|
2031
|
+
}
|
|
2032
|
+
_getFetchOptions(p) {
|
|
2033
|
+
const fetchOptions = {
|
|
2034
|
+
method: p.method,
|
|
2035
|
+
headers: {
|
|
2036
|
+
"Content-Type": "application/json",
|
|
2037
|
+
"X-Langfuse-Sdk-Name": "langfuse-js",
|
|
2038
|
+
"X-Langfuse-Sdk-Version": this.getLibraryVersion(),
|
|
2039
|
+
"X-Langfuse-Sdk-Variant": this.getLibraryId(),
|
|
2040
|
+
"X-Langfuse-Sdk-Integration": this.sdkIntegration,
|
|
2041
|
+
"X-Langfuse-Public-Key": this.publicKey,
|
|
2042
|
+
...this.additionalHeaders,
|
|
2043
|
+
...this.constructAuthorizationHeader(this.publicKey, this.secretKey)
|
|
2044
|
+
},
|
|
2045
|
+
body: p.body,
|
|
2046
|
+
...p.fetchTimeout !== void 0 ? {
|
|
2047
|
+
signal: AbortSignal.timeout(p.fetchTimeout)
|
|
2048
|
+
} : {}
|
|
2049
|
+
};
|
|
2050
|
+
return fetchOptions;
|
|
2051
|
+
}
|
|
2052
|
+
constructAuthorizationHeader(publicKey, secretKey) {
|
|
2053
|
+
if (secretKey === void 0) {
|
|
2054
|
+
return {
|
|
2055
|
+
Authorization: "Bearer " + publicKey
|
|
2056
|
+
};
|
|
2057
|
+
} else {
|
|
2058
|
+
const encodedCredentials = typeof btoa === "function" ? (
|
|
2059
|
+
// btoa() is available, the code is running in a browser or edge environment
|
|
2060
|
+
btoa(publicKey + ":" + secretKey)
|
|
2061
|
+
) : (
|
|
2062
|
+
// btoa() is not available, the code is running in Node.js
|
|
2063
|
+
Buffer.from(publicKey + ":" + secretKey).toString("base64")
|
|
2064
|
+
);
|
|
2065
|
+
return {
|
|
2066
|
+
Authorization: "Basic " + encodedCredentials
|
|
2067
|
+
};
|
|
2068
|
+
}
|
|
2069
|
+
}
|
|
2070
|
+
async fetchWithRetry(url, options, retryOptions) {
|
|
2071
|
+
AbortSignal.timeout ??= function timeout(ms) {
|
|
2072
|
+
const ctrl = new AbortController();
|
|
2073
|
+
setTimeout(() => ctrl.abort(), ms);
|
|
2074
|
+
return ctrl.signal;
|
|
2075
|
+
};
|
|
2076
|
+
return await retriable(async () => {
|
|
2077
|
+
let res = null;
|
|
2078
|
+
try {
|
|
2079
|
+
res = await this.fetch(url, {
|
|
2080
|
+
signal: AbortSignal.timeout(this.requestTimeout),
|
|
2081
|
+
...options
|
|
2082
|
+
});
|
|
2083
|
+
} catch (e) {
|
|
2084
|
+
throw new LangfuseFetchNetworkError(e);
|
|
2085
|
+
}
|
|
2086
|
+
if (res.status < 200 || res.status >= 400) {
|
|
2087
|
+
const body = await res.json();
|
|
2088
|
+
throw new LangfuseFetchHttpError(res, JSON.stringify(body));
|
|
2089
|
+
}
|
|
2090
|
+
const returnBody = await res.json();
|
|
2091
|
+
if (res.status === 207 && returnBody.errors.length > 0) {
|
|
2092
|
+
throw new LangfuseFetchHttpError(res, JSON.stringify(returnBody.errors));
|
|
2093
|
+
}
|
|
2094
|
+
return res;
|
|
2095
|
+
}, {
|
|
2096
|
+
...this._retryOptions,
|
|
2097
|
+
...retryOptions
|
|
2098
|
+
}, (string) => this._events.emit("retry", string + ", " + url + ", " + JSON.stringify(options)));
|
|
2099
|
+
}
|
|
2100
|
+
async fetchAndLogErrors(url, options) {
|
|
2101
|
+
const res = await this.fetch(url, options);
|
|
2102
|
+
const data = res.status === 429 ? await res.text() : await res.json();
|
|
2103
|
+
if (res.status < 200 || res.status >= 400) {
|
|
2104
|
+
logIngestionError(new LangfuseFetchHttpError(res, JSON.stringify(data)));
|
|
2105
|
+
}
|
|
2106
|
+
return data;
|
|
2107
|
+
}
|
|
2108
|
+
async shutdownAsync() {
|
|
2109
|
+
clearTimeout(this._flushTimer);
|
|
2110
|
+
try {
|
|
2111
|
+
await this.flushAsync();
|
|
2112
|
+
await Promise.all(Object.values(this.pendingIngestionPromises).map((x) => x.catch(() => {
|
|
2113
|
+
})));
|
|
2114
|
+
await this.flushAsync();
|
|
2115
|
+
} catch (e) {
|
|
2116
|
+
console.error("[Langfuse SDK] Error while shutting down Langfuse", e);
|
|
2117
|
+
}
|
|
2118
|
+
}
|
|
2119
|
+
async _exportLocalEvents(projectId) {
|
|
2120
|
+
if (this.isLocalEventExportEnabled) {
|
|
2121
|
+
clearTimeout(this._flushTimer);
|
|
2122
|
+
await this.flushAsync();
|
|
2123
|
+
const events = this.localEventExportMap.get(projectId) ?? [];
|
|
2124
|
+
this.localEventExportMap.delete(projectId);
|
|
2125
|
+
return events;
|
|
2126
|
+
} else {
|
|
2127
|
+
this._events.emit("error", "Local event exports are disabled, but _exportLocalEvents() was called.");
|
|
2128
|
+
return [];
|
|
2129
|
+
}
|
|
2130
|
+
}
|
|
2131
|
+
shutdown() {
|
|
2132
|
+
console.warn("shutdown() is deprecated. It does not wait for all events to be processed. Please use shutdownAsync() instead.");
|
|
2133
|
+
void this.shutdownAsync();
|
|
2134
|
+
}
|
|
2135
|
+
async awaitAllQueuedAndPendingRequests() {
|
|
2136
|
+
clearTimeout(this._flushTimer);
|
|
2137
|
+
await this.flushAsync();
|
|
2138
|
+
await Promise.all(Object.values(this.pendingIngestionPromises));
|
|
2139
|
+
}
|
|
2140
|
+
};
|
|
2141
|
+
var LangfuseCore = class extends LangfuseCoreStateless {
|
|
2142
|
+
constructor(params) {
|
|
2143
|
+
const {
|
|
2144
|
+
publicKey,
|
|
2145
|
+
secretKey,
|
|
2146
|
+
enabled,
|
|
2147
|
+
_isLocalEventExportEnabled
|
|
2148
|
+
} = params;
|
|
2149
|
+
let isObservabilityEnabled = enabled === false ? false : true;
|
|
2150
|
+
if (_isLocalEventExportEnabled) {
|
|
2151
|
+
isObservabilityEnabled = true;
|
|
2152
|
+
} else if (!secretKey) {
|
|
2153
|
+
isObservabilityEnabled = false;
|
|
2154
|
+
if (enabled !== false) {
|
|
2155
|
+
console.warn("Langfuse secret key was not passed to constructor or not set as 'LANGFUSE_SECRET_KEY' environment variable. No observability data will be sent to Langfuse.");
|
|
2156
|
+
}
|
|
2157
|
+
} else if (!publicKey) {
|
|
2158
|
+
isObservabilityEnabled = false;
|
|
2159
|
+
if (enabled !== false) {
|
|
2160
|
+
console.warn("Langfuse public key was not passed to constructor or not set as 'LANGFUSE_PUBLIC_KEY' environment variable. No observability data will be sent to Langfuse.");
|
|
2161
|
+
}
|
|
2162
|
+
}
|
|
2163
|
+
super({
|
|
2164
|
+
...params,
|
|
2165
|
+
enabled: isObservabilityEnabled
|
|
2166
|
+
});
|
|
2167
|
+
this._promptCache = new LangfusePromptCache();
|
|
2168
|
+
}
|
|
2169
|
+
trace(body) {
|
|
2170
|
+
const id = this.traceStateless(body ?? {});
|
|
2171
|
+
const t = new LangfuseTraceClient(this, id);
|
|
2172
|
+
if (getEnv("DEFER") && body) {
|
|
2173
|
+
try {
|
|
2174
|
+
const deferRuntime = getEnv("__deferRuntime");
|
|
2175
|
+
if (deferRuntime) {
|
|
2176
|
+
deferRuntime.langfuseTraces([{
|
|
2177
|
+
id,
|
|
2178
|
+
name: body.name || "",
|
|
2179
|
+
url: t.getTraceUrl()
|
|
2180
|
+
}]);
|
|
2181
|
+
}
|
|
2182
|
+
} catch {
|
|
2183
|
+
}
|
|
2184
|
+
}
|
|
2185
|
+
return t;
|
|
2186
|
+
}
|
|
2187
|
+
span(body) {
|
|
2188
|
+
const traceId = body.traceId || this.traceStateless({
|
|
2189
|
+
name: body.name
|
|
2190
|
+
});
|
|
2191
|
+
const id = this.spanStateless({
|
|
2192
|
+
...body,
|
|
2193
|
+
traceId
|
|
2194
|
+
});
|
|
2195
|
+
return new LangfuseSpanClient(this, id, traceId);
|
|
2196
|
+
}
|
|
2197
|
+
generation(body) {
|
|
2198
|
+
const traceId = body.traceId || this.traceStateless({
|
|
2199
|
+
name: body.name
|
|
2200
|
+
});
|
|
2201
|
+
const id = this.generationStateless({
|
|
2202
|
+
...body,
|
|
2203
|
+
traceId
|
|
2204
|
+
});
|
|
2205
|
+
return new LangfuseGenerationClient(this, id, traceId);
|
|
2206
|
+
}
|
|
2207
|
+
event(body) {
|
|
2208
|
+
const traceId = body.traceId || this.traceStateless({
|
|
2209
|
+
name: body.name
|
|
2210
|
+
});
|
|
2211
|
+
const id = this.eventStateless({
|
|
2212
|
+
...body,
|
|
2213
|
+
traceId
|
|
2214
|
+
});
|
|
2215
|
+
return new LangfuseEventClient(this, id, traceId);
|
|
2216
|
+
}
|
|
2217
|
+
score(body) {
|
|
2218
|
+
this.scoreStateless(body);
|
|
2219
|
+
return this;
|
|
2220
|
+
}
|
|
2221
|
+
async getDataset(name, options) {
|
|
2222
|
+
const dataset = await this._getDataset(name);
|
|
2223
|
+
const items = [];
|
|
2224
|
+
let page = 1;
|
|
2225
|
+
while (true) {
|
|
2226
|
+
const itemsResponse = await this._getDatasetItems({
|
|
2227
|
+
datasetName: name,
|
|
2228
|
+
limit: options?.fetchItemsPageSize ?? 50,
|
|
2229
|
+
page
|
|
2230
|
+
});
|
|
2231
|
+
items.push(...itemsResponse.data);
|
|
2232
|
+
if (itemsResponse.meta.totalPages <= page) {
|
|
2233
|
+
break;
|
|
2234
|
+
}
|
|
2235
|
+
page++;
|
|
2236
|
+
}
|
|
2237
|
+
const returnDataset = {
|
|
2238
|
+
...dataset,
|
|
2239
|
+
description: dataset.description ?? void 0,
|
|
2240
|
+
metadata: dataset.metadata ?? void 0,
|
|
2241
|
+
items: items.map((item) => ({
|
|
2242
|
+
...item,
|
|
2243
|
+
link: async (obj, runName, runArgs) => {
|
|
2244
|
+
await this.awaitAllQueuedAndPendingRequests();
|
|
2245
|
+
const data = await this.createDatasetRunItem({
|
|
2246
|
+
runName,
|
|
2247
|
+
datasetItemId: item.id,
|
|
2248
|
+
observationId: obj.observationId,
|
|
2249
|
+
traceId: obj.traceId,
|
|
2250
|
+
runDescription: runArgs?.description,
|
|
2251
|
+
metadata: runArgs?.metadata
|
|
2252
|
+
});
|
|
2253
|
+
return data;
|
|
2254
|
+
}
|
|
2255
|
+
}))
|
|
2256
|
+
};
|
|
2257
|
+
return returnDataset;
|
|
2258
|
+
}
|
|
2259
|
+
async createPrompt(body) {
|
|
2260
|
+
const labels = body.labels ?? [];
|
|
2261
|
+
const promptResponse = body.type === "chat" ? await this.createPromptStateless({
|
|
2262
|
+
...body,
|
|
2263
|
+
prompt: body.prompt.map((item) => {
|
|
2264
|
+
if ("type" in item && item.type === ChatMessageType.Placeholder) {
|
|
2265
|
+
return {
|
|
2266
|
+
type: ChatMessageType.Placeholder,
|
|
2267
|
+
name: item.name
|
|
2268
|
+
};
|
|
2269
|
+
} else {
|
|
2270
|
+
return {
|
|
2271
|
+
type: ChatMessageType.ChatMessage,
|
|
2272
|
+
...item
|
|
2273
|
+
};
|
|
2274
|
+
}
|
|
2275
|
+
}),
|
|
2276
|
+
labels: body.isActive ? [.../* @__PURE__ */ new Set([...labels, "production"])] : labels
|
|
2277
|
+
// backward compatibility for isActive
|
|
2278
|
+
}) : await this.createPromptStateless({
|
|
2279
|
+
...body,
|
|
2280
|
+
type: body.type ?? "text",
|
|
2281
|
+
labels: body.isActive ? [.../* @__PURE__ */ new Set([...labels, "production"])] : labels
|
|
2282
|
+
// backward compatibility for isActive
|
|
2283
|
+
});
|
|
2284
|
+
if (promptResponse.type === "chat") {
|
|
2285
|
+
return new ChatPromptClient(promptResponse);
|
|
2286
|
+
}
|
|
2287
|
+
return new TextPromptClient(promptResponse);
|
|
2288
|
+
}
|
|
2289
|
+
async updatePrompt(body) {
|
|
2290
|
+
const newPrompt = await this.updatePromptStateless(body);
|
|
2291
|
+
this._promptCache.invalidate(body.name);
|
|
2292
|
+
return newPrompt;
|
|
2293
|
+
}
|
|
2294
|
+
async getPrompt(name, version2, options) {
|
|
2295
|
+
const cacheKey = this._getPromptCacheKey({
|
|
2296
|
+
name,
|
|
2297
|
+
version: version2,
|
|
2298
|
+
label: options?.label
|
|
2299
|
+
});
|
|
2300
|
+
const cachedPrompt = this._promptCache.getIncludingExpired(cacheKey);
|
|
2301
|
+
if (!cachedPrompt || options?.cacheTtlSeconds === 0) {
|
|
2302
|
+
try {
|
|
2303
|
+
return await this._fetchPromptAndUpdateCache({
|
|
2304
|
+
name,
|
|
2305
|
+
version: version2,
|
|
2306
|
+
label: options?.label,
|
|
2307
|
+
cacheTtlSeconds: options?.cacheTtlSeconds,
|
|
2308
|
+
maxRetries: options?.maxRetries,
|
|
2309
|
+
fetchTimeout: options?.fetchTimeoutMs
|
|
2310
|
+
});
|
|
2311
|
+
} catch (err) {
|
|
2312
|
+
if (options?.fallback) {
|
|
2313
|
+
const sharedFallbackParams = {
|
|
2314
|
+
name,
|
|
2315
|
+
version: version2 ?? 0,
|
|
2316
|
+
labels: options.label ? [options.label] : [],
|
|
2317
|
+
cacheTtlSeconds: options?.cacheTtlSeconds,
|
|
2318
|
+
config: {},
|
|
2319
|
+
tags: []
|
|
2320
|
+
};
|
|
2321
|
+
if (options.type === "chat") {
|
|
2322
|
+
return new ChatPromptClient({
|
|
2323
|
+
...sharedFallbackParams,
|
|
2324
|
+
type: "chat",
|
|
2325
|
+
prompt: options.fallback.map((msg) => ({
|
|
2326
|
+
type: ChatMessageType.ChatMessage,
|
|
2327
|
+
...msg
|
|
2328
|
+
}))
|
|
2329
|
+
}, true);
|
|
2330
|
+
} else {
|
|
2331
|
+
return new TextPromptClient({
|
|
2332
|
+
...sharedFallbackParams,
|
|
2333
|
+
type: "text",
|
|
2334
|
+
prompt: options.fallback
|
|
2335
|
+
}, true);
|
|
2336
|
+
}
|
|
2337
|
+
}
|
|
2338
|
+
throw err;
|
|
2339
|
+
}
|
|
2340
|
+
}
|
|
2341
|
+
if (cachedPrompt.isExpired) {
|
|
2342
|
+
if (!this._promptCache.isRefreshing(cacheKey)) {
|
|
2343
|
+
const refreshPromptPromise = this._fetchPromptAndUpdateCache({
|
|
2344
|
+
name,
|
|
2345
|
+
version: version2,
|
|
2346
|
+
label: options?.label,
|
|
2347
|
+
cacheTtlSeconds: options?.cacheTtlSeconds,
|
|
2348
|
+
maxRetries: options?.maxRetries,
|
|
2349
|
+
fetchTimeout: options?.fetchTimeoutMs
|
|
2350
|
+
}).catch(() => {
|
|
2351
|
+
console.warn(`Failed to refresh prompt cache '${cacheKey}', stale cache will be used until next refresh succeeds.`);
|
|
2352
|
+
});
|
|
2353
|
+
this._promptCache.addRefreshingPromise(cacheKey, refreshPromptPromise);
|
|
2354
|
+
}
|
|
2355
|
+
return cachedPrompt.value;
|
|
2356
|
+
}
|
|
2357
|
+
return cachedPrompt.value;
|
|
2358
|
+
}
|
|
2359
|
+
_getPromptCacheKey(params) {
|
|
2360
|
+
const {
|
|
2361
|
+
name,
|
|
2362
|
+
version: version2,
|
|
2363
|
+
label
|
|
2364
|
+
} = params;
|
|
2365
|
+
const parts = [name];
|
|
2366
|
+
if (version2 !== void 0) {
|
|
2367
|
+
parts.push("version:" + version2.toString());
|
|
2368
|
+
} else if (label !== void 0) {
|
|
2369
|
+
parts.push("label:" + label);
|
|
2370
|
+
} else {
|
|
2371
|
+
parts.push("label:production");
|
|
2372
|
+
}
|
|
2373
|
+
return parts.join("-");
|
|
2374
|
+
}
|
|
2375
|
+
async _fetchPromptAndUpdateCache(params) {
|
|
2376
|
+
const cacheKey = this._getPromptCacheKey(params);
|
|
2377
|
+
try {
|
|
2378
|
+
const {
|
|
2379
|
+
name,
|
|
2380
|
+
version: version2,
|
|
2381
|
+
cacheTtlSeconds,
|
|
2382
|
+
label,
|
|
2383
|
+
maxRetries,
|
|
2384
|
+
fetchTimeout
|
|
2385
|
+
} = params;
|
|
2386
|
+
const {
|
|
2387
|
+
data,
|
|
2388
|
+
fetchResult
|
|
2389
|
+
} = await this.getPromptStateless(name, version2, label, maxRetries, fetchTimeout);
|
|
2390
|
+
if (fetchResult === "failure") {
|
|
2391
|
+
throw Error(data.message ?? "Internal error while fetching prompt");
|
|
2392
|
+
}
|
|
2393
|
+
let prompt;
|
|
2394
|
+
if (data.type === "chat") {
|
|
2395
|
+
prompt = new ChatPromptClient(data);
|
|
2396
|
+
} else {
|
|
2397
|
+
prompt = new TextPromptClient(data);
|
|
2398
|
+
}
|
|
2399
|
+
this._promptCache.set(cacheKey, prompt, cacheTtlSeconds);
|
|
2400
|
+
return prompt;
|
|
2401
|
+
} catch (error) {
|
|
2402
|
+
console.error(`[Langfuse SDK] Error while fetching prompt '${cacheKey}':`, error);
|
|
2403
|
+
throw error;
|
|
2404
|
+
}
|
|
2405
|
+
}
|
|
2406
|
+
async fetchMedia(id) {
|
|
2407
|
+
return await this._fetchMedia(id);
|
|
2408
|
+
}
|
|
2409
|
+
/**
|
|
2410
|
+
* Replaces the media reference strings in an object with base64 data URIs for the media content.
|
|
2411
|
+
*
|
|
2412
|
+
* This method recursively traverses an object (up to a maximum depth of 10) looking for media reference strings
|
|
2413
|
+
* in the format "@@@langfuseMedia:...@@@". When found, it fetches the actual media content using the provided
|
|
2414
|
+
* Langfuse client and replaces the reference string with a base64 data URI.
|
|
2415
|
+
*
|
|
2416
|
+
* If fetching media content fails for a reference string, a warning is logged and the reference string is left unchanged.
|
|
2417
|
+
*
|
|
2418
|
+
* @param params - Configuration object
|
|
2419
|
+
* @param params.obj - The object to process. Can be a primitive value, array, or nested object
|
|
2420
|
+
* @param params.langfuseClient - Langfuse client instance used to fetch media content
|
|
2421
|
+
* @param params.resolveWith - The representation of the media content to replace the media reference string with. Currently only "base64DataUri" is supported.
|
|
2422
|
+
* @param params.maxDepth - Optional. Default is 10. The maximum depth to traverse the object.
|
|
2423
|
+
*
|
|
2424
|
+
* @returns A deep copy of the input object with all media references replaced with base64 data URIs where possible
|
|
2425
|
+
*
|
|
2426
|
+
* @example
|
|
2427
|
+
* ```typescript
|
|
2428
|
+
* const obj = {
|
|
2429
|
+
* image: "@@@langfuseMedia:type=image/jpeg|id=123|source=bytes@@@",
|
|
2430
|
+
* nested: {
|
|
2431
|
+
* pdf: "@@@langfuseMedia:type=application/pdf|id=456|source=bytes@@@"
|
|
2432
|
+
* }
|
|
2433
|
+
* };
|
|
2434
|
+
*
|
|
2435
|
+
* const result = await LangfuseMedia.resolveMediaReferences({
|
|
2436
|
+
* obj,
|
|
2437
|
+
* langfuseClient
|
|
2438
|
+
* });
|
|
2439
|
+
*
|
|
2440
|
+
* // Result:
|
|
2441
|
+
* // {
|
|
2442
|
+
* // image: "data:image/jpeg;base64,/9j/4AAQSkZJRg...",
|
|
2443
|
+
* // nested: {
|
|
2444
|
+
* // pdf: "data:application/pdf;base64,JVBERi0xLjcK..."
|
|
2445
|
+
* // }
|
|
2446
|
+
* // }
|
|
2447
|
+
* ```
|
|
2448
|
+
*/
|
|
2449
|
+
async resolveMediaReferences(params) {
|
|
2450
|
+
const {
|
|
2451
|
+
obj,
|
|
2452
|
+
...rest
|
|
2453
|
+
} = params;
|
|
2454
|
+
return LangfuseMedia.resolveMediaReferences({
|
|
2455
|
+
...rest,
|
|
2456
|
+
langfuseClient: this,
|
|
2457
|
+
obj
|
|
2458
|
+
});
|
|
2459
|
+
}
|
|
2460
|
+
_updateSpan(body) {
|
|
2461
|
+
this.updateSpanStateless(body);
|
|
2462
|
+
return this;
|
|
2463
|
+
}
|
|
2464
|
+
_updateGeneration(body) {
|
|
2465
|
+
this.updateGenerationStateless(body);
|
|
2466
|
+
return this;
|
|
2467
|
+
}
|
|
2468
|
+
};
|
|
2469
|
+
var LangfuseObjectClient = class {
|
|
2470
|
+
constructor({
|
|
2471
|
+
client,
|
|
2472
|
+
id,
|
|
2473
|
+
traceId,
|
|
2474
|
+
observationId
|
|
2475
|
+
}) {
|
|
2476
|
+
this.client = client;
|
|
2477
|
+
this.id = id;
|
|
2478
|
+
this.traceId = traceId;
|
|
2479
|
+
this.observationId = observationId;
|
|
2480
|
+
}
|
|
2481
|
+
event(body) {
|
|
2482
|
+
return this.client.event({
|
|
2483
|
+
...body,
|
|
2484
|
+
traceId: this.traceId,
|
|
2485
|
+
parentObservationId: this.observationId
|
|
2486
|
+
});
|
|
2487
|
+
}
|
|
2488
|
+
span(body) {
|
|
2489
|
+
return this.client.span({
|
|
2490
|
+
...body,
|
|
2491
|
+
traceId: this.traceId,
|
|
2492
|
+
parentObservationId: this.observationId
|
|
2493
|
+
});
|
|
2494
|
+
}
|
|
2495
|
+
generation(body) {
|
|
2496
|
+
return this.client.generation({
|
|
2497
|
+
...body,
|
|
2498
|
+
traceId: this.traceId,
|
|
2499
|
+
parentObservationId: this.observationId
|
|
2500
|
+
});
|
|
2501
|
+
}
|
|
2502
|
+
score(body) {
|
|
2503
|
+
this.client.score({
|
|
2504
|
+
...body,
|
|
2505
|
+
traceId: this.traceId,
|
|
2506
|
+
observationId: this.observationId
|
|
2507
|
+
});
|
|
2508
|
+
return this;
|
|
2509
|
+
}
|
|
2510
|
+
getTraceUrl() {
|
|
2511
|
+
return `${this.client.baseUrl}/trace/${this.traceId}`;
|
|
2512
|
+
}
|
|
2513
|
+
};
|
|
2514
|
+
var LangfuseTraceClient = class extends LangfuseObjectClient {
|
|
2515
|
+
constructor(client, traceId) {
|
|
2516
|
+
super({
|
|
2517
|
+
client,
|
|
2518
|
+
id: traceId,
|
|
2519
|
+
traceId,
|
|
2520
|
+
observationId: null
|
|
2521
|
+
});
|
|
2522
|
+
}
|
|
2523
|
+
update(body) {
|
|
2524
|
+
this.client.trace({
|
|
2525
|
+
...body,
|
|
2526
|
+
id: this.id
|
|
2527
|
+
});
|
|
2528
|
+
return this;
|
|
2529
|
+
}
|
|
2530
|
+
};
|
|
2531
|
+
var LangfuseObservationClient = class extends LangfuseObjectClient {
|
|
2532
|
+
constructor(client, id, traceId) {
|
|
2533
|
+
super({
|
|
2534
|
+
client,
|
|
2535
|
+
id,
|
|
2536
|
+
traceId,
|
|
2537
|
+
observationId: id
|
|
2538
|
+
});
|
|
2539
|
+
}
|
|
2540
|
+
};
|
|
2541
|
+
var LangfuseSpanClient = class extends LangfuseObservationClient {
|
|
2542
|
+
constructor(client, id, traceId) {
|
|
2543
|
+
super(client, id, traceId);
|
|
2544
|
+
}
|
|
2545
|
+
update(body) {
|
|
2546
|
+
this.client._updateSpan({
|
|
2547
|
+
...body,
|
|
2548
|
+
id: this.id,
|
|
2549
|
+
traceId: this.traceId
|
|
2550
|
+
});
|
|
2551
|
+
return this;
|
|
2552
|
+
}
|
|
2553
|
+
end(body) {
|
|
2554
|
+
this.client._updateSpan({
|
|
2555
|
+
...body,
|
|
2556
|
+
id: this.id,
|
|
2557
|
+
traceId: this.traceId,
|
|
2558
|
+
endTime: /* @__PURE__ */ new Date()
|
|
2559
|
+
});
|
|
2560
|
+
return this;
|
|
2561
|
+
}
|
|
2562
|
+
};
|
|
2563
|
+
var LangfuseGenerationClient = class extends LangfuseObservationClient {
|
|
2564
|
+
constructor(client, id, traceId) {
|
|
2565
|
+
super(client, id, traceId);
|
|
2566
|
+
}
|
|
2567
|
+
update(body) {
|
|
2568
|
+
this.client._updateGeneration({
|
|
2569
|
+
...body,
|
|
2570
|
+
id: this.id,
|
|
2571
|
+
traceId: this.traceId
|
|
2572
|
+
});
|
|
2573
|
+
return this;
|
|
2574
|
+
}
|
|
2575
|
+
end(body) {
|
|
2576
|
+
this.client._updateGeneration({
|
|
2577
|
+
...body,
|
|
2578
|
+
id: this.id,
|
|
2579
|
+
traceId: this.traceId,
|
|
2580
|
+
endTime: /* @__PURE__ */ new Date()
|
|
2581
|
+
});
|
|
2582
|
+
return this;
|
|
2583
|
+
}
|
|
2584
|
+
};
|
|
2585
|
+
var LangfuseEventClient = class extends LangfuseObservationClient {
|
|
2586
|
+
constructor(client, id, traceId) {
|
|
2587
|
+
super(client, id, traceId);
|
|
2588
|
+
}
|
|
2589
|
+
};
|
|
2590
|
+
|
|
2591
|
+
// ../../node_modules/.pnpm/langfuse@3.39.2/node_modules/langfuse/lib/index.mjs
|
|
2592
|
+
var cookieStore = {
|
|
2593
|
+
getItem(key) {
|
|
2594
|
+
try {
|
|
2595
|
+
const nameEQ = key + "=";
|
|
2596
|
+
const ca = document.cookie.split(";");
|
|
2597
|
+
for (let i = 0; i < ca.length; i++) {
|
|
2598
|
+
let c = ca[i];
|
|
2599
|
+
while (c.charAt(0) == " ") {
|
|
2600
|
+
c = c.substring(1, c.length);
|
|
2601
|
+
}
|
|
2602
|
+
if (c.indexOf(nameEQ) === 0) {
|
|
2603
|
+
return decodeURIComponent(c.substring(nameEQ.length, c.length));
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
} catch (err) {
|
|
2607
|
+
}
|
|
2608
|
+
return null;
|
|
2609
|
+
},
|
|
2610
|
+
setItem(key, value) {
|
|
2611
|
+
try {
|
|
2612
|
+
const cdomain = "", expires = "", secure = "";
|
|
2613
|
+
const new_cookie_val = key + "=" + encodeURIComponent(value) + expires + "; path=/" + cdomain + secure;
|
|
2614
|
+
document.cookie = new_cookie_val;
|
|
2615
|
+
} catch (err) {
|
|
2616
|
+
return;
|
|
2617
|
+
}
|
|
2618
|
+
},
|
|
2619
|
+
removeItem(name) {
|
|
2620
|
+
try {
|
|
2621
|
+
cookieStore.setItem(name, "");
|
|
2622
|
+
} catch (err) {
|
|
2623
|
+
return;
|
|
2624
|
+
}
|
|
2625
|
+
},
|
|
2626
|
+
clear() {
|
|
2627
|
+
document.cookie = "";
|
|
2628
|
+
},
|
|
2629
|
+
getAllKeys() {
|
|
2630
|
+
const ca = document.cookie.split(";");
|
|
2631
|
+
const keys = [];
|
|
2632
|
+
for (let i = 0; i < ca.length; i++) {
|
|
2633
|
+
let c = ca[i];
|
|
2634
|
+
while (c.charAt(0) == " ") {
|
|
2635
|
+
c = c.substring(1, c.length);
|
|
2636
|
+
}
|
|
2637
|
+
keys.push(c.split("=")[0]);
|
|
2638
|
+
}
|
|
2639
|
+
return keys;
|
|
2640
|
+
}
|
|
2641
|
+
};
|
|
2642
|
+
var createStorageLike = (store) => {
|
|
2643
|
+
return {
|
|
2644
|
+
getItem(key) {
|
|
2645
|
+
return store.getItem(key);
|
|
2646
|
+
},
|
|
2647
|
+
setItem(key, value) {
|
|
2648
|
+
store.setItem(key, value);
|
|
2649
|
+
},
|
|
2650
|
+
removeItem(key) {
|
|
2651
|
+
store.removeItem(key);
|
|
2652
|
+
},
|
|
2653
|
+
clear() {
|
|
2654
|
+
store.clear();
|
|
2655
|
+
},
|
|
2656
|
+
getAllKeys() {
|
|
2657
|
+
const keys = [];
|
|
2658
|
+
for (const key in localStorage) {
|
|
2659
|
+
keys.push(key);
|
|
2660
|
+
}
|
|
2661
|
+
return keys;
|
|
2662
|
+
}
|
|
2663
|
+
};
|
|
2664
|
+
};
|
|
2665
|
+
var checkStoreIsSupported = (storage, key = "__mplssupport__") => {
|
|
2666
|
+
if (!window) {
|
|
2667
|
+
return false;
|
|
2668
|
+
}
|
|
2669
|
+
try {
|
|
2670
|
+
const val = "xyz";
|
|
2671
|
+
storage.setItem(key, val);
|
|
2672
|
+
if (storage.getItem(key) !== val) {
|
|
2673
|
+
return false;
|
|
2674
|
+
}
|
|
2675
|
+
storage.removeItem(key);
|
|
2676
|
+
return true;
|
|
2677
|
+
} catch (err) {
|
|
2678
|
+
return false;
|
|
2679
|
+
}
|
|
2680
|
+
};
|
|
2681
|
+
var localStore = void 0;
|
|
2682
|
+
var sessionStore = void 0;
|
|
2683
|
+
var createMemoryStorage = () => {
|
|
2684
|
+
const _cache = {};
|
|
2685
|
+
const store = {
|
|
2686
|
+
getItem(key) {
|
|
2687
|
+
return _cache[key];
|
|
2688
|
+
},
|
|
2689
|
+
setItem(key, value) {
|
|
2690
|
+
_cache[key] = value !== null ? value : void 0;
|
|
2691
|
+
},
|
|
2692
|
+
removeItem(key) {
|
|
2693
|
+
delete _cache[key];
|
|
2694
|
+
},
|
|
2695
|
+
clear() {
|
|
2696
|
+
for (const key in _cache) {
|
|
2697
|
+
delete _cache[key];
|
|
2698
|
+
}
|
|
2699
|
+
},
|
|
2700
|
+
getAllKeys() {
|
|
2701
|
+
const keys = [];
|
|
2702
|
+
for (const key in _cache) {
|
|
2703
|
+
keys.push(key);
|
|
2704
|
+
}
|
|
2705
|
+
return keys;
|
|
2706
|
+
}
|
|
2707
|
+
};
|
|
2708
|
+
return store;
|
|
2709
|
+
};
|
|
2710
|
+
var getStorage = (type, window2) => {
|
|
2711
|
+
if (typeof window2 !== void 0 && window2) {
|
|
2712
|
+
if (!localStorage) {
|
|
2713
|
+
const _localStore = createStorageLike(window2.localStorage);
|
|
2714
|
+
localStore = checkStoreIsSupported(_localStore) ? _localStore : void 0;
|
|
2715
|
+
}
|
|
2716
|
+
if (!sessionStore) {
|
|
2717
|
+
const _sessionStore = createStorageLike(window2.sessionStorage);
|
|
2718
|
+
sessionStore = checkStoreIsSupported(_sessionStore) ? _sessionStore : void 0;
|
|
2719
|
+
}
|
|
2720
|
+
}
|
|
2721
|
+
switch (type) {
|
|
2722
|
+
case "cookie":
|
|
2723
|
+
return cookieStore || localStore || sessionStore || createMemoryStorage();
|
|
2724
|
+
case "localStorage":
|
|
2725
|
+
return localStore || sessionStore || createMemoryStorage();
|
|
2726
|
+
case "sessionStorage":
|
|
2727
|
+
return sessionStore || createMemoryStorage();
|
|
2728
|
+
case "memory":
|
|
2729
|
+
return createMemoryStorage();
|
|
2730
|
+
default:
|
|
2731
|
+
return createMemoryStorage();
|
|
2732
|
+
}
|
|
2733
|
+
};
|
|
2734
|
+
var ContentType;
|
|
2735
|
+
(function(ContentType2) {
|
|
2736
|
+
ContentType2["Json"] = "application/json";
|
|
2737
|
+
ContentType2["FormData"] = "multipart/form-data";
|
|
2738
|
+
ContentType2["UrlEncoded"] = "application/x-www-form-urlencoded";
|
|
2739
|
+
ContentType2["Text"] = "text/plain";
|
|
2740
|
+
})(ContentType || (ContentType = {}));
|
|
2741
|
+
var HttpClient = class {
|
|
2742
|
+
constructor(apiConfig = {}) {
|
|
2743
|
+
this.baseUrl = "";
|
|
2744
|
+
this.securityData = null;
|
|
2745
|
+
this.abortControllers = /* @__PURE__ */ new Map();
|
|
2746
|
+
this.customFetch = (...fetchParams) => fetch(...fetchParams);
|
|
2747
|
+
this.baseApiParams = {
|
|
2748
|
+
credentials: "same-origin",
|
|
2749
|
+
headers: {},
|
|
2750
|
+
redirect: "follow",
|
|
2751
|
+
referrerPolicy: "no-referrer"
|
|
2752
|
+
};
|
|
2753
|
+
this.setSecurityData = (data) => {
|
|
2754
|
+
this.securityData = data;
|
|
2755
|
+
};
|
|
2756
|
+
this.contentFormatters = {
|
|
2757
|
+
[ContentType.Json]: (input) => input !== null && (typeof input === "object" || typeof input === "string") ? JSON.stringify(input) : input,
|
|
2758
|
+
[ContentType.Text]: (input) => input !== null && typeof input !== "string" ? JSON.stringify(input) : input,
|
|
2759
|
+
[ContentType.FormData]: (input) => Object.keys(input || {}).reduce((formData, key) => {
|
|
2760
|
+
const property = input[key];
|
|
2761
|
+
formData.append(key, property instanceof Blob ? property : typeof property === "object" && property !== null ? JSON.stringify(property) : `${property}`);
|
|
2762
|
+
return formData;
|
|
2763
|
+
}, new FormData()),
|
|
2764
|
+
[ContentType.UrlEncoded]: (input) => this.toQueryString(input)
|
|
2765
|
+
};
|
|
2766
|
+
this.createAbortSignal = (cancelToken) => {
|
|
2767
|
+
if (this.abortControllers.has(cancelToken)) {
|
|
2768
|
+
const abortController2 = this.abortControllers.get(cancelToken);
|
|
2769
|
+
if (abortController2) {
|
|
2770
|
+
return abortController2.signal;
|
|
2771
|
+
}
|
|
2772
|
+
return void 0;
|
|
2773
|
+
}
|
|
2774
|
+
const abortController = new AbortController();
|
|
2775
|
+
this.abortControllers.set(cancelToken, abortController);
|
|
2776
|
+
return abortController.signal;
|
|
2777
|
+
};
|
|
2778
|
+
this.abortRequest = (cancelToken) => {
|
|
2779
|
+
const abortController = this.abortControllers.get(cancelToken);
|
|
2780
|
+
if (abortController) {
|
|
2781
|
+
abortController.abort();
|
|
2782
|
+
this.abortControllers.delete(cancelToken);
|
|
2783
|
+
}
|
|
2784
|
+
};
|
|
2785
|
+
this.request = async ({
|
|
2786
|
+
body,
|
|
2787
|
+
secure,
|
|
2788
|
+
path,
|
|
2789
|
+
type,
|
|
2790
|
+
query,
|
|
2791
|
+
format,
|
|
2792
|
+
baseUrl,
|
|
2793
|
+
cancelToken,
|
|
2794
|
+
...params
|
|
2795
|
+
}) => {
|
|
2796
|
+
const secureParams = (typeof secure === "boolean" ? secure : this.baseApiParams.secure) && this.securityWorker && await this.securityWorker(this.securityData) || {};
|
|
2797
|
+
const requestParams = this.mergeRequestParams(params, secureParams);
|
|
2798
|
+
const queryString = query && this.toQueryString(query);
|
|
2799
|
+
const payloadFormatter = this.contentFormatters[type || ContentType.Json];
|
|
2800
|
+
const responseFormat = format || requestParams.format;
|
|
2801
|
+
return this.customFetch(`${baseUrl || this.baseUrl || ""}${path}${queryString ? `?${queryString}` : ""}`, {
|
|
2802
|
+
...requestParams,
|
|
2803
|
+
headers: {
|
|
2804
|
+
...requestParams.headers || {},
|
|
2805
|
+
...type && type !== ContentType.FormData ? {
|
|
2806
|
+
"Content-Type": type
|
|
2807
|
+
} : {}
|
|
2808
|
+
},
|
|
2809
|
+
signal: (cancelToken ? this.createAbortSignal(cancelToken) : requestParams.signal) || null,
|
|
2810
|
+
body: typeof body === "undefined" || body === null ? null : payloadFormatter(body)
|
|
2811
|
+
}).then(async (response) => {
|
|
2812
|
+
const r = response.clone();
|
|
2813
|
+
r.data = null;
|
|
2814
|
+
r.error = null;
|
|
2815
|
+
const data = !responseFormat ? r : await response[responseFormat]().then((data2) => {
|
|
2816
|
+
if (r.ok) {
|
|
2817
|
+
r.data = data2;
|
|
2818
|
+
} else {
|
|
2819
|
+
r.error = data2;
|
|
2820
|
+
}
|
|
2821
|
+
return r;
|
|
2822
|
+
}).catch((e) => {
|
|
2823
|
+
r.error = e;
|
|
2824
|
+
return r;
|
|
2825
|
+
});
|
|
2826
|
+
if (cancelToken) {
|
|
2827
|
+
this.abortControllers.delete(cancelToken);
|
|
2828
|
+
}
|
|
2829
|
+
if (!response.ok) throw data;
|
|
2830
|
+
return data.data;
|
|
2831
|
+
});
|
|
2832
|
+
};
|
|
2833
|
+
Object.assign(this, apiConfig);
|
|
2834
|
+
}
|
|
2835
|
+
encodeQueryParam(key, value) {
|
|
2836
|
+
const encodedKey = encodeURIComponent(key);
|
|
2837
|
+
return `${encodedKey}=${encodeURIComponent(typeof value === "number" ? value : `${value}`)}`;
|
|
2838
|
+
}
|
|
2839
|
+
addQueryParam(query, key) {
|
|
2840
|
+
return this.encodeQueryParam(key, query[key]);
|
|
2841
|
+
}
|
|
2842
|
+
addArrayQueryParam(query, key) {
|
|
2843
|
+
const value = query[key];
|
|
2844
|
+
return value.map((v) => this.encodeQueryParam(key, v)).join("&");
|
|
2845
|
+
}
|
|
2846
|
+
toQueryString(rawQuery) {
|
|
2847
|
+
const query = rawQuery || {};
|
|
2848
|
+
const keys = Object.keys(query).filter((key) => "undefined" !== typeof query[key]);
|
|
2849
|
+
return keys.map((key) => Array.isArray(query[key]) ? this.addArrayQueryParam(query, key) : this.addQueryParam(query, key)).join("&");
|
|
2850
|
+
}
|
|
2851
|
+
addQueryParams(rawQuery) {
|
|
2852
|
+
const queryString = this.toQueryString(rawQuery);
|
|
2853
|
+
return queryString ? `?${queryString}` : "";
|
|
2854
|
+
}
|
|
2855
|
+
mergeRequestParams(params1, params2) {
|
|
2856
|
+
return {
|
|
2857
|
+
...this.baseApiParams,
|
|
2858
|
+
...params1,
|
|
2859
|
+
...params2 || {},
|
|
2860
|
+
headers: {
|
|
2861
|
+
...this.baseApiParams.headers || {},
|
|
2862
|
+
...params1.headers || {},
|
|
2863
|
+
...params2 && params2.headers || {}
|
|
2864
|
+
}
|
|
2865
|
+
};
|
|
2866
|
+
}
|
|
2867
|
+
};
|
|
2868
|
+
var LangfusePublicApi = class extends HttpClient {
|
|
2869
|
+
constructor() {
|
|
2870
|
+
super(...arguments);
|
|
2871
|
+
this.api = {
|
|
2872
|
+
/**
|
|
2873
|
+
* @description Add an item to an annotation queue
|
|
2874
|
+
*
|
|
2875
|
+
* @tags AnnotationQueues
|
|
2876
|
+
* @name AnnotationQueuesCreateQueueItem
|
|
2877
|
+
* @request POST:/api/public/annotation-queues/{queueId}/items
|
|
2878
|
+
* @secure
|
|
2879
|
+
*/
|
|
2880
|
+
annotationQueuesCreateQueueItem: (queueId, data, params = {}) => this.request({
|
|
2881
|
+
path: `/api/public/annotation-queues/${queueId}/items`,
|
|
2882
|
+
method: "POST",
|
|
2883
|
+
body: data,
|
|
2884
|
+
secure: true,
|
|
2885
|
+
type: ContentType.Json,
|
|
2886
|
+
format: "json",
|
|
2887
|
+
...params
|
|
2888
|
+
}),
|
|
2889
|
+
/**
|
|
2890
|
+
* @description Remove an item from an annotation queue
|
|
2891
|
+
*
|
|
2892
|
+
* @tags AnnotationQueues
|
|
2893
|
+
* @name AnnotationQueuesDeleteQueueItem
|
|
2894
|
+
* @request DELETE:/api/public/annotation-queues/{queueId}/items/{itemId}
|
|
2895
|
+
* @secure
|
|
2896
|
+
*/
|
|
2897
|
+
annotationQueuesDeleteQueueItem: (queueId, itemId, params = {}) => this.request({
|
|
2898
|
+
path: `/api/public/annotation-queues/${queueId}/items/${itemId}`,
|
|
2899
|
+
method: "DELETE",
|
|
2900
|
+
secure: true,
|
|
2901
|
+
format: "json",
|
|
2902
|
+
...params
|
|
2903
|
+
}),
|
|
2904
|
+
/**
|
|
2905
|
+
* @description Get an annotation queue by ID
|
|
2906
|
+
*
|
|
2907
|
+
* @tags AnnotationQueues
|
|
2908
|
+
* @name AnnotationQueuesGetQueue
|
|
2909
|
+
* @request GET:/api/public/annotation-queues/{queueId}
|
|
2910
|
+
* @secure
|
|
2911
|
+
*/
|
|
2912
|
+
annotationQueuesGetQueue: (queueId, params = {}) => this.request({
|
|
2913
|
+
path: `/api/public/annotation-queues/${queueId}`,
|
|
2914
|
+
method: "GET",
|
|
2915
|
+
secure: true,
|
|
2916
|
+
format: "json",
|
|
2917
|
+
...params
|
|
2918
|
+
}),
|
|
2919
|
+
/**
|
|
2920
|
+
* @description Get a specific item from an annotation queue
|
|
2921
|
+
*
|
|
2922
|
+
* @tags AnnotationQueues
|
|
2923
|
+
* @name AnnotationQueuesGetQueueItem
|
|
2924
|
+
* @request GET:/api/public/annotation-queues/{queueId}/items/{itemId}
|
|
2925
|
+
* @secure
|
|
2926
|
+
*/
|
|
2927
|
+
annotationQueuesGetQueueItem: (queueId, itemId, params = {}) => this.request({
|
|
2928
|
+
path: `/api/public/annotation-queues/${queueId}/items/${itemId}`,
|
|
2929
|
+
method: "GET",
|
|
2930
|
+
secure: true,
|
|
2931
|
+
format: "json",
|
|
2932
|
+
...params
|
|
2933
|
+
}),
|
|
2934
|
+
/**
|
|
2935
|
+
* @description Get items for a specific annotation queue
|
|
2936
|
+
*
|
|
2937
|
+
* @tags AnnotationQueues
|
|
2938
|
+
* @name AnnotationQueuesListQueueItems
|
|
2939
|
+
* @request GET:/api/public/annotation-queues/{queueId}/items
|
|
2940
|
+
* @secure
|
|
2941
|
+
*/
|
|
2942
|
+
annotationQueuesListQueueItems: ({
|
|
2943
|
+
queueId,
|
|
2944
|
+
...query
|
|
2945
|
+
}, params = {}) => this.request({
|
|
2946
|
+
path: `/api/public/annotation-queues/${queueId}/items`,
|
|
2947
|
+
method: "GET",
|
|
2948
|
+
query,
|
|
2949
|
+
secure: true,
|
|
2950
|
+
format: "json",
|
|
2951
|
+
...params
|
|
2952
|
+
}),
|
|
2953
|
+
/**
|
|
2954
|
+
* @description Get all annotation queues
|
|
2955
|
+
*
|
|
2956
|
+
* @tags AnnotationQueues
|
|
2957
|
+
* @name AnnotationQueuesListQueues
|
|
2958
|
+
* @request GET:/api/public/annotation-queues
|
|
2959
|
+
* @secure
|
|
2960
|
+
*/
|
|
2961
|
+
annotationQueuesListQueues: (query, params = {}) => this.request({
|
|
2962
|
+
path: `/api/public/annotation-queues`,
|
|
2963
|
+
method: "GET",
|
|
2964
|
+
query,
|
|
2965
|
+
secure: true,
|
|
2966
|
+
format: "json",
|
|
2967
|
+
...params
|
|
2968
|
+
}),
|
|
2969
|
+
/**
|
|
2970
|
+
* @description Update an annotation queue item
|
|
2971
|
+
*
|
|
2972
|
+
* @tags AnnotationQueues
|
|
2973
|
+
* @name AnnotationQueuesUpdateQueueItem
|
|
2974
|
+
* @request PATCH:/api/public/annotation-queues/{queueId}/items/{itemId}
|
|
2975
|
+
* @secure
|
|
2976
|
+
*/
|
|
2977
|
+
annotationQueuesUpdateQueueItem: (queueId, itemId, data, params = {}) => this.request({
|
|
2978
|
+
path: `/api/public/annotation-queues/${queueId}/items/${itemId}`,
|
|
2979
|
+
method: "PATCH",
|
|
2980
|
+
body: data,
|
|
2981
|
+
secure: true,
|
|
2982
|
+
type: ContentType.Json,
|
|
2983
|
+
format: "json",
|
|
2984
|
+
...params
|
|
2985
|
+
}),
|
|
2986
|
+
/**
|
|
2987
|
+
* @description Create a comment. Comments may be attached to different object types (trace, observation, session, prompt).
|
|
2988
|
+
*
|
|
2989
|
+
* @tags Comments
|
|
2990
|
+
* @name CommentsCreate
|
|
2991
|
+
* @request POST:/api/public/comments
|
|
2992
|
+
* @secure
|
|
2993
|
+
*/
|
|
2994
|
+
commentsCreate: (data, params = {}) => this.request({
|
|
2995
|
+
path: `/api/public/comments`,
|
|
2996
|
+
method: "POST",
|
|
2997
|
+
body: data,
|
|
2998
|
+
secure: true,
|
|
2999
|
+
type: ContentType.Json,
|
|
3000
|
+
format: "json",
|
|
3001
|
+
...params
|
|
3002
|
+
}),
|
|
3003
|
+
/**
|
|
3004
|
+
* @description Get all comments
|
|
3005
|
+
*
|
|
3006
|
+
* @tags Comments
|
|
3007
|
+
* @name CommentsGet
|
|
3008
|
+
* @request GET:/api/public/comments
|
|
3009
|
+
* @secure
|
|
3010
|
+
*/
|
|
3011
|
+
commentsGet: (query, params = {}) => this.request({
|
|
3012
|
+
path: `/api/public/comments`,
|
|
3013
|
+
method: "GET",
|
|
3014
|
+
query,
|
|
3015
|
+
secure: true,
|
|
3016
|
+
format: "json",
|
|
3017
|
+
...params
|
|
3018
|
+
}),
|
|
3019
|
+
/**
|
|
3020
|
+
* @description Get a comment by id
|
|
3021
|
+
*
|
|
3022
|
+
* @tags Comments
|
|
3023
|
+
* @name CommentsGetById
|
|
3024
|
+
* @request GET:/api/public/comments/{commentId}
|
|
3025
|
+
* @secure
|
|
3026
|
+
*/
|
|
3027
|
+
commentsGetById: (commentId, params = {}) => this.request({
|
|
3028
|
+
path: `/api/public/comments/${commentId}`,
|
|
3029
|
+
method: "GET",
|
|
3030
|
+
secure: true,
|
|
3031
|
+
format: "json",
|
|
3032
|
+
...params
|
|
3033
|
+
}),
|
|
3034
|
+
/**
|
|
3035
|
+
* @description Create a dataset item
|
|
3036
|
+
*
|
|
3037
|
+
* @tags DatasetItems
|
|
3038
|
+
* @name DatasetItemsCreate
|
|
3039
|
+
* @request POST:/api/public/dataset-items
|
|
3040
|
+
* @secure
|
|
3041
|
+
*/
|
|
3042
|
+
datasetItemsCreate: (data, params = {}) => this.request({
|
|
3043
|
+
path: `/api/public/dataset-items`,
|
|
3044
|
+
method: "POST",
|
|
3045
|
+
body: data,
|
|
3046
|
+
secure: true,
|
|
3047
|
+
type: ContentType.Json,
|
|
3048
|
+
format: "json",
|
|
3049
|
+
...params
|
|
3050
|
+
}),
|
|
3051
|
+
/**
|
|
3052
|
+
* @description Delete a dataset item and all its run items. This action is irreversible.
|
|
3053
|
+
*
|
|
3054
|
+
* @tags DatasetItems
|
|
3055
|
+
* @name DatasetItemsDelete
|
|
3056
|
+
* @request DELETE:/api/public/dataset-items/{id}
|
|
3057
|
+
* @secure
|
|
3058
|
+
*/
|
|
3059
|
+
datasetItemsDelete: (id, params = {}) => this.request({
|
|
3060
|
+
path: `/api/public/dataset-items/${id}`,
|
|
3061
|
+
method: "DELETE",
|
|
3062
|
+
secure: true,
|
|
3063
|
+
format: "json",
|
|
3064
|
+
...params
|
|
3065
|
+
}),
|
|
3066
|
+
/**
|
|
3067
|
+
* @description Get a dataset item
|
|
3068
|
+
*
|
|
3069
|
+
* @tags DatasetItems
|
|
3070
|
+
* @name DatasetItemsGet
|
|
3071
|
+
* @request GET:/api/public/dataset-items/{id}
|
|
3072
|
+
* @secure
|
|
3073
|
+
*/
|
|
3074
|
+
datasetItemsGet: (id, params = {}) => this.request({
|
|
3075
|
+
path: `/api/public/dataset-items/${id}`,
|
|
3076
|
+
method: "GET",
|
|
3077
|
+
secure: true,
|
|
3078
|
+
format: "json",
|
|
3079
|
+
...params
|
|
3080
|
+
}),
|
|
3081
|
+
/**
|
|
3082
|
+
* @description Get dataset items
|
|
3083
|
+
*
|
|
3084
|
+
* @tags DatasetItems
|
|
3085
|
+
* @name DatasetItemsList
|
|
3086
|
+
* @request GET:/api/public/dataset-items
|
|
3087
|
+
* @secure
|
|
3088
|
+
*/
|
|
3089
|
+
datasetItemsList: (query, params = {}) => this.request({
|
|
3090
|
+
path: `/api/public/dataset-items`,
|
|
3091
|
+
method: "GET",
|
|
3092
|
+
query,
|
|
3093
|
+
secure: true,
|
|
3094
|
+
format: "json",
|
|
3095
|
+
...params
|
|
3096
|
+
}),
|
|
3097
|
+
/**
|
|
3098
|
+
* @description Create a dataset run item
|
|
3099
|
+
*
|
|
3100
|
+
* @tags DatasetRunItems
|
|
3101
|
+
* @name DatasetRunItemsCreate
|
|
3102
|
+
* @request POST:/api/public/dataset-run-items
|
|
3103
|
+
* @secure
|
|
3104
|
+
*/
|
|
3105
|
+
datasetRunItemsCreate: (data, params = {}) => this.request({
|
|
3106
|
+
path: `/api/public/dataset-run-items`,
|
|
3107
|
+
method: "POST",
|
|
3108
|
+
body: data,
|
|
3109
|
+
secure: true,
|
|
3110
|
+
type: ContentType.Json,
|
|
3111
|
+
format: "json",
|
|
3112
|
+
...params
|
|
3113
|
+
}),
|
|
3114
|
+
/**
|
|
3115
|
+
* @description List dataset run items
|
|
3116
|
+
*
|
|
3117
|
+
* @tags DatasetRunItems
|
|
3118
|
+
* @name DatasetRunItemsList
|
|
3119
|
+
* @request GET:/api/public/dataset-run-items
|
|
3120
|
+
* @secure
|
|
3121
|
+
*/
|
|
3122
|
+
datasetRunItemsList: (query, params = {}) => this.request({
|
|
3123
|
+
path: `/api/public/dataset-run-items`,
|
|
3124
|
+
method: "GET",
|
|
3125
|
+
query,
|
|
3126
|
+
secure: true,
|
|
3127
|
+
...params
|
|
3128
|
+
}),
|
|
3129
|
+
/**
|
|
3130
|
+
* @description Create a dataset
|
|
3131
|
+
*
|
|
3132
|
+
* @tags Datasets
|
|
3133
|
+
* @name DatasetsCreate
|
|
3134
|
+
* @request POST:/api/public/v2/datasets
|
|
3135
|
+
* @secure
|
|
3136
|
+
*/
|
|
3137
|
+
datasetsCreate: (data, params = {}) => this.request({
|
|
3138
|
+
path: `/api/public/v2/datasets`,
|
|
3139
|
+
method: "POST",
|
|
3140
|
+
body: data,
|
|
3141
|
+
secure: true,
|
|
3142
|
+
type: ContentType.Json,
|
|
3143
|
+
format: "json",
|
|
3144
|
+
...params
|
|
3145
|
+
}),
|
|
3146
|
+
/**
|
|
3147
|
+
* @description Delete a dataset run and all its run items. This action is irreversible.
|
|
3148
|
+
*
|
|
3149
|
+
* @tags Datasets
|
|
3150
|
+
* @name DatasetsDeleteRun
|
|
3151
|
+
* @request DELETE:/api/public/datasets/{datasetName}/runs/{runName}
|
|
3152
|
+
* @secure
|
|
3153
|
+
*/
|
|
3154
|
+
datasetsDeleteRun: (datasetName, runName, params = {}) => this.request({
|
|
3155
|
+
path: `/api/public/datasets/${datasetName}/runs/${runName}`,
|
|
3156
|
+
method: "DELETE",
|
|
3157
|
+
secure: true,
|
|
3158
|
+
format: "json",
|
|
3159
|
+
...params
|
|
3160
|
+
}),
|
|
3161
|
+
/**
|
|
3162
|
+
* @description Get a dataset
|
|
3163
|
+
*
|
|
3164
|
+
* @tags Datasets
|
|
3165
|
+
* @name DatasetsGet
|
|
3166
|
+
* @request GET:/api/public/v2/datasets/{datasetName}
|
|
3167
|
+
* @secure
|
|
3168
|
+
*/
|
|
3169
|
+
datasetsGet: (datasetName, params = {}) => this.request({
|
|
3170
|
+
path: `/api/public/v2/datasets/${datasetName}`,
|
|
3171
|
+
method: "GET",
|
|
3172
|
+
secure: true,
|
|
3173
|
+
format: "json",
|
|
3174
|
+
...params
|
|
3175
|
+
}),
|
|
3176
|
+
/**
|
|
3177
|
+
* @description Get a dataset run and its items
|
|
3178
|
+
*
|
|
3179
|
+
* @tags Datasets
|
|
3180
|
+
* @name DatasetsGetRun
|
|
3181
|
+
* @request GET:/api/public/datasets/{datasetName}/runs/{runName}
|
|
3182
|
+
* @secure
|
|
3183
|
+
*/
|
|
3184
|
+
datasetsGetRun: (datasetName, runName, params = {}) => this.request({
|
|
3185
|
+
path: `/api/public/datasets/${datasetName}/runs/${runName}`,
|
|
3186
|
+
method: "GET",
|
|
3187
|
+
secure: true,
|
|
3188
|
+
format: "json",
|
|
3189
|
+
...params
|
|
3190
|
+
}),
|
|
3191
|
+
/**
|
|
3192
|
+
* @description Get dataset runs
|
|
3193
|
+
*
|
|
3194
|
+
* @tags Datasets
|
|
3195
|
+
* @name DatasetsGetRuns
|
|
3196
|
+
* @request GET:/api/public/datasets/{datasetName}/runs
|
|
3197
|
+
* @secure
|
|
3198
|
+
*/
|
|
3199
|
+
datasetsGetRuns: ({
|
|
3200
|
+
datasetName,
|
|
3201
|
+
...query
|
|
3202
|
+
}, params = {}) => this.request({
|
|
3203
|
+
path: `/api/public/datasets/${datasetName}/runs`,
|
|
3204
|
+
method: "GET",
|
|
3205
|
+
query,
|
|
3206
|
+
secure: true,
|
|
3207
|
+
format: "json",
|
|
3208
|
+
...params
|
|
3209
|
+
}),
|
|
3210
|
+
/**
|
|
3211
|
+
* @description Get all datasets
|
|
3212
|
+
*
|
|
3213
|
+
* @tags Datasets
|
|
3214
|
+
* @name DatasetsList
|
|
3215
|
+
* @request GET:/api/public/v2/datasets
|
|
3216
|
+
* @secure
|
|
3217
|
+
*/
|
|
3218
|
+
datasetsList: (query, params = {}) => this.request({
|
|
3219
|
+
path: `/api/public/v2/datasets`,
|
|
3220
|
+
method: "GET",
|
|
3221
|
+
query,
|
|
3222
|
+
secure: true,
|
|
3223
|
+
format: "json",
|
|
3224
|
+
...params
|
|
3225
|
+
}),
|
|
3226
|
+
/**
|
|
3227
|
+
* @description Check health of API and database
|
|
3228
|
+
*
|
|
3229
|
+
* @tags Health
|
|
3230
|
+
* @name HealthHealth
|
|
3231
|
+
* @request GET:/api/public/health
|
|
3232
|
+
*/
|
|
3233
|
+
healthHealth: (params = {}) => this.request({
|
|
3234
|
+
path: `/api/public/health`,
|
|
3235
|
+
method: "GET",
|
|
3236
|
+
format: "json",
|
|
3237
|
+
...params
|
|
3238
|
+
}),
|
|
3239
|
+
/**
|
|
3240
|
+
* @description Batched ingestion for Langfuse Tracing. If you want to use tracing via the API, such as to build your own Langfuse client implementation, this is the only API route you need to implement. Within each batch, there can be multiple events. Each event has a type, an id, a timestamp, metadata and a body. Internally, we refer to this as the "event envelope" as it tells us something about the event but not the trace. We use the event id within this envelope to deduplicate messages to avoid processing the same event twice, i.e. the event id should be unique per request. The event.body.id is the ID of the actual trace and will be used for updates and will be visible within the Langfuse App. I.e. if you want to update a trace, you'd use the same body id, but separate event IDs. Notes: - Introduction to data model: https://langfuse.com/docs/tracing-data-model - Batch sizes are limited to 3.5 MB in total. You need to adjust the number of events per batch accordingly. - The API does not return a 4xx status code for input errors. Instead, it responds with a 207 status code, which includes a list of the encountered errors.
|
|
3241
|
+
*
|
|
3242
|
+
* @tags Ingestion
|
|
3243
|
+
* @name IngestionBatch
|
|
3244
|
+
* @request POST:/api/public/ingestion
|
|
3245
|
+
* @secure
|
|
3246
|
+
*/
|
|
3247
|
+
ingestionBatch: (data, params = {}) => this.request({
|
|
3248
|
+
path: `/api/public/ingestion`,
|
|
3249
|
+
method: "POST",
|
|
3250
|
+
body: data,
|
|
3251
|
+
secure: true,
|
|
3252
|
+
type: ContentType.Json,
|
|
3253
|
+
format: "json",
|
|
3254
|
+
...params
|
|
3255
|
+
}),
|
|
3256
|
+
/**
|
|
3257
|
+
* @description Get a media record
|
|
3258
|
+
*
|
|
3259
|
+
* @tags Media
|
|
3260
|
+
* @name MediaGet
|
|
3261
|
+
* @request GET:/api/public/media/{mediaId}
|
|
3262
|
+
* @secure
|
|
3263
|
+
*/
|
|
3264
|
+
mediaGet: (mediaId, params = {}) => this.request({
|
|
3265
|
+
path: `/api/public/media/${mediaId}`,
|
|
3266
|
+
method: "GET",
|
|
3267
|
+
secure: true,
|
|
3268
|
+
format: "json",
|
|
3269
|
+
...params
|
|
3270
|
+
}),
|
|
3271
|
+
/**
|
|
3272
|
+
* @description Get a presigned upload URL for a media record
|
|
3273
|
+
*
|
|
3274
|
+
* @tags Media
|
|
3275
|
+
* @name MediaGetUploadUrl
|
|
3276
|
+
* @request POST:/api/public/media
|
|
3277
|
+
* @secure
|
|
3278
|
+
*/
|
|
3279
|
+
mediaGetUploadUrl: (data, params = {}) => this.request({
|
|
3280
|
+
path: `/api/public/media`,
|
|
3281
|
+
method: "POST",
|
|
3282
|
+
body: data,
|
|
3283
|
+
secure: true,
|
|
3284
|
+
type: ContentType.Json,
|
|
3285
|
+
format: "json",
|
|
3286
|
+
...params
|
|
3287
|
+
}),
|
|
3288
|
+
/**
|
|
3289
|
+
* @description Patch a media record
|
|
3290
|
+
*
|
|
3291
|
+
* @tags Media
|
|
3292
|
+
* @name MediaPatch
|
|
3293
|
+
* @request PATCH:/api/public/media/{mediaId}
|
|
3294
|
+
* @secure
|
|
3295
|
+
*/
|
|
3296
|
+
mediaPatch: (mediaId, data, params = {}) => this.request({
|
|
3297
|
+
path: `/api/public/media/${mediaId}`,
|
|
3298
|
+
method: "PATCH",
|
|
3299
|
+
body: data,
|
|
3300
|
+
secure: true,
|
|
3301
|
+
type: ContentType.Json,
|
|
3302
|
+
...params
|
|
3303
|
+
}),
|
|
3304
|
+
/**
|
|
3305
|
+
* @description Get metrics from the Langfuse project using a query object
|
|
3306
|
+
*
|
|
3307
|
+
* @tags Metrics
|
|
3308
|
+
* @name MetricsMetrics
|
|
3309
|
+
* @request GET:/api/public/metrics
|
|
3310
|
+
* @secure
|
|
3311
|
+
*/
|
|
3312
|
+
metricsMetrics: (query, params = {}) => this.request({
|
|
3313
|
+
path: `/api/public/metrics`,
|
|
3314
|
+
method: "GET",
|
|
3315
|
+
query,
|
|
3316
|
+
secure: true,
|
|
3317
|
+
format: "json",
|
|
3318
|
+
...params
|
|
3319
|
+
}),
|
|
3320
|
+
/**
|
|
3321
|
+
* @description Create a model
|
|
3322
|
+
*
|
|
3323
|
+
* @tags Models
|
|
3324
|
+
* @name ModelsCreate
|
|
3325
|
+
* @request POST:/api/public/models
|
|
3326
|
+
* @secure
|
|
3327
|
+
*/
|
|
3328
|
+
modelsCreate: (data, params = {}) => this.request({
|
|
3329
|
+
path: `/api/public/models`,
|
|
3330
|
+
method: "POST",
|
|
3331
|
+
body: data,
|
|
3332
|
+
secure: true,
|
|
3333
|
+
type: ContentType.Json,
|
|
3334
|
+
format: "json",
|
|
3335
|
+
...params
|
|
3336
|
+
}),
|
|
3337
|
+
/**
|
|
3338
|
+
* @description Delete a model. Cannot delete models managed by Langfuse. You can create your own definition with the same modelName to override the definition though.
|
|
3339
|
+
*
|
|
3340
|
+
* @tags Models
|
|
3341
|
+
* @name ModelsDelete
|
|
3342
|
+
* @request DELETE:/api/public/models/{id}
|
|
3343
|
+
* @secure
|
|
3344
|
+
*/
|
|
3345
|
+
modelsDelete: (id, params = {}) => this.request({
|
|
3346
|
+
path: `/api/public/models/${id}`,
|
|
3347
|
+
method: "DELETE",
|
|
3348
|
+
secure: true,
|
|
3349
|
+
...params
|
|
3350
|
+
}),
|
|
3351
|
+
/**
|
|
3352
|
+
* @description Get a model
|
|
3353
|
+
*
|
|
3354
|
+
* @tags Models
|
|
3355
|
+
* @name ModelsGet
|
|
3356
|
+
* @request GET:/api/public/models/{id}
|
|
3357
|
+
* @secure
|
|
3358
|
+
*/
|
|
3359
|
+
modelsGet: (id, params = {}) => this.request({
|
|
3360
|
+
path: `/api/public/models/${id}`,
|
|
3361
|
+
method: "GET",
|
|
3362
|
+
secure: true,
|
|
3363
|
+
format: "json",
|
|
3364
|
+
...params
|
|
3365
|
+
}),
|
|
3366
|
+
/**
|
|
3367
|
+
* @description Get all models
|
|
3368
|
+
*
|
|
3369
|
+
* @tags Models
|
|
3370
|
+
* @name ModelsList
|
|
3371
|
+
* @request GET:/api/public/models
|
|
3372
|
+
* @secure
|
|
3373
|
+
*/
|
|
3374
|
+
modelsList: (query, params = {}) => this.request({
|
|
3375
|
+
path: `/api/public/models`,
|
|
3376
|
+
method: "GET",
|
|
3377
|
+
query,
|
|
3378
|
+
secure: true,
|
|
3379
|
+
format: "json",
|
|
3380
|
+
...params
|
|
3381
|
+
}),
|
|
3382
|
+
/**
|
|
3383
|
+
* @description Get a observation
|
|
3384
|
+
*
|
|
3385
|
+
* @tags Observations
|
|
3386
|
+
* @name ObservationsGet
|
|
3387
|
+
* @request GET:/api/public/observations/{observationId}
|
|
3388
|
+
* @secure
|
|
3389
|
+
*/
|
|
3390
|
+
observationsGet: (observationId, params = {}) => this.request({
|
|
3391
|
+
path: `/api/public/observations/${observationId}`,
|
|
3392
|
+
method: "GET",
|
|
3393
|
+
secure: true,
|
|
3394
|
+
format: "json",
|
|
3395
|
+
...params
|
|
3396
|
+
}),
|
|
3397
|
+
/**
|
|
3398
|
+
* @description Get a list of observations
|
|
3399
|
+
*
|
|
3400
|
+
* @tags Observations
|
|
3401
|
+
* @name ObservationsGetMany
|
|
3402
|
+
* @request GET:/api/public/observations
|
|
3403
|
+
* @secure
|
|
3404
|
+
*/
|
|
3405
|
+
observationsGetMany: (query, params = {}) => this.request({
|
|
3406
|
+
path: `/api/public/observations`,
|
|
3407
|
+
method: "GET",
|
|
3408
|
+
query,
|
|
3409
|
+
secure: true,
|
|
3410
|
+
format: "json",
|
|
3411
|
+
...params
|
|
3412
|
+
}),
|
|
3413
|
+
/**
|
|
3414
|
+
* @description Get all memberships for the organization associated with the API key (requires organization-scoped API key)
|
|
3415
|
+
*
|
|
3416
|
+
* @tags Organizations
|
|
3417
|
+
* @name OrganizationsGetOrganizationMemberships
|
|
3418
|
+
* @request GET:/api/public/organizations/memberships
|
|
3419
|
+
* @secure
|
|
3420
|
+
*/
|
|
3421
|
+
organizationsGetOrganizationMemberships: (params = {}) => this.request({
|
|
3422
|
+
path: `/api/public/organizations/memberships`,
|
|
3423
|
+
method: "GET",
|
|
3424
|
+
secure: true,
|
|
3425
|
+
format: "json",
|
|
3426
|
+
...params
|
|
3427
|
+
}),
|
|
3428
|
+
/**
|
|
3429
|
+
* @description Get all projects for the organization associated with the API key (requires organization-scoped API key)
|
|
3430
|
+
*
|
|
3431
|
+
* @tags Organizations
|
|
3432
|
+
* @name OrganizationsGetOrganizationProjects
|
|
3433
|
+
* @request GET:/api/public/organizations/projects
|
|
3434
|
+
* @secure
|
|
3435
|
+
*/
|
|
3436
|
+
organizationsGetOrganizationProjects: (params = {}) => this.request({
|
|
3437
|
+
path: `/api/public/organizations/projects`,
|
|
3438
|
+
method: "GET",
|
|
3439
|
+
secure: true,
|
|
3440
|
+
format: "json",
|
|
3441
|
+
...params
|
|
3442
|
+
}),
|
|
3443
|
+
/**
|
|
3444
|
+
* @description Get all memberships for a specific project (requires organization-scoped API key)
|
|
3445
|
+
*
|
|
3446
|
+
* @tags Organizations
|
|
3447
|
+
* @name OrganizationsGetProjectMemberships
|
|
3448
|
+
* @request GET:/api/public/projects/{projectId}/memberships
|
|
3449
|
+
* @secure
|
|
3450
|
+
*/
|
|
3451
|
+
organizationsGetProjectMemberships: (projectId, params = {}) => this.request({
|
|
3452
|
+
path: `/api/public/projects/${projectId}/memberships`,
|
|
3453
|
+
method: "GET",
|
|
3454
|
+
secure: true,
|
|
3455
|
+
format: "json",
|
|
3456
|
+
...params
|
|
3457
|
+
}),
|
|
3458
|
+
/**
|
|
3459
|
+
* @description Create or update a membership for the organization associated with the API key (requires organization-scoped API key)
|
|
3460
|
+
*
|
|
3461
|
+
* @tags Organizations
|
|
3462
|
+
* @name OrganizationsUpdateOrganizationMembership
|
|
3463
|
+
* @request PUT:/api/public/organizations/memberships
|
|
3464
|
+
* @secure
|
|
3465
|
+
*/
|
|
3466
|
+
organizationsUpdateOrganizationMembership: (data, params = {}) => this.request({
|
|
3467
|
+
path: `/api/public/organizations/memberships`,
|
|
3468
|
+
method: "PUT",
|
|
3469
|
+
body: data,
|
|
3470
|
+
secure: true,
|
|
3471
|
+
type: ContentType.Json,
|
|
3472
|
+
format: "json",
|
|
3473
|
+
...params
|
|
3474
|
+
}),
|
|
3475
|
+
/**
|
|
3476
|
+
* @description Create or update a membership for a specific project (requires organization-scoped API key). The user must already be a member of the organization.
|
|
3477
|
+
*
|
|
3478
|
+
* @tags Organizations
|
|
3479
|
+
* @name OrganizationsUpdateProjectMembership
|
|
3480
|
+
* @request PUT:/api/public/projects/{projectId}/memberships
|
|
3481
|
+
* @secure
|
|
3482
|
+
*/
|
|
3483
|
+
organizationsUpdateProjectMembership: (projectId, data, params = {}) => this.request({
|
|
3484
|
+
path: `/api/public/projects/${projectId}/memberships`,
|
|
3485
|
+
method: "PUT",
|
|
3486
|
+
body: data,
|
|
3487
|
+
secure: true,
|
|
3488
|
+
type: ContentType.Json,
|
|
3489
|
+
format: "json",
|
|
3490
|
+
...params
|
|
3491
|
+
}),
|
|
3492
|
+
/**
|
|
3493
|
+
* @description Create a new project (requires organization-scoped API key)
|
|
3494
|
+
*
|
|
3495
|
+
* @tags Projects
|
|
3496
|
+
* @name ProjectsCreate
|
|
3497
|
+
* @request POST:/api/public/projects
|
|
3498
|
+
* @secure
|
|
3499
|
+
*/
|
|
3500
|
+
projectsCreate: (data, params = {}) => this.request({
|
|
3501
|
+
path: `/api/public/projects`,
|
|
3502
|
+
method: "POST",
|
|
3503
|
+
body: data,
|
|
3504
|
+
secure: true,
|
|
3505
|
+
type: ContentType.Json,
|
|
3506
|
+
format: "json",
|
|
3507
|
+
...params
|
|
3508
|
+
}),
|
|
3509
|
+
/**
|
|
3510
|
+
* @description Create a new API key for a project (requires organization-scoped API key)
|
|
3511
|
+
*
|
|
3512
|
+
* @tags Projects
|
|
3513
|
+
* @name ProjectsCreateApiKey
|
|
3514
|
+
* @request POST:/api/public/projects/{projectId}/apiKeys
|
|
3515
|
+
* @secure
|
|
3516
|
+
*/
|
|
3517
|
+
projectsCreateApiKey: (projectId, data, params = {}) => this.request({
|
|
3518
|
+
path: `/api/public/projects/${projectId}/apiKeys`,
|
|
3519
|
+
method: "POST",
|
|
3520
|
+
body: data,
|
|
3521
|
+
secure: true,
|
|
3522
|
+
type: ContentType.Json,
|
|
3523
|
+
format: "json",
|
|
3524
|
+
...params
|
|
3525
|
+
}),
|
|
3526
|
+
/**
|
|
3527
|
+
* @description Delete a project by ID (requires organization-scoped API key). Project deletion is processed asynchronously.
|
|
3528
|
+
*
|
|
3529
|
+
* @tags Projects
|
|
3530
|
+
* @name ProjectsDelete
|
|
3531
|
+
* @request DELETE:/api/public/projects/{projectId}
|
|
3532
|
+
* @secure
|
|
3533
|
+
*/
|
|
3534
|
+
projectsDelete: (projectId, params = {}) => this.request({
|
|
3535
|
+
path: `/api/public/projects/${projectId}`,
|
|
3536
|
+
method: "DELETE",
|
|
3537
|
+
secure: true,
|
|
3538
|
+
format: "json",
|
|
3539
|
+
...params
|
|
3540
|
+
}),
|
|
3541
|
+
/**
|
|
3542
|
+
* @description Delete an API key for a project (requires organization-scoped API key)
|
|
3543
|
+
*
|
|
3544
|
+
* @tags Projects
|
|
3545
|
+
* @name ProjectsDeleteApiKey
|
|
3546
|
+
* @request DELETE:/api/public/projects/{projectId}/apiKeys/{apiKeyId}
|
|
3547
|
+
* @secure
|
|
3548
|
+
*/
|
|
3549
|
+
projectsDeleteApiKey: (projectId, apiKeyId, params = {}) => this.request({
|
|
3550
|
+
path: `/api/public/projects/${projectId}/apiKeys/${apiKeyId}`,
|
|
3551
|
+
method: "DELETE",
|
|
3552
|
+
secure: true,
|
|
3553
|
+
format: "json",
|
|
3554
|
+
...params
|
|
3555
|
+
}),
|
|
3556
|
+
/**
|
|
3557
|
+
* @description Get Project associated with API key
|
|
3558
|
+
*
|
|
3559
|
+
* @tags Projects
|
|
3560
|
+
* @name ProjectsGet
|
|
3561
|
+
* @request GET:/api/public/projects
|
|
3562
|
+
* @secure
|
|
3563
|
+
*/
|
|
3564
|
+
projectsGet: (params = {}) => this.request({
|
|
3565
|
+
path: `/api/public/projects`,
|
|
3566
|
+
method: "GET",
|
|
3567
|
+
secure: true,
|
|
3568
|
+
format: "json",
|
|
3569
|
+
...params
|
|
3570
|
+
}),
|
|
3571
|
+
/**
|
|
3572
|
+
* @description Get all API keys for a project (requires organization-scoped API key)
|
|
3573
|
+
*
|
|
3574
|
+
* @tags Projects
|
|
3575
|
+
* @name ProjectsGetApiKeys
|
|
3576
|
+
* @request GET:/api/public/projects/{projectId}/apiKeys
|
|
3577
|
+
* @secure
|
|
3578
|
+
*/
|
|
3579
|
+
projectsGetApiKeys: (projectId, params = {}) => this.request({
|
|
3580
|
+
path: `/api/public/projects/${projectId}/apiKeys`,
|
|
3581
|
+
method: "GET",
|
|
3582
|
+
secure: true,
|
|
3583
|
+
format: "json",
|
|
3584
|
+
...params
|
|
3585
|
+
}),
|
|
3586
|
+
/**
|
|
3587
|
+
* @description Update a project by ID (requires organization-scoped API key).
|
|
3588
|
+
*
|
|
3589
|
+
* @tags Projects
|
|
3590
|
+
* @name ProjectsUpdate
|
|
3591
|
+
* @request PUT:/api/public/projects/{projectId}
|
|
3592
|
+
* @secure
|
|
3593
|
+
*/
|
|
3594
|
+
projectsUpdate: (projectId, data, params = {}) => this.request({
|
|
3595
|
+
path: `/api/public/projects/${projectId}`,
|
|
3596
|
+
method: "PUT",
|
|
3597
|
+
body: data,
|
|
3598
|
+
secure: true,
|
|
3599
|
+
type: ContentType.Json,
|
|
3600
|
+
format: "json",
|
|
3601
|
+
...params
|
|
3602
|
+
}),
|
|
3603
|
+
/**
|
|
3604
|
+
* @description Create a new version for the prompt with the given `name`
|
|
3605
|
+
*
|
|
3606
|
+
* @tags Prompts
|
|
3607
|
+
* @name PromptsCreate
|
|
3608
|
+
* @request POST:/api/public/v2/prompts
|
|
3609
|
+
* @secure
|
|
3610
|
+
*/
|
|
3611
|
+
promptsCreate: (data, params = {}) => this.request({
|
|
3612
|
+
path: `/api/public/v2/prompts`,
|
|
3613
|
+
method: "POST",
|
|
3614
|
+
body: data,
|
|
3615
|
+
secure: true,
|
|
3616
|
+
type: ContentType.Json,
|
|
3617
|
+
format: "json",
|
|
3618
|
+
...params
|
|
3619
|
+
}),
|
|
3620
|
+
/**
|
|
3621
|
+
* @description Get a prompt
|
|
3622
|
+
*
|
|
3623
|
+
* @tags Prompts
|
|
3624
|
+
* @name PromptsGet
|
|
3625
|
+
* @request GET:/api/public/v2/prompts/{promptName}
|
|
3626
|
+
* @secure
|
|
3627
|
+
*/
|
|
3628
|
+
promptsGet: ({
|
|
3629
|
+
promptName,
|
|
3630
|
+
...query
|
|
3631
|
+
}, params = {}) => this.request({
|
|
3632
|
+
path: `/api/public/v2/prompts/${promptName}`,
|
|
3633
|
+
method: "GET",
|
|
3634
|
+
query,
|
|
3635
|
+
secure: true,
|
|
3636
|
+
format: "json",
|
|
3637
|
+
...params
|
|
3638
|
+
}),
|
|
3639
|
+
/**
|
|
3640
|
+
* @description Get a list of prompt names with versions and labels
|
|
3641
|
+
*
|
|
3642
|
+
* @tags Prompts
|
|
3643
|
+
* @name PromptsList
|
|
3644
|
+
* @request GET:/api/public/v2/prompts
|
|
3645
|
+
* @secure
|
|
3646
|
+
*/
|
|
3647
|
+
promptsList: (query, params = {}) => this.request({
|
|
3648
|
+
path: `/api/public/v2/prompts`,
|
|
3649
|
+
method: "GET",
|
|
3650
|
+
query,
|
|
3651
|
+
secure: true,
|
|
3652
|
+
format: "json",
|
|
3653
|
+
...params
|
|
3654
|
+
}),
|
|
3655
|
+
/**
|
|
3656
|
+
* @description Update labels for a specific prompt version
|
|
3657
|
+
*
|
|
3658
|
+
* @tags PromptVersion
|
|
3659
|
+
* @name PromptVersionUpdate
|
|
3660
|
+
* @request PATCH:/api/public/v2/prompts/{name}/versions/{version}
|
|
3661
|
+
* @secure
|
|
3662
|
+
*/
|
|
3663
|
+
promptVersionUpdate: (name, version2, data, params = {}) => this.request({
|
|
3664
|
+
path: `/api/public/v2/prompts/${name}/versions/${version2}`,
|
|
3665
|
+
method: "PATCH",
|
|
3666
|
+
body: data,
|
|
3667
|
+
secure: true,
|
|
3668
|
+
type: ContentType.Json,
|
|
3669
|
+
format: "json",
|
|
3670
|
+
...params
|
|
3671
|
+
}),
|
|
3672
|
+
/**
|
|
3673
|
+
* @description Create a new user in the organization (requires organization-scoped API key)
|
|
3674
|
+
*
|
|
3675
|
+
* @tags Scim
|
|
3676
|
+
* @name ScimCreateUser
|
|
3677
|
+
* @request POST:/api/public/scim/Users
|
|
3678
|
+
* @secure
|
|
3679
|
+
*/
|
|
3680
|
+
scimCreateUser: (data, params = {}) => this.request({
|
|
3681
|
+
path: `/api/public/scim/Users`,
|
|
3682
|
+
method: "POST",
|
|
3683
|
+
body: data,
|
|
3684
|
+
secure: true,
|
|
3685
|
+
type: ContentType.Json,
|
|
3686
|
+
format: "json",
|
|
3687
|
+
...params
|
|
3688
|
+
}),
|
|
3689
|
+
/**
|
|
3690
|
+
* @description Remove a user from the organization (requires organization-scoped API key). Note that this only removes the user from the organization but does not delete the user entity itself.
|
|
3691
|
+
*
|
|
3692
|
+
* @tags Scim
|
|
3693
|
+
* @name ScimDeleteUser
|
|
3694
|
+
* @request DELETE:/api/public/scim/Users/{userId}
|
|
3695
|
+
* @secure
|
|
3696
|
+
*/
|
|
3697
|
+
scimDeleteUser: (userId, params = {}) => this.request({
|
|
3698
|
+
path: `/api/public/scim/Users/${userId}`,
|
|
3699
|
+
method: "DELETE",
|
|
3700
|
+
secure: true,
|
|
3701
|
+
format: "json",
|
|
3702
|
+
...params
|
|
3703
|
+
}),
|
|
3704
|
+
/**
|
|
3705
|
+
* @description Get SCIM Resource Types (requires organization-scoped API key)
|
|
3706
|
+
*
|
|
3707
|
+
* @tags Scim
|
|
3708
|
+
* @name ScimGetResourceTypes
|
|
3709
|
+
* @request GET:/api/public/scim/ResourceTypes
|
|
3710
|
+
* @secure
|
|
3711
|
+
*/
|
|
3712
|
+
scimGetResourceTypes: (params = {}) => this.request({
|
|
3713
|
+
path: `/api/public/scim/ResourceTypes`,
|
|
3714
|
+
method: "GET",
|
|
3715
|
+
secure: true,
|
|
3716
|
+
format: "json",
|
|
3717
|
+
...params
|
|
3718
|
+
}),
|
|
3719
|
+
/**
|
|
3720
|
+
* @description Get SCIM Schemas (requires organization-scoped API key)
|
|
3721
|
+
*
|
|
3722
|
+
* @tags Scim
|
|
3723
|
+
* @name ScimGetSchemas
|
|
3724
|
+
* @request GET:/api/public/scim/Schemas
|
|
3725
|
+
* @secure
|
|
3726
|
+
*/
|
|
3727
|
+
scimGetSchemas: (params = {}) => this.request({
|
|
3728
|
+
path: `/api/public/scim/Schemas`,
|
|
3729
|
+
method: "GET",
|
|
3730
|
+
secure: true,
|
|
3731
|
+
format: "json",
|
|
3732
|
+
...params
|
|
3733
|
+
}),
|
|
3734
|
+
/**
|
|
3735
|
+
* @description Get SCIM Service Provider Configuration (requires organization-scoped API key)
|
|
3736
|
+
*
|
|
3737
|
+
* @tags Scim
|
|
3738
|
+
* @name ScimGetServiceProviderConfig
|
|
3739
|
+
* @request GET:/api/public/scim/ServiceProviderConfig
|
|
3740
|
+
* @secure
|
|
3741
|
+
*/
|
|
3742
|
+
scimGetServiceProviderConfig: (params = {}) => this.request({
|
|
3743
|
+
path: `/api/public/scim/ServiceProviderConfig`,
|
|
3744
|
+
method: "GET",
|
|
3745
|
+
secure: true,
|
|
3746
|
+
format: "json",
|
|
3747
|
+
...params
|
|
3748
|
+
}),
|
|
3749
|
+
/**
|
|
3750
|
+
* @description Get a specific user by ID (requires organization-scoped API key)
|
|
3751
|
+
*
|
|
3752
|
+
* @tags Scim
|
|
3753
|
+
* @name ScimGetUser
|
|
3754
|
+
* @request GET:/api/public/scim/Users/{userId}
|
|
3755
|
+
* @secure
|
|
3756
|
+
*/
|
|
3757
|
+
scimGetUser: (userId, params = {}) => this.request({
|
|
3758
|
+
path: `/api/public/scim/Users/${userId}`,
|
|
3759
|
+
method: "GET",
|
|
3760
|
+
secure: true,
|
|
3761
|
+
format: "json",
|
|
3762
|
+
...params
|
|
3763
|
+
}),
|
|
3764
|
+
/**
|
|
3765
|
+
* @description List users in the organization (requires organization-scoped API key)
|
|
3766
|
+
*
|
|
3767
|
+
* @tags Scim
|
|
3768
|
+
* @name ScimListUsers
|
|
3769
|
+
* @request GET:/api/public/scim/Users
|
|
3770
|
+
* @secure
|
|
3771
|
+
*/
|
|
3772
|
+
scimListUsers: (query, params = {}) => this.request({
|
|
3773
|
+
path: `/api/public/scim/Users`,
|
|
3774
|
+
method: "GET",
|
|
3775
|
+
query,
|
|
3776
|
+
secure: true,
|
|
3777
|
+
format: "json",
|
|
3778
|
+
...params
|
|
3779
|
+
}),
|
|
3780
|
+
/**
|
|
3781
|
+
* @description Create a score configuration (config). Score configs are used to define the structure of scores
|
|
3782
|
+
*
|
|
3783
|
+
* @tags ScoreConfigs
|
|
3784
|
+
* @name ScoreConfigsCreate
|
|
3785
|
+
* @request POST:/api/public/score-configs
|
|
3786
|
+
* @secure
|
|
3787
|
+
*/
|
|
3788
|
+
scoreConfigsCreate: (data, params = {}) => this.request({
|
|
3789
|
+
path: `/api/public/score-configs`,
|
|
3790
|
+
method: "POST",
|
|
3791
|
+
body: data,
|
|
3792
|
+
secure: true,
|
|
3793
|
+
type: ContentType.Json,
|
|
3794
|
+
format: "json",
|
|
3795
|
+
...params
|
|
3796
|
+
}),
|
|
3797
|
+
/**
|
|
3798
|
+
* @description Get all score configs
|
|
3799
|
+
*
|
|
3800
|
+
* @tags ScoreConfigs
|
|
3801
|
+
* @name ScoreConfigsGet
|
|
3802
|
+
* @request GET:/api/public/score-configs
|
|
3803
|
+
* @secure
|
|
3804
|
+
*/
|
|
3805
|
+
scoreConfigsGet: (query, params = {}) => this.request({
|
|
3806
|
+
path: `/api/public/score-configs`,
|
|
3807
|
+
method: "GET",
|
|
3808
|
+
query,
|
|
3809
|
+
secure: true,
|
|
3810
|
+
format: "json",
|
|
3811
|
+
...params
|
|
3812
|
+
}),
|
|
3813
|
+
/**
|
|
3814
|
+
* @description Get a score config
|
|
3815
|
+
*
|
|
3816
|
+
* @tags ScoreConfigs
|
|
3817
|
+
* @name ScoreConfigsGetById
|
|
3818
|
+
* @request GET:/api/public/score-configs/{configId}
|
|
3819
|
+
* @secure
|
|
3820
|
+
*/
|
|
3821
|
+
scoreConfigsGetById: (configId, params = {}) => this.request({
|
|
3822
|
+
path: `/api/public/score-configs/${configId}`,
|
|
3823
|
+
method: "GET",
|
|
3824
|
+
secure: true,
|
|
3825
|
+
format: "json",
|
|
3826
|
+
...params
|
|
3827
|
+
}),
|
|
3828
|
+
/**
|
|
3829
|
+
* @description Create a score (supports both trace and session scores)
|
|
3830
|
+
*
|
|
3831
|
+
* @tags Score
|
|
3832
|
+
* @name ScoreCreate
|
|
3833
|
+
* @request POST:/api/public/scores
|
|
3834
|
+
* @secure
|
|
3835
|
+
*/
|
|
3836
|
+
scoreCreate: (data, params = {}) => this.request({
|
|
3837
|
+
path: `/api/public/scores`,
|
|
3838
|
+
method: "POST",
|
|
3839
|
+
body: data,
|
|
3840
|
+
secure: true,
|
|
3841
|
+
type: ContentType.Json,
|
|
3842
|
+
format: "json",
|
|
3843
|
+
...params
|
|
3844
|
+
}),
|
|
3845
|
+
/**
|
|
3846
|
+
* @description Delete a score (supports both trace and session scores)
|
|
3847
|
+
*
|
|
3848
|
+
* @tags Score
|
|
3849
|
+
* @name ScoreDelete
|
|
3850
|
+
* @request DELETE:/api/public/scores/{scoreId}
|
|
3851
|
+
* @secure
|
|
3852
|
+
*/
|
|
3853
|
+
scoreDelete: (scoreId, params = {}) => this.request({
|
|
3854
|
+
path: `/api/public/scores/${scoreId}`,
|
|
3855
|
+
method: "DELETE",
|
|
3856
|
+
secure: true,
|
|
3857
|
+
...params
|
|
3858
|
+
}),
|
|
3859
|
+
/**
|
|
3860
|
+
* @description Get a list of scores (supports both trace and session scores)
|
|
3861
|
+
*
|
|
3862
|
+
* @tags ScoreV2
|
|
3863
|
+
* @name ScoreV2Get
|
|
3864
|
+
* @request GET:/api/public/v2/scores
|
|
3865
|
+
* @secure
|
|
3866
|
+
*/
|
|
3867
|
+
scoreV2Get: (query, params = {}) => this.request({
|
|
3868
|
+
path: `/api/public/v2/scores`,
|
|
3869
|
+
method: "GET",
|
|
3870
|
+
query,
|
|
3871
|
+
secure: true,
|
|
3872
|
+
format: "json",
|
|
3873
|
+
...params
|
|
3874
|
+
}),
|
|
3875
|
+
/**
|
|
3876
|
+
* @description Get a score (supports both trace and session scores)
|
|
3877
|
+
*
|
|
3878
|
+
* @tags ScoreV2
|
|
3879
|
+
* @name ScoreV2GetById
|
|
3880
|
+
* @request GET:/api/public/v2/scores/{scoreId}
|
|
3881
|
+
* @secure
|
|
3882
|
+
*/
|
|
3883
|
+
scoreV2GetById: (scoreId, params = {}) => this.request({
|
|
3884
|
+
path: `/api/public/v2/scores/${scoreId}`,
|
|
3885
|
+
method: "GET",
|
|
3886
|
+
secure: true,
|
|
3887
|
+
format: "json",
|
|
3888
|
+
...params
|
|
3889
|
+
}),
|
|
3890
|
+
/**
|
|
3891
|
+
* @description Get a session. Please note that `traces` on this endpoint are not paginated, if you plan to fetch large sessions, consider `GET /api/public/traces?sessionId=<sessionId>`
|
|
3892
|
+
*
|
|
3893
|
+
* @tags Sessions
|
|
3894
|
+
* @name SessionsGet
|
|
3895
|
+
* @request GET:/api/public/sessions/{sessionId}
|
|
3896
|
+
* @secure
|
|
3897
|
+
*/
|
|
3898
|
+
sessionsGet: (sessionId, params = {}) => this.request({
|
|
3899
|
+
path: `/api/public/sessions/${sessionId}`,
|
|
3900
|
+
method: "GET",
|
|
3901
|
+
secure: true,
|
|
3902
|
+
format: "json",
|
|
3903
|
+
...params
|
|
3904
|
+
}),
|
|
3905
|
+
/**
|
|
3906
|
+
* @description Get sessions
|
|
3907
|
+
*
|
|
3908
|
+
* @tags Sessions
|
|
3909
|
+
* @name SessionsList
|
|
3910
|
+
* @request GET:/api/public/sessions
|
|
3911
|
+
* @secure
|
|
3912
|
+
*/
|
|
3913
|
+
sessionsList: (query, params = {}) => this.request({
|
|
3914
|
+
path: `/api/public/sessions`,
|
|
3915
|
+
method: "GET",
|
|
3916
|
+
query,
|
|
3917
|
+
secure: true,
|
|
3918
|
+
format: "json",
|
|
3919
|
+
...params
|
|
3920
|
+
}),
|
|
3921
|
+
/**
|
|
3922
|
+
* @description Delete a specific trace
|
|
3923
|
+
*
|
|
3924
|
+
* @tags Trace
|
|
3925
|
+
* @name TraceDelete
|
|
3926
|
+
* @request DELETE:/api/public/traces/{traceId}
|
|
3927
|
+
* @secure
|
|
3928
|
+
*/
|
|
3929
|
+
traceDelete: (traceId, params = {}) => this.request({
|
|
3930
|
+
path: `/api/public/traces/${traceId}`,
|
|
3931
|
+
method: "DELETE",
|
|
3932
|
+
secure: true,
|
|
3933
|
+
format: "json",
|
|
3934
|
+
...params
|
|
3935
|
+
}),
|
|
3936
|
+
/**
|
|
3937
|
+
* @description Delete multiple traces
|
|
3938
|
+
*
|
|
3939
|
+
* @tags Trace
|
|
3940
|
+
* @name TraceDeleteMultiple
|
|
3941
|
+
* @request DELETE:/api/public/traces
|
|
3942
|
+
* @secure
|
|
3943
|
+
*/
|
|
3944
|
+
traceDeleteMultiple: (data, params = {}) => this.request({
|
|
3945
|
+
path: `/api/public/traces`,
|
|
3946
|
+
method: "DELETE",
|
|
3947
|
+
body: data,
|
|
3948
|
+
secure: true,
|
|
3949
|
+
type: ContentType.Json,
|
|
3950
|
+
format: "json",
|
|
3951
|
+
...params
|
|
3952
|
+
}),
|
|
3953
|
+
/**
|
|
3954
|
+
* @description Get a specific trace
|
|
3955
|
+
*
|
|
3956
|
+
* @tags Trace
|
|
3957
|
+
* @name TraceGet
|
|
3958
|
+
* @request GET:/api/public/traces/{traceId}
|
|
3959
|
+
* @secure
|
|
3960
|
+
*/
|
|
3961
|
+
traceGet: (traceId, params = {}) => this.request({
|
|
3962
|
+
path: `/api/public/traces/${traceId}`,
|
|
3963
|
+
method: "GET",
|
|
3964
|
+
secure: true,
|
|
3965
|
+
format: "json",
|
|
3966
|
+
...params
|
|
3967
|
+
}),
|
|
3968
|
+
/**
|
|
3969
|
+
* @description Get list of traces
|
|
3970
|
+
*
|
|
3971
|
+
* @tags Trace
|
|
3972
|
+
* @name TraceList
|
|
3973
|
+
* @request GET:/api/public/traces
|
|
3974
|
+
* @secure
|
|
3975
|
+
*/
|
|
3976
|
+
traceList: (query, params = {}) => this.request({
|
|
3977
|
+
path: `/api/public/traces`,
|
|
3978
|
+
method: "GET",
|
|
3979
|
+
query,
|
|
3980
|
+
secure: true,
|
|
3981
|
+
format: "json",
|
|
3982
|
+
...params
|
|
3983
|
+
})
|
|
3984
|
+
};
|
|
3985
|
+
}
|
|
3986
|
+
};
|
|
3987
|
+
var version = "3.39.2";
|
|
3988
|
+
var Langfuse = class extends LangfuseCore {
|
|
3989
|
+
constructor(params) {
|
|
3990
|
+
const langfuseConfig = utils.configLangfuseSDK(params);
|
|
3991
|
+
super(langfuseConfig);
|
|
3992
|
+
if (typeof window !== "undefined" && "Deno" in window === false) {
|
|
3993
|
+
this._storageKey = params?.persistence_name ? `lf_${params.persistence_name}` : `lf_${langfuseConfig.publicKey}_langfuse`;
|
|
3994
|
+
this._storage = getStorage(params?.persistence || "localStorage", window);
|
|
3995
|
+
} else {
|
|
3996
|
+
this._storageKey = `lf_${langfuseConfig.publicKey}_langfuse`;
|
|
3997
|
+
this._storage = getStorage("memory", void 0);
|
|
3998
|
+
}
|
|
3999
|
+
this.api = new LangfusePublicApi({
|
|
4000
|
+
baseUrl: this.baseUrl,
|
|
4001
|
+
baseApiParams: {
|
|
4002
|
+
headers: {
|
|
4003
|
+
"X-Langfuse-Sdk-Name": "langfuse-js",
|
|
4004
|
+
"X-Langfuse-Sdk-Version": this.getLibraryVersion(),
|
|
4005
|
+
"X-Langfuse-Sdk-Variant": this.getLibraryId(),
|
|
4006
|
+
"X-Langfuse-Sdk-Integration": this.sdkIntegration,
|
|
4007
|
+
"X-Langfuse-Public-Key": this.publicKey,
|
|
4008
|
+
...this.additionalHeaders,
|
|
4009
|
+
...this.constructAuthorizationHeader(this.publicKey, this.secretKey)
|
|
4010
|
+
}
|
|
4011
|
+
}
|
|
4012
|
+
}).api;
|
|
4013
|
+
}
|
|
4014
|
+
getPersistedProperty(key) {
|
|
4015
|
+
if (!this._storageCache) {
|
|
4016
|
+
this._storageCache = JSON.parse(this._storage.getItem(this._storageKey) || "{}") || {};
|
|
4017
|
+
}
|
|
4018
|
+
return this._storageCache[key];
|
|
4019
|
+
}
|
|
4020
|
+
setPersistedProperty(key, value) {
|
|
4021
|
+
if (!this._storageCache) {
|
|
4022
|
+
this._storageCache = JSON.parse(this._storage.getItem(this._storageKey) || "{}") || {};
|
|
4023
|
+
}
|
|
4024
|
+
if (value === null) {
|
|
4025
|
+
delete this._storageCache[key];
|
|
4026
|
+
} else {
|
|
4027
|
+
this._storageCache[key] = value;
|
|
4028
|
+
}
|
|
4029
|
+
this._storage.setItem(this._storageKey, JSON.stringify(this._storageCache));
|
|
4030
|
+
}
|
|
4031
|
+
fetch(url, options) {
|
|
4032
|
+
return fetch(url, options);
|
|
4033
|
+
}
|
|
4034
|
+
getLibraryId() {
|
|
4035
|
+
return "langfuse";
|
|
4036
|
+
}
|
|
4037
|
+
getLibraryVersion() {
|
|
4038
|
+
return version;
|
|
4039
|
+
}
|
|
4040
|
+
getCustomUserAgent() {
|
|
4041
|
+
return;
|
|
4042
|
+
}
|
|
4043
|
+
};
|
|
4044
|
+
var LangfuseSingleton = class _LangfuseSingleton {
|
|
4045
|
+
/**
|
|
4046
|
+
* Returns the singleton instance of the Langfuse client.
|
|
4047
|
+
* @param params Optional parameters for initializing the Langfuse instance. Only used for the first call.
|
|
4048
|
+
* @returns The singleton instance of the Langfuse client.
|
|
4049
|
+
*/
|
|
4050
|
+
static getInstance(params) {
|
|
4051
|
+
if (!_LangfuseSingleton.instance) {
|
|
4052
|
+
_LangfuseSingleton.instance = new Langfuse(params);
|
|
4053
|
+
}
|
|
4054
|
+
return _LangfuseSingleton.instance;
|
|
4055
|
+
}
|
|
4056
|
+
};
|
|
4057
|
+
LangfuseSingleton.instance = null;
|
|
4058
|
+
|
|
4059
|
+
// src/ai-trace-langfuse/langfuse.ts
|
|
4060
|
+
function content(captured) {
|
|
4061
|
+
return captured?.text ?? null;
|
|
4062
|
+
}
|
|
4063
|
+
function contentMeta(name, captured) {
|
|
4064
|
+
if (!captured) return {};
|
|
4065
|
+
return { [`${name}Chars`]: captured.chars, ...captured.truncated ? { [`${name}Truncated`]: true } : {}, ...captured.redactions ? { [`${name}Redactions`]: captured.redactions } : {} };
|
|
4066
|
+
}
|
|
4067
|
+
function iso(at) {
|
|
4068
|
+
return at === null ? void 0 : new Date(at).toISOString();
|
|
4069
|
+
}
|
|
4070
|
+
function usageDetails(usage) {
|
|
4071
|
+
if (!usage) return void 0;
|
|
4072
|
+
const pairs = [["input", usage.inputTokens], ["output", usage.outputTokens], ["cache_read_input_tokens", usage.cacheReadTokens], ["cache_creation_input_tokens", usage.cacheWriteTokens], ["reasoning_tokens", usage.reasoningTokens]];
|
|
4073
|
+
const kept = pairs.filter((pair) => pair[1] !== null);
|
|
4074
|
+
return kept.length ? Object.fromEntries(kept) : void 0;
|
|
4075
|
+
}
|
|
4076
|
+
function toolLevel(e) {
|
|
4077
|
+
if (e.isError) return "ERROR";
|
|
4078
|
+
return e.endedAt === null ? "WARNING" : "DEFAULT";
|
|
4079
|
+
}
|
|
4080
|
+
var MAPPERS = {
|
|
4081
|
+
run_started: (e) => ({ method: "trace", body: { id: e.traceId, name: `agent:${e.agentId}`, sessionId: e.sessionId ?? void 0, input: content(e.input), timestamp: iso(e.at), tags: [...e.tags, ...e.provider ? [`provider:${e.provider}`] : []], metadata: { runId: e.runId, agentId: e.agentId, provider: e.provider, model: e.model, ...contentMeta("input", e.input) } } }),
|
|
4082
|
+
model_turn: (e) => ({
|
|
4083
|
+
method: "generation",
|
|
4084
|
+
body: { id: e.turnId, traceId: e.traceId, name: `turn-${e.index}`, model: e.model ?? void 0, input: content(e.input), output: content(e.output), startTime: iso(e.startedAt), endTime: iso(e.endedAt), completionStartTime: iso(e.ttftMs === null ? null : e.startedAt + e.ttftMs), usageDetails: usageDetails(e.usage), costDetails: e.costUsd === null ? void 0 : { total: e.costUsd }, level: e.error ? "ERROR" : "DEFAULT", statusMessage: e.error ?? void 0, metadata: { stopReason: e.stopReason, costSource: e.costSource, ...contentMeta("input", e.input), ...contentMeta("output", e.output), ...contentMeta("reasoning", e.reasoning), ...e.reasoning?.text ? { reasoning: e.reasoning.text } : {} } }
|
|
4085
|
+
}),
|
|
4086
|
+
tool_call: (e) => ({ method: "span", body: { id: `${e.traceId}:tool:${e.toolCallId}`, traceId: e.traceId, parentObservationId: e.turnId, name: `tool:${e.name}`, input: content(e.input), output: content(e.output), startTime: iso(e.startedAt), endTime: iso(e.endedAt), level: toolLevel(e), statusMessage: e.errorClass ?? (e.endedAt === null ? "unresolved" : void 0), metadata: { toolName: e.name, toolCallId: e.toolCallId, isError: e.isError, errorClass: e.errorClass, ...contentMeta("input", e.input), ...contentMeta("output", e.output) } } }),
|
|
4087
|
+
run_finished: (e) => ({ method: "trace", body: { id: e.traceId, output: e.error ? { error: e.error.message, code: e.error.code } : null, tags: [`outcome:${e.outcome}`], metadata: { outcome: e.outcome, ...e.totals } } })
|
|
4088
|
+
};
|
|
4089
|
+
function toLangfuseCall({ event }) {
|
|
4090
|
+
return MAPPERS[event.kind](event);
|
|
4091
|
+
}
|
|
4092
|
+
function attributed({ call, attribution }) {
|
|
4093
|
+
if (!attribution || call.method !== "trace") return call;
|
|
4094
|
+
const { body } = call;
|
|
4095
|
+
return { method: call.method, body: {
|
|
4096
|
+
...body,
|
|
4097
|
+
metadata: { ...body.metadata, ...attribution.attributes },
|
|
4098
|
+
// Both trace calls (`run_started`, `run_finished`) always carry a tags list.
|
|
4099
|
+
tags: [...body.tags, ...attribution.tags]
|
|
4100
|
+
} };
|
|
4101
|
+
}
|
|
4102
|
+
function createLangfuseAiTraceSink({ client, attribution }) {
|
|
4103
|
+
return {
|
|
4104
|
+
record(event) {
|
|
4105
|
+
const call = attributed({ call: toLangfuseCall({ event }), attribution });
|
|
4106
|
+
client[call.method](call.body);
|
|
4107
|
+
},
|
|
4108
|
+
flush: async () => {
|
|
4109
|
+
await client.flushAsync();
|
|
4110
|
+
},
|
|
4111
|
+
shutdown: async () => {
|
|
4112
|
+
await client.shutdownAsync();
|
|
4113
|
+
}
|
|
4114
|
+
};
|
|
4115
|
+
}
|
|
4116
|
+
function createLangfuseClient({ publicKey, secretKey, baseUrl, environment, release }) {
|
|
4117
|
+
return new Langfuse({ publicKey, secretKey, ...baseUrl ? { baseUrl } : {}, ...environment ? { environment } : {}, ...release ? { release } : {} });
|
|
4118
|
+
}
|
|
4119
|
+
|
|
4120
|
+
// src/attribution.ts
|
|
4121
|
+
var EMPTY = Object.freeze({ attributes: Object.freeze({}), groups: Object.freeze({}), tags: Object.freeze([]) });
|
|
4122
|
+
function stringMap(value, name) {
|
|
4123
|
+
if (value === void 0) return {};
|
|
4124
|
+
if (!value || typeof value !== "object" || Array.isArray(value) || Object.values(value).some((entry) => typeof entry !== "string")) {
|
|
4125
|
+
throw new TypeError(`attribution.${name} must be an object of strings`);
|
|
4126
|
+
}
|
|
4127
|
+
return { ...value };
|
|
4128
|
+
}
|
|
4129
|
+
function attributionOf(value) {
|
|
4130
|
+
if (value === void 0) return EMPTY;
|
|
4131
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) throw new TypeError("attribution must be an object");
|
|
4132
|
+
const { attributes, groups, tags } = value;
|
|
4133
|
+
if (tags !== void 0 && (!Array.isArray(tags) || tags.some((tag) => typeof tag !== "string"))) throw new TypeError("attribution.tags must be a list of strings");
|
|
4134
|
+
return { attributes: stringMap(attributes, "attributes"), groups: stringMap(groups, "groups"), tags: [...tags ?? []] };
|
|
4135
|
+
}
|
|
4136
|
+
|
|
4137
|
+
// src/ai-trace-langfuse/index.ts
|
|
4138
|
+
function textOf(value, name, { required }) {
|
|
4139
|
+
if (value === void 0 && !required) return void 0;
|
|
4140
|
+
if (typeof value !== "string" || !value.trim()) throw new TypeError(`${name} must be a non-empty string`);
|
|
4141
|
+
return value.trim();
|
|
4142
|
+
}
|
|
4143
|
+
function createLangfuseProvider(required, optional = {}) {
|
|
4144
|
+
const config = { publicKey: textOf(required.publicKey, "publicKey", { required: true }), secretKey: textOf(required.secretKey, "secretKey", { required: true }) };
|
|
4145
|
+
const extras = Object.fromEntries(["baseUrl", "environment", "release"].map((name) => [name, textOf(required[name], name, { required: false })]).filter(([, value]) => value !== void 0));
|
|
4146
|
+
const borrowed = optional.client;
|
|
4147
|
+
const client = borrowed ? borrowedView({ client: borrowed }) : createLangfuseClient({ ...config, ...extras });
|
|
4148
|
+
const port = createLangfuseAiTraceSink({ client, attribution: attributionOf(required.attribution) });
|
|
4149
|
+
return { port, dispose: async (_required, _optional = {}) => {
|
|
4150
|
+
await client.shutdownAsync();
|
|
4151
|
+
} };
|
|
4152
|
+
}
|
|
4153
|
+
function borrowedView({ client }) {
|
|
4154
|
+
return {
|
|
4155
|
+
trace: (body) => client.trace(body),
|
|
4156
|
+
generation: (body) => client.generation(body),
|
|
4157
|
+
span: (body) => client.span(body),
|
|
4158
|
+
flushAsync: () => client.flushAsync(),
|
|
4159
|
+
shutdownAsync: () => client.flushAsync()
|
|
4160
|
+
};
|
|
4161
|
+
}
|
|
4162
|
+
var index_default = {
|
|
4163
|
+
definition: {
|
|
4164
|
+
setup(sdk) {
|
|
4165
|
+
sdk.providers.register({ contract: "ai_trace", id: "langfuse", contractVersion: 1, factory: createLangfuseProvider });
|
|
4166
|
+
}
|
|
4167
|
+
}
|
|
4168
|
+
};
|
|
4169
|
+
export {
|
|
4170
|
+
createLangfuseProvider,
|
|
4171
|
+
index_default as default
|
|
4172
|
+
};
|