@langfuse/client 4.0.0-alpha.2 → 4.0.0-alpha.3

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.
@@ -1,144 +0,0 @@
1
- import { getGlobalLogger, } from "@langfuse/core";
2
- import { LangfusePromptCache } from "./promptCache.js";
3
- import { ChatPromptClient, TextPromptClient, } from "./promptClients.js";
4
- import { ChatMessageType, } from "./types.js";
5
- export class PromptManager {
6
- constructor(params) {
7
- const { apiClient } = params;
8
- this.apiClient = apiClient;
9
- this.cache = new LangfusePromptCache();
10
- }
11
- get logger() {
12
- return getGlobalLogger();
13
- }
14
- async create(body) {
15
- var _a;
16
- const requestBody = body.type === "chat"
17
- ? {
18
- ...body,
19
- prompt: body.prompt.map((item) => {
20
- if ("type" in item && item.type === ChatMessageType.Placeholder) {
21
- return {
22
- type: ChatMessageType.Placeholder,
23
- name: item.name,
24
- };
25
- }
26
- else {
27
- // Handle regular ChatMessage (without type field) from API
28
- return { type: ChatMessageType.ChatMessage, ...item };
29
- }
30
- }),
31
- }
32
- : {
33
- ...body,
34
- type: (_a = body.type) !== null && _a !== void 0 ? _a : "text",
35
- };
36
- const promptResponse = await this.apiClient.prompts.create(requestBody);
37
- if (promptResponse.type === "chat") {
38
- return new ChatPromptClient(promptResponse);
39
- }
40
- return new TextPromptClient(promptResponse);
41
- }
42
- async update(params) {
43
- const { name, version, newLabels } = params;
44
- const newPrompt = await this.apiClient.promptVersion.update(name, version, {
45
- newLabels,
46
- });
47
- this.cache.invalidate(name);
48
- return newPrompt;
49
- }
50
- async get(name, options) {
51
- var _a;
52
- const cacheKey = this.cache.createKey({
53
- name,
54
- label: options === null || options === void 0 ? void 0 : options.label,
55
- });
56
- const cachedPrompt = this.cache.getIncludingExpired(cacheKey);
57
- if (!cachedPrompt || (options === null || options === void 0 ? void 0 : options.cacheTtlSeconds) === 0) {
58
- try {
59
- return await this.fetchPromptAndUpdateCache({
60
- name,
61
- version: options === null || options === void 0 ? void 0 : options.version,
62
- label: options === null || options === void 0 ? void 0 : options.label,
63
- cacheTtlSeconds: options === null || options === void 0 ? void 0 : options.cacheTtlSeconds,
64
- maxRetries: options === null || options === void 0 ? void 0 : options.maxRetries,
65
- fetchTimeoutMs: options === null || options === void 0 ? void 0 : options.fetchTimeoutMs,
66
- });
67
- }
68
- catch (err) {
69
- if (options === null || options === void 0 ? void 0 : options.fallback) {
70
- const sharedFallbackParams = {
71
- name,
72
- version: (_a = options === null || options === void 0 ? void 0 : options.version) !== null && _a !== void 0 ? _a : 0,
73
- labels: options.label ? [options.label] : [],
74
- cacheTtlSeconds: options === null || options === void 0 ? void 0 : options.cacheTtlSeconds,
75
- config: {},
76
- tags: [],
77
- };
78
- if (options.type === "chat") {
79
- return new ChatPromptClient({
80
- ...sharedFallbackParams,
81
- type: "chat",
82
- prompt: options.fallback.map((msg) => ({
83
- type: ChatMessageType.ChatMessage,
84
- ...msg,
85
- })),
86
- }, true);
87
- }
88
- else {
89
- return new TextPromptClient({
90
- ...sharedFallbackParams,
91
- type: "text",
92
- prompt: options.fallback,
93
- }, true);
94
- }
95
- }
96
- throw err;
97
- }
98
- }
99
- if (cachedPrompt.isExpired) {
100
- // If the cache is not currently being refreshed, start refreshing it and register the promise in the cache
101
- if (!this.cache.isRefreshing(cacheKey)) {
102
- const refreshPromptPromise = this.fetchPromptAndUpdateCache({
103
- name,
104
- version: options === null || options === void 0 ? void 0 : options.version,
105
- label: options === null || options === void 0 ? void 0 : options.label,
106
- cacheTtlSeconds: options === null || options === void 0 ? void 0 : options.cacheTtlSeconds,
107
- maxRetries: options === null || options === void 0 ? void 0 : options.maxRetries,
108
- fetchTimeoutMs: options === null || options === void 0 ? void 0 : options.fetchTimeoutMs,
109
- }).catch(() => {
110
- this.logger.warn(`Failed to refresh prompt cache '${cacheKey}', stale cache will be used until next refresh succeeds.`);
111
- });
112
- this.cache.addRefreshingPromise(cacheKey, refreshPromptPromise);
113
- }
114
- return cachedPrompt.value;
115
- }
116
- return cachedPrompt.value;
117
- }
118
- async fetchPromptAndUpdateCache(params) {
119
- const cacheKey = this.cache.createKey(params);
120
- try {
121
- const { name, version, cacheTtlSeconds, label, maxRetries, fetchTimeoutMs, } = params;
122
- const data = await this.apiClient.prompts.get(name, {
123
- version,
124
- label,
125
- }, {
126
- maxRetries,
127
- timeoutInSeconds: fetchTimeoutMs ? fetchTimeoutMs / 1000 : undefined,
128
- });
129
- let prompt;
130
- if (data.type === "chat") {
131
- prompt = new ChatPromptClient(data);
132
- }
133
- else {
134
- prompt = new TextPromptClient(data);
135
- }
136
- this.cache.set(cacheKey, prompt, cacheTtlSeconds);
137
- return prompt;
138
- }
139
- catch (error) {
140
- this.logger.error(`Error fetching prompt '${cacheKey}':`, error);
141
- throw error;
142
- }
143
- }
144
- }
@@ -1,18 +0,0 @@
1
- import { ChatMessage, PlaceholderMessage, ChatMessageWithPlaceholders, CreatePromptRequest } from "@langfuse/core";
2
- export declare enum ChatMessageType {
3
- ChatMessage = "chatmessage",
4
- Placeholder = "placeholder"
5
- }
6
- export type ChatMessageOrPlaceholder = ChatMessage | ({
7
- type: ChatMessageType.Placeholder;
8
- } & PlaceholderMessage);
9
- export type LangchainMessagesPlaceholder = {
10
- variableName: string;
11
- optional?: boolean;
12
- };
13
- export type CreateChatPromptBodyWithPlaceholders = {
14
- type: "chat";
15
- } & Omit<CreatePromptRequest.Chat, "type" | "prompt"> & {
16
- prompt: (ChatMessage | ChatMessageWithPlaceholders)[];
17
- };
18
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/prompt/types.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EACX,kBAAkB,EAClB,2BAA2B,EAC3B,mBAAmB,EACpB,MAAM,gBAAgB,CAAC;AAExB,oBAAY,eAAe;IACzB,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;CAC5B;AAED,MAAM,MAAM,wBAAwB,GAChC,WAAW,GACX,CAAC;IAAE,IAAI,EAAE,eAAe,CAAC,WAAW,CAAA;CAAE,GAAG,kBAAkB,CAAC,CAAC;AAEjE,MAAM,MAAM,4BAA4B,GAAG;IACzC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,oCAAoC,GAAG;IACjD,IAAI,EAAE,MAAM,CAAC;CACd,GAAG,IAAI,CAAC,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,QAAQ,CAAC,GAAG;IACpD,MAAM,EAAE,CAAC,WAAW,GAAG,2BAA2B,CAAC,EAAE,CAAC;CACvD,CAAC"}
@@ -1,5 +0,0 @@
1
- export var ChatMessageType;
2
- (function (ChatMessageType) {
3
- ChatMessageType["ChatMessage"] = "chatmessage";
4
- ChatMessageType["Placeholder"] = "placeholder";
5
- })(ChatMessageType || (ChatMessageType = {}));
@@ -1,27 +0,0 @@
1
- import { LangfuseAPIClient, ScoreBody } from "@langfuse/core";
2
- import { Span } from "@opentelemetry/api";
3
- export declare class ScoreManager {
4
- private apiClient;
5
- private eventQueue;
6
- private flushPromise;
7
- private flushTimer;
8
- private flushAtCount;
9
- private flushIntervalSeconds;
10
- constructor(params: {
11
- apiClient: LangfuseAPIClient;
12
- });
13
- get logger(): import("@langfuse/core").Logger;
14
- create(data: ScoreBody): void;
15
- observation(observation: {
16
- otelSpan: Span;
17
- }, data: Omit<ScoreBody, "traceId" | "sessionId" | "observationId" | "datasetRunId">): void;
18
- trace(observation: {
19
- otelSpan: Span;
20
- }, data: Omit<ScoreBody, "traceId" | "sessionId" | "observationId" | "datasetRunId">): void;
21
- activeObservation(data: Omit<ScoreBody, "traceId" | "sessionId" | "observationId" | "datasetRunId">): void;
22
- activeTrace(data: Omit<ScoreBody, "traceId" | "sessionId" | "observationId" | "datasetRunId">): void;
23
- private handleFlush;
24
- flush(): Promise<void>;
25
- shutdown(): Promise<void>;
26
- }
27
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/score/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,iBAAiB,EAIjB,SAAS,EAIV,MAAM,gBAAgB,CAAC;AACxB,OAAO,EAAE,IAAI,EAAS,MAAM,oBAAoB,CAAC;AAKjD,qBAAa,YAAY;IACvB,OAAO,CAAC,SAAS,CAAoB;IACrC,OAAO,CAAC,UAAU,CAAwB;IAC1C,OAAO,CAAC,YAAY,CAA8B;IAClD,OAAO,CAAC,UAAU,CAAa;IAC/B,OAAO,CAAC,YAAY,CAAS;IAC7B,OAAO,CAAC,oBAAoB,CAAS;gBAEzB,MAAM,EAAE;QAAE,SAAS,EAAE,iBAAiB,CAAA;KAAE;IAYpD,IAAI,MAAM,oCAET;IAEM,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI;IAgC7B,WAAW,CAChB,WAAW,EAAE;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,EAC/B,IAAI,EAAE,IAAI,CACR,SAAS,EACT,SAAS,GAAG,WAAW,GAAG,eAAe,GAAG,cAAc,CAC3D;IAWI,KAAK,CACV,WAAW,EAAE;QAAE,QAAQ,EAAE,IAAI,CAAA;KAAE,EAC/B,IAAI,EAAE,IAAI,CACR,SAAS,EACT,SAAS,GAAG,WAAW,GAAG,eAAe,GAAG,cAAc,CAC3D;IAUI,iBAAiB,CACtB,IAAI,EAAE,IAAI,CACR,SAAS,EACT,SAAS,GAAG,WAAW,GAAG,eAAe,GAAG,cAAc,CAC3D;IAkBI,WAAW,CAChB,IAAI,EAAE,IAAI,CACR,SAAS,EACT,SAAS,GAAG,WAAW,GAAG,eAAe,GAAG,cAAc,CAC3D;YAiBW,WAAW;IAkCZ,KAAK;IAIL,QAAQ;CAGtB"}
@@ -1,125 +0,0 @@
1
- import { getEnv, generateUUID, getGlobalLogger, safeSetTimeout, } from "@langfuse/core";
2
- import { trace } from "@opentelemetry/api";
3
- const MAX_QUEUE_SIZE = 100000; // prevent memory leaks
4
- const MAX_BATCH_SIZE = 100;
5
- export class ScoreManager {
6
- constructor(params) {
7
- this.eventQueue = [];
8
- this.flushPromise = null;
9
- this.flushTimer = null;
10
- this.apiClient = params.apiClient;
11
- const envFlushAtCount = getEnv("LANGFUSE_FLUSH_AT");
12
- const envFlushIntervalSeconds = getEnv("LANGFUSE_FLUSH_INTERVAL");
13
- this.flushAtCount = envFlushAtCount ? Number(envFlushAtCount) : 10;
14
- this.flushIntervalSeconds = envFlushIntervalSeconds
15
- ? Number(envFlushIntervalSeconds)
16
- : 1;
17
- }
18
- get logger() {
19
- return getGlobalLogger();
20
- }
21
- create(data) {
22
- var _a, _b;
23
- const scoreData = {
24
- ...data,
25
- id: (_a = data.id) !== null && _a !== void 0 ? _a : generateUUID(),
26
- environment: (_b = data.environment) !== null && _b !== void 0 ? _b : getEnv("LANGFUSE_TRACING_ENVIRONMENT"),
27
- };
28
- const scoreIngestionEvent = {
29
- id: generateUUID(),
30
- type: "score-create",
31
- timestamp: new Date().toISOString(),
32
- body: scoreData,
33
- };
34
- if (this.eventQueue.length >= MAX_QUEUE_SIZE) {
35
- this.logger.error(`Score queue is at max size ${MAX_QUEUE_SIZE}. Dropping score.`);
36
- return;
37
- }
38
- this.eventQueue.push(scoreIngestionEvent);
39
- if (this.eventQueue.length >= this.flushAtCount) {
40
- this.flushPromise = this.flush();
41
- }
42
- else if (!this.flushTimer) {
43
- this.flushTimer = safeSetTimeout(() => {
44
- this.flushPromise = this.flush();
45
- }, this.flushIntervalSeconds * 1000);
46
- }
47
- }
48
- observation(observation, data) {
49
- const { spanId, traceId } = observation.otelSpan.spanContext();
50
- this.create({
51
- ...data,
52
- traceId,
53
- observationId: spanId,
54
- });
55
- }
56
- trace(observation, data) {
57
- const { traceId } = observation.otelSpan.spanContext();
58
- this.create({
59
- ...data,
60
- traceId,
61
- });
62
- }
63
- activeObservation(data) {
64
- const currentOtelSpan = trace.getActiveSpan();
65
- if (!currentOtelSpan) {
66
- this.logger.warn("No active span in context to score.");
67
- return;
68
- }
69
- const { spanId, traceId } = currentOtelSpan.spanContext();
70
- this.create({
71
- ...data,
72
- traceId,
73
- observationId: spanId,
74
- });
75
- }
76
- activeTrace(data) {
77
- const currentOtelSpan = trace.getActiveSpan();
78
- if (!currentOtelSpan) {
79
- this.logger.warn("No active span in context to score trace.");
80
- return;
81
- }
82
- const { traceId } = currentOtelSpan.spanContext();
83
- this.create({
84
- ...data,
85
- traceId,
86
- });
87
- }
88
- async handleFlush() {
89
- try {
90
- if (this.flushTimer) {
91
- clearTimeout(this.flushTimer);
92
- this.flushTimer = null;
93
- }
94
- const promises = [];
95
- while (this.eventQueue.length > 0) {
96
- const batch = this.eventQueue.splice(0, MAX_BATCH_SIZE);
97
- promises.push(this.apiClient.ingestion
98
- .batch({ batch })
99
- .then((res) => {
100
- var _a;
101
- if (((_a = res.errors) === null || _a === void 0 ? void 0 : _a.length) > 0) {
102
- this.logger.error("Error ingesting scores:", res.errors);
103
- }
104
- })
105
- .catch((err) => {
106
- this.logger.error("Failed to export score batch:", err);
107
- }));
108
- }
109
- await Promise.all(promises);
110
- }
111
- catch (err) {
112
- this.logger.error("Error flushing Score Manager: ", err);
113
- }
114
- finally {
115
- this.flushPromise = null;
116
- }
117
- }
118
- async flush() {
119
- var _a;
120
- return (_a = this.flushPromise) !== null && _a !== void 0 ? _a : this.handleFlush();
121
- }
122
- async shutdown() {
123
- await this.flush();
124
- }
125
- }