@llumiverse/common 1.0.0-dev.20260224.234313Z → 1.0.0-dev.20260331.080752Z

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 (41) hide show
  1. package/lib/cjs/capability/openai.js +4 -1
  2. package/lib/cjs/capability/openai.js.map +1 -1
  3. package/lib/cjs/capability.js +28 -1
  4. package/lib/cjs/capability.js.map +1 -1
  5. package/lib/cjs/options/context-windows.js +2 -1
  6. package/lib/cjs/options/context-windows.js.map +1 -1
  7. package/lib/cjs/options/openai.js +101 -0
  8. package/lib/cjs/options/openai.js.map +1 -1
  9. package/lib/cjs/options/vertexai.js +219 -65
  10. package/lib/cjs/options/vertexai.js.map +1 -1
  11. package/lib/cjs/types.js +104 -1
  12. package/lib/cjs/types.js.map +1 -1
  13. package/lib/esm/capability/openai.js +4 -1
  14. package/lib/esm/capability/openai.js.map +1 -1
  15. package/lib/esm/capability.js +28 -1
  16. package/lib/esm/capability.js.map +1 -1
  17. package/lib/esm/options/context-windows.js +2 -1
  18. package/lib/esm/options/context-windows.js.map +1 -1
  19. package/lib/esm/options/openai.js +101 -0
  20. package/lib/esm/options/openai.js.map +1 -1
  21. package/lib/esm/options/vertexai.js +217 -65
  22. package/lib/esm/options/vertexai.js.map +1 -1
  23. package/lib/esm/types.js +102 -0
  24. package/lib/esm/types.js.map +1 -1
  25. package/lib/types/capability/openai.d.ts.map +1 -1
  26. package/lib/types/capability.d.ts.map +1 -1
  27. package/lib/types/options/context-windows.d.ts.map +1 -1
  28. package/lib/types/options/openai.d.ts +17 -2
  29. package/lib/types/options/openai.d.ts.map +1 -1
  30. package/lib/types/options/vertexai.d.ts +17 -1
  31. package/lib/types/options/vertexai.d.ts.map +1 -1
  32. package/lib/types/types.d.ts +95 -0
  33. package/lib/types/types.d.ts.map +1 -1
  34. package/package.json +1 -1
  35. package/src/LlumiverseError.test.ts +265 -0
  36. package/src/capability/openai.ts +21 -18
  37. package/src/capability.ts +30 -1
  38. package/src/options/context-windows.ts +2 -1
  39. package/src/options/openai.ts +126 -3
  40. package/src/options/vertexai.ts +262 -77
  41. package/src/types.ts +139 -0
package/src/types.ts CHANGED
@@ -172,6 +172,137 @@ export interface ResultValidationError {
172
172
  data?: CompletionResult[];
173
173
  }
174
174
 
