@lockllm/sdk 1.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 (72) hide show
  1. package/CHANGELOG.md +81 -0
  2. package/CODE_OF_CONDUCT.md +130 -0
  3. package/CONTRIBUTING.md +259 -0
  4. package/LICENSE +21 -0
  5. package/README.md +928 -0
  6. package/SECURITY.md +261 -0
  7. package/dist/client.d.ts +39 -0
  8. package/dist/client.d.ts.map +1 -0
  9. package/dist/client.js +65 -0
  10. package/dist/client.js.map +1 -0
  11. package/dist/client.mjs +61 -0
  12. package/dist/errors.d.ts +60 -0
  13. package/dist/errors.d.ts.map +1 -0
  14. package/dist/errors.js +175 -0
  15. package/dist/errors.js.map +1 -0
  16. package/dist/errors.mjs +164 -0
  17. package/dist/index.d.ts +17 -0
  18. package/dist/index.d.ts.map +1 -0
  19. package/dist/index.js +49 -0
  20. package/dist/index.js.map +1 -0
  21. package/dist/index.mjs +17 -0
  22. package/dist/scan.d.ts +32 -0
  23. package/dist/scan.d.ts.map +1 -0
  24. package/dist/scan.js +40 -0
  25. package/dist/scan.js.map +1 -0
  26. package/dist/scan.mjs +36 -0
  27. package/dist/types/common.d.ts +31 -0
  28. package/dist/types/common.d.ts.map +1 -0
  29. package/dist/types/common.js +6 -0
  30. package/dist/types/common.js.map +1 -0
  31. package/dist/types/common.mjs +5 -0
  32. package/dist/types/errors.d.ts +22 -0
  33. package/dist/types/errors.d.ts.map +1 -0
  34. package/dist/types/errors.js +6 -0
  35. package/dist/types/errors.js.map +1 -0
  36. package/dist/types/errors.mjs +5 -0
  37. package/dist/types/providers.d.ts +24 -0
  38. package/dist/types/providers.d.ts.map +1 -0
  39. package/dist/types/providers.js +26 -0
  40. package/dist/types/providers.js.map +1 -0
  41. package/dist/types/providers.mjs +23 -0
  42. package/dist/types/scan.d.ts +36 -0
  43. package/dist/types/scan.d.ts.map +1 -0
  44. package/dist/types/scan.js +6 -0
  45. package/dist/types/scan.js.map +1 -0
  46. package/dist/types/scan.mjs +5 -0
  47. package/dist/utils.d.ts +84 -0
  48. package/dist/utils.d.ts.map +1 -0
  49. package/dist/utils.js +225 -0
  50. package/dist/utils.js.map +1 -0
  51. package/dist/utils.mjs +215 -0
  52. package/dist/wrappers/anthropic-wrapper.d.ts +72 -0
  53. package/dist/wrappers/anthropic-wrapper.d.ts.map +1 -0
  54. package/dist/wrappers/anthropic-wrapper.js +78 -0
  55. package/dist/wrappers/anthropic-wrapper.js.map +1 -0
  56. package/dist/wrappers/anthropic-wrapper.mjs +74 -0
  57. package/dist/wrappers/generic-wrapper.d.ts +180 -0
  58. package/dist/wrappers/generic-wrapper.d.ts.map +1 -0
  59. package/dist/wrappers/generic-wrapper.js +246 -0
  60. package/dist/wrappers/generic-wrapper.js.map +1 -0
  61. package/dist/wrappers/generic-wrapper.mjs +225 -0
  62. package/dist/wrappers/index.d.ts +27 -0
  63. package/dist/wrappers/index.d.ts.map +1 -0
  64. package/dist/wrappers/index.js +48 -0
  65. package/dist/wrappers/index.js.map +1 -0
  66. package/dist/wrappers/index.mjs +26 -0
  67. package/dist/wrappers/openai-wrapper.d.ts +70 -0
  68. package/dist/wrappers/openai-wrapper.d.ts.map +1 -0
  69. package/dist/wrappers/openai-wrapper.js +76 -0
  70. package/dist/wrappers/openai-wrapper.js.map +1 -0
  71. package/dist/wrappers/openai-wrapper.mjs +72 -0
  72. package/package.json +106 -0
