promptfoo 0.20.0 → 0.21.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 (184) hide show
  1. package/README.md +1 -1
  2. package/dist/package.json +4 -4
  3. package/dist/src/assertions.d.ts.map +1 -1
  4. package/dist/src/assertions.js +5 -0
  5. package/dist/src/assertions.js.map +1 -1
  6. package/dist/src/evaluator.js +1 -1
  7. package/dist/src/evaluator.js.map +1 -1
  8. package/dist/src/index.d.ts +1 -5
  9. package/dist/src/index.d.ts.map +1 -1
  10. package/dist/src/index.js +1 -1
  11. package/dist/src/index.js.map +1 -1
  12. package/dist/src/matchers.d.ts +3 -2
  13. package/dist/src/matchers.d.ts.map +1 -1
  14. package/dist/src/matchers.js +37 -9
  15. package/dist/src/matchers.js.map +1 -1
  16. package/dist/src/providers/anthropic.d.ts +5 -3
  17. package/dist/src/providers/anthropic.d.ts.map +1 -1
  18. package/dist/src/providers/anthropic.js +8 -10
  19. package/dist/src/providers/anthropic.js.map +1 -1
  20. package/dist/src/providers/azureopenai.d.ts +9 -8
  21. package/dist/src/providers/azureopenai.d.ts.map +1 -1
  22. package/dist/src/providers/azureopenai.js +33 -36
  23. package/dist/src/providers/azureopenai.js.map +1 -1
  24. package/dist/src/providers/openai.d.ts +12 -12
  25. package/dist/src/providers/openai.d.ts.map +1 -1
  26. package/dist/src/providers/openai.js +54 -65
  27. package/dist/src/providers/openai.js.map +1 -1
  28. package/dist/src/providers/replicate.d.ts +4 -2
  29. package/dist/src/providers/replicate.d.ts.map +1 -1
  30. package/dist/src/providers/replicate.js +10 -8
  31. package/dist/src/providers/replicate.js.map +1 -1
  32. package/dist/src/providers/webhook.d.ts +9 -0
  33. package/dist/src/providers/webhook.d.ts.map +1 -0
  34. package/dist/src/providers/webhook.js +54 -0
  35. package/dist/src/providers/webhook.js.map +1 -0
  36. package/dist/src/providers.d.ts +1 -1
  37. package/dist/src/providers.d.ts.map +1 -1
  38. package/dist/src/providers.js +36 -28
  39. package/dist/src/providers.js.map +1 -1
  40. package/dist/src/suggestions.d.ts.map +1 -1
  41. package/dist/src/suggestions.js +1 -3
  42. package/dist/src/suggestions.js.map +1 -1
  43. package/dist/src/types.d.ts +7 -1
  44. package/dist/src/types.d.ts.map +1 -1
  45. package/dist/src/util.js +1 -1
  46. package/dist/src/util.js.map +1 -1
  47. package/dist/src/web/nextui/404/index.html +1 -1
  48. package/dist/src/web/nextui/404.html +1 -1
  49. package/dist/src/web/nextui/_next/static/Bl3o5lF4ON7Fjki46lPhr/_buildManifest.js +1 -0
  50. package/dist/src/web/nextui/_next/static/chunks/226-7bbb6c98a19542fd.js +37 -0
  51. package/dist/src/web/nextui/_next/static/chunks/249-ea9c0f034888ccff.js +125 -0
  52. package/dist/src/web/nextui/_next/static/chunks/339-501c32916b785ef1.js +1 -0
  53. package/dist/src/web/nextui/_next/static/chunks/365-e426ea5bc7e815fc.js +8 -0
  54. package/dist/src/web/nextui/_next/static/chunks/396-0a51429a01e24cdd.js +1 -0
  55. package/dist/src/web/nextui/_next/static/chunks/596-297f7ff4a0436e87.js +25 -0
  56. package/dist/src/web/nextui/_next/static/chunks/613-572c22424de64659.js +1 -0
  57. package/dist/src/web/nextui/_next/static/chunks/706-ae1d3352d28419e9.js +9 -0
  58. package/dist/src/web/nextui/_next/static/chunks/891-7035926a62c1c4e0.js +1 -0
  59. package/dist/src/web/nextui/_next/static/chunks/app/eval/[id]/not-found-366629541fd598e9.js +1 -0
  60. package/dist/src/web/nextui/_next/static/chunks/app/eval/[id]/page-319d2ee38d37574e.js +1 -0
  61. package/dist/src/web/nextui/_next/static/chunks/app/eval/page-a6b1ff91723b7beb.js +1 -0
  62. package/dist/src/web/nextui/_next/static/chunks/app/layout-024c4adc71c9feb0.js +1 -0
  63. package/dist/src/web/nextui/_next/static/chunks/app/page-1ae60660130041b2.js +1 -0
  64. package/dist/src/web/nextui/_next/static/chunks/app/setup/page-6ef16148040bf4f4.js +1 -0
  65. package/dist/src/web/nextui/_next/static/chunks/{ca377847-cb6ae6a6a073aebb.js → ca377847-26b462611379a4f7.js} +3 -3
  66. package/dist/src/web/nextui/_next/static/chunks/{fd9d1056-ac777be631f5a9e9.js → fd9d1056-fba4b53a2f01213b.js} +1 -1
  67. package/dist/src/web/nextui/_next/static/chunks/framework-8883d1e9be70c3da.js +25 -0
  68. package/dist/src/web/nextui/_next/static/chunks/main-8ea85465d428ecfe.js +1 -0
  69. package/dist/src/web/nextui/_next/static/chunks/main-app-581ccf0003955b21.js +1 -0
  70. package/dist/src/web/nextui/_next/static/chunks/pages/_app-52924524f99094ab.js +1 -0
  71. package/dist/src/web/nextui/_next/static/chunks/pages/_error-c92d5c4bb2b49926.js +1 -0
  72. package/dist/src/web/nextui/_next/static/chunks/webpack-55c264ce2fd85eb7.js +1 -0
  73. package/dist/src/web/nextui/_next/static/css/4d399fceacd06992.css +1 -0
  74. package/dist/src/web/nextui/eval/index.html +1 -1
  75. package/dist/src/web/nextui/eval/index.txt +6 -6
  76. package/dist/src/web/nextui/index.html +1 -1
  77. package/dist/src/web/nextui/index.txt +5 -5
  78. package/dist/src/web/nextui/setup/index.html +27 -1
  79. package/dist/src/web/nextui/setup/index.txt +9 -9
  80. package/dist/src/web/server.d.ts.map +1 -1
  81. package/dist/src/web/server.js +9 -5
  82. package/dist/src/web/server.js.map +1 -1
  83. package/package.json +4 -4
  84. package/dist/src/web/nextui/_next/static/US6gOx8LHTX_Hzm9aYNrC/_buildManifest.js +0 -1
  85. package/dist/src/web/nextui/_next/static/chunks/339-4fc8a80fa840e771.js +0 -1
  86. package/dist/src/web/nextui/_next/static/chunks/373-8a280796c0f2d1af.js +0 -1
  87. package/dist/src/web/nextui/_next/static/chunks/583-125d32af505e9bc4.js +0 -1
  88. package/dist/src/web/nextui/_next/static/chunks/596-07e4a23a5c6cdf04.js +0 -25
  89. package/dist/src/web/nextui/_next/static/chunks/658-a62210d07dc4dcb6.js +0 -15
  90. package/dist/src/web/nextui/_next/static/chunks/707-699cbd84b259c37b.js +0 -37
  91. package/dist/src/web/nextui/_next/static/chunks/858-ceb6fa22e614492b.js +0 -125
  92. package/dist/src/web/nextui/_next/static/chunks/891-3000ea7c0a292558.js +0 -1
  93. package/dist/src/web/nextui/_next/static/chunks/app/eval/[id]/not-found-50e40614fa05600e.js +0 -1
  94. package/dist/src/web/nextui/_next/static/chunks/app/eval/[id]/page-c19c44ed1b2dfb58.js +0 -1
  95. package/dist/src/web/nextui/_next/static/chunks/app/eval/page-d4a1813b2f8c4532.js +0 -1
  96. package/dist/src/web/nextui/_next/static/chunks/app/layout-664a8d716d2d24b1.js +0 -1
  97. package/dist/src/web/nextui/_next/static/chunks/app/page-1f8ef6a00a2355f0.js +0 -1
  98. package/dist/src/web/nextui/_next/static/chunks/app/setup/page-182018a3c6397345.js +0 -1
  99. package/dist/src/web/nextui/_next/static/chunks/framework-43665103d101a22d.js +0 -25
  100. package/dist/src/web/nextui/_next/static/chunks/main-50cc0a98559591ce.js +0 -1
  101. package/dist/src/web/nextui/_next/static/chunks/main-app-c9dc13756d166550.js +0 -1
  102. package/dist/src/web/nextui/_next/static/chunks/pages/_app-6b79a29ad0d63b21.js +0 -1
  103. package/dist/src/web/nextui/_next/static/chunks/pages/_error-9aeb3e4d490fe4b8.js +0 -1
  104. package/dist/src/web/nextui/_next/static/chunks/webpack-6e474e42be502dd7.js +0 -1
  105. package/dist/src/web/nextui/_next/static/css/a35c840ac696f161.css +0 -1
  106. package/dist/src/web/nextui/api +0 -1
  107. package/src/__mocks__/esm.ts +0 -3
  108. package/src/assertions.ts +0 -580
  109. package/src/cache.ts +0 -109
  110. package/src/esm.ts +0 -13
  111. package/src/evaluator.ts +0 -500
  112. package/src/index.ts +0 -52
  113. package/src/logger.ts +0 -46
  114. package/src/main.ts +0 -442
  115. package/src/matchers.ts +0 -120
  116. package/src/onboarding.ts +0 -69
  117. package/src/prompts.ts +0 -39
  118. package/src/providers/anthropic.ts +0 -88
  119. package/src/providers/azureopenai.ts +0 -299
  120. package/src/providers/llama.ts +0 -95
  121. package/src/providers/localai.ts +0 -111
  122. package/src/providers/ollama.ts +0 -89
  123. package/src/providers/openai.ts +0 -337
  124. package/src/providers/replicate.ts +0 -99
  125. package/src/providers/scriptCompletion.ts +0 -35
  126. package/src/providers/shared.ts +0 -34
  127. package/src/providers.ts +0 -192
  128. package/src/share.ts +0 -27
  129. package/src/suggestions.ts +0 -63
  130. package/src/table.ts +0 -43
  131. package/src/tableOutput.html +0 -52
  132. package/src/telemetry.ts +0 -70
  133. package/src/types.ts +0 -299
  134. package/src/updates.ts +0 -46
  135. package/src/util.ts +0 -543
  136. package/src/web/nextui/.eslintrc.json +0 -3
  137. package/src/web/nextui/next.config.js +0 -14
  138. package/src/web/nextui/package-lock.json +0 -4644
  139. package/src/web/nextui/package.json +0 -47
  140. package/src/web/nextui/public/favicon.ico +0 -0
  141. package/src/web/nextui/public/logo.svg +0 -30
  142. package/src/web/nextui/src/app/Home.css +0 -3
  143. package/src/web/nextui/src/app/api/route.ts +0 -6
  144. package/src/web/nextui/src/app/components/DarkMode.css +0 -22
  145. package/src/web/nextui/src/app/components/DarkMode.tsx +0 -17
  146. package/src/web/nextui/src/app/components/Logo.css +0 -32
  147. package/src/web/nextui/src/app/components/Logo.tsx +0 -11
  148. package/src/web/nextui/src/app/components/PageShell.css +0 -33
  149. package/src/web/nextui/src/app/components/PageShell.tsx +0 -87
  150. package/src/web/nextui/src/app/eval/ConfigModal.tsx +0 -84
  151. package/src/web/nextui/src/app/eval/Eval.css +0 -13
  152. package/src/web/nextui/src/app/eval/Eval.tsx +0 -79
  153. package/src/web/nextui/src/app/eval/EvalOutputPromptDialog.tsx +0 -127
  154. package/src/web/nextui/src/app/eval/ResultsCharts.tsx +0 -355
  155. package/src/web/nextui/src/app/eval/ResultsTable.css +0 -179
  156. package/src/web/nextui/src/app/eval/ResultsTable.tsx +0 -503
  157. package/src/web/nextui/src/app/eval/ResultsView.tsx +0 -301
  158. package/src/web/nextui/src/app/eval/ShareModal.tsx +0 -70
  159. package/src/web/nextui/src/app/eval/[id]/not-found.tsx +0 -5
  160. package/src/web/nextui/src/app/eval/[id]/page.css +0 -9
  161. package/src/web/nextui/src/app/eval/[id]/page.tsx +0 -20
  162. package/src/web/nextui/src/app/eval/index.css +0 -0
  163. package/src/web/nextui/src/app/eval/page.tsx +0 -8
  164. package/src/web/nextui/src/app/eval/store.ts +0 -18
  165. package/src/web/nextui/src/app/eval/types.ts +0 -20
  166. package/src/web/nextui/src/app/globals.css +0 -58
  167. package/src/web/nextui/src/app/layout.tsx +0 -25
  168. package/src/web/nextui/src/app/page.tsx +0 -7
  169. package/src/web/nextui/src/app/setup/AssertsForm.tsx +0 -118
  170. package/src/web/nextui/src/app/setup/PromptDialog.tsx +0 -77
  171. package/src/web/nextui/src/app/setup/PromptsSection.tsx +0 -190
  172. package/src/web/nextui/src/app/setup/ProviderConfigDialog.tsx +0 -99
  173. package/src/web/nextui/src/app/setup/ProviderSelector.tsx +0 -149
  174. package/src/web/nextui/src/app/setup/RunTestSuiteButton.tsx +0 -88
  175. package/src/web/nextui/src/app/setup/TestCaseDialog.tsx +0 -108
  176. package/src/web/nextui/src/app/setup/TestCasesSection.tsx +0 -154
  177. package/src/web/nextui/src/app/setup/VarsForm.tsx +0 -57
  178. package/src/web/nextui/src/app/setup/page.css +0 -3
  179. package/src/web/nextui/src/app/setup/page.tsx +0 -160
  180. package/src/web/nextui/src/util/api.ts +0 -1
  181. package/src/web/nextui/src/util/store.ts +0 -53
  182. package/src/web/nextui/tsconfig.json +0 -28
  183. package/src/web/server.ts +0 -151
  184. /package/dist/src/web/nextui/_next/static/{US6gOx8LHTX_Hzm9aYNrC → Bl3o5lF4ON7Fjki46lPhr}/_ssgManifest.js +0 -0
