@mate-academy/prompt-client 1.0.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +120 -69
- package/dist/LLMPromptClient.constants.d.ts +2 -0
- package/dist/LLMPromptClient.constants.js +3 -1
- package/dist/LLMPromptClient.errors.d.ts +5 -0
- package/dist/LLMPromptClient.errors.js +10 -1
- package/dist/LLMPromptClient.typedefs.d.ts +88 -3
- package/dist/LLMPromptClient.typedefs.js +8 -1
- package/dist/PromptManagement.typedefs.d.ts +6 -5
- package/dist/index.d.ts +0 -4
- package/dist/index.js +0 -4
- package/dist/providers/InMemory/InMemory.factory.js +1 -8
- package/dist/providers/InMemory/InMemory.typedefs.d.ts +9 -13
- package/dist/providers/InMemory/InMemoryPrompt.client.d.ts +14 -2
- package/dist/providers/InMemory/InMemoryPrompt.client.js +113 -0
- package/dist/providers/Langfuse/Langfuse.factory.js +7 -9
- package/dist/providers/Langfuse/Langfuse.helpers.d.ts +8 -1
- package/dist/providers/Langfuse/Langfuse.helpers.js +27 -11
- package/dist/providers/Langfuse/Langfuse.typedefs.d.ts +0 -2
- package/dist/providers/Langfuse/LangfusePrompt.client.d.ts +18 -5
- package/dist/providers/Langfuse/LangfusePrompt.client.js +169 -18
- package/dist/providers/Langfuse/LangfusePrompt.d.ts +13 -2
- package/dist/providers/Langfuse/LangfusePrompt.js +19 -1
- package/dist/utilities/index.d.ts +0 -1
- package/dist/utilities/index.js +0 -1
- package/package.json +3 -4
- package/dist/LLMTracer.errors.d.ts +0 -4
- package/dist/LLMTracer.errors.js +0 -11
- package/dist/LLMTracer.typedefs.d.ts +0 -45
- package/dist/LLMTracer.typedefs.js +0 -2
- package/dist/providers/InMemory/InMemoryTracer.client.d.ts +0 -15
- package/dist/providers/InMemory/InMemoryTracer.client.js +0 -63
- package/dist/providers/Langfuse/LangfuseTracer.client.d.ts +0 -13
- package/dist/providers/Langfuse/LangfuseTracer.client.js +0 -49
- package/dist/utilities/usageDetails/index.d.ts +0 -1
- package/dist/utilities/usageDetails/index.js +0 -17
- package/dist/utilities/usageDetails/usageDetails.helpers.d.ts +0 -17
- package/dist/utilities/usageDetails/usageDetails.helpers.js +0 -33
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.InMemoryPromptClient = void 0;
|
|
4
4
|
const LLMPromptClient_typedefs_1 = require("../../LLMPromptClient.typedefs");
|
|
5
|
+
const LLMPromptClient_constants_1 = require("../../LLMPromptClient.constants");
|
|
5
6
|
const LLMPromptClient_errors_1 = require("../../LLMPromptClient.errors");
|
|
6
7
|
const InMemory_typedefs_1 = require("../../providers/InMemory/InMemory.typedefs");
|
|
7
8
|
const template_1 = require("../../utilities/template");
|
|
@@ -10,6 +11,7 @@ const FALLBACK_PROMPT_VERSION = 0;
|
|
|
10
11
|
class InMemoryPromptClient {
|
|
11
12
|
constructor(options) {
|
|
12
13
|
this.prompts = new Map(Object.entries(options.prompts ?? {}));
|
|
14
|
+
this.chatPrompts = new Map(Object.entries(options.chatPrompts ?? {}));
|
|
13
15
|
this.missingPromptBehavior = options.missingPromptBehavior
|
|
14
16
|
?? InMemory_typedefs_1.InMemoryMissingPromptBehaviors.Throw;
|
|
15
17
|
}
|
|
@@ -26,14 +28,58 @@ class InMemoryPromptClient {
|
|
|
26
28
|
}
|
|
27
29
|
throw new LLMPromptClient_errors_1.LLMPromptNotFoundError(name);
|
|
28
30
|
}
|
|
31
|
+
async getChatPrompt(name, options) {
|
|
32
|
+
const seedChatPrompt = this.chatPrompts.get(name);
|
|
33
|
+
if (seedChatPrompt) {
|
|
34
|
+
return this.buildChatPrompt(name, seedChatPrompt);
|
|
35
|
+
}
|
|
36
|
+
if (options?.fallback !== undefined) {
|
|
37
|
+
return this.buildFallbackChatPrompt(name, options.fallback);
|
|
38
|
+
}
|
|
39
|
+
if (this.missingPromptBehavior === InMemory_typedefs_1.InMemoryMissingPromptBehaviors.GenerateStub) {
|
|
40
|
+
return this.buildChatPrompt(name, {
|
|
41
|
+
messages: [{
|
|
42
|
+
role: LLMPromptClient_typedefs_1.LLMPromptMessageRoles.System,
|
|
43
|
+
content: `Mock prompt for ${name}`,
|
|
44
|
+
}],
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
throw new LLMPromptClient_errors_1.LLMPromptNotFoundError(name);
|
|
48
|
+
}
|
|
49
|
+
async listPrompts(options) {
|
|
50
|
+
const matchingNames = this.collectMatchingNames(options.label);
|
|
51
|
+
const page = options.page ?? LLMPromptClient_constants_1.DEFAULT_PROMPT_LIST_PAGE;
|
|
52
|
+
const pageSize = options.pageSize ?? LLMPromptClient_constants_1.DEFAULT_PROMPT_LIST_PAGE_SIZE;
|
|
53
|
+
const startIndex = (page - 1) * pageSize;
|
|
54
|
+
return {
|
|
55
|
+
promptNames: matchingNames.slice(startIndex, startIndex + pageSize),
|
|
56
|
+
page,
|
|
57
|
+
totalPages: Math.max(1, Math.ceil(matchingNames.length / pageSize)),
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
async getPromptRecord(name, options) {
|
|
61
|
+
const seedPrompt = this.prompts.get(name);
|
|
62
|
+
if (seedPrompt && this.matchesLabel(seedPrompt.labels, options.label)) {
|
|
63
|
+
return this.buildTextPromptRecord(name, seedPrompt);
|
|
64
|
+
}
|
|
65
|
+
const seedChatPrompt = this.chatPrompts.get(name);
|
|
66
|
+
if (seedChatPrompt && this.matchesLabel(seedChatPrompt.labels, options.label)) {
|
|
67
|
+
return this.buildChatPromptRecord(name, seedChatPrompt);
|
|
68
|
+
}
|
|
69
|
+
throw new LLMPromptClient_errors_1.LLMPromptNotFoundError(name);
|
|
70
|
+
}
|
|
29
71
|
shutdown() {
|
|
30
72
|
return Promise.resolve();
|
|
31
73
|
}
|
|
32
74
|
setPrompt(name, seedPrompt) {
|
|
33
75
|
this.prompts.set(name, seedPrompt);
|
|
34
76
|
}
|
|
77
|
+
setChatPrompt(name, seedChatPrompt) {
|
|
78
|
+
this.chatPrompts.set(name, seedChatPrompt);
|
|
79
|
+
}
|
|
35
80
|
clear() {
|
|
36
81
|
this.prompts.clear();
|
|
82
|
+
this.chatPrompts.clear();
|
|
37
83
|
}
|
|
38
84
|
buildPrompt(name, seedPrompt) {
|
|
39
85
|
return {
|
|
@@ -57,5 +103,72 @@ class InMemoryPromptClient {
|
|
|
57
103
|
compile: (variables) => (0, template_1.compileTemplateVariables)(fallback, variables),
|
|
58
104
|
};
|
|
59
105
|
}
|
|
106
|
+
buildChatPrompt(name, seedChatPrompt) {
|
|
107
|
+
return {
|
|
108
|
+
name,
|
|
109
|
+
version: seedChatPrompt.version ?? DEFAULT_SEED_PROMPT_VERSION,
|
|
110
|
+
type: LLMPromptClient_typedefs_1.LLMPromptTypes.Chat,
|
|
111
|
+
messages: seedChatPrompt.messages,
|
|
112
|
+
config: seedChatPrompt.config ?? {},
|
|
113
|
+
isFallback: false,
|
|
114
|
+
compile: (variables) => this.compileMessages(seedChatPrompt.messages, variables),
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
buildFallbackChatPrompt(name, fallback) {
|
|
118
|
+
return {
|
|
119
|
+
name,
|
|
120
|
+
version: FALLBACK_PROMPT_VERSION,
|
|
121
|
+
type: LLMPromptClient_typedefs_1.LLMPromptTypes.Chat,
|
|
122
|
+
messages: fallback,
|
|
123
|
+
config: {},
|
|
124
|
+
isFallback: true,
|
|
125
|
+
compile: (variables) => this.compileMessages(fallback, variables),
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
compileMessages(messages, variables) {
|
|
129
|
+
return messages.map((message) => ({
|
|
130
|
+
role: message.role,
|
|
131
|
+
content: (0, template_1.compileTemplateVariables)(message.content, variables),
|
|
132
|
+
}));
|
|
133
|
+
}
|
|
134
|
+
collectMatchingNames(label) {
|
|
135
|
+
const matchingNames = [];
|
|
136
|
+
const seenNames = new Set();
|
|
137
|
+
const collect = (entries) => {
|
|
138
|
+
entries.forEach(([name, seedPrompt]) => {
|
|
139
|
+
if (seenNames.has(name) || !this.matchesLabel(seedPrompt.labels, label)) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
matchingNames.push(name);
|
|
143
|
+
seenNames.add(name);
|
|
144
|
+
});
|
|
145
|
+
};
|
|
146
|
+
collect([...this.prompts.entries()]);
|
|
147
|
+
collect([...this.chatPrompts.entries()]);
|
|
148
|
+
return matchingNames;
|
|
149
|
+
}
|
|
150
|
+
matchesLabel(labels, label) {
|
|
151
|
+
return (labels ?? [LLMPromptClient_constants_1.DEFAULT_PROMPT_LABEL]).includes(label);
|
|
152
|
+
}
|
|
153
|
+
buildTextPromptRecord(name, seedPrompt) {
|
|
154
|
+
return {
|
|
155
|
+
name,
|
|
156
|
+
type: LLMPromptClient_typedefs_1.LLMPromptTypes.Text,
|
|
157
|
+
version: seedPrompt.version ?? DEFAULT_SEED_PROMPT_VERSION,
|
|
158
|
+
labels: seedPrompt.labels ?? [LLMPromptClient_constants_1.DEFAULT_PROMPT_LABEL],
|
|
159
|
+
config: seedPrompt.config ?? {},
|
|
160
|
+
text: seedPrompt.prompt,
|
|
161
|
+
};
|
|
162
|
+
}
|
|
163
|
+
buildChatPromptRecord(name, seedChatPrompt) {
|
|
164
|
+
return {
|
|
165
|
+
name,
|
|
166
|
+
type: LLMPromptClient_typedefs_1.LLMPromptTypes.Chat,
|
|
167
|
+
version: seedChatPrompt.version ?? DEFAULT_SEED_PROMPT_VERSION,
|
|
168
|
+
labels: seedChatPrompt.labels ?? [LLMPromptClient_constants_1.DEFAULT_PROMPT_LABEL],
|
|
169
|
+
config: seedChatPrompt.config ?? {},
|
|
170
|
+
messages: seedChatPrompt.messages,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
60
173
|
}
|
|
61
174
|
exports.InMemoryPromptClient = InMemoryPromptClient;
|
|
@@ -1,23 +1,21 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createLangfusePromptManagement = void 0;
|
|
4
|
-
const
|
|
4
|
+
const client_1 = require("@langfuse/client");
|
|
5
5
|
const LangfusePrompt_client_1 = require("../../providers/Langfuse/LangfusePrompt.client");
|
|
6
|
-
const
|
|
6
|
+
const MILLISECONDS_PER_SECOND = 1000;
|
|
7
7
|
const createLangfusePromptManagement = (options, logger) => {
|
|
8
|
-
const client = new
|
|
8
|
+
const client = new client_1.LangfuseClient({
|
|
9
9
|
publicKey: options.credentials.publicKey,
|
|
10
10
|
secretKey: options.credentials.secretKey,
|
|
11
11
|
baseUrl: options.credentials.baseUrl,
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
...(options.fetchTimeoutMs !== undefined
|
|
13
|
+
? { timeout: Math.ceil(options.fetchTimeoutMs / MILLISECONDS_PER_SECOND) }
|
|
14
|
+
: {}),
|
|
15
15
|
});
|
|
16
16
|
return {
|
|
17
17
|
promptClient: new LangfusePrompt_client_1.LangfusePromptClient(client, options, logger),
|
|
18
|
-
|
|
19
|
-
flush: () => client.flushAsync(),
|
|
20
|
-
shutdown: () => client.shutdownAsync(),
|
|
18
|
+
shutdown: () => client.shutdown(),
|
|
21
19
|
};
|
|
22
20
|
};
|
|
23
21
|
exports.createLangfusePromptManagement = createLangfusePromptManagement;
|
|
@@ -1 +1,8 @@
|
|
|
1
|
-
|
|
1
|
+
import { type LLMPromptMessage } from '../../LLMPromptClient.typedefs';
|
|
2
|
+
export declare const isLangfusePromptNotFoundError: (error: unknown) => boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Narrows raw Langfuse chat prompt entries down to well-formed
|
|
5
|
+
* `LLMPromptMessage`s, dropping placeholder entries (no `role`/`content`)
|
|
6
|
+
* and any message whose role falls outside `LLMPromptMessageRoles`.
|
|
7
|
+
*/
|
|
8
|
+
export declare const collectPromptMessages: (entries: unknown[]) => LLMPromptMessage[];
|
|
@@ -1,16 +1,32 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
if (typeof error !== 'object' || error === null || !('name' in error)) {
|
|
3
|
+
exports.collectPromptMessages = exports.isLangfusePromptNotFoundError = void 0;
|
|
4
|
+
const LLMPromptClient_typedefs_1 = require("../../LLMPromptClient.typedefs");
|
|
5
|
+
const NOT_FOUND_STATUS_CODE = 404;
|
|
6
|
+
const PROMPT_MESSAGE_ROLES = new Set(Object.values(LLMPromptClient_typedefs_1.LLMPromptMessageRoles));
|
|
7
|
+
const isLangfusePromptNotFoundError = (error) => {
|
|
8
|
+
if (typeof error !== 'object' || error === null || !('statusCode' in error)) {
|
|
10
9
|
return false;
|
|
11
10
|
}
|
|
12
|
-
const
|
|
13
|
-
return
|
|
14
|
-
&& LANGFUSE_INFRA_ERROR_NAMES.includes(errorName);
|
|
11
|
+
const statusCode = error.statusCode;
|
|
12
|
+
return statusCode === NOT_FOUND_STATUS_CODE;
|
|
15
13
|
};
|
|
16
|
-
exports.
|
|
14
|
+
exports.isLangfusePromptNotFoundError = isLangfusePromptNotFoundError;
|
|
15
|
+
const isPromptMessage = (entry) => {
|
|
16
|
+
if (typeof entry !== 'object' || entry === null) {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
const candidate = entry;
|
|
20
|
+
return typeof candidate.role === 'string'
|
|
21
|
+
&& typeof candidate.content === 'string'
|
|
22
|
+
&& PROMPT_MESSAGE_ROLES.has(candidate.role);
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Narrows raw Langfuse chat prompt entries down to well-formed
|
|
26
|
+
* `LLMPromptMessage`s, dropping placeholder entries (no `role`/`content`)
|
|
27
|
+
* and any message whose role falls outside `LLMPromptMessageRoles`.
|
|
28
|
+
*/
|
|
29
|
+
const collectPromptMessages = (entries) => entries
|
|
30
|
+
.filter(isPromptMessage)
|
|
31
|
+
.map((message) => ({ role: message.role, content: message.content }));
|
|
32
|
+
exports.collectPromptMessages = collectPromptMessages;
|
|
@@ -1,16 +1,29 @@
|
|
|
1
|
-
import { type
|
|
2
|
-
import { type GetPromptOptions, type LLMPrompt, type LLMPromptClient } from '../../LLMPromptClient.typedefs';
|
|
1
|
+
import { type LangfuseClient } from '@langfuse/client';
|
|
2
|
+
import { type GetChatPromptOptions, type GetPromptOptions, type GetPromptRecordOptions, type LLMChatPrompt, type LLMPrompt, type LLMPromptClient, type LLMPromptCatalogPage, type LLMPromptRecord, type ListPromptsOptions } from '../../LLMPromptClient.typedefs';
|
|
3
3
|
import { type LangfuseProviderOptions } from '../../providers/Langfuse/Langfuse.typedefs';
|
|
4
4
|
import { type PromptManagementLogger } from '../../utilities/logger';
|
|
5
5
|
export declare class LangfusePromptClient implements LLMPromptClient {
|
|
6
6
|
private readonly client;
|
|
7
7
|
private readonly providerOptions;
|
|
8
8
|
private readonly logger;
|
|
9
|
-
constructor(client:
|
|
9
|
+
constructor(client: LangfuseClient, providerOptions: LangfuseProviderOptions, logger: PromptManagementLogger);
|
|
10
10
|
getPrompt(name: string, options?: GetPromptOptions): Promise<LLMPrompt>;
|
|
11
|
+
getChatPrompt(name: string, options?: GetChatPromptOptions): Promise<LLMChatPrompt>;
|
|
12
|
+
listPrompts(options: ListPromptsOptions): Promise<LLMPromptCatalogPage>;
|
|
13
|
+
getPromptRecord(name: string, options: GetPromptRecordOptions): Promise<LLMPromptRecord>;
|
|
11
14
|
shutdown(): Promise<void>;
|
|
12
|
-
private
|
|
13
|
-
private
|
|
15
|
+
private fetchTextPrompt;
|
|
16
|
+
private fetchChatPrompt;
|
|
17
|
+
private resolveSelectionOptions;
|
|
18
|
+
private resolveCacheTtlSeconds;
|
|
19
|
+
private buildTextFallbackPrompt;
|
|
20
|
+
private resolveFallbackLabels;
|
|
21
|
+
private buildChatFallbackPrompt;
|
|
22
|
+
private classifyFetchError;
|
|
14
23
|
private ensureTextPrompt;
|
|
24
|
+
private ensureChatPrompt;
|
|
15
25
|
private reportPromptResolution;
|
|
26
|
+
private reportSkippedChatEntries;
|
|
27
|
+
private fetchRawPrompt;
|
|
28
|
+
private buildRequestOptions;
|
|
16
29
|
}
|
|
@@ -1,11 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.LangfusePromptClient = void 0;
|
|
4
|
+
const client_1 = require("@langfuse/client");
|
|
5
|
+
const LLMPromptClient_typedefs_1 = require("../../LLMPromptClient.typedefs");
|
|
4
6
|
const LLMPromptClient_constants_1 = require("../../LLMPromptClient.constants");
|
|
5
7
|
const LLMPromptClient_errors_1 = require("../../LLMPromptClient.errors");
|
|
6
8
|
const Langfuse_helpers_1 = require("../../providers/Langfuse/Langfuse.helpers");
|
|
7
9
|
const LangfusePrompt_1 = require("../../providers/Langfuse/LangfusePrompt");
|
|
8
10
|
const LANGFUSE_TEXT_PROMPT_TYPE = 'text';
|
|
11
|
+
const LANGFUSE_CHAT_PROMPT_TYPE = 'chat';
|
|
12
|
+
const MILLISECONDS_PER_SECOND = 1000;
|
|
9
13
|
class LangfusePromptClient {
|
|
10
14
|
constructor(client, providerOptions, logger) {
|
|
11
15
|
this.client = client;
|
|
@@ -13,42 +17,102 @@ class LangfusePromptClient {
|
|
|
13
17
|
this.logger = logger;
|
|
14
18
|
}
|
|
15
19
|
async getPrompt(name, options) {
|
|
16
|
-
const nativePrompt = await this.
|
|
20
|
+
const nativePrompt = await this.fetchTextPrompt(name, options);
|
|
17
21
|
this.ensureTextPrompt(name, nativePrompt);
|
|
18
22
|
this.reportPromptResolution(name, nativePrompt);
|
|
19
23
|
return new LangfusePrompt_1.LangfusePrompt(nativePrompt);
|
|
20
24
|
}
|
|
25
|
+
async getChatPrompt(name, options) {
|
|
26
|
+
const nativePrompt = await this.fetchChatPrompt(name, options);
|
|
27
|
+
this.ensureChatPrompt(name, nativePrompt);
|
|
28
|
+
this.reportPromptResolution(name, nativePrompt);
|
|
29
|
+
this.reportSkippedChatEntries(name, nativePrompt);
|
|
30
|
+
return new LangfusePrompt_1.LangfuseChatPrompt(nativePrompt);
|
|
31
|
+
}
|
|
32
|
+
async listPrompts(options) {
|
|
33
|
+
try {
|
|
34
|
+
const promptListPage = await this.client.api.prompts.list({
|
|
35
|
+
label: options.label,
|
|
36
|
+
page: options.page ?? LLMPromptClient_constants_1.DEFAULT_PROMPT_LIST_PAGE,
|
|
37
|
+
limit: options.pageSize ?? LLMPromptClient_constants_1.DEFAULT_PROMPT_LIST_PAGE_SIZE,
|
|
38
|
+
}, this.buildRequestOptions());
|
|
39
|
+
return {
|
|
40
|
+
promptNames: promptListPage.data.map((promptSummary) => promptSummary.name),
|
|
41
|
+
page: promptListPage.meta.page,
|
|
42
|
+
totalPages: promptListPage.meta.totalPages,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
catch (error) {
|
|
46
|
+
this.logger.error('Failed to list Langfuse prompts', {
|
|
47
|
+
error,
|
|
48
|
+
label: options.label,
|
|
49
|
+
});
|
|
50
|
+
throw new LLMPromptClient_errors_1.LLMPromptListError(options.label, error);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
async getPromptRecord(name, options) {
|
|
54
|
+
const rawPrompt = await this.fetchRawPrompt(name, options);
|
|
55
|
+
if (rawPrompt.type === LANGFUSE_CHAT_PROMPT_TYPE) {
|
|
56
|
+
return {
|
|
57
|
+
name: rawPrompt.name,
|
|
58
|
+
type: LLMPromptClient_typedefs_1.LLMPromptTypes.Chat,
|
|
59
|
+
version: rawPrompt.version,
|
|
60
|
+
labels: rawPrompt.labels,
|
|
61
|
+
config: rawPrompt.config,
|
|
62
|
+
messages: (0, Langfuse_helpers_1.collectPromptMessages)(rawPrompt.prompt),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return {
|
|
66
|
+
name: rawPrompt.name,
|
|
67
|
+
type: LLMPromptClient_typedefs_1.LLMPromptTypes.Text,
|
|
68
|
+
version: rawPrompt.version,
|
|
69
|
+
labels: rawPrompt.labels,
|
|
70
|
+
config: rawPrompt.config,
|
|
71
|
+
text: rawPrompt.prompt,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
21
74
|
shutdown() {
|
|
22
|
-
return this.client.
|
|
75
|
+
return this.client.shutdown();
|
|
23
76
|
}
|
|
24
|
-
async
|
|
77
|
+
async fetchTextPrompt(name, options) {
|
|
25
78
|
try {
|
|
26
|
-
|
|
27
|
-
...this.
|
|
28
|
-
cacheTtlSeconds: options
|
|
29
|
-
?? this.providerOptions.defaultCacheTtlSeconds
|
|
30
|
-
?? LLMPromptClient_constants_1.DEFAULT_PROMPT_CACHE_TTL_SECONDS,
|
|
79
|
+
return await this.client.prompt.get(name, {
|
|
80
|
+
...this.resolveSelectionOptions(options),
|
|
81
|
+
cacheTtlSeconds: this.resolveCacheTtlSeconds(options),
|
|
31
82
|
fallback: options?.fallback,
|
|
32
83
|
maxRetries: this.providerOptions.maxRetries,
|
|
33
84
|
fetchTimeoutMs: this.providerOptions.fetchTimeoutMs,
|
|
34
85
|
type: LANGFUSE_TEXT_PROMPT_TYPE,
|
|
35
86
|
});
|
|
36
|
-
return nativePrompt;
|
|
37
87
|
}
|
|
38
88
|
catch (error) {
|
|
39
|
-
if (
|
|
40
|
-
this.
|
|
41
|
-
error,
|
|
42
|
-
promptName: name,
|
|
43
|
-
});
|
|
44
|
-
throw new LLMPromptClient_errors_1.LLMPromptFetchError(name, error);
|
|
89
|
+
if (options?.fallback !== undefined) {
|
|
90
|
+
return this.buildTextFallbackPrompt(name, options.fallback, options);
|
|
45
91
|
}
|
|
46
|
-
throw
|
|
92
|
+
throw this.classifyFetchError(name, error);
|
|
47
93
|
}
|
|
48
94
|
}
|
|
49
|
-
|
|
95
|
+
async fetchChatPrompt(name, options) {
|
|
96
|
+
try {
|
|
97
|
+
return await this.client.prompt.get(name, {
|
|
98
|
+
...this.resolveSelectionOptions(options),
|
|
99
|
+
cacheTtlSeconds: this.resolveCacheTtlSeconds(options),
|
|
100
|
+
fallback: options?.fallback,
|
|
101
|
+
maxRetries: this.providerOptions.maxRetries,
|
|
102
|
+
fetchTimeoutMs: this.providerOptions.fetchTimeoutMs,
|
|
103
|
+
type: LANGFUSE_CHAT_PROMPT_TYPE,
|
|
104
|
+
});
|
|
105
|
+
}
|
|
106
|
+
catch (error) {
|
|
107
|
+
if (options?.fallback !== undefined) {
|
|
108
|
+
return this.buildChatFallbackPrompt(name, options.fallback, options);
|
|
109
|
+
}
|
|
110
|
+
throw this.classifyFetchError(name, error);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
resolveSelectionOptions(options) {
|
|
50
114
|
if (options?.version !== undefined) {
|
|
51
|
-
return {};
|
|
115
|
+
return { version: options.version };
|
|
52
116
|
}
|
|
53
117
|
return {
|
|
54
118
|
label: options?.label
|
|
@@ -56,6 +120,54 @@ class LangfusePromptClient {
|
|
|
56
120
|
?? LLMPromptClient_constants_1.DEFAULT_PROMPT_LABEL,
|
|
57
121
|
};
|
|
58
122
|
}
|
|
123
|
+
resolveCacheTtlSeconds(options) {
|
|
124
|
+
return options?.cacheTtlSeconds
|
|
125
|
+
?? this.providerOptions.defaultCacheTtlSeconds
|
|
126
|
+
?? LLMPromptClient_constants_1.DEFAULT_PROMPT_CACHE_TTL_SECONDS;
|
|
127
|
+
}
|
|
128
|
+
buildTextFallbackPrompt(name, fallback, options) {
|
|
129
|
+
return new client_1.TextPromptClient({
|
|
130
|
+
name,
|
|
131
|
+
version: options?.version ?? 0,
|
|
132
|
+
labels: this.resolveFallbackLabels(options),
|
|
133
|
+
tags: [],
|
|
134
|
+
config: {},
|
|
135
|
+
type: LANGFUSE_TEXT_PROMPT_TYPE,
|
|
136
|
+
prompt: fallback,
|
|
137
|
+
}, true);
|
|
138
|
+
}
|
|
139
|
+
resolveFallbackLabels(options) {
|
|
140
|
+
const selection = this.resolveSelectionOptions(options);
|
|
141
|
+
return selection.label === undefined ? [] : [selection.label];
|
|
142
|
+
}
|
|
143
|
+
buildChatFallbackPrompt(name, fallback, options) {
|
|
144
|
+
return new client_1.ChatPromptClient({
|
|
145
|
+
name,
|
|
146
|
+
version: options?.version ?? 0,
|
|
147
|
+
labels: this.resolveFallbackLabels(options),
|
|
148
|
+
tags: [],
|
|
149
|
+
config: {},
|
|
150
|
+
type: LANGFUSE_CHAT_PROMPT_TYPE,
|
|
151
|
+
prompt: fallback.map((message) => ({
|
|
152
|
+
role: message.role,
|
|
153
|
+
content: message.content,
|
|
154
|
+
})),
|
|
155
|
+
}, true);
|
|
156
|
+
}
|
|
157
|
+
classifyFetchError(name, error) {
|
|
158
|
+
if ((0, Langfuse_helpers_1.isLangfusePromptNotFoundError)(error)) {
|
|
159
|
+
this.logger.warn('Langfuse prompt not found', {
|
|
160
|
+
error,
|
|
161
|
+
promptName: name,
|
|
162
|
+
});
|
|
163
|
+
return new LLMPromptClient_errors_1.LLMPromptNotFoundError(name, error);
|
|
164
|
+
}
|
|
165
|
+
this.logger.error('Failed to fetch Langfuse prompt', {
|
|
166
|
+
error,
|
|
167
|
+
promptName: name,
|
|
168
|
+
});
|
|
169
|
+
return new LLMPromptClient_errors_1.LLMPromptFetchError(name, error);
|
|
170
|
+
}
|
|
59
171
|
ensureTextPrompt(name, nativePrompt) {
|
|
60
172
|
if (nativePrompt.type !== LANGFUSE_TEXT_PROMPT_TYPE) {
|
|
61
173
|
this.logger.error('Langfuse prompt is not a text prompt', {
|
|
@@ -65,6 +177,15 @@ class LangfusePromptClient {
|
|
|
65
177
|
throw new LLMPromptClient_errors_1.LLMPromptFetchError(name);
|
|
66
178
|
}
|
|
67
179
|
}
|
|
180
|
+
ensureChatPrompt(name, nativePrompt) {
|
|
181
|
+
if (nativePrompt.type !== LANGFUSE_CHAT_PROMPT_TYPE) {
|
|
182
|
+
this.logger.error('Langfuse prompt is not a chat prompt', {
|
|
183
|
+
promptName: name,
|
|
184
|
+
promptType: nativePrompt.type,
|
|
185
|
+
});
|
|
186
|
+
throw new LLMPromptClient_errors_1.LLMPromptFetchError(name);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
68
189
|
reportPromptResolution(name, nativePrompt) {
|
|
69
190
|
if (nativePrompt.isFallback) {
|
|
70
191
|
this.logger.warn('Langfuse prompt resolved to the provided fallback', {
|
|
@@ -77,5 +198,35 @@ class LangfusePromptClient {
|
|
|
77
198
|
promptVersion: nativePrompt.version,
|
|
78
199
|
});
|
|
79
200
|
}
|
|
201
|
+
reportSkippedChatEntries(name, nativePrompt) {
|
|
202
|
+
const skippedEntryCount = nativePrompt.prompt.length
|
|
203
|
+
- (0, Langfuse_helpers_1.collectPromptMessages)(nativePrompt.prompt).length;
|
|
204
|
+
if (skippedEntryCount > 0) {
|
|
205
|
+
this.logger.warn('Langfuse chat prompt contains unsupported entries', {
|
|
206
|
+
promptName: name,
|
|
207
|
+
skippedEntryCount,
|
|
208
|
+
});
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
async fetchRawPrompt(name, options) {
|
|
212
|
+
try {
|
|
213
|
+
return await this.client.api.prompts.get(name, { label: options.label }, this.buildRequestOptions());
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
throw this.classifyFetchError(name, error);
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
buildRequestOptions() {
|
|
220
|
+
return {
|
|
221
|
+
...(this.providerOptions.maxRetries !== undefined
|
|
222
|
+
? { maxRetries: this.providerOptions.maxRetries }
|
|
223
|
+
: {}),
|
|
224
|
+
...(this.providerOptions.fetchTimeoutMs !== undefined
|
|
225
|
+
? {
|
|
226
|
+
timeoutInSeconds: Math.ceil(this.providerOptions.fetchTimeoutMs / MILLISECONDS_PER_SECOND),
|
|
227
|
+
}
|
|
228
|
+
: {}),
|
|
229
|
+
};
|
|
230
|
+
}
|
|
80
231
|
}
|
|
81
232
|
exports.LangfusePromptClient = LangfusePromptClient;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type TextPromptClient } from 'langfuse';
|
|
2
|
-
import { LLMPromptTypes, type LLMPrompt } from '../../LLMPromptClient.typedefs';
|
|
1
|
+
import { type ChatPromptClient, type TextPromptClient } from '@langfuse/client';
|
|
2
|
+
import { LLMPromptTypes, type LLMChatPrompt, type LLMPrompt, type LLMPromptMessage } from '../../LLMPromptClient.typedefs';
|
|
3
3
|
export declare class LangfusePrompt implements LLMPrompt {
|
|
4
4
|
readonly nativePrompt: TextPromptClient;
|
|
5
5
|
readonly type = LLMPromptTypes.Text;
|
|
@@ -11,3 +11,14 @@ export declare class LangfusePrompt implements LLMPrompt {
|
|
|
11
11
|
get isFallback(): boolean;
|
|
12
12
|
compile(variables?: Record<string, string>): string;
|
|
13
13
|
}
|
|
14
|
+
export declare class LangfuseChatPrompt implements LLMChatPrompt {
|
|
15
|
+
readonly nativePrompt: ChatPromptClient;
|
|
16
|
+
readonly type = LLMPromptTypes.Chat;
|
|
17
|
+
constructor(nativePrompt: ChatPromptClient);
|
|
18
|
+
get name(): string;
|
|
19
|
+
get version(): number;
|
|
20
|
+
get messages(): LLMPromptMessage[];
|
|
21
|
+
get config(): unknown;
|
|
22
|
+
get isFallback(): boolean;
|
|
23
|
+
compile(variables?: Record<string, string>): LLMPromptMessage[];
|
|
24
|
+
}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LangfusePrompt = void 0;
|
|
3
|
+
exports.LangfuseChatPrompt = exports.LangfusePrompt = void 0;
|
|
4
4
|
const LLMPromptClient_typedefs_1 = require("../../LLMPromptClient.typedefs");
|
|
5
|
+
const Langfuse_helpers_1 = require("../../providers/Langfuse/Langfuse.helpers");
|
|
5
6
|
class LangfusePrompt {
|
|
6
7
|
constructor(nativePrompt) {
|
|
7
8
|
this.nativePrompt = nativePrompt;
|
|
@@ -27,3 +28,20 @@ class LangfusePrompt {
|
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
exports.LangfusePrompt = LangfusePrompt;
|
|
31
|
+
class LangfuseChatPrompt {
|
|
32
|
+
constructor(nativePrompt) {
|
|
33
|
+
this.nativePrompt = nativePrompt;
|
|
34
|
+
this.type = LLMPromptClient_typedefs_1.LLMPromptTypes.Chat;
|
|
35
|
+
}
|
|
36
|
+
get name() { return this.nativePrompt.name; }
|
|
37
|
+
get version() { return this.nativePrompt.version; }
|
|
38
|
+
get messages() {
|
|
39
|
+
return (0, Langfuse_helpers_1.collectPromptMessages)(this.nativePrompt.prompt);
|
|
40
|
+
}
|
|
41
|
+
get config() { return this.nativePrompt.config; }
|
|
42
|
+
get isFallback() { return this.nativePrompt.isFallback; }
|
|
43
|
+
compile(variables) {
|
|
44
|
+
return (0, Langfuse_helpers_1.collectPromptMessages)(this.nativePrompt.compile(variables));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
exports.LangfuseChatPrompt = LangfuseChatPrompt;
|
package/dist/utilities/index.js
CHANGED
|
@@ -16,4 +16,3 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("../utilities/logger"), exports);
|
|
18
18
|
__exportStar(require("../utilities/template"), exports);
|
|
19
|
-
__exportStar(require("../utilities/usageDetails"), exports);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mate-academy/prompt-client",
|
|
3
|
-
"version": "
|
|
4
|
-
"description": "Provider-agnostic LLM prompt management
|
|
3
|
+
"version": "2.0.0",
|
|
4
|
+
"description": "Provider-agnostic LLM prompt management client (Langfuse, InMemory)",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
@@ -25,7 +25,6 @@
|
|
|
25
25
|
"llm",
|
|
26
26
|
"prompt",
|
|
27
27
|
"langfuse",
|
|
28
|
-
"tracing",
|
|
29
28
|
"mate-academy"
|
|
30
29
|
],
|
|
31
30
|
"author": "Mate academy developers",
|
|
@@ -49,7 +48,7 @@
|
|
|
49
48
|
}
|
|
50
49
|
},
|
|
51
50
|
"dependencies": {
|
|
52
|
-
"langfuse": "^
|
|
51
|
+
"@langfuse/client": "^5.4.1"
|
|
53
52
|
},
|
|
54
53
|
"devDependencies": {
|
|
55
54
|
"@eslint/js": "^9.36.0",
|
package/dist/LLMTracer.errors.js
DELETED
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.LLMTracerError = void 0;
|
|
4
|
-
class LLMTracerError extends Error {
|
|
5
|
-
constructor(message, cause) {
|
|
6
|
-
super(message);
|
|
7
|
-
this.cause = cause;
|
|
8
|
-
this.name = 'LLMTracerError';
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
exports.LLMTracerError = LLMTracerError;
|