@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.
Files changed (37) hide show
  1. package/README.md +120 -69
  2. package/dist/LLMPromptClient.constants.d.ts +2 -0
  3. package/dist/LLMPromptClient.constants.js +3 -1
  4. package/dist/LLMPromptClient.errors.d.ts +5 -0
  5. package/dist/LLMPromptClient.errors.js +10 -1
  6. package/dist/LLMPromptClient.typedefs.d.ts +88 -3
  7. package/dist/LLMPromptClient.typedefs.js +8 -1
  8. package/dist/PromptManagement.typedefs.d.ts +6 -5
  9. package/dist/index.d.ts +0 -4
  10. package/dist/index.js +0 -4
  11. package/dist/providers/InMemory/InMemory.factory.js +1 -8
  12. package/dist/providers/InMemory/InMemory.typedefs.d.ts +9 -13
  13. package/dist/providers/InMemory/InMemoryPrompt.client.d.ts +14 -2
  14. package/dist/providers/InMemory/InMemoryPrompt.client.js +113 -0
  15. package/dist/providers/Langfuse/Langfuse.factory.js +7 -9
  16. package/dist/providers/Langfuse/Langfuse.helpers.d.ts +8 -1
  17. package/dist/providers/Langfuse/Langfuse.helpers.js +27 -11
  18. package/dist/providers/Langfuse/Langfuse.typedefs.d.ts +0 -2
  19. package/dist/providers/Langfuse/LangfusePrompt.client.d.ts +18 -5
  20. package/dist/providers/Langfuse/LangfusePrompt.client.js +169 -18
  21. package/dist/providers/Langfuse/LangfusePrompt.d.ts +13 -2
  22. package/dist/providers/Langfuse/LangfusePrompt.js +19 -1
  23. package/dist/utilities/index.d.ts +0 -1
  24. package/dist/utilities/index.js +0 -1
  25. package/package.json +3 -4
  26. package/dist/LLMTracer.errors.d.ts +0 -4
  27. package/dist/LLMTracer.errors.js +0 -11
  28. package/dist/LLMTracer.typedefs.d.ts +0 -45
  29. package/dist/LLMTracer.typedefs.js +0 -2
  30. package/dist/providers/InMemory/InMemoryTracer.client.d.ts +0 -15
  31. package/dist/providers/InMemory/InMemoryTracer.client.js +0 -63
  32. package/dist/providers/Langfuse/LangfuseTracer.client.d.ts +0 -13
  33. package/dist/providers/Langfuse/LangfuseTracer.client.js +0 -49
  34. package/dist/utilities/usageDetails/index.d.ts +0 -1
  35. package/dist/utilities/usageDetails/index.js +0 -17
  36. package/dist/utilities/usageDetails/usageDetails.helpers.d.ts +0 -17
  37. 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 langfuse_1 = require("langfuse");
4
+ const client_1 = require("@langfuse/client");
5
5
  const LangfusePrompt_client_1 = require("../../providers/Langfuse/LangfusePrompt.client");
6
- const LangfuseTracer_client_1 = require("../../providers/Langfuse/LangfuseTracer.client");
6
+ const MILLISECONDS_PER_SECOND = 1000;
7
7
  const createLangfusePromptManagement = (options, logger) => {
8
- const client = new langfuse_1.Langfuse({
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
- requestTimeout: options.fetchTimeoutMs,
13
- flushAt: options.flushAt,
14
- flushInterval: options.flushIntervalMs,
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
- tracer: new LangfuseTracer_client_1.LangfuseTracer(client, logger),
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
- export declare const isLangfuseInfraError: (error: unknown) => boolean;
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.isLangfuseInfraError = void 0;
4
- const LANGFUSE_INFRA_ERROR_NAMES = [
5
- 'LangfuseFetchHttpError',
6
- 'LangfuseFetchNetworkError',
7
- ];
8
- const isLangfuseInfraError = (error) => {
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 errorName = error.name;
13
- return typeof errorName === 'string'
14
- && LANGFUSE_INFRA_ERROR_NAMES.includes(errorName);
11
+ const statusCode = error.statusCode;
12
+ return statusCode === NOT_FOUND_STATUS_CODE;
15
13
  };
16
- exports.isLangfuseInfraError = isLangfuseInfraError;
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;
@@ -9,6 +9,4 @@ export interface LangfuseProviderOptions {
9
9
  defaultCacheTtlSeconds?: number;
10
10
  fetchTimeoutMs?: number;
11
11
  maxRetries?: number;
12
- flushAt?: number;
13
- flushIntervalMs?: number;
14
12
  }
@@ -1,16 +1,29 @@
1
- import { type Langfuse } from 'langfuse';
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: Langfuse, providerOptions: LangfuseProviderOptions, logger: PromptManagementLogger);
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 fetchPrompt;
13
- private resolveLabelOption;
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.fetchPrompt(name, options);
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.shutdownAsync();
75
+ return this.client.shutdown();
23
76
  }
24
- async fetchPrompt(name, options) {
77
+ async fetchTextPrompt(name, options) {
25
78
  try {
26
- const nativePrompt = await this.client.getPrompt(name, options?.version, {
27
- ...this.resolveLabelOption(options),
28
- cacheTtlSeconds: options?.cacheTtlSeconds
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 ((0, Langfuse_helpers_1.isLangfuseInfraError)(error)) {
40
- this.logger.error('Failed to fetch Langfuse prompt', {
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 new LLMPromptClient_errors_1.LLMPromptNotFoundError(name, error);
92
+ throw this.classifyFetchError(name, error);
47
93
  }
48
94
  }
49
- resolveLabelOption(options) {
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;
@@ -1,3 +1,2 @@
1
1
  export * from '../utilities/logger';
2
2
  export * from '../utilities/template';
3
- export * from '../utilities/usageDetails';
@@ -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": "1.0.0",
4
- "description": "Provider-agnostic LLM prompt management and tracing client (Langfuse, InMemory)",
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": "^3.38.20"
51
+ "@langfuse/client": "^5.4.1"
53
52
  },
54
53
  "devDependencies": {
55
54
  "@eslint/js": "^9.36.0",
@@ -1,4 +0,0 @@
1
- export declare class LLMTracerError extends Error {
2
- readonly cause?: unknown | undefined;
3
- constructor(message: string, cause?: unknown | undefined);
4
- }
@@ -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;