@@ -1,88 +0,0 @@
1
- import Anthropic from '@anthropic-ai/sdk';
2
- import logger from '../logger';
3
-
4
- import type { ApiProvider, ProviderResponse } from '../types.js';
5
-
6
- interface AnthropicCompletionOptions {
7
- temperature?: number;
8
- top_p?: number;
9
- top_k?: number;
10
- }
11
-
12
- export class AnthropicCompletionProvider implements ApiProvider {
13
- static ANTHROPIC_COMPLETION_MODELS = [
14
- 'claude-1',
15
- 'claude-1-100k',
16
- 'claude-instant-1',
17
- 'claude-instant-1-100k',
18
- ];
19
-
20
- modelName: string;
21
- apiKey?: string;
22
- anthropic: Anthropic;
23
- options: AnthropicCompletionOptions;
24
-
25
- constructor(modelName: string, apiKey?: string, context?: AnthropicCompletionOptions) {
26
- this.modelName = modelName;
27
- this.apiKey = apiKey || process.env.ANTHROPIC_API_KEY;
28
- this.anthropic = new Anthropic({ apiKey: this.apiKey });
29
- this.options = context || {};
30
- }
31
-
32
- id(): string {
33
- return `anthropic:${this.modelName}`;
34
- }
35
-
36
- toString(): string {
37
- return `[Anthropic Provider ${this.modelName}]`;
38
- }
39
-
40
- async callApi(prompt: string, options?: AnthropicCompletionOptions): Promise<ProviderResponse> {
41
- if (!this.apiKey) {
42
- throw new Error(
43
- 'Anthropic API key is not set. Set ANTHROPIC_API_KEY environment variable or pass it as an argument to the constructor.',
44
- );
45
- }
46
-
47
- let stop: string[];
48
- try {
49
- stop = process.env.ANTHROPIC_STOP
50
- ? JSON.parse(process.env.ANTHROPIC_STOP)
51
- : ['<|im_end|>', '<|endoftext|>'];
52
- } catch (err) {
53
- throw new Error(`ANTHROPIC_STOP is not a valid JSON string: ${err}`);
54
- }
55
-
56
- const params: Anthropic.CompletionCreateParams = {
57
- model: this.modelName,
58
- prompt: `${Anthropic.HUMAN_PROMPT} ${prompt} ${Anthropic.AI_PROMPT}`,
59
- max_tokens_to_sample: parseInt(process.env.ANTHROPIC_MAX_TOKENS || '1024'),
60
- temperature:
61
- options?.temperature ??
62
- this.options.temperature ??
63
- parseFloat(process.env.ANTHROPIC_TEMPERATURE || '0'),
64
- stop_sequences: stop,
65
- };
66
-
67
- logger.debug(`Calling Anthropic API: ${JSON.stringify(params)}`);
68
- let response;
69
- try {
70
- response = await this.anthropic.completions.create(params);
71
- } catch (err) {
72
- return {
73
- error: `API call error: ${String(err)}`,
74
- };
75
- }
76
- logger.debug(`\tAnthropic API response: ${JSON.stringify(response)}`);
77
- try {
78
- return {
79
- output: response.completion,
80
- tokenUsage: {}, // TODO: add token usage once Anthropic API supports it
81
- };
82
- } catch (err) {
83
- return {
84
- error: `API response error: ${String(err)}: ${JSON.stringify(response)}`,
85
- };
86
- }
87
- }
88
- }
@@ -1,299 +0,0 @@
1
- import logger from '../logger';
2
- import { fetchWithCache } from '../cache';
3
- import { REQUEST_TIMEOUT_MS, parseChatPrompt } from './shared';
4
-
5
- import type { ApiProvider, ProviderEmbeddingResponse, ProviderResponse } from '../types.js';
6
-
7
- interface AzureOpenAiCompletionOptions {
8
- temperature?: number;
9
- top_p?: number;
10
- frequency_penalty?: number;
11
- presence_penalty?: number;
12
- best_of?: number;
13
- functions?: {
14
- name: string;
15
- description?: string;
16
- parameters: any;
17
- }[];
18
- function_call?: 'none' | 'auto';
19
- }
20
-
21
- class AzureOpenAiGenericProvider implements ApiProvider {
22
- deploymentName: string;
23
- apiKey?: string;
24
- apiHost?: string;
25
-
26
- constructor(deploymentName: string, apiKey?: string) {
27
- this.deploymentName = deploymentName;
28
-
29
- this.apiKey = apiKey || process.env.AZURE_OPENAI_API_KEY;
30
-
31
- this.apiHost = process.env.AZURE_OPENAI_API_HOST;
32
- }
33
-
34
- id(): string {
35
- return `azureopenai:${this.deploymentName}`;
36
- }
37
-
38
- toString(): string {
39
- return `[Azure OpenAI Provider ${this.deploymentName}]`;
40
- }
41
-
42
- // @ts-ignore: Prompt is not used in this implementation
43
- async callApi(prompt: string, options?: AzureOpenAiCompletionOptions): Promise<ProviderResponse> {
44
- throw new Error('Not implemented');
45
- }
46
- }
47
-
48
- export class AzureOpenAiEmbeddingProvider extends AzureOpenAiGenericProvider {
49
- async callEmbeddingApi(text: string): Promise<ProviderEmbeddingResponse> {
50
- if (!this.apiKey) {
51
- throw new Error('Azure OpenAI API key must be set for similarity comparison');
52
- }
53
- if (!this.apiHost) {
54
- throw new Error('Azure OpenAI API host must be set');
55
- }
56
-
57
- const body = {
58
- input: text,
59
- model: this.deploymentName,
60
- };
61
- let data,
62
- cached = false;
63
- try {
64
- ({ data, cached } = (await fetchWithCache(
65
- `https://${this.apiHost}/openai/deployments/${this.deploymentName}/embeddings?api-version=2023-07-01-preview`,
66
- {
67
- method: 'POST',
68
- headers: {
69
- 'Content-Type': 'application/json',
70
- 'api-key': this.apiKey,
71
- },
72
- body: JSON.stringify(body),
73
- },
74
- REQUEST_TIMEOUT_MS,
75
- )) as unknown as any);
76
- } catch (err) {
77
- return {
78
- error: `API call error: ${String(err)}`,
79
- tokenUsage: {
80
- total: 0,
81
- prompt: 0,
82
- completion: 0,
83
- },
84
- };
85
- }
86
- logger.debug(`\tAzure OpenAI API response (embeddings): ${JSON.stringify(data)}`);
87
-
88
- try {
89
- const embedding = data?.data?.[0]?.embedding;
90
- if (!embedding) {
91
- throw new Error('No embedding returned');
92
- }
93
- const ret = {
94
- embedding,
95
- tokenUsage: cached
96
- ? { cached: data.usage.total_tokens }
97
- : {
98
- total: data.usage.total_tokens,
99
- prompt: data.usage.prompt_tokens,
100
- completion: data.usage.completion_tokens,
101
- },
102
- };
103
- return ret;
104
- } catch (err) {
105
- return {
106
- error: `API response error: ${String(err)}: ${JSON.stringify(data)}`,
107
- tokenUsage: {
108
- total: data?.usage?.total_tokens,
109
- prompt: data?.usage?.prompt_tokens,
110
- completion: data?.usage?.completion_tokens,
111
- },
112
- };
113
- }
114
- }
115
- }
116
-
117
- export class AzureOpenAiCompletionProvider extends AzureOpenAiGenericProvider {
118
- options: AzureOpenAiCompletionOptions;
119
-
120
- constructor(
121
- deploymentName: string,
122
- apiKey?: string,
123
- context?: AzureOpenAiCompletionOptions,
124
- id?: string,
125
- ) {
126
- super(deploymentName, apiKey);
127
- this.options = context || {};
128
- this.id = id ? () => id : this.id;
129
- }
130
-
131
- async callApi(prompt: string, options?: AzureOpenAiCompletionOptions): Promise<ProviderResponse> {
132
- if (!this.apiKey) {
133
- throw new Error(
134
- 'Azure OpenAI API key is not set. Set AZURE_OPENAI_API_KEY environment variable or pass it as an argument to the constructor.',
135
- );
136
- }
137
- if (!this.apiHost) {
138
- throw new Error('Azure OpenAI API host must be set');
139
- }
140
-
141
- let stop: string;
142
- try {
143
- stop = process.env.OPENAI_STOP
144
- ? JSON.parse(process.env.OPENAI_STOP)
145
- : ['<|im_end|>', '<|endoftext|>'];
146
- } catch (err) {
147
- throw new Error(`OPENAI_STOP is not a valid JSON string: ${err}`);
148
- }
149
- const body = {
150
- model: this.deploymentName,
151
- prompt,
152
- max_tokens: parseInt(process.env.OPENAI_MAX_TOKENS || '1024'),
153
- temperature:
154
- options?.temperature ??
155
- this.options.temperature ??
156
- parseFloat(process.env.OPENAI_TEMPERATURE || '0'),
157
- top_p: options?.top_p ?? this.options.top_p ?? parseFloat(process.env.OPENAI_TOP_P || '1'),
158
- presence_penalty:
159
- options?.presence_penalty ??
160
- this.options.presence_penalty ??
161
- parseFloat(process.env.OPENAI_PRESENCE_PENALTY || '0'),
162
- frequency_penalty:
163
- options?.frequency_penalty ??
164
- this.options.frequency_penalty ??
165
- parseFloat(process.env.OPENAI_FREQUENCY_PENALTY || '0'),
166
- best_of:
167
- options?.best_of ?? this.options.best_of ?? parseInt(process.env.OPENAI_BEST_OF || '1'),
168
- stop,
169
- };
170
- logger.debug(`Calling Azure OpenAI API: ${JSON.stringify(body)}`);
171
- let data,
172
- cached = false;
173
- try {
174
- ({ data, cached } = (await fetchWithCache(
175
- `https://${this.apiHost}/openai/deployments/${this.deploymentName}/completions?api-version=2023-07-01-preview`,
176
- {
177
- method: 'POST',
178
- headers: {
179
- 'Content-Type': 'application/json',
180
- 'api-key': this.apiKey,
181
- },
182
- body: JSON.stringify(body),
183
- },
184
- REQUEST_TIMEOUT_MS,
185
- )) as unknown as any);
186
- } catch (err) {
187
- return {
188
- error: `API call error: ${String(err)}`,
189
- };
190
- }
191
- logger.debug(`\tAzure OpenAI API response: ${JSON.stringify(data)}`);
192
- try {
193
- return {
194
- output: data.choices[0].text,
195
- tokenUsage: cached
196
- ? { cached: data.usage.total_tokens }
197
- : {
198
- total: data.usage.total_tokens,
199
- prompt: data.usage.prompt_tokens,
200
- completion: data.usage.completion_tokens,
201
- },
202
- };
203
- } catch (err) {
204
- return {
205
- error: `API response error: ${String(err)}: ${JSON.stringify(data)}`,
206
- };
207
- }
208
- }
209
- }
210
-
211
- export class AzureOpenAiChatCompletionProvider extends AzureOpenAiGenericProvider {
212
- options: AzureOpenAiCompletionOptions;
213
-
214
- constructor(
215
- deploymentName: string,
216
- apiKey?: string,
217
- context?: AzureOpenAiCompletionOptions,
218
- id?: string,
219
- ) {
220
- super(deploymentName, apiKey);
221
- this.options = context || {};
222
- this.id = id ? () => id : this.id;
223
- }
224
-
225
- async callApi(prompt: string, options?: AzureOpenAiCompletionOptions): Promise<ProviderResponse> {
226
- if (!this.apiKey) {
227
- throw new Error(
228
- 'Azure OpenAI API key is not set. Set AZURE_OPENAI_API_KEY environment variable or pass it as an argument to the constructor.',
229
- );
230
- }
231
- if (!this.apiHost) {
232
- throw new Error('Azure OpenAI API host must be set');
233
- }
234
-
235
- const messages = parseChatPrompt(prompt);
236
- const body = {
237
- model: this.deploymentName,
238
- messages: messages,
239
- max_tokens: parseInt(process.env.OPENAI_MAX_TOKENS || '1024'),
240
- temperature:
241
- options?.temperature ??
242
- this.options.temperature ??
243
- parseFloat(process.env.OPENAI_TEMPERATURE || '0'),
244
- top_p: options?.top_p ?? this.options.top_p ?? parseFloat(process.env.OPENAI_TOP_P || '1'),
245
- presence_penalty:
246
- options?.presence_penalty ??
247
- this.options.presence_penalty ??
248
- parseFloat(process.env.OPENAI_PRESENCE_PENALTY || '0'),
249
- frequency_penalty:
250
- options?.frequency_penalty ??
251
- this.options.frequency_penalty ??
252
- parseFloat(process.env.OPENAI_FREQUENCY_PENALTY || '0'),
253
- functions: options?.functions || this.options.functions || undefined,
254
- function_call: options?.function_call || this.options.function_call || undefined,
255
- };
256
- logger.debug(`Calling Azure OpenAI API: ${JSON.stringify(body)}`);
257
-
258
- let data,
259
- cached = false;
260
- try {
261
- ({ data, cached } = (await fetchWithCache(
262
- `https://${this.apiHost}/openai/deployments/${this.deploymentName}/chat/completions?api-version=2023-07-01-preview`,
263
- {
264
- method: 'POST',
265
- headers: {
266
- 'Content-Type': 'application/json',
267
- 'api-key': this.apiKey,
268
- },
269
- body: JSON.stringify(body),
270
- },
271
- REQUEST_TIMEOUT_MS,
272
- )) as unknown as any);
273
- } catch (err) {
274
- return {
275
- error: `API call error: ${String(err)}`,
276
- };
277
- }
278
-
279
- logger.debug(`\tAzure OpenAI API response: ${JSON.stringify(data)}`);
280
- try {
281
- const message = data.choices[0].message;
282
- const output = message.content == null ? message.function_call : message.content;
283
- return {
284
- output,
285
- tokenUsage: cached
286
- ? { cached: data.usage.total_tokens }
287
- : {
288
- total: data.usage.total_tokens,
289
- prompt: data.usage.prompt_tokens,
290
- completion: data.usage.completion_tokens,
291
- },
292
- };
293
- } catch (err) {
294
- return {
295
- error: `API response error: ${String(err)}: ${JSON.stringify(data)}`,
296
- };
297
- }
298
- }
299
- }
@@ -1,95 +0,0 @@
1
- import { fetchWithCache } from '../cache';
2
- import { REQUEST_TIMEOUT_MS } from './shared';
3
-
4
- import type { ApiProvider, ProviderResponse } from '../types.js';
5
-
6
- interface LlamaCompletionOptions {
7
- n_predict?: number;
8
- temperature?: number;
9
- top_k?: number;
10
- top_p?: number;
11
- n_keep?: number;
12
- stop?: string[];
13
- repeat_penalty?: number;
14
- repeat_last_n?: number;
15
- penalize_nl?: boolean;
16
- presence_penalty?: number;
17
- frequency_penalty?: number;
18
- mirostat?: boolean;
19
- mirostat_tau?: number;
20
- mirostat_eta?: number;
21
- seed?: number;
22
- ignore_eos?: boolean;
23
- logit_bias?: Record<string, number>;
24
- }
25
-
26
- export class LlamaProvider implements ApiProvider {
27
- modelName: string;
28
- options?: LlamaCompletionOptions;
29
-
30
- constructor(modelName: string, options?: LlamaCompletionOptions) {
31
- this.modelName = modelName;
32
- this.options = options;
33
- }
34
-
35
- id(): string {
36
- return `llama:${this.modelName}`;
37
- }
38
-
39
- toString(): string {
40
- return `[Llama Provider ${this.modelName}]`;
41
- }
42
-
43
- async callApi(prompt: string, options?: LlamaCompletionOptions): Promise<ProviderResponse> {
44
- options = Object.assign({}, this.options, options);
45
- const body = {
46
- prompt,
47
- n_predict: options?.n_predict || 512,
48
- temperature: options?.temperature,
49
- top_k: options?.top_k,
50
- top_p: options?.top_p,
51
- n_keep: options?.n_keep,
52
- stop: options?.stop,
53
- repeat_penalty: options?.repeat_penalty,
54
- repeat_last_n: options?.repeat_last_n,
55
- penalize_nl: options?.penalize_nl,
56
- presence_penalty: options?.presence_penalty,
57
- frequency_penalty: options?.frequency_penalty,
58
- mirostat: options?.mirostat,
59
- mirostat_tau: options?.mirostat_tau,
60
- mirostat_eta: options?.mirostat_eta,
61
- seed: options?.seed,
62
- ignore_eos: options?.ignore_eos,
63
- logit_bias: options?.logit_bias,
64
- };
65
-
66
- let response;
67
- try {
68
- response = await fetchWithCache(
69
- `${process.env.LLAMA_BASE_URL || 'http://localhost:8080'}/completion`,
70
- {
71
- method: 'POST',
72
- headers: {
73
- 'Content-Type': 'application/json',
74
- },
75
- body: JSON.stringify(body),
76
- },
77
- REQUEST_TIMEOUT_MS,
78
- );
79
- } catch (err) {
80
- return {
81
- error: `API call error: ${String(err)}`,
82
- };
83
- }
84
-
85
- try {
86
- return {
87
- output: response.data.content,
88
- };
89
- } catch (err) {
90
- return {
91
- error: `API response error: ${String(err)}: ${JSON.stringify(response.data)}`,
92
- };
93
- }
94
- }
95
- }
@@ -1,111 +0,0 @@
1
- import logger from '../logger';
2
- import { fetchWithCache } from '../cache';
3
- import { REQUEST_TIMEOUT_MS, parseChatPrompt } from './shared';
4
-
5
- import type { ApiProvider, ProviderResponse } from '../types.js';
6
-
7
- class LocalAiGenericProvider implements ApiProvider {
8
- modelName: string;
9
- apiBaseUrl: string;
10
-
11
- constructor(modelName: string) {
12
- this.modelName = modelName;
13
- this.apiBaseUrl = process.env.LOCALAI_BASE_URL || 'http://localhost:8080/v1';
14
- }
15
-
16
- id(): string {
17
- return `localai:${this.modelName}`;
18
- }
19
-
20
- toString(): string {
21
- return `[LocalAI Provider ${this.modelName}]`;
22
- }
23
-
24
- // @ts-ignore: Prompt is not used in this implementation
25
- async callApi(prompt: string): Promise<ProviderResponse> {
26
- throw new Error('Not implemented');
27
- }
28
- }
29
-
30
- export class LocalAiChatProvider extends LocalAiGenericProvider {
31
- async callApi(prompt: string): Promise<ProviderResponse> {
32
- const messages = parseChatPrompt(prompt);
33
- const body = {
34
- model: this.modelName,
35
- messages: messages,
36
- temperature: process.env.LOCALAI_TEMPERATURE || 0.7,
37
- };
38
- logger.debug(`Calling LocalAI API: ${JSON.stringify(body)}`);
39
-
40
- let data,
41
- cached = false;
42
- try {
43
- ({ data, cached } = (await fetchWithCache(
44
- `${this.apiBaseUrl}/chat/completions`,
45
- {
46
- method: 'POST',
47
- headers: {
48
- 'Content-Type': 'application/json',
49
- },
50
- body: JSON.stringify(body),
51
- },
52
- REQUEST_TIMEOUT_MS,
53
- )) as unknown as any);
54
- } catch (err) {
55
- return {
56
- error: `API call error: ${String(err)}`,
57
- };
58
- }
59
- logger.debug(` LocalAI API response: ${JSON.stringify(data)}`);
60
- try {
61
- return {
62
- output: data.choices[0].text,
63
- };
64
- } catch (err) {
65
- return {
66
- error: `API response error: ${String(err)}: ${JSON.stringify(data)}`,
67
- };
68
- }
69
- }
70
- }
71
-
72
- export class LocalAiCompletionProvider extends LocalAiGenericProvider {
73
- async callApi(prompt: string): Promise<ProviderResponse> {
74
- const body = {
75
- model: this.modelName,
76
- prompt,
77
- temperature: process.env.LOCALAI_TEMPERATURE || 0.7,
78
- };
79
- logger.debug(`Calling LocalAI API: ${JSON.stringify(body)}`);
80
-
81
- let data,
82
- cached = false;
83
- try {
84
- ({ data, cached } = (await fetchWithCache(
85
- `${this.apiBaseUrl}/completions`,
86
- {
87
- method: 'POST',
88
- headers: {
89
- 'Content-Type': 'application/json',
90
- },
91
- body: JSON.stringify(body),
92
- },
93
- REQUEST_TIMEOUT_MS,
94
- )) as unknown as any);
95
- } catch (err) {
96
- return {
97
- error: `API call error: ${String(err)}`,
98
- };
99
- }
100
- logger.debug(` LocalAI API response: ${JSON.stringify(data)}`);
101
- try {
102
- return {
103
- output: data.choices[0].text,
104
- };
105
- } catch (err) {
106
- return {
107
- error: `API response error: ${String(err)}: ${JSON.stringify(data)}`,
108
- };
109
- }
110
- }
111
- }
@@ -1,89 +0,0 @@
1
- import logger from '../logger';
2
- import { fetchWithCache } from '../cache';
3
-
4
- import type { ApiProvider, ProviderResponse } from '../types.js';
5
- import { REQUEST_TIMEOUT_MS } from './shared';
6
-
7
- interface OllamaJsonL {
8
- model: string;
9
- created_at: string;
10
- response?: string;
11
- done: boolean;
12
- context?: number[];
13
- total_duration?: number;
14
- load_duration?: number;
15
- sample_count?: number;
16
- sample_duration?: number;
17
- prompt_eval_count?: number;
18
- prompt_eval_duration?: number;
19
- eval_count?: number;
20
- eval_duration?: number;
21
- }
22
-
23
- export class OllamaProvider implements ApiProvider {
24
- modelName: string;
25
-
26
- constructor(modelName: string) {
27
- this.modelName = modelName;
28
- }
29
-
30
- id(): string {
31
- return `ollama:${this.modelName}`;
32
- }
33
-
34
- toString(): string {
35
- return `[Ollama Provider ${this.modelName}]`;
36
- }
37
-
38
- async callApi(prompt: string): Promise<ProviderResponse> {
39
- const params = {
40
- model: this.modelName,
41
- prompt,
42
- };
43
-
44
- logger.debug(`Calling Ollama API: ${JSON.stringify(params)}`);
45
- let response;
46
- try {
47
- response = await fetchWithCache(
48
- `${process.env.OLLAMA_BASE_URL || 'http://localhost:11434'}/api/generate`,
49
- {
50
- method: 'POST',
51
- headers: {
52
- 'Content-Type': 'application/json',
53
- },
54
- body: JSON.stringify(params),
55
- },
56
- REQUEST_TIMEOUT_MS,
57
- 'text',
58
- );
59
- } catch (err) {
60
- return {
61
- error: `API call error: ${String(err)}`,
62
- };
63
- }
64
- logger.debug(`\tOllama API response: ${response.data}`);
65
-
66
- try {
67
- const output = response.data
68
- .split('\n')
69
- .filter((line: string) => line.trim() !== '')
70
- .map((line: string) => {
71
- const parsed = JSON.parse(line) as OllamaJsonL;
72
- if (parsed.response) {
73
- return parsed.response;
74
- }
75
- return null;
76
- })
77
- .filter((s: string | null) => s !== null)
78
- .join('');
79
-
80
- return {
81
- output,
82
- };
83
- } catch (err) {
84
- return {
85
- error: `API response error: ${String(err)}: ${JSON.stringify(response.data)}`,
86
- };
87
- }
88
- }
89
- }