@@ -0,0 +1,84 @@
1
+ /**
2
+ * Utility functions for HTTP requests and common operations
3
+ */
4
+ import type { RequestOptions } from './types/common';
5
+ import type { ProviderName } from './types/providers';
6
+ /**
7
+ * Get the proxy URL for a specific provider
8
+ *
9
+ * @param provider - The provider name
10
+ * @returns The full proxy URL for the provider
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const url = getProxyURL('openai');
15
+ * // Returns: 'https://api.lockllm.com/v1/proxy/openai'
16
+ * ```
17
+ */
18
+ export declare function getProxyURL(provider: ProviderName): string;
19
+ /**
20
+ * Get all available proxy URLs
21
+ *
22
+ * @returns Record of all provider proxy URLs
23
+ *
24
+ * @example
25
+ * ```typescript
26
+ * const urls = getAllProxyURLs();
27
+ * console.log(urls.openai); // 'https://api.lockllm.com/v1/proxy/openai'
28
+ * console.log(urls.anthropic); // 'https://api.lockllm.com/v1/proxy/anthropic'
29
+ * ```
30
+ */
31
+ export declare function getAllProxyURLs(): Record<ProviderName, string>;
32
+ /**
33
+ * Generate a unique request ID
34
+ */
35
+ export declare function generateRequestId(): string;
36
+ /**
37
+ * Sleep for a specified number of milliseconds
38
+ */
39
+ export declare function sleep(ms: number): Promise<void>;
40
+ /**
41
+ * Parse Retry-After header value to milliseconds
42
+ */
43
+ export declare function parseRetryAfter(retryAfter: string | null): number | undefined;
44
+ /**
45
+ * Exponential backoff delay calculation
46
+ */
47
+ export declare function calculateBackoff(attempt: number, baseDelay?: number): number;
48
+ /**
49
+ * HTTP client for making requests to LockLLM API
50
+ */
51
+ export declare class HttpClient {
52
+ private baseURL;
53
+ private apiKey;
54
+ private timeout;
55
+ private maxRetries;
56
+ constructor(baseURL: string, apiKey: string, timeout?: number, maxRetries?: number);
57
+ /**
58
+ * Make a GET request
59
+ */
60
+ get<T = any>(path: string, options?: RequestOptions): Promise<{
61
+ data: T;
62
+ requestId: string;
63
+ }>;
64
+ /**
65
+ * Make a POST request
66
+ */
67
+ post<T = any>(path: string, body?: any, options?: RequestOptions): Promise<{
68
+ data: T;
69
+ requestId: string;
70
+ }>;
71
+ /**
72
+ * Make an HTTP request with retry logic
73
+ */
74
+ private request;
75
+ /**
76
+ * Make a single HTTP request
77
+ */
78
+ private makeRequest;
79
+ /**
80
+ * Check if an error is retryable
81
+ */
82
+ private isRetryableError;
83
+ }
84
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAQH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,gBAAgB,CAAC;AACrD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAItD;;;;;;;;;;;GAWG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAE1D;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,IAAI,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAoB9D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,IAAI,MAAM,CAE1C;AAED;;GAEG;AACH,wBAAgB,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAE/C;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAgB7E;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,GAAE,MAAa,GAAG,MAAM,CAElF;AAED;;GAEG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,UAAU,CAAS;gBAGzB,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,EACd,OAAO,GAAE,MAAc,EACvB,UAAU,GAAE,MAAU;IAQxB;;OAEG;IACG,GAAG,CAAC,CAAC,GAAG,GAAG,EACf,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAI1C;;OAEG;IACG,IAAI,CAAC,CAAC,GAAG,GAAG,EAChB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,GAAG,EACV,OAAO,CAAC,EAAE,cAAc,GACvB,OAAO,CAAC;QAAE,IAAI,EAAE,CAAC,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;IAI1C;;OAEG;YACW,OAAO;IAoFrB;;OAEG;YACW,WAAW;IAqCzB;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAkBzB"}
package/dist/utils.js ADDED
@@ -0,0 +1,225 @@
1
+ "use strict";
2
+ /**
3
+ * Utility functions for HTTP requests and common operations
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.HttpClient = void 0;
7
+ exports.getProxyURL = getProxyURL;
8
+ exports.getAllProxyURLs = getAllProxyURLs;
9
+ exports.generateRequestId = generateRequestId;
10
+ exports.sleep = sleep;
11
+ exports.parseRetryAfter = parseRetryAfter;
12
+ exports.calculateBackoff = calculateBackoff;
13
+ const errors_1 = require("./errors");
14
+ const LOCKLLM_PROXY_BASE = 'https://api.lockllm.com/v1/proxy';
15
+ /**
16
+ * Get the proxy URL for a specific provider
17
+ *
18
+ * @param provider - The provider name
19
+ * @returns The full proxy URL for the provider
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * const url = getProxyURL('openai');
24
+ * // Returns: 'https://api.lockllm.com/v1/proxy/openai'
25
+ * ```
26
+ */
27
+ function getProxyURL(provider) {
28
+ return `${LOCKLLM_PROXY_BASE}/${provider}`;
29
+ }
30
+ /**
31
+ * Get all available proxy URLs
32
+ *
33
+ * @returns Record of all provider proxy URLs
34
+ *
35
+ * @example
36
+ * ```typescript
37
+ * const urls = getAllProxyURLs();
38
+ * console.log(urls.openai); // 'https://api.lockllm.com/v1/proxy/openai'
39
+ * console.log(urls.anthropic); // 'https://api.lockllm.com/v1/proxy/anthropic'
40
+ * ```
41
+ */
42
+ function getAllProxyURLs() {
43
+ return {
44
+ openai: getProxyURL('openai'),
45
+ anthropic: getProxyURL('anthropic'),
46
+ gemini: getProxyURL('gemini'),
47
+ cohere: getProxyURL('cohere'),
48
+ openrouter: getProxyURL('openrouter'),
49
+ perplexity: getProxyURL('perplexity'),
50
+ mistral: getProxyURL('mistral'),
51
+ groq: getProxyURL('groq'),
52
+ deepseek: getProxyURL('deepseek'),
53
+ together: getProxyURL('together'),
54
+ xai: getProxyURL('xai'),
55
+ fireworks: getProxyURL('fireworks'),
56
+ anyscale: getProxyURL('anyscale'),
57
+ huggingface: getProxyURL('huggingface'),
58
+ azure: getProxyURL('azure'),
59
+ bedrock: getProxyURL('bedrock'),
60
+ 'vertex-ai': getProxyURL('vertex-ai'),
61
+ };
62
+ }
63
+ /**
64
+ * Generate a unique request ID
65
+ */
66
+ function generateRequestId() {
67
+ return `req_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
68
+ }
69
+ /**
70
+ * Sleep for a specified number of milliseconds
71
+ */
72
+ function sleep(ms) {
73
+ return new Promise((resolve) => setTimeout(resolve, ms));
74
+ }
75
+ /**
76
+ * Parse Retry-After header value to milliseconds
77
+ */
78
+ function parseRetryAfter(retryAfter) {
79
+ if (!retryAfter)
80
+ return undefined;
81
+ // If it's a number, it's seconds
82
+ const seconds = parseInt(retryAfter, 10);
83
+ if (!isNaN(seconds)) {
84
+ return seconds * 1000;
85
+ }
86
+ // If it's a date string, calculate diff
87
+ const date = new Date(retryAfter);
88
+ if (!isNaN(date.getTime())) {
89
+ return Math.max(0, date.getTime() - Date.now());
90
+ }
91
+ return undefined;
92
+ }
93
+ /**
94
+ * Exponential backoff delay calculation
95
+ */
96
+ function calculateBackoff(attempt, baseDelay = 1000) {
97
+ return Math.min(baseDelay * Math.pow(2, attempt), 30000);
98
+ }
99
+ /**
100
+ * HTTP client for making requests to LockLLM API
101
+ */
102
+ class HttpClient {
103
+ constructor(baseURL, apiKey, timeout = 60000, maxRetries = 3) {
104
+ this.baseURL = baseURL.replace(/\/$/, ''); // Remove trailing slash
105
+ this.apiKey = apiKey;
106
+ this.timeout = timeout;
107
+ this.maxRetries = maxRetries;
108
+ }
109
+ /**
110
+ * Make a GET request
111
+ */
112
+ async get(path, options) {
113
+ return this.request('GET', path, undefined, options);
114
+ }
115
+ /**
116
+ * Make a POST request
117
+ */
118
+ async post(path, body, options) {
119
+ return this.request('POST', path, body, options);
120
+ }
121
+ /**
122
+ * Make an HTTP request with retry logic
123
+ */
124
+ async request(method, path, body, options) {
125
+ const url = `${this.baseURL}${path}`;
126
+ const requestId = generateRequestId();
127
+ let lastError;
128
+ for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
129
+ try {
130
+ const response = await this.makeRequest(method, url, body, requestId, options);
131
+ const responseRequestId = response.headers.get('X-Request-Id') || requestId;
132
+ // Success
133
+ if (response.ok) {
134
+ const data = await response.json();
135
+ return {
136
+ data: data,
137
+ requestId: responseRequestId,
138
+ };
139
+ }
140
+ // Handle rate limiting with retry
141
+ if (response.status === 429) {
142
+ const retryAfter = parseRetryAfter(response.headers.get('Retry-After'));
143
+ if (attempt < this.maxRetries) {
144
+ const delay = retryAfter || calculateBackoff(attempt);
145
+ await sleep(delay);
146
+ continue;
147
+ }
148
+ const errorData = await response.json().catch(() => ({}));
149
+ throw new errors_1.RateLimitError(errorData.error?.message || 'Rate limit exceeded', retryAfter, responseRequestId);
150
+ }
151
+ // Handle other errors
152
+ const errorData = await response.json().catch(() => ({}));
153
+ throw (0, errors_1.parseError)(errorData, responseRequestId);
154
+ }
155
+ catch (error) {
156
+ // If it's already a LockLLMError, rethrow immediately (don't retry)
157
+ if (error instanceof errors_1.LockLLMError && !(error instanceof errors_1.RateLimitError)) {
158
+ throw error;
159
+ }
160
+ lastError = error;
161
+ // Retry on network errors
162
+ if (attempt < this.maxRetries && this.isRetryableError(error)) {
163
+ await sleep(calculateBackoff(attempt));
164
+ continue;
165
+ }
166
+ // No more retries
167
+ break;
168
+ }
169
+ }
170
+ // All retries exhausted
171
+ if (lastError instanceof errors_1.LockLLMError) {
172
+ throw lastError;
173
+ }
174
+ throw new errors_1.NetworkError(lastError?.message || 'Network request failed', lastError, requestId);
175
+ }
176
+ /**
177
+ * Make a single HTTP request
178
+ */
179
+ async makeRequest(method, url, body, requestId, options) {
180
+ const controller = new AbortController();
181
+ const timeoutMs = options?.timeout || this.timeout;
182
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
183
+ try {
184
+ const headers = {
185
+ 'Content-Type': 'application/json',
186
+ Authorization: `Bearer ${this.apiKey}`,
187
+ 'X-Request-Id': requestId,
188
+ ...options?.headers,
189
+ };
190
+ // Use user's signal if provided, otherwise use timeout controller
191
+ // If user provides a signal, they're responsible for timeout
192
+ const signal = options?.signal || controller.signal;
193
+ const response = await fetch(url, {
194
+ method,
195
+ headers,
196
+ body: body ? JSON.stringify(body) : undefined,
197
+ signal,
198
+ });
199
+ return response;
200
+ }
201
+ finally {
202
+ clearTimeout(timeoutId);
203
+ }
204
+ }
205
+ /**
206
+ * Check if an error is retryable
207
+ */
208
+ isRetryableError(error) {
209
+ // Retry on network errors
210
+ if (error instanceof TypeError && error.message.includes('fetch')) {
211
+ return true;
212
+ }
213
+ // Retry on timeout
214
+ if (error.name === 'AbortError') {
215
+ return true;
216
+ }
217
+ // Retry on rate limit (handled separately)
218
+ if (error instanceof errors_1.RateLimitError) {
219
+ return true;
220
+ }
221
+ return false;
222
+ }
223
+ }
224
+ exports.HttpClient = HttpClient;
225
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../src/utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,UAAU,GACX,MAAM,UAAU,CAAC;AAIlB,MAAM,kBAAkB,GAAG,kCAAkC,CAAC;AAE9D;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,WAAW,CAAC,QAAsB;IAChD,OAAO,GAAG,kBAAkB,IAAI,QAAQ,EAAE,CAAC;AAC7C,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,eAAe;IAC7B,OAAO;QACL,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC;QAC7B,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC;QACnC,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC;QAC7B,MAAM,EAAE,WAAW,CAAC,QAAQ,CAAC;QAC7B,UAAU,EAAE,WAAW,CAAC,YAAY,CAAC;QACrC,UAAU,EAAE,WAAW,CAAC,YAAY,CAAC;QACrC,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC;QAC/B,IAAI,EAAE,WAAW,CAAC,MAAM,CAAC;QACzB,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC;QACjC,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC;QACjC,GAAG,EAAE,WAAW,CAAC,KAAK,CAAC;QACvB,SAAS,EAAE,WAAW,CAAC,WAAW,CAAC;QACnC,QAAQ,EAAE,WAAW,CAAC,UAAU,CAAC;QACjC,WAAW,EAAE,WAAW,CAAC,aAAa,CAAC;QACvC,KAAK,EAAE,WAAW,CAAC,OAAO,CAAC;QAC3B,OAAO,EAAE,WAAW,CAAC,SAAS,CAAC;QAC/B,WAAW,EAAE,WAAW,CAAC,WAAW,CAAC;KACtC,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB;IAC/B,OAAO,OAAO,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;AAC5E,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,KAAK,CAAC,EAAU;IAC9B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,CAAC,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,UAAyB;IACvD,IAAI,CAAC,UAAU;QAAE,OAAO,SAAS,CAAC;IAElC,iCAAiC;IACjC,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;IACzC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;QACpB,OAAO,OAAO,GAAG,IAAI,CAAC;IACxB,CAAC;IAED,wCAAwC;IACxC,MAAM,IAAI,GAAG,IAAI,IAAI,CAAC,UAAU,CAAC,CAAC;IAClC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,OAAe,EAAE,YAAoB,IAAI;IACxE,OAAO,IAAI,CAAC,GAAG,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,EAAE,KAAK,CAAC,CAAC;AAC3D,CAAC;AAED;;GAEG;AACH,MAAM,OAAO,UAAU;IAMrB,YACE,OAAe,EACf,MAAc,EACd,UAAkB,KAAK,EACvB,aAAqB,CAAC;QAEtB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,CAAC,wBAAwB;QACnE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;QACrB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,GAAG,CACP,IAAY,EACZ,OAAwB;QAExB,OAAO,IAAI,CAAC,OAAO,CAAI,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;IAC1D,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,IAAI,CACR,IAAY,EACZ,IAAU,EACV,OAAwB;QAExB,OAAO,IAAI,CAAC,OAAO,CAAI,MAAM,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;IACtD,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,OAAO,CACnB,MAAc,EACd,IAAY,EACZ,IAAU,EACV,OAAwB;QAExB,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,GAAG,IAAI,EAAE,CAAC;QACrC,MAAM,SAAS,GAAG,iBAAiB,EAAE,CAAC;QACtC,IAAI,SAA4B,CAAC;QAEjC,KAAK,IAAI,OAAO,GAAG,CAAC,EAAE,OAAO,IAAI,IAAI,CAAC,UAAU,EAAE,OAAO,EAAE,EAAE,CAAC;YAC5D,IAAI,CAAC;gBACH,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,WAAW,CACrC,MAAM,EACN,GAAG,EACH,IAAI,EACJ,SAAS,EACT,OAAO,CACR,CAAC;gBAEF,MAAM,iBAAiB,GACrB,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,SAAS,CAAC;gBAEpD,UAAU;gBACV,IAAI,QAAQ,CAAC,EAAE,EAAE,CAAC;oBAChB,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;oBACnC,OAAO;wBACL,IAAI,EAAE,IAAS;wBACf,SAAS,EAAE,iBAAiB;qBAC7B,CAAC;gBACJ,CAAC;gBAED,kCAAkC;gBAClC,IAAI,QAAQ,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;oBAC5B,MAAM,UAAU,GAAG,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;oBAExE,IAAI,OAAO,GAAG,IAAI,CAAC,UAAU,EAAE,CAAC;wBAC9B,MAAM,KAAK,GAAG,UAAU,IAAI,gBAAgB,CAAC,OAAO,CAAC,CAAC;wBACtD,MAAM,KAAK,CAAC,KAAK,CAAC,CAAC;wBACnB,SAAS;oBACX,CAAC;oBAED,MAAM,SAAS,GAAQ,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;oBAC/D,MAAM,IAAI,cAAc,CACtB,SAAS,CAAC,KAAK,EAAE,OAAO,IAAI,qBAAqB,EACjD,UAAU,EACV,iBAAiB,CAClB,CAAC;gBACJ,CAAC;gBAED,sBAAsB;gBACtB,MAAM,SAAS,GAAQ,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;gBAC/D,MAAM,UAAU,CAAC,SAAS,EAAE,iBAAiB,CAAC,CAAC;YACjD,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,oEAAoE;gBACpE,IAAI,KAAK,YAAY,YAAY,IAAI,CAAC,CAAC,KAAK,YAAY,cAAc,CAAC,EAAE,CAAC;oBACxE,MAAM,KAAK,CAAC;gBACd,CAAC;gBAED,SAAS,GAAG,KAAc,CAAC;gBAE3B,0BAA0B;gBAC1B,IAAI,OAAO,GAAG,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,EAAE,CAAC;oBAC9D,MAAM,KAAK,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC,CAAC;oBACvC,SAAS;gBACX,CAAC;gBAED,kBAAkB;gBAClB,MAAM;YACR,CAAC;QACH,CAAC;QAED,wBAAwB;QACxB,IAAI,SAAS,YAAY,YAAY,EAAE,CAAC;YACtC,MAAM,SAAS,CAAC;QAClB,CAAC;QAED,MAAM,IAAI,YAAY,CACpB,SAAS,EAAE,OAAO,IAAI,wBAAwB,EAC9C,SAAS,EACT,SAAS,CACV,CAAC;IACJ,CAAC;IAED;;OAEG;IACK,KAAK,CAAC,WAAW,CACvB,MAAc,EACd,GAAW,EACX,IAAS,EACT,SAAiB,EACjB,OAAwB;QAExB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;QACzC,MAAM,SAAS,GAAG,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC;QAEnD,MAAM,SAAS,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;QAElE,IAAI,CAAC;YACH,MAAM,OAAO,GAA2B;gBACtC,cAAc,EAAE,kBAAkB;gBAClC,aAAa,EAAE,UAAU,IAAI,CAAC,MAAM,EAAE;gBACtC,cAAc,EAAE,SAAS;gBACzB,GAAG,OAAO,EAAE,OAAO;aACpB,CAAC;YAEF,kEAAkE;YAClE,6DAA6D;YAC7D,MAAM,MAAM,GAAG,OAAO,EAAE,MAAM,IAAI,UAAU,CAAC,MAAM,CAAC;YAEpD,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM;gBACN,OAAO;gBACP,IAAI,EAAE,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;gBAC7C,MAAM;aACP,CAAC,CAAC;YAEH,OAAO,QAAQ,CAAC;QAClB,CAAC;gBAAS,CAAC;YACT,YAAY,CAAC,SAAS,CAAC,CAAC;QAC1B,CAAC;IACH,CAAC;IAED;;OAEG;IACK,gBAAgB,CAAC,KAAU;QACjC,0BAA0B;QAC1B,IAAI,KAAK,YAAY,SAAS,IAAI,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAClE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,mBAAmB;QACnB,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAChC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,2CAA2C;QAC3C,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;YACpC,OAAO,IAAI,CAAC;QACd,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;CACF"}
package/dist/utils.mjs ADDED
@@ -0,0 +1,215 @@
1
+ /**
2
+ * Utility functions for HTTP requests and common operations
3
+ */
4
+ import { LockLLMError, NetworkError, RateLimitError, parseError, } from './errors';
5
+ const LOCKLLM_PROXY_BASE = 'https://api.lockllm.com/v1/proxy';
6
+ /**
7
+ * Get the proxy URL for a specific provider
8
+ *
9
+ * @param provider - The provider name
10
+ * @returns The full proxy URL for the provider
11
+ *
12
+ * @example
13
+ * ```typescript
14
+ * const url = getProxyURL('openai');
15
+ * // Returns: 'https://api.lockllm.com/v1/proxy/openai'
16
+ * ```
17
+ */
18
+ export function getProxyURL(provider) {
19
+ return `${LOCKLLM_PROXY_BASE}/${provider}`;
20
+ }
21
+ /**
22
+ * Get all available proxy URLs
23
+ *
24
+ * @returns Record of all provider proxy URLs
25
+ *
26
+ * @example
27
+ * ```typescript
28
+ * const urls = getAllProxyURLs();
29
+ * console.log(urls.openai); // 'https://api.lockllm.com/v1/proxy/openai'
30
+ * console.log(urls.anthropic); // 'https://api.lockllm.com/v1/proxy/anthropic'
31
+ * ```
32
+ */
33
+ export function getAllProxyURLs() {
34
+ return {
35
+ openai: getProxyURL('openai'),
36
+ anthropic: getProxyURL('anthropic'),
37
+ gemini: getProxyURL('gemini'),
38
+ cohere: getProxyURL('cohere'),
39
+ openrouter: getProxyURL('openrouter'),
40
+ perplexity: getProxyURL('perplexity'),
41
+ mistral: getProxyURL('mistral'),
42
+ groq: getProxyURL('groq'),
43
+ deepseek: getProxyURL('deepseek'),
44
+ together: getProxyURL('together'),
45
+ xai: getProxyURL('xai'),
46
+ fireworks: getProxyURL('fireworks'),
47
+ anyscale: getProxyURL('anyscale'),
48
+ huggingface: getProxyURL('huggingface'),
49
+ azure: getProxyURL('azure'),
50
+ bedrock: getProxyURL('bedrock'),
51
+ 'vertex-ai': getProxyURL('vertex-ai'),
52
+ };
53
+ }
54
+ /**
55
+ * Generate a unique request ID
56
+ */
57
+ export function generateRequestId() {
58
+ return `req_${Date.now()}_${Math.random().toString(36).substring(2, 15)}`;
59
+ }
60
+ /**
61
+ * Sleep for a specified number of milliseconds
62
+ */
63
+ export function sleep(ms) {
64
+ return new Promise((resolve) => setTimeout(resolve, ms));
65
+ }
66
+ /**
67
+ * Parse Retry-After header value to milliseconds
68
+ */
69
+ export function parseRetryAfter(retryAfter) {
70
+ if (!retryAfter)
71
+ return undefined;
72
+ // If it's a number, it's seconds
73
+ const seconds = parseInt(retryAfter, 10);
74
+ if (!isNaN(seconds)) {
75
+ return seconds * 1000;
76
+ }
77
+ // If it's a date string, calculate diff
78
+ const date = new Date(retryAfter);
79
+ if (!isNaN(date.getTime())) {
80
+ return Math.max(0, date.getTime() - Date.now());
81
+ }
82
+ return undefined;
83
+ }
84
+ /**
85
+ * Exponential backoff delay calculation
86
+ */
87
+ export function calculateBackoff(attempt, baseDelay = 1000) {
88
+ return Math.min(baseDelay * Math.pow(2, attempt), 30000);
89
+ }
90
+ /**
91
+ * HTTP client for making requests to LockLLM API
92
+ */
93
+ export class HttpClient {
94
+ constructor(baseURL, apiKey, timeout = 60000, maxRetries = 3) {
95
+ this.baseURL = baseURL.replace(/\/$/, ''); // Remove trailing slash
96
+ this.apiKey = apiKey;
97
+ this.timeout = timeout;
98
+ this.maxRetries = maxRetries;
99
+ }
100
+ /**
101
+ * Make a GET request
102
+ */
103
+ async get(path, options) {
104
+ return this.request('GET', path, undefined, options);
105
+ }
106
+ /**
107
+ * Make a POST request
108
+ */
109
+ async post(path, body, options) {
110
+ return this.request('POST', path, body, options);
111
+ }
112
+ /**
113
+ * Make an HTTP request with retry logic
114
+ */
115
+ async request(method, path, body, options) {
116
+ const url = `${this.baseURL}${path}`;
117
+ const requestId = generateRequestId();
118
+ let lastError;
119
+ for (let attempt = 0; attempt <= this.maxRetries; attempt++) {
120
+ try {
121
+ const response = await this.makeRequest(method, url, body, requestId, options);
122
+ const responseRequestId = response.headers.get('X-Request-Id') || requestId;
123
+ // Success
124
+ if (response.ok) {
125
+ const data = await response.json();
126
+ return {
127
+ data: data,
128
+ requestId: responseRequestId,
129
+ };
130
+ }
131
+ // Handle rate limiting with retry
132
+ if (response.status === 429) {
133
+ const retryAfter = parseRetryAfter(response.headers.get('Retry-After'));
134
+ if (attempt < this.maxRetries) {
135
+ const delay = retryAfter || calculateBackoff(attempt);
136
+ await sleep(delay);
137
+ continue;
138
+ }
139
+ const errorData = await response.json().catch(() => ({}));
140
+ throw new RateLimitError(errorData.error?.message || 'Rate limit exceeded', retryAfter, responseRequestId);
141
+ }
142
+ // Handle other errors
143
+ const errorData = await response.json().catch(() => ({}));
144
+ throw parseError(errorData, responseRequestId);
145
+ }
146
+ catch (error) {
147
+ // If it's already a LockLLMError, rethrow immediately (don't retry)
148
+ if (error instanceof LockLLMError && !(error instanceof RateLimitError)) {
149
+ throw error;
150
+ }
151
+ lastError = error;
152
+ // Retry on network errors
153
+ if (attempt < this.maxRetries && this.isRetryableError(error)) {
154
+ await sleep(calculateBackoff(attempt));
155
+ continue;
156
+ }
157
+ // No more retries
158
+ break;
159
+ }
160
+ }
161
+ // All retries exhausted
162
+ if (lastError instanceof LockLLMError) {
163
+ throw lastError;
164
+ }
165
+ throw new NetworkError(lastError?.message || 'Network request failed', lastError, requestId);
166
+ }
167
+ /**
168
+ * Make a single HTTP request
169
+ */
170
+ async makeRequest(method, url, body, requestId, options) {
171
+ const controller = new AbortController();
172
+ const timeoutMs = options?.timeout || this.timeout;
173
+ const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
174
+ try {
175
+ const headers = {
176
+ 'Content-Type': 'application/json',
177
+ Authorization: `Bearer ${this.apiKey}`,
178
+ 'X-Request-Id': requestId,
179
+ ...options?.headers,
180
+ };
181
+ // Use user's signal if provided, otherwise use timeout controller
182
+ // If user provides a signal, they're responsible for timeout
183
+ const signal = options?.signal || controller.signal;
184
+ const response = await fetch(url, {
185
+ method,
186
+ headers,
187
+ body: body ? JSON.stringify(body) : undefined,
188
+ signal,
189
+ });
190
+ return response;
191
+ }
192
+ finally {
193
+ clearTimeout(timeoutId);
194
+ }
195
+ }
196
+ /**
197
+ * Check if an error is retryable
198
+ */
199
+ isRetryableError(error) {
200
+ // Retry on network errors
201
+ if (error instanceof TypeError && error.message.includes('fetch')) {
202
+ return true;
203
+ }
204
+ // Retry on timeout
205
+ if (error.name === 'AbortError') {
206
+ return true;
207
+ }
208
+ // Retry on rate limit (handled separately)
209
+ if (error instanceof RateLimitError) {
210
+ return true;
211
+ }
212
+ return false;
213
+ }
214
+ }
215
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1,72 @@
1
+ /**
2
+ * Anthropic SDK wrapper - Drop-in replacement
3
+ *
4
+ * This wrapper allows you to use the official Anthropic SDK with LockLLM protection
5
+ * by simply changing how you initialize the client.
6
+ *
7
+ * @example
8
+ * ```typescript
9
+ * // Replace this:
10
+ * // import Anthropic from '@anthropic-ai/sdk';
11
+ * // const anthropic = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY });
12
+ *
13
+ * // With this:
14
+ * import { createAnthropic } from '@lockllm/sdk/wrappers';
15
+ * const anthropic = createAnthropic({
16
+ * apiKey: process.env.LOCKLLM_API_KEY
17
+ * });
18
+ *
19
+ * // Everything else stays the same!
20
+ * const message = await anthropic.messages.create({
21
+ * model: "claude-3-5-sonnet-20241022",
22
+ * max_tokens: 1024,
23
+ * messages: [{ role: "user", content: "Hello!" }]
24
+ * });
25
+ * ```
26
+ */
27
+ export interface CreateAnthropicConfig {
28
+ /**
29
+ * Your LockLLM API key
30
+ * Get it from: https://www.lockllm.com/dashboard
31
+ */
32
+ apiKey: string;
33
+ /**
34
+ * Base URL for LockLLM proxy (default: https://api.lockllm.com/v1/proxy/anthropic)
35
+ * Override this only if you're using a custom LockLLM endpoint
36
+ */
37
+ baseURL?: string;
38
+ /**
39
+ * Other Anthropic client options
40
+ */
41
+ [key: string]: any;
42
+ }
43
+ /**
44
+ * Create an Anthropic client that routes through LockLLM proxy
45
+ *
46
+ * All requests are automatically scanned for prompt injection before being
47
+ * forwarded to Anthropic. Your Anthropic API key should be configured in the
48
+ * LockLLM dashboard at https://www.lockllm.com/dashboard
49
+ *
50
+ * @param config - Configuration options
51
+ * @returns Anthropic client instance
52
+ *
53
+ * @example
54
+ * ```typescript
55
+ * const anthropic = createAnthropic({
56
+ * apiKey: process.env.LOCKLLM_API_KEY
57
+ * });
58
+ *
59
+ * const message = await anthropic.messages.create({
60
+ * model: "claude-3-5-sonnet-20241022",
61
+ * max_tokens: 1024,
62
+ * messages: [{ role: "user", content: "Hello!" }]
63
+ * });
64
+ * ```
65
+ */
66
+ /**
67
+ * Lazy-load Anthropic SDK constructor
68
+ * @internal - exposed for testing purposes
69
+ */
70
+ export declare function getAnthropicConstructor(requireFn?: NodeJS.Require): any;
71
+ export declare function createAnthropic(config: CreateAnthropicConfig): any;
72
+ //# sourceMappingURL=anthropic-wrapper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anthropic-wrapper.d.ts","sourceRoot":"","sources":["../../src/wrappers/anthropic-wrapper.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH,MAAM,WAAW,qBAAqB;IACpC;;;OAGG;IACH,MAAM,EAAE,MAAM,CAAC;IAEf;;;OAGG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IAEjB;;OAEG;IACH,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;CACpB;AAED;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,iBAAU,GAAG,GAAG,CAShE;AAED,wBAAgB,eAAe,CAAC,MAAM,EAAE,qBAAqB,GAAG,GAAG,CAYlE"}