universal-llm-client 3.1.0 → 4.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 (41) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +177 -0
  3. package/dist/ai-model.d.ts +89 -0
  4. package/dist/ai-model.d.ts.map +1 -1
  5. package/dist/ai-model.js +96 -0
  6. package/dist/ai-model.js.map +1 -1
  7. package/dist/auditor.d.ts +5 -1
  8. package/dist/auditor.d.ts.map +1 -1
  9. package/dist/auditor.js +9 -0
  10. package/dist/auditor.js.map +1 -1
  11. package/dist/client.d.ts +14 -0
  12. package/dist/client.d.ts.map +1 -1
  13. package/dist/client.js +52 -0
  14. package/dist/client.js.map +1 -1
  15. package/dist/index.d.ts +2 -1
  16. package/dist/index.d.ts.map +1 -1
  17. package/dist/index.js +10 -0
  18. package/dist/index.js.map +1 -1
  19. package/dist/interfaces.d.ts +143 -1
  20. package/dist/interfaces.d.ts.map +1 -1
  21. package/dist/interfaces.js.map +1 -1
  22. package/dist/providers/google.d.ts.map +1 -1
  23. package/dist/providers/google.js +21 -0
  24. package/dist/providers/google.js.map +1 -1
  25. package/dist/providers/ollama.d.ts +13 -1
  26. package/dist/providers/ollama.d.ts.map +1 -1
  27. package/dist/providers/ollama.js +42 -7
  28. package/dist/providers/ollama.js.map +1 -1
  29. package/dist/providers/openai.d.ts +4 -0
  30. package/dist/providers/openai.d.ts.map +1 -1
  31. package/dist/providers/openai.js +51 -1
  32. package/dist/providers/openai.js.map +1 -1
  33. package/dist/router.d.ts +70 -0
  34. package/dist/router.d.ts.map +1 -1
  35. package/dist/router.js +343 -0
  36. package/dist/router.js.map +1 -1
  37. package/dist/structured-output.d.ts +467 -0
  38. package/dist/structured-output.d.ts.map +1 -0
  39. package/dist/structured-output.js +505 -0
  40. package/dist/structured-output.js.map +1 -0
  41. package/package.json +15 -4
@@ -0,0 +1,505 @@
1
+ /**
2
+ * Structured Output Core Types
3
+ *
4
+ * Core types for structured output support in universal-llm-client.
5
+ * Provides type-safe Zod schema integration and JSON Schema support.
6
+ *
7
+ * @module structured-output
8
+ */
9
+ import { z } from 'zod';
10
+ /**
11
+ * Custom error class for structured output validation failures.
12
+ *
13
+ * Thrown when:
14
+ * - JSON parsing of LLM response fails
15
+ * - Zod schema validation fails
16
+ *
17
+ * Features:
18
+ * - `rawOutput` property containing the original LLM response
19
+ * - `cause` property for the underlying error (ZodError, SyntaxError, etc.)
20
+ *
21
+ * @example
22
+ * ```typescript
23
+ * try {
24
+ * const result = await model.generateStructured(UserSchema, messages);
25
+ * } catch (error) {
26
+ * if (error instanceof StructuredOutputError) {
27
+ * console.log('Raw LLM output:', error.rawOutput);
28
+ * if (error.cause instanceof z.ZodError) {
29
+ * console.log('Validation issues:', error.cause.issues);
30
+ * }
31
+ * }
32
+ * }
33
+ * ```
34
+ */
35
+ export class StructuredOutputError extends Error {
36
+ /** The raw output from the LLM that failed validation */
37
+ rawOutput;
38
+ /** The underlying cause (e.g., ZodError for schema validation failures) */
39
+ cause;
40
+ constructor(message, options) {
41
+ super(message);
42
+ this.rawOutput = options.rawOutput;
43
+ this.cause = options.cause;
44
+ // Maintains proper stack trace for where error was thrown (only available in V8)
45
+ if (Error.captureStackTrace) {
46
+ Error.captureStackTrace(this, StructuredOutputError);
47
+ }
48
+ }
49
+ }
50
+ // ============================================================================
51
+ // Type Guards
52
+ // ============================================================================
53
+ /**
54
+ * Type guard to check if a structured output result is successful.
55
+ *
56
+ * @param result The result to check
57
+ * @returns true if the result is successful
58
+ *
59
+ * @example
60
+ * ```typescript
61
+ * const result = await model.tryParseStructured(UserSchema, messages);
62
+ *
63
+ * if (isStructuredOutputSuccess(result)) {
64
+ * console.log('User:', result.value.name);
65
+ * } else {
66
+ * console.log('Error:', result.error.message);
67
+ * }
68
+ * ```
69
+ */
70
+ export function isStructuredOutputSuccess(result) {
71
+ return result.ok === true;
72
+ }
73
+ /**
74
+ * Type guard to check if a structured output result is a failure.
75
+ *
76
+ * @param result The result to check
77
+ * @returns true if the result is a failure
78
+ *
79
+ * @example
80
+ * ```typescript
81
+ * const result = await model.tryParseStructured(UserSchema, messages);
82
+ *
83
+ * if (isStructuredOutputFailure(result)) {
84
+ * console.log('Error:', result.error.message);
85
+ * console.log('Raw:', result.rawOutput);
86
+ * }
87
+ * ```
88
+ */
89
+ export function isStructuredOutputFailure(result) {
90
+ return result.ok === false;
91
+ }
92
+ // ============================================================================
93
+ // Schema Conversion Utilities
94
+ // ============================================================================
95
+ /**
96
+ * Convert a Zod schema to JSON Schema.
97
+ *
98
+ * Uses Zod 4's native `z.toJSONSchema()` for conversion.
99
+ * Handles all Zod types including objects, arrays, primitives, enums, and nested structures.
100
+ *
101
+ * @param schema The Zod schema to convert
102
+ * @returns JSON Schema representation
103
+ *
104
+ * @example
105
+ * ```typescript
106
+ * const UserSchema = z.object({
107
+ * name: z.string(),
108
+ * age: z.number(),
109
+ * });
110
+ *
111
+ * const jsonSchema = zodToJsonSchema(UserSchema);
112
+ * // { type: 'object', properties: { name: { type: 'string' }, ... }, required: ['name', 'age'] }
113
+ * ```
114
+ */
115
+ export function zodToJsonSchema(schema) {
116
+ const result = z.toJSONSchema(schema, {
117
+ target: 'draft-07',
118
+ unrepresentable: 'any',
119
+ });
120
+ // Cast to our JSONSchema type and clean up
121
+ const cleanResult = result;
122
+ delete cleanResult.$schema;
123
+ return cleanResult;
124
+ }
125
+ /**
126
+ * Normalize a raw JSON Schema.
127
+ *
128
+ * Currently passes through without modification.
129
+ * Future versions may add normalization for provider compatibility.
130
+ *
131
+ * @param schema The JSON Schema to normalize
132
+ * @returns Normalized JSON Schema
133
+ */
134
+ export function normalizeJsonSchema(schema) {
135
+ // Deep clone to avoid mutating the input
136
+ return JSON.parse(JSON.stringify(schema));
137
+ }
138
+ /**
139
+ * Get the JSON Schema from options.
140
+ *
141
+ * Converts Zod schema to JSON Schema if necessary, or normalizes raw JSON Schema.
142
+ *
143
+ * @param options The structured output options
144
+ * @returns JSON Schema
145
+ */
146
+ export function getJsonSchema(options) {
147
+ if (options.schema) {
148
+ return zodToJsonSchema(options.schema);
149
+ }
150
+ if (options.jsonSchema) {
151
+ return normalizeJsonSchema(options.jsonSchema);
152
+ }
153
+ throw new Error('Either schema or jsonSchema must be provided');
154
+ }
155
+ /**
156
+ * Features that some providers don't support.
157
+ * These are removed when transforming schemas for those providers.
158
+ */
159
+ const GOOGLE_UNSUPPORTED_FEATURES = [
160
+ 'pattern',
161
+ 'minLength',
162
+ 'maxLength',
163
+ 'minimum',
164
+ 'maximum',
165
+ 'exclusiveMinimum',
166
+ 'exclusiveMaximum',
167
+ // Google doesn't support additionalProperties in response schema
168
+ 'additionalProperties',
169
+ ];
170
+ /**
171
+ * Strip unsupported features from a JSON Schema for a specific provider.
172
+ *
173
+ * Google/Gemini doesn't support certain JSON Schema features like pattern, min/max.
174
+ * This function removes those recursively.
175
+ *
176
+ * @param schema The JSON Schema to transform
177
+ * @param provider The target provider
178
+ * @returns Cleaned JSON Schema
179
+ *
180
+ * @example
181
+ * ```typescript
182
+ * const schema = {
183
+ * type: 'string',
184
+ * pattern: '^[a-z]+$',
185
+ * minLength: 1,
186
+ * };
187
+ *
188
+ * const cleaned = stripUnsupportedFeatures(schema, 'google');
189
+ * // { type: 'string' } - pattern and minLength removed
190
+ * ```
191
+ */
192
+ export function stripUnsupportedFeatures(schema, provider) {
193
+ // Only Google needs transformation currently
194
+ if (provider !== 'google') {
195
+ return schema;
196
+ }
197
+ // Deep clone to avoid mutating input
198
+ const result = JSON.parse(JSON.stringify(schema));
199
+ // Remove unsupported top-level properties
200
+ for (const feature of GOOGLE_UNSUPPORTED_FEATURES) {
201
+ delete result[feature];
202
+ }
203
+ // Recursively clean nested schemas
204
+ if (result.properties) {
205
+ for (const key of Object.keys(result.properties)) {
206
+ if (result.properties[key]) {
207
+ result.properties[key] = stripUnsupportedFeatures(result.properties[key], provider);
208
+ }
209
+ }
210
+ }
211
+ if (result.items) {
212
+ if (Array.isArray(result.items)) {
213
+ result.items = result.items.map(item => stripUnsupportedFeatures(item, provider));
214
+ }
215
+ else {
216
+ result.items = stripUnsupportedFeatures(result.items, provider);
217
+ }
218
+ }
219
+ // Handle oneOf, anyOf, allOf
220
+ for (const key of ['oneOf', 'anyOf', 'allOf']) {
221
+ const schemas = result[key];
222
+ if (Array.isArray(schemas)) {
223
+ result[key] = schemas.map(s => stripUnsupportedFeatures(s, provider));
224
+ }
225
+ }
226
+ return result;
227
+ }
228
+ /**
229
+ * Convert structured output options to a provider-specific schema.
230
+ *
231
+ * This function:
232
+ * 1. Extracts/converts the JSON Schema from options
233
+ * 2. Applies provider-specific transformations (e.g., removing unsupported features for Google)
234
+ * 3. Adds name/description for LLM guidance
235
+ *
236
+ * @param provider The target provider
237
+ * @param options The structured output options
238
+ * @returns Provider-ready schema with name and description
239
+ *
240
+ * @example
241
+ * ```typescript
242
+ * const result = convertToProviderSchema('openai', {
243
+ * schema: z.object({ name: z.string() }),
244
+ * name: 'User',
245
+ * description: 'A user object',
246
+ * });
247
+ *
248
+ * // result.schema - JSON Schema
249
+ * // result.name - 'User'
250
+ * // result.description - 'A user object'
251
+ * ```
252
+ */
253
+ export function convertToProviderSchema(provider, options) {
254
+ // Get the JSON Schema (convert from Zod or normalize raw)
255
+ const jsonSchema = getJsonSchema(options);
256
+ // Apply provider-specific transformations
257
+ const schema = stripUnsupportedFeatures(jsonSchema, provider);
258
+ // Generate a default name if not provided (some providers require it)
259
+ const name = options.name ?? 'response';
260
+ return {
261
+ schema,
262
+ name,
263
+ description: options.description,
264
+ };
265
+ }
266
+ // ============================================================================
267
+ // Validation Functions
268
+ // ============================================================================
269
+ /**
270
+ * Parse and validate structured output from raw LLM response text.
271
+ *
272
+ * This function:
273
+ * 1. Parses JSON from the raw output string
274
+ * 2. Validates the parsed data against the Zod schema
275
+ * 3. Throws StructuredOutputError on failure
276
+ *
277
+ * @param schema The Zod schema to validate against
278
+ * @param rawOutput The raw string output from the LLM
279
+ * @returns The validated and typed data
280
+ * @throws StructuredOutputError if JSON parsing fails or schema validation fails
281
+ *
282
+ * @example
283
+ * ```typescript
284
+ * const schema = z.object({ name: z.string(), age: z.number() });
285
+ * const rawOutput = '{"name": "Alice", "age": 30}';
286
+ * const result = parseStructured(schema, rawOutput); // { name: "Alice", age: 30 }
287
+ * ```
288
+ */
289
+ export function parseStructured(schema, rawOutput) {
290
+ // Step 1: Parse JSON
291
+ let parsed;
292
+ try {
293
+ parsed = JSON.parse(rawOutput);
294
+ }
295
+ catch (error) {
296
+ // JSON parsing failed - wrap in StructuredOutputError
297
+ const syntaxError = error instanceof SyntaxError
298
+ ? error
299
+ : new SyntaxError(String(error));
300
+ throw new StructuredOutputError(`Failed to parse JSON: ${syntaxError.message}`, { rawOutput, cause: syntaxError });
301
+ }
302
+ // Step 2: Validate against Zod schema
303
+ const result = schema.safeParse(parsed);
304
+ if (!result.success) {
305
+ // Schema validation failed - throw with ZodError as cause
306
+ throw new StructuredOutputError(`Validation failed: ${result.error.issues.map((e) => e.message).join(', ')}`, { rawOutput, cause: result.error });
307
+ }
308
+ return result.data;
309
+ }
310
+ /**
311
+ * Try to parse and validate structured output, returning a result object.
312
+ *
313
+ * This is the non-throwing variant of `parseStructured`. Instead of throwing
314
+ * on validation failure, it returns a result object with `ok: false` and
315
+ * the error details.
316
+ *
317
+ * @param schema The Zod schema to validate against
318
+ * @param rawOutput The raw string output from the LLM
319
+ * @returns A result object: `{ ok: true, value }` on success, `{ ok: false, error, rawOutput }` on failure
320
+ *
321
+ * @example
322
+ * ```typescript
323
+ * const schema = z.object({ name: z.string(), age: z.number() });
324
+ *
325
+ * // Success case
326
+ * const result1 = tryParseStructured(schema, '{"name": "Alice", "age": 30}');
327
+ * if (result1.ok) {
328
+ * console.log(result1.value.name); // "Alice"
329
+ * }
330
+ *
331
+ * // Failure case
332
+ * const result2 = tryParseStructured(schema, 'invalid json');
333
+ * if (!result2.ok) {
334
+ * console.log(result2.error.message); // Error message
335
+ * console.log(result2.rawOutput); // Original output
336
+ * }
337
+ * ```
338
+ */
339
+ export function tryParseStructured(schema, rawOutput) {
340
+ try {
341
+ const value = parseStructured(schema, rawOutput);
342
+ return { ok: true, value };
343
+ }
344
+ catch (error) {
345
+ if (error instanceof StructuredOutputError) {
346
+ return {
347
+ ok: false,
348
+ error,
349
+ rawOutput,
350
+ };
351
+ }
352
+ // Re-throw unexpected errors
353
+ throw error;
354
+ }
355
+ }
356
+ /**
357
+ * Validate already-parsed data against a Zod schema.
358
+ *
359
+ * This is useful when you have already parsed JSON and need to validate
360
+ * it against a schema, with optional raw output for error messages.
361
+ *
362
+ * @param schema The Zod schema to validate against
363
+ * @param data The parsed data to validate
364
+ * @param rawOutput Optional raw output string for error messages
365
+ * @returns The validated and typed data
366
+ * @throws StructuredOutputError if schema validation fails
367
+ *
368
+ * @example
369
+ * ```typescript
370
+ * const schema = z.object({ name: z.string(), age: z.number() });
371
+ * const data = JSON.parse('{"name": "Alice", "age": 30}');
372
+ * const result = validateStructuredOutput(schema, data); // { name: "Alice", age: 30 }
373
+ * ```
374
+ */
375
+ export function validateStructuredOutput(schema, data, rawOutput) {
376
+ const result = schema.safeParse(data);
377
+ if (!result.success) {
378
+ const rawData = rawOutput ?? JSON.stringify(data);
379
+ throw new StructuredOutputError(`Validation failed: ${result.error.issues.map((e) => e.message).join(', ')}`, { rawOutput: rawData, cause: result.error });
380
+ }
381
+ return result.data;
382
+ }
383
+ // ============================================================================
384
+ // Streaming JSON Parsing
385
+ // ============================================================================
386
+ /**
387
+ * Incremental JSON parser for streaming structured output.
388
+ *
389
+ * Allows parsing partial JSON as it streams in, returning validated partial
390
+ * objects when possible. Useful for structured output streaming where you
391
+ * want to see partial results before the complete JSON arrives.
392
+ */
393
+ export class StreamingJsonParser {
394
+ buffer = '';
395
+ schema;
396
+ constructor(schema) {
397
+ this.schema = schema;
398
+ }
399
+ /**
400
+ * Feed a chunk of JSON text to the parser.
401
+ * Returns a validated partial object if the current buffer can be parsed
402
+ * as valid JSON that passes the schema, or undefined if not yet valid.
403
+ *
404
+ * For partial objects, this attempts to:
405
+ * 1. Add closing braces/brackets to make valid JSON
406
+ * 2. Fill in missing required fields with null/empty values
407
+ * 3. Validate against schema
408
+ *
409
+ * @param chunk Text chunk from the stream
410
+ * @returns Validated partial object or undefined
411
+ */
412
+ feed(chunk) {
413
+ this.buffer += chunk;
414
+ // Try to parse as complete JSON first
415
+ try {
416
+ const parsed = JSON.parse(this.buffer);
417
+ const result = this.schema.safeParse(parsed);
418
+ if (result.success) {
419
+ return { partial: result.data, complete: true };
420
+ }
421
+ }
422
+ catch {
423
+ // Not yet valid complete JSON
424
+ }
425
+ // Try to create a valid partial by closing braces
426
+ const partialResult = this.tryParsePartial();
427
+ return { partial: partialResult, complete: false };
428
+ }
429
+ /**
430
+ * Get the current buffer content.
431
+ */
432
+ getBuffer() {
433
+ return this.buffer;
434
+ }
435
+ /**
436
+ * Reset the parser state.
437
+ */
438
+ reset() {
439
+ this.buffer = '';
440
+ }
441
+ /**
442
+ * Attempt to parse partial JSON by adding closing brackets.
443
+ */
444
+ tryParsePartial() {
445
+ // Count unclosed brackets and braces
446
+ let braceCount = 0;
447
+ let bracketCount = 0;
448
+ let inString = false;
449
+ let escaped = false;
450
+ for (let i = 0; i < this.buffer.length; i++) {
451
+ const char = this.buffer[i];
452
+ if (escaped) {
453
+ escaped = false;
454
+ continue;
455
+ }
456
+ if (char === '\\' && inString) {
457
+ escaped = true;
458
+ continue;
459
+ }
460
+ if (char === '"') {
461
+ inString = !inString;
462
+ continue;
463
+ }
464
+ if (inString)
465
+ continue;
466
+ if (char === '{')
467
+ braceCount++;
468
+ else if (char === '}')
469
+ braceCount--;
470
+ else if (char === '[')
471
+ bracketCount++;
472
+ else if (char === ']')
473
+ bracketCount--;
474
+ }
475
+ // Build closing sequence
476
+ let closing = '';
477
+ while (bracketCount > 0) {
478
+ closing += ']';
479
+ bracketCount--;
480
+ }
481
+ while (braceCount > 0) {
482
+ closing += '}';
483
+ braceCount--;
484
+ }
485
+ // Try parsing with closing
486
+ const candidate = this.buffer + closing;
487
+ try {
488
+ const parsed = JSON.parse(candidate);
489
+ const result = this.schema.safeParse(parsed);
490
+ if (result.success) {
491
+ return result.data;
492
+ }
493
+ }
494
+ catch {
495
+ // Silently fail for partial JSON
496
+ }
497
+ return undefined;
498
+ }
499
+ }
500
+ // ============================================================================
501
+ // Re-exports for Convenience
502
+ // ============================================================================
503
+ // Re-export Zod for users who need it
504
+ export { z } from 'zod';
505
+ //# sourceMappingURL=structured-output.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"structured-output.js","sourceRoot":"","sources":["../src/structured-output.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "universal-llm-client",
3
- "version": "3.1.0",
3
+ "version": "4.0.0",
4
4
  "type": "module",
5
5
  "description": "A universal LLM client with transparent provider failover, streaming tool execution, pluggable reasoning, and native observability.",
6
6
  "main": "./dist/index.js",
@@ -29,6 +29,10 @@
29
29
  "./http": {
30
30
  "import": "./dist/http.js",
31
31
  "types": "./dist/http.d.ts"
32
+ },
33
+ "./structured-output": {
34
+ "import": "./dist/structured-output.js",
35
+ "types": "./dist/structured-output.d.ts"
32
36
  }
33
37
  },
34
38
  "files": [
@@ -46,7 +50,10 @@
46
50
  "test": "bun test",
47
51
  "typecheck": "tsc --noEmit",
48
52
  "lint": "tsc --noEmit --strict",
49
- "prepack": "bun run build"
53
+ "prepack": "bun run build",
54
+ "docs:dev": "vitepress dev docs",
55
+ "docs:build": "vitepress build docs",
56
+ "docs:preview": "vitepress preview docs"
50
57
  },
51
58
  "keywords": [
52
59
  "llm",
@@ -70,10 +77,14 @@
70
77
  "devDependencies": {
71
78
  "@types/node": "^22.0.0",
72
79
  "rimraf": "^6.0.1",
73
- "typescript": "^5.8.3"
80
+ "typescript": "^5.8.3",
81
+ "vitepress": "^1.6.4",
82
+ "vue": "^3.5.30",
83
+ "zod": "^4.0.0"
74
84
  },
75
85
  "peerDependencies": {
76
- "@modelcontextprotocol/sdk": ">=1.24.0"
86
+ "@modelcontextprotocol/sdk": ">=1.24.0",
87
+ "zod": "^4.0.0"
77
88
  },
78
89
  "peerDependenciesMeta": {
79
90
  "@modelcontextprotocol/sdk": {