@llumiverse/drivers 1.0.0-dev.20260202.145450Z → 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 (240) hide show
  1. package/lib/cjs/adobe/firefly.js +120 -0
  2. package/lib/cjs/adobe/firefly.js.map +1 -0
  3. package/lib/cjs/azure/azure_foundry.js +432 -0
  4. package/lib/cjs/azure/azure_foundry.js.map +1 -0
  5. package/lib/cjs/bedrock/converse.js +359 -0
  6. package/lib/cjs/bedrock/converse.js.map +1 -0
  7. package/lib/cjs/bedrock/index.js +1441 -0
  8. package/lib/cjs/bedrock/index.js.map +1 -0
  9. package/lib/cjs/bedrock/nova-image-payload.js +207 -0
  10. package/lib/cjs/bedrock/nova-image-payload.js.map +1 -0
  11. package/lib/cjs/bedrock/payloads.js +3 -0
  12. package/lib/cjs/bedrock/payloads.js.map +1 -0
  13. package/lib/cjs/bedrock/s3.js +107 -0
  14. package/lib/cjs/bedrock/s3.js.map +1 -0
  15. package/lib/cjs/bedrock/twelvelabs.js +87 -0
  16. package/lib/cjs/bedrock/twelvelabs.js.map +1 -0
  17. package/lib/cjs/groq/index.js +326 -0
  18. package/lib/cjs/groq/index.js.map +1 -0
  19. package/lib/cjs/huggingface_ie.js +201 -0
  20. package/lib/cjs/huggingface_ie.js.map +1 -0
  21. package/lib/cjs/index.js +31 -0
  22. package/lib/cjs/index.js.map +1 -0
  23. package/lib/cjs/mistral/index.js +176 -0
  24. package/lib/cjs/mistral/index.js.map +1 -0
  25. package/lib/cjs/mistral/types.js +83 -0
  26. package/lib/cjs/mistral/types.js.map +1 -0
  27. package/lib/cjs/openai/azure_openai.js +72 -0
  28. package/lib/cjs/openai/azure_openai.js.map +1 -0
  29. package/lib/cjs/openai/index.js +1100 -0
  30. package/lib/cjs/openai/index.js.map +1 -0
  31. package/lib/cjs/openai/openai.js +21 -0
  32. package/lib/cjs/openai/openai.js.map +1 -0
  33. package/lib/cjs/openai/openai_compatible.js +63 -0
  34. package/lib/cjs/openai/openai_compatible.js.map +1 -0
  35. package/lib/cjs/openai/openai_format.js +131 -0
  36. package/lib/cjs/openai/openai_format.js.map +1 -0
  37. package/lib/cjs/package.json +3 -0
  38. package/lib/cjs/replicate.js +275 -0
  39. package/lib/cjs/replicate.js.map +1 -0
  40. package/lib/cjs/test-driver/TestErrorCompletionStream.js +20 -0
  41. package/lib/cjs/test-driver/TestErrorCompletionStream.js.map +1 -0
  42. package/lib/cjs/test-driver/TestValidationErrorCompletionStream.js +24 -0
  43. package/lib/cjs/test-driver/TestValidationErrorCompletionStream.js.map +1 -0
  44. package/lib/cjs/test-driver/index.js +109 -0
  45. package/lib/cjs/test-driver/index.js.map +1 -0
  46. package/lib/cjs/test-driver/utils.js +30 -0
  47. package/lib/cjs/test-driver/utils.js.map +1 -0
  48. package/lib/cjs/togetherai/index.js +126 -0
  49. package/lib/cjs/togetherai/index.js.map +1 -0
  50. package/lib/cjs/togetherai/interfaces.js +3 -0
  51. package/lib/cjs/togetherai/interfaces.js.map +1 -0
  52. package/lib/cjs/vertexai/debug.js +12 -0
  53. package/lib/cjs/vertexai/debug.js.map +1 -0
  54. package/lib/cjs/vertexai/embeddings/embeddings-image.js +27 -0
  55. package/lib/cjs/vertexai/embeddings/embeddings-image.js.map +1 -0
  56. package/lib/cjs/vertexai/embeddings/embeddings-text.js +23 -0
  57. package/lib/cjs/vertexai/embeddings/embeddings-text.js.map +1 -0
  58. package/lib/cjs/vertexai/index.js +635 -0
  59. package/lib/cjs/vertexai/index.js.map +1 -0
  60. package/lib/cjs/vertexai/models/claude.js +842 -0
  61. package/lib/cjs/vertexai/models/claude.js.map +1 -0
  62. package/lib/cjs/vertexai/models/gemini.js +1110 -0
  63. package/lib/cjs/vertexai/models/gemini.js.map +1 -0
  64. package/lib/cjs/vertexai/models/imagen.js +303 -0
  65. package/lib/cjs/vertexai/models/imagen.js.map +1 -0
  66. package/lib/cjs/vertexai/models/llama.js +183 -0
  67. package/lib/cjs/vertexai/models/llama.js.map +1 -0
  68. package/lib/cjs/vertexai/models.js +35 -0
  69. package/lib/cjs/vertexai/models.js.map +1 -0
  70. package/lib/cjs/watsonx/index.js +161 -0
  71. package/lib/cjs/watsonx/index.js.map +1 -0
  72. package/lib/cjs/watsonx/interfaces.js +3 -0
  73. package/lib/cjs/watsonx/interfaces.js.map +1 -0
  74. package/lib/cjs/xai/index.js +65 -0
  75. package/lib/cjs/xai/index.js.map +1 -0
  76. package/lib/esm/adobe/firefly.js +116 -0
  77. package/lib/esm/adobe/firefly.js.map +1 -0
  78. package/lib/esm/azure/azure_foundry.js +426 -0
  79. package/lib/esm/azure/azure_foundry.js.map +1 -0
  80. package/lib/esm/bedrock/converse.js +352 -0
  81. package/lib/esm/bedrock/converse.js.map +1 -0
  82. package/lib/esm/bedrock/index.js +1434 -0
  83. package/lib/esm/bedrock/index.js.map +1 -0
  84. package/lib/esm/bedrock/nova-image-payload.js +203 -0
  85. package/lib/esm/bedrock/nova-image-payload.js.map +1 -0
  86. package/lib/esm/bedrock/payloads.js +2 -0
  87. package/lib/esm/bedrock/payloads.js.map +1 -0
  88. package/lib/esm/bedrock/s3.js +99 -0
  89. package/lib/esm/bedrock/s3.js.map +1 -0
  90. package/lib/esm/bedrock/twelvelabs.js +84 -0
  91. package/lib/esm/bedrock/twelvelabs.js.map +1 -0
  92. package/lib/esm/groq/index.js +319 -0
  93. package/lib/esm/groq/index.js.map +1 -0
  94. package/lib/esm/huggingface_ie.js +197 -0
  95. package/lib/esm/huggingface_ie.js.map +1 -0
  96. package/lib/esm/index.js +15 -0
  97. package/lib/esm/index.js.map +1 -0
  98. package/lib/esm/mistral/index.js +172 -0
  99. package/lib/esm/mistral/index.js.map +1 -0
  100. package/lib/esm/mistral/types.js +80 -0
  101. package/lib/esm/mistral/types.js.map +1 -0
  102. package/lib/esm/openai/azure_openai.js +68 -0
  103. package/lib/esm/openai/azure_openai.js.map +1 -0
  104. package/lib/esm/openai/index.js +1093 -0
  105. package/lib/esm/openai/index.js.map +1 -0
  106. package/lib/esm/openai/openai.js +14 -0
  107. package/lib/esm/openai/openai.js.map +1 -0
  108. package/lib/esm/openai/openai_compatible.js +56 -0
  109. package/lib/esm/openai/openai_compatible.js.map +1 -0
  110. package/lib/esm/openai/openai_format.js +127 -0
  111. package/lib/esm/openai/openai_format.js.map +1 -0
  112. package/lib/esm/replicate.js +268 -0
  113. package/lib/esm/replicate.js.map +1 -0
  114. package/lib/esm/test-driver/TestErrorCompletionStream.js +16 -0
  115. package/lib/esm/test-driver/TestErrorCompletionStream.js.map +1 -0
  116. package/lib/esm/test-driver/TestValidationErrorCompletionStream.js +20 -0
  117. package/lib/esm/test-driver/TestValidationErrorCompletionStream.js.map +1 -0
  118. package/lib/esm/test-driver/index.js +91 -0
  119. package/lib/esm/test-driver/index.js.map +1 -0
  120. package/lib/esm/test-driver/utils.js +25 -0
  121. package/lib/esm/test-driver/utils.js.map +1 -0
  122. package/lib/esm/togetherai/index.js +122 -0
  123. package/lib/esm/togetherai/index.js.map +1 -0
  124. package/lib/esm/togetherai/interfaces.js +2 -0
  125. package/lib/esm/togetherai/interfaces.js.map +1 -0
  126. package/lib/esm/vertexai/debug.js +6 -0
  127. package/lib/esm/vertexai/debug.js.map +1 -0
  128. package/lib/esm/vertexai/embeddings/embeddings-image.js +24 -0
  129. package/lib/esm/vertexai/embeddings/embeddings-image.js.map +1 -0
  130. package/lib/esm/vertexai/embeddings/embeddings-text.js +20 -0
  131. package/lib/esm/vertexai/embeddings/embeddings-text.js.map +1 -0
  132. package/lib/esm/vertexai/index.js +630 -0
  133. package/lib/esm/vertexai/index.js.map +1 -0
  134. package/lib/esm/vertexai/models/claude.js +833 -0
  135. package/lib/esm/vertexai/models/claude.js.map +1 -0
  136. package/lib/esm/vertexai/models/gemini.js +1104 -0
  137. package/lib/esm/vertexai/models/gemini.js.map +1 -0
  138. package/lib/esm/vertexai/models/imagen.js +299 -0
  139. package/lib/esm/vertexai/models/imagen.js.map +1 -0
  140. package/lib/esm/vertexai/models/llama.js +179 -0
  141. package/lib/esm/vertexai/models/llama.js.map +1 -0
  142. package/lib/esm/vertexai/models.js +32 -0
  143. package/lib/esm/vertexai/models.js.map +1 -0
  144. package/lib/esm/watsonx/index.js +157 -0
  145. package/lib/esm/watsonx/index.js.map +1 -0
  146. package/lib/esm/watsonx/interfaces.js +2 -0
  147. package/lib/esm/watsonx/interfaces.js.map +1 -0
  148. package/lib/esm/xai/index.js +58 -0
  149. package/lib/esm/xai/index.js.map +1 -0
  150. package/lib/types/adobe/firefly.d.ts +30 -0
  151. package/lib/types/adobe/firefly.d.ts.map +1 -0
  152. package/lib/types/azure/azure_foundry.d.ts +52 -0
  153. package/lib/types/azure/azure_foundry.d.ts.map +1 -0
  154. package/lib/types/bedrock/converse.d.ts +8 -0
  155. package/lib/types/bedrock/converse.d.ts.map +1 -0
  156. package/lib/types/bedrock/index.d.ts +135 -0
  157. package/lib/types/bedrock/index.d.ts.map +1 -0
  158. package/lib/types/bedrock/nova-image-payload.d.ts +74 -0
  159. package/lib/types/bedrock/nova-image-payload.d.ts.map +1 -0
  160. package/lib/types/bedrock/payloads.d.ts +12 -0
  161. package/lib/types/bedrock/payloads.d.ts.map +1 -0
  162. package/lib/types/bedrock/s3.d.ts +23 -0
  163. package/lib/types/bedrock/s3.d.ts.map +1 -0
  164. package/lib/types/bedrock/twelvelabs.d.ts +50 -0
  165. package/lib/types/bedrock/twelvelabs.d.ts.map +1 -0
  166. package/lib/types/groq/index.d.ts +27 -0
  167. package/lib/types/groq/index.d.ts.map +1 -0
  168. package/lib/types/huggingface_ie.d.ts +35 -0
  169. package/lib/types/huggingface_ie.d.ts.map +1 -0
  170. package/lib/types/index.d.ts +15 -0
  171. package/lib/types/index.d.ts.map +1 -0
  172. package/lib/types/mistral/index.d.ts +25 -0
  173. package/lib/types/mistral/index.d.ts.map +1 -0
  174. package/lib/types/mistral/types.d.ts +127 -0
  175. package/lib/types/mistral/types.d.ts.map +1 -0
  176. package/lib/types/openai/azure_openai.d.ts +25 -0
  177. package/lib/types/openai/azure_openai.d.ts.map +1 -0
  178. package/lib/types/openai/index.d.ts +126 -0
  179. package/lib/types/openai/index.d.ts.map +1 -0
  180. package/lib/types/openai/openai.d.ts +15 -0
  181. package/lib/types/openai/openai.d.ts.map +1 -0
  182. package/lib/types/openai/openai_compatible.d.ts +31 -0
  183. package/lib/types/openai/openai_compatible.d.ts.map +1 -0
  184. package/lib/types/openai/openai_format.d.ts +21 -0
  185. package/lib/types/openai/openai_format.d.ts.map +1 -0
  186. package/lib/types/replicate.d.ts +48 -0
  187. package/lib/types/replicate.d.ts.map +1 -0
  188. package/lib/types/test-driver/TestErrorCompletionStream.d.ts +9 -0
  189. package/lib/types/test-driver/TestErrorCompletionStream.d.ts.map +1 -0
  190. package/lib/types/test-driver/TestValidationErrorCompletionStream.d.ts +9 -0
  191. package/lib/types/test-driver/TestValidationErrorCompletionStream.d.ts.map +1 -0
  192. package/lib/types/test-driver/index.d.ts +24 -0
  193. package/lib/types/test-driver/index.d.ts.map +1 -0
  194. package/lib/types/test-driver/utils.d.ts +5 -0
  195. package/lib/types/test-driver/utils.d.ts.map +1 -0
  196. package/lib/types/togetherai/index.d.ts +23 -0
  197. package/lib/types/togetherai/index.d.ts.map +1 -0
  198. package/lib/types/togetherai/interfaces.d.ts +96 -0
  199. package/lib/types/togetherai/interfaces.d.ts.map +1 -0
  200. package/lib/types/vertexai/debug.d.ts +2 -0
  201. package/lib/types/vertexai/debug.d.ts.map +1 -0
  202. package/lib/types/vertexai/embeddings/embeddings-image.d.ts +11 -0
  203. package/lib/types/vertexai/embeddings/embeddings-image.d.ts.map +1 -0
  204. package/lib/types/vertexai/embeddings/embeddings-text.d.ts +10 -0
  205. package/lib/types/vertexai/embeddings/embeddings-text.d.ts.map +1 -0
  206. package/lib/types/vertexai/index.d.ts +79 -0
  207. package/lib/types/vertexai/index.d.ts.map +1 -0
  208. package/lib/types/vertexai/models/claude.d.ts +103 -0
  209. package/lib/types/vertexai/models/claude.d.ts.map +1 -0
  210. package/lib/types/vertexai/models/gemini.d.ts +78 -0
  211. package/lib/types/vertexai/models/gemini.d.ts.map +1 -0
  212. package/lib/types/vertexai/models/imagen.d.ts +75 -0
  213. package/lib/types/vertexai/models/imagen.d.ts.map +1 -0
  214. package/lib/types/vertexai/models/llama.d.ts +20 -0
  215. package/lib/types/vertexai/models/llama.d.ts.map +1 -0
  216. package/lib/types/vertexai/models.d.ts +20 -0
  217. package/lib/types/vertexai/models.d.ts.map +1 -0
  218. package/lib/types/watsonx/index.d.ts +27 -0
  219. package/lib/types/watsonx/index.d.ts.map +1 -0
  220. package/lib/types/watsonx/interfaces.d.ts +65 -0
  221. package/lib/types/watsonx/interfaces.d.ts.map +1 -0
  222. package/lib/types/xai/index.d.ts +18 -0
  223. package/lib/types/xai/index.d.ts.map +1 -0
  224. package/package.json +18 -18
  225. package/src/bedrock/converse.ts +85 -10
  226. package/src/bedrock/error-handling.test.ts +352 -0
  227. package/src/bedrock/index.ts +293 -16
  228. package/src/groq/index.ts +9 -4
  229. package/src/mistral/index.ts +25 -22
  230. package/src/mistral/types.ts +0 -5
  231. package/src/openai/error-handling.test.ts +567 -0
  232. package/src/openai/index.ts +513 -33
  233. package/src/openai/openai_compatible.ts +7 -0
  234. package/src/openai/openai_format.ts +1 -1
  235. package/src/vertexai/index.ts +61 -13
  236. package/src/vertexai/models/claude-error-handling.test.ts +432 -0
  237. package/src/vertexai/models/claude.ts +287 -10
  238. package/src/vertexai/models/gemini-error-handling.test.ts +353 -0
  239. package/src/vertexai/models/gemini.ts +329 -52
  240. package/src/vertexai/models.ts +7 -2
