@bernierllc/ai-provider-openai 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.
- package/.eslintrc.js +35 -0
- package/README.md +294 -0
- package/__tests__/OpenAIProvider.test.ts +574 -0
- package/__tests__/error-handling.test.ts +315 -0
- package/__tests__/model-registry.test.ts +270 -0
- package/__tests__/openai-specific.test.ts +333 -0
- package/dist/OpenAIProvider.d.ts +22 -0
- package/dist/OpenAIProvider.d.ts.map +1 -0
- package/dist/OpenAIProvider.js +320 -0
- package/dist/OpenAIProvider.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +23 -0
- package/dist/index.js.map +1 -0
- package/dist/models/model-registry.d.ts +8 -0
- package/dist/models/model-registry.d.ts.map +1 -0
- package/dist/models/model-registry.js +147 -0
- package/dist/models/model-registry.js.map +1 -0
- package/dist/types/openai-types.d.ts +28 -0
- package/dist/types/openai-types.d.ts.map +1 -0
- package/dist/types/openai-types.js +3 -0
- package/dist/types/openai-types.js.map +1 -0
- package/dist/utils/error-handling.d.ts +5 -0
- package/dist/utils/error-handling.d.ts.map +1 -0
- package/dist/utils/error-handling.js +67 -0
- package/dist/utils/error-handling.js.map +1 -0
- package/jest.config.cjs +29 -0
- package/package.json +63 -0
- package/src/OpenAIProvider.ts +435 -0
- package/src/index.ts +12 -0
- package/src/models/model-registry.ts +178 -0
- package/src/types/openai-types.ts +51 -0
- package/src/utils/error-handling.ts +101 -0
- package/tsconfig.json +31 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
/*
|
|
2
|
+
Copyright (c) 2025 Bernier LLC
|
|
3
|
+
|
|
4
|
+
This file is licensed to the client under a limited-use license.
|
|
5
|
+
The client may use and modify this code only within the scope of the project it was delivered for.
|
|
6
|
+
Redistribution or use in other products or commercial offerings is not permitted without written consent from Bernier LLC.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
import { AIProviderError } from '@bernierllc/ai-provider-core';
|
|
10
|
+
import OpenAI from 'openai';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Convert OpenAI API errors to AIProviderError
|
|
14
|
+
*/
|
|
15
|
+
export function handleOpenAIError(error: unknown): AIProviderError {
|
|
16
|
+
if (error instanceof OpenAI.APIError) {
|
|
17
|
+
const status = typeof error.status === 'number' ? error.status : undefined;
|
|
18
|
+
return new AIProviderError(
|
|
19
|
+
`OpenAI API Error: ${error.message}`,
|
|
20
|
+
mapOpenAIErrorCode(status),
|
|
21
|
+
'openai',
|
|
22
|
+
{
|
|
23
|
+
status,
|
|
24
|
+
type: error.type,
|
|
25
|
+
code: error.code
|
|
26
|
+
}
|
|
27
|
+
);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
if (error instanceof Error) {
|
|
31
|
+
return new AIProviderError(
|
|
32
|
+
error.message,
|
|
33
|
+
'UNKNOWN_ERROR',
|
|
34
|
+
'openai'
|
|
35
|
+
);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
return new AIProviderError(
|
|
39
|
+
'Unknown error occurred',
|
|
40
|
+
'UNKNOWN_ERROR',
|
|
41
|
+
'openai'
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
/**
|
|
46
|
+
* Map OpenAI HTTP status codes to error codes
|
|
47
|
+
*/
|
|
48
|
+
function mapOpenAIErrorCode(status: number | undefined): string {
|
|
49
|
+
if (!status) return 'UNKNOWN_ERROR';
|
|
50
|
+
|
|
51
|
+
switch (status) {
|
|
52
|
+
case 400:
|
|
53
|
+
return 'INVALID_REQUEST';
|
|
54
|
+
case 401:
|
|
55
|
+
return 'AUTHENTICATION_ERROR';
|
|
56
|
+
case 403:
|
|
57
|
+
return 'PERMISSION_DENIED';
|
|
58
|
+
case 404:
|
|
59
|
+
return 'NOT_FOUND';
|
|
60
|
+
case 429:
|
|
61
|
+
return 'RATE_LIMIT_ERROR';
|
|
62
|
+
case 500:
|
|
63
|
+
case 502:
|
|
64
|
+
case 503:
|
|
65
|
+
return 'SERVER_ERROR';
|
|
66
|
+
case 504:
|
|
67
|
+
return 'TIMEOUT_ERROR';
|
|
68
|
+
default:
|
|
69
|
+
return 'UNKNOWN_ERROR';
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Check if error is retryable
|
|
75
|
+
*/
|
|
76
|
+
export function isRetryableError(error: AIProviderError): boolean {
|
|
77
|
+
const retryableCodes = [
|
|
78
|
+
'RATE_LIMIT_ERROR',
|
|
79
|
+
'SERVER_ERROR',
|
|
80
|
+
'TIMEOUT_ERROR',
|
|
81
|
+
'NETWORK_ERROR'
|
|
82
|
+
];
|
|
83
|
+
return retryableCodes.includes(error.code);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Get suggested retry delay based on error
|
|
88
|
+
*/
|
|
89
|
+
export function getRetryDelay(error: AIProviderError, attempt: number): number {
|
|
90
|
+
// Rate limit errors may include retry-after header
|
|
91
|
+
if (error.code === 'RATE_LIMIT_ERROR') {
|
|
92
|
+
return Math.min(Math.pow(2, attempt) * 1000, 60000); // Cap at 60 seconds
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// Exponential backoff for other retryable errors
|
|
96
|
+
if (isRetryableError(error)) {
|
|
97
|
+
return Math.min(Math.pow(2, attempt) * 500, 30000); // Cap at 30 seconds
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
return 0; // Non-retryable
|
|
101
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"target": "ES2020",
|
|
4
|
+
"module": "commonjs",
|
|
5
|
+
"lib": ["ES2020"],
|
|
6
|
+
"declaration": true,
|
|
7
|
+
"declarationMap": true,
|
|
8
|
+
"sourceMap": true,
|
|
9
|
+
"outDir": "./dist",
|
|
10
|
+
"rootDir": "./src",
|
|
11
|
+
"removeComments": true,
|
|
12
|
+
"strict": true,
|
|
13
|
+
"noImplicitAny": true,
|
|
14
|
+
"strictNullChecks": true,
|
|
15
|
+
"strictFunctionTypes": true,
|
|
16
|
+
"strictBindCallApply": true,
|
|
17
|
+
"strictPropertyInitialization": true,
|
|
18
|
+
"noImplicitThis": true,
|
|
19
|
+
"alwaysStrict": true,
|
|
20
|
+
"noUnusedLocals": true,
|
|
21
|
+
"noUnusedParameters": true,
|
|
22
|
+
"noImplicitReturns": true,
|
|
23
|
+
"noFallthroughCasesInSwitch": true,
|
|
24
|
+
"esModuleInterop": true,
|
|
25
|
+
"skipLibCheck": true,
|
|
26
|
+
"forceConsistentCasingInFileNames": true,
|
|
27
|
+
"resolveJsonModule": true
|
|
28
|
+
},
|
|
29
|
+
"include": ["src/**/*"],
|
|
30
|
+
"exclude": ["node_modules", "dist", "__tests__", "**/*.test.ts"]
|
|
31
|
+
}
|