175
+ /**
176
+ * Context information for LlumiverseError.
177
+ * Provides details about where and how the error occurred.
178
+ */
179
+ export interface LlumiverseErrorContext {
180
+ /** The provider that generated the error (e.g., 'openai', 'bedrock', 'vertexai') */
181
+ provider: string;
182
+ /** The model that was being used when the error occurred */
183
+ model: string;
184
+ /** The operation that failed */
185
+ operation: 'execute' | 'stream';
186
+ }
187
+
188
+ /**
189
+ * Standardized error class for Llumiverse driver errors.
190
+ *
191
+ * Normalizes errors from different LLM providers (OpenAI, Anthropic, Bedrock, VertexAI, etc.)
192
+ * into a consistent format. The primary value is the `retryable` flag, which enables upstream
193
+ * consumers to implement smart retry logic.
194
+ *
195
+ * @example
196
+ * ```typescript
197
+ * try {
198
+ * const result = await driver.execute(segments, options);
199
+ * } catch (error) {
200
+ * if (LlumiverseError.isLlumiverseError(error)) {
201
+ * console.log(`Provider: ${error.context.provider}`);
202
+ * console.log(`Model: ${error.context.model}`);
203
+ * console.log(`Retryable: ${error.retryable}`);
204
+ *
205
+ * if (error.retryable) {
206
+ * // Implement retry logic with exponential backoff
207
+ * await retryWithBackoff(() => driver.execute(segments, options));
208
+ * } else {
209
+ * // Handle non-retryable error (e.g., invalid API key, malformed request)
210
+ * logError(error);
211
+ * }
212
+ * }
213
+ * throw error;
214
+ * }
215
+ * ```
216
+ */
217
+ export class LlumiverseError extends Error {
218
+ /**
219
+ * HTTP status code (e.g., 429, 500) if available.
220
+ * Undefined if the error doesn't have a numeric status code.
221
+ */
222
+ readonly code?: number;
223
+
224
+ /**
225
+ * Provider-specific error name/type (e.g., "ThrottlingException", "ValidationException").
226
+ * Optional - used to preserve the semantic error type from the provider SDK.
227
+ */
228
+ readonly name: string;
229
+
230
+ /**
231
+ * Whether this error is retryable.
232
+ * - True: Definitely retryable (rate limits, timeouts, server errors)
233
+ * - False: Definitely not retryable (auth failures, invalid requests, malformed schemas)
234
+ * - Undefined: Unknown retryability - allows consumers to decide default behavior
235
+ *
236
+ * When undefined, consumers can choose their retry strategy:
237
+ * - Conservative: Don't retry unknown errors (avoid spam)
238
+ * - Resilient: Retry unknown errors (prioritize success)
239
+ */
240
+ readonly retryable?: boolean;
241
+
242
+ /**
243
+ * Context about where and how the error occurred.
244
+ * Includes provider, model, operation type.
245
+ */
246
+ readonly context: LlumiverseErrorContext;
247
+
248
+ /**
249
+ * The original error from the provider SDK.
250
+ * Preserved for debugging and detailed error inspection.
251
+ */
252
+ readonly originalError: unknown;
253
+
254
+ constructor(
255
+ message: string,
256
+ retryable: boolean | undefined,
257
+ context: LlumiverseErrorContext,
258
+ originalError: unknown,
259
+ code?: number,
260
+ name?: string
261
+ ) {
262
+ super(message);
263
+ this.name = name || 'LlumiverseError';
264
+ this.code = code;
265
+ this.retryable = retryable;
266
+ this.context = context;
267
+ this.originalError = originalError;
268
+
269
+ // Preserve stack trace from original error if available
270
+ if (originalError instanceof Error && originalError.stack) {
271
+ this.stack = originalError.stack;
272
+ }
273
+ }
274
+
275
+ /**
276
+ * Serialize the error to JSON for logging or transmission.
277
+ * Includes all error properties except the original error object itself.
278
+ */
279
+ toJSON(): Record<string, unknown> {
280
+ return {
281
+ name: this.name,
282
+ message: this.message,
283
+ code: this.code,
284
+ retryable: this.retryable,
285
+ context: this.context,
286
+ stack: this.stack,
287
+ // Include original error message if available
288
+ originalErrorMessage: this.originalError instanceof Error
289
+ ? this.originalError.message
290
+ : String(this.originalError),
291
+ };
292
+ }
293
+
294
+ /**
295
+ * Type guard to check if an error is a LlumiverseError.
296
+ * Useful for conditional error handling.
297
+ *
298
+ * @param error - The error to check
299
+ * @returns True if the error is a LlumiverseError
300
+ */
301
+ static isLlumiverseError(error: unknown): error is LlumiverseError {
302
+ return error instanceof LlumiverseError;
303
+ }
304
+ }
305
+
175
306
  // ============== Result Types ===============
176
307
 
177
308
  export interface BaseResult {
@@ -402,6 +533,14 @@ export interface ExecutionOptions extends StatelessExecutionOptions {
402
533
  * - N > 0: Truncate text to approximately N tokens (using ~4 chars/token estimate)
403
534
  */
404
535
  stripTextMaxTokens?: number;
536
+
537
+ /**
538
+ * Number of turns to keep heartbeat messages before stripping.
539
+ * - 0: Strip immediately
540
+ * - 1 (default): Keep for 1 turn then strip
541
+ * - undefined: Same as 1, strip after 1 turn
542
+ */
543
+ stripHeartbeatsAfterTurns?: number;
405
544
  }
406
545
 
407
546
  //Common names to share between different models