@@ -0,0 +1,352 @@
1
+ import { LlumiverseError } from '@llumiverse/core';
2
+ import { beforeEach, describe, expect, it } from 'vitest';
3
+ import { BedrockDriver } from './index.js';
4
+
5
+ describe('BedrockDriver Error Handling', () => {
6
+ let driver: BedrockDriver;
7
+
8
+ beforeEach(() => {
9
+ driver = new BedrockDriver({ region: 'us-east-1' });
10
+ });
11
+
12
+ describe('formatLlumiverseError', () => {
13
+ it('should handle ValidationException with status code in message', () => {
14
+ const awsError = {
15
+ name: 'ValidationException',
16
+ message: "1 validation error detected: Value '32424.0' at 'inferenceConfig.temperature' failed to satisfy constraint: Member must have value less than or equal to 1",
17
+ $fault: 'client',
18
+ $metadata: {
19
+ httpStatusCode: 400,
20
+ requestId: 'e3ed39d8-bdf5-40e6-9d2c-9a1cc8323f61',
21
+ attempts: 1,
22
+ totalRetryDelay: 0,
23
+ },
24
+ };
25
+
26
+ const error = driver.formatLlumiverseError(awsError, {
27
+ provider: 'bedrock',
28
+ model: 'test-model',
29
+ operation: 'execute',
30
+ });
31
+
32
+ expect(error).toBeInstanceOf(LlumiverseError);
33
+ expect(error.code).toBe(400);
34
+ expect(error.retryable).toBe(false);
35
+ expect(error.message).toContain('[400]');
36
+ expect(error.message).toContain('validation error detected');
37
+ expect(error.message).toContain('Request ID: e3ed39d8-bdf5-40e6-9d2c-9a1cc8323f61');
38
+ expect(error.context.provider).toBe('bedrock');
39
+ });
40
+
41
+ it('should handle ThrottlingException as retryable', () => {
42
+ const awsError = {
43
+ name: 'ThrottlingException',
44
+ message: 'The number of requests exceeds the limit',
45
+ $fault: 'client',
46
+ $metadata: {
47
+ httpStatusCode: 429,
48
+ requestId: 'abc123',
49
+ },
50
+ };
51
+
52
+ const error = driver.formatLlumiverseError(awsError, {
53
+ provider: 'bedrock',
54
+ model: 'test-model',
55
+ operation: 'execute',
56
+ });
57
+
58
+ expect(error.retryable).toBe(true);
59
+ expect(error.code).toBe(429);
60
+ expect(error.message).toContain('[429]');
61
+ expect(error.message).toContain('Request ID: abc123');
62
+ });
63
+
64
+ it('should handle InternalServerException as retryable', () => {
65
+ const awsError = {
66
+ name: 'InternalServerException',
67
+ message: 'An internal server error occurred',
68
+ $fault: 'server',
69
+ $metadata: {
70
+ httpStatusCode: 500,
71
+ requestId: 'server-error-123',
72
+ },
73
+ };
74
+
75
+ const error = driver.formatLlumiverseError(awsError, {
76
+ provider: 'bedrock',
77
+ model: 'test-model',
78
+ operation: 'execute',
79
+ });
80
+
81
+ expect(error.retryable).toBe(true);
82
+ expect(error.code).toBe(500);
83
+ expect(error.message).toContain('[500]');
84
+ });
85
+
86
+ it('should handle ServiceUnavailableException as retryable', () => {
87
+ const awsError = {
88
+ name: 'ServiceUnavailableException',
89
+ message: 'Service is temporarily unavailable',
90
+ $fault: 'server',
91
+ $metadata: {
92
+ httpStatusCode: 503,
93
+ requestId: 'unavail-123',
94
+ },
95
+ };
96
+
97
+ const error = driver.formatLlumiverseError(awsError, {
98
+ provider: 'bedrock',
99
+ model: 'test-model',
100
+ operation: 'execute',
101
+ });
102
+
103
+ expect(error.retryable).toBe(true);
104
+ expect(error.code).toBe(503);
105
+ });
106
+
107
+ it('should handle AccessDeniedException as not retryable', () => {
108
+ const awsError = {
109
+ name: 'AccessDeniedException',
110
+ message: 'Access denied',
111
+ $fault: 'client',
112
+ $metadata: {
113
+ httpStatusCode: 403,
114
+ requestId: 'access-denied-123',
115
+ },
116
+ };
117
+
118
+ const error = driver.formatLlumiverseError(awsError, {
119
+ provider: 'bedrock',
120
+ model: 'test-model',
121
+ operation: 'execute',
122
+ });
123
+
124
+ expect(error.retryable).toBe(false);
125
+ expect(error.code).toBe(403);
126
+ });
127
+
128
+ it('should handle ResourceNotFoundException as not retryable', () => {
129
+ const awsError = {
130
+ name: 'ResourceNotFoundException',
131
+ message: 'Resource not found',
132
+ $fault: 'client',
133
+ $metadata: {
134
+ httpStatusCode: 404,
135
+ requestId: 'not-found-123',
136
+ },
137
+ };
138
+
139
+ const error = driver.formatLlumiverseError(awsError, {
140
+ provider: 'bedrock',
141
+ model: 'test-model',
142
+ operation: 'execute',
143
+ });
144
+
145
+ expect(error.retryable).toBe(false);
146
+ expect(error.code).toBe(404);
147
+ });
148
+
149
+ it('should handle ServiceQuotaExceededException as retryable', () => {
150
+ const awsError = {
151
+ name: 'ServiceQuotaExceededException',
152
+ message: 'Service quota exceeded',
153
+ $fault: 'client',
154
+ $metadata: {
155
+ httpStatusCode: 402,
156
+ requestId: 'quota-123',
157
+ },
158
+ };
159
+
160
+ const error = driver.formatLlumiverseError(awsError, {
161
+ provider: 'bedrock',
162
+ model: 'test-model',
163
+ operation: 'execute',
164
+ });
165
+
166
+ expect(error.retryable).toBe(true);
167
+ });
168
+
169
+ it('should handle ConflictException as not retryable', () => {
170
+ const awsError = {
171
+ name: 'ConflictException',
172
+ message: 'Conflict',
173
+ $fault: 'client',
174
+ $metadata: {
175
+ httpStatusCode: 409,
176
+ requestId: 'conflict-123',
177
+ },
178
+ };
179
+
180
+ const error = driver.formatLlumiverseError(awsError, {
181
+ provider: 'bedrock',
182
+ model: 'test-model',
183
+ operation: 'execute',
184
+ });
185
+
186
+ expect(error.retryable).toBe(false);
187
+ expect(error.code).toBe(409);
188
+ });
189
+
190
+ it('should handle ResourceInUseException as not retryable', () => {
191
+ const awsError = {
192
+ name: 'ResourceInUseException',
193
+ message: 'Resource in use',
194
+ $fault: 'client',
195
+ $metadata: {
196
+ httpStatusCode: 400,
197
+ requestId: 'in-use-123',
198
+ },
199
+ };
200
+
201
+ const error = driver.formatLlumiverseError(awsError, {
202
+ provider: 'bedrock',
203
+ model: 'test-model',
204
+ operation: 'execute',
205
+ });
206
+
207
+ expect(error.retryable).toBe(false);
208
+ });
209
+
210
+ it('should handle error without status code using error name', () => {
211
+ const awsError = {
212
+ name: 'ThrottlingException',
213
+ message: 'Rate limited',
214
+ $fault: 'client',
215
+ $metadata: {
216
+ requestId: 'no-status-123',
217
+ },
218
+ };
219
+
220
+ const error = driver.formatLlumiverseError(awsError, {
221
+ provider: 'bedrock',
222
+ model: 'test-model',
223
+ operation: 'execute',
224
+ });
225
+
226
+ expect(error.code).toBeUndefined(); // No status code available
227
+ expect(error.name).toBe('ThrottlingException'); // Error name preserved
228
+ expect(error.retryable).toBe(true);
229
+ expect(error.message).not.toContain('[ThrottlingException]'); // status code format only for numbers
230
+ expect(error.message).toContain('Rate limited');
231
+ });
232
+
233
+ it('should fall back to fault type for unknown errors', () => {
234
+ const serverError = {
235
+ name: 'UnknownServerError',
236
+ message: 'Unknown error',
237
+ $fault: 'server',
238
+ $metadata: {
239
+ httpStatusCode: 599,
240
+ },
241
+ };
242
+
243
+ const error = driver.formatLlumiverseError(serverError, {
244
+ provider: 'bedrock',
245
+ model: 'test-model',
246
+ operation: 'execute',
247
+ });
248
+
249
+ expect(error.retryable).toBe(true); // 5xx is retryable
250
+
251
+ const clientError = {
252
+ name: 'UnknownClientError',
253
+ message: 'Unknown error',
254
+ $fault: 'client',
255
+ $metadata: {
256
+ httpStatusCode: 499,
257
+ },
258
+ };
259
+
260
+ const error2 = driver.formatLlumiverseError(clientError, {
261
+ provider: 'bedrock',
262
+ model: 'test-model',
263
+ operation: 'execute',
264
+ });
265
+
266
+ expect(error2.retryable).toBe(false); // 4xx is not retryable
267
+ });
268
+
269
+ it('should handle non-AWS errors by delegating to parent', () => {
270
+ const regularError = new Error('Regular error');
271
+
272
+ const error = driver.formatLlumiverseError(regularError, {
273
+ provider: 'bedrock',
274
+ model: 'test-model',
275
+ operation: 'execute',
276
+ });
277
+
278
+ expect(error).toBeInstanceOf(LlumiverseError);
279
+ expect(error.code).toBeUndefined(); // No numeric status code available
280
+ expect(error.retryable).toBeUndefined(); // Unknown errors - let consumer decide
281
+ });
282
+
283
+ it('should preserve original error for debugging', () => {
284
+ const awsError = {
285
+ name: 'ValidationException',
286
+ message: 'Validation failed',
287
+ $fault: 'client',
288
+ $metadata: {
289
+ httpStatusCode: 400,
290
+ requestId: 'test-123',
291
+ },
292
+ };
293
+
294
+ const error = driver.formatLlumiverseError(awsError, {
295
+ provider: 'bedrock',
296
+ model: 'test-model',
297
+ operation: 'execute',
298
+ });
299
+
300
+ expect(error.originalError).toBe(awsError);
301
+ expect((error.originalError as any).$metadata.requestId).toBe('test-123');
302
+ });
303
+ });
304
+
305
+ describe('isBedrockErrorRetryable', () => {
306
+ it('should classify retryable errors correctly', () => {
307
+ const retryableErrors = [
308
+ 'ThrottlingException',
309
+ 'ServiceUnavailableException',
310
+ 'InternalServerException',
311
+ 'ServiceQuotaExceededException',
312
+ ];
313
+
314
+ retryableErrors.forEach((errorName) => {
315
+ const result = (driver as any).isBedrockErrorRetryable(errorName, undefined, undefined);
316
+ expect(result, `${errorName} should be retryable`).toBe(true);
317
+ });
318
+ });
319
+
320
+ it('should classify non-retryable errors correctly', () => {
321
+ const nonRetryableErrors = [
322
+ 'ValidationException',
323
+ 'AccessDeniedException',
324
+ 'ResourceNotFoundException',
325
+ 'ConflictException',
326
+ 'ResourceInUseException',
327
+ 'TooManyTagsException',
328
+ ];
329
+
330
+ nonRetryableErrors.forEach((errorName) => {
331
+ const result = (driver as any).isBedrockErrorRetryable(errorName, undefined, undefined);
332
+ expect(result, `${errorName} should not be retryable`).toBe(false);
333
+ });
334
+ });
335
+
336
+ it('should use HTTP status codes when available', () => {
337
+ expect((driver as any).isBedrockErrorRetryable('UnknownError', 429, undefined)).toBe(true);
338
+ expect((driver as any).isBedrockErrorRetryable('UnknownError', 408, undefined)).toBe(true);
339
+ expect((driver as any).isBedrockErrorRetryable('UnknownError', 529, undefined)).toBe(true);
340
+ expect((driver as any).isBedrockErrorRetryable('UnknownError', 500, undefined)).toBe(true);
341
+ expect((driver as any).isBedrockErrorRetryable('UnknownError', 503, undefined)).toBe(true);
342
+ expect((driver as any).isBedrockErrorRetryable('UnknownError', 400, undefined)).toBe(false);
343
+ expect((driver as any).isBedrockErrorRetryable('UnknownError', 403, undefined)).toBe(false);
344
+ expect((driver as any).isBedrockErrorRetryable('UnknownError', 404, undefined)).toBe(false);
345
+ });
346
+
347
+ it('should use fault type as fallback', () => {
348
+ expect((driver as any).isBedrockErrorRetryable('UnknownError', undefined, 'server')).toBe(true);
349
+ expect((driver as any).isBedrockErrorRetryable('UnknownError', undefined, 'client')).toBe(false);
350
+ });
351
+ });
352
+ });