universal-llm-client 4.5.0 → 4.5.1

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 (174) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +2 -0
  3. package/dist/ai-model.d.ts +0 -1
  4. package/dist/ai-model.js +0 -1
  5. package/dist/auditor.d.ts +0 -1
  6. package/dist/auditor.js +0 -1
  7. package/dist/client.d.ts +0 -1
  8. package/dist/client.js +0 -1
  9. package/dist/gemma-channel.d.ts +0 -1
  10. package/dist/gemma-channel.js +0 -1
  11. package/dist/gemma-diffusion.d.ts +0 -1
  12. package/dist/gemma-diffusion.js +0 -1
  13. package/dist/http.d.ts +0 -1
  14. package/dist/http.js +0 -1
  15. package/dist/index.d.ts +0 -1
  16. package/dist/index.js +0 -1
  17. package/dist/interfaces.d.ts +0 -1
  18. package/dist/interfaces.js +0 -1
  19. package/dist/mcp.d.ts +0 -1
  20. package/dist/mcp.js +0 -1
  21. package/dist/providers/anthropic.d.ts +0 -1
  22. package/dist/providers/anthropic.js +0 -1
  23. package/dist/providers/google.d.ts +0 -1
  24. package/dist/providers/google.js +0 -1
  25. package/dist/providers/index.d.ts +0 -1
  26. package/dist/providers/index.js +0 -1
  27. package/dist/providers/ollama.d.ts +0 -1
  28. package/dist/providers/ollama.js +0 -1
  29. package/dist/providers/openai.d.ts +2 -1
  30. package/dist/providers/openai.js +303 -74
  31. package/dist/router.d.ts +0 -1
  32. package/dist/router.js +0 -1
  33. package/dist/stream-decoder.d.ts +0 -1
  34. package/dist/stream-decoder.js +0 -1
  35. package/dist/structured-output.d.ts +0 -1
  36. package/dist/structured-output.js +0 -1
  37. package/dist/thinking.d.ts +0 -1
  38. package/dist/thinking.js +0 -1
  39. package/dist/tools.d.ts +0 -1
  40. package/dist/tools.js +0 -1
  41. package/dist/zod-adapter.d.ts +0 -1
  42. package/dist/zod-adapter.js +0 -1
  43. package/package.json +1 -2
  44. package/dist/ai-model.d.ts.map +0 -1
  45. package/dist/ai-model.js.map +0 -1
  46. package/dist/auditor.d.ts.map +0 -1
  47. package/dist/auditor.js.map +0 -1
  48. package/dist/client.d.ts.map +0 -1
  49. package/dist/client.js.map +0 -1
  50. package/dist/gemma-channel.d.ts.map +0 -1
  51. package/dist/gemma-channel.js.map +0 -1
  52. package/dist/gemma-diffusion.d.ts.map +0 -1
  53. package/dist/gemma-diffusion.js.map +0 -1
  54. package/dist/http.d.ts.map +0 -1
  55. package/dist/http.js.map +0 -1
  56. package/dist/index.d.ts.map +0 -1
  57. package/dist/index.js.map +0 -1
  58. package/dist/interfaces.d.ts.map +0 -1
  59. package/dist/interfaces.js.map +0 -1
  60. package/dist/mcp.d.ts.map +0 -1
  61. package/dist/mcp.js.map +0 -1
  62. package/dist/providers/anthropic.d.ts.map +0 -1
  63. package/dist/providers/anthropic.js.map +0 -1
  64. package/dist/providers/google.d.ts.map +0 -1
  65. package/dist/providers/google.js.map +0 -1
  66. package/dist/providers/index.d.ts.map +0 -1
  67. package/dist/providers/index.js.map +0 -1
  68. package/dist/providers/ollama.d.ts.map +0 -1
  69. package/dist/providers/ollama.js.map +0 -1
  70. package/dist/providers/openai.d.ts.map +0 -1
  71. package/dist/providers/openai.js.map +0 -1
  72. package/dist/router.d.ts.map +0 -1
  73. package/dist/router.js.map +0 -1
  74. package/dist/stream-decoder.d.ts.map +0 -1
  75. package/dist/stream-decoder.js.map +0 -1
  76. package/dist/structured-output.d.ts.map +0 -1
  77. package/dist/structured-output.js.map +0 -1
  78. package/dist/thinking.d.ts.map +0 -1
  79. package/dist/thinking.js.map +0 -1
  80. package/dist/tools.d.ts.map +0 -1
  81. package/dist/tools.js.map +0 -1
  82. package/dist/zod-adapter.d.ts.map +0 -1
  83. package/dist/zod-adapter.js.map +0 -1
  84. package/src/ai-model.ts +0 -400
  85. package/src/auditor.ts +0 -213
  86. package/src/client.ts +0 -402
  87. package/src/debug/debug-google-streaming.ts +0 -97
  88. package/src/debug/debug-tool-execution.ts +0 -86
  89. package/src/debug/test-lmstudio-tools.ts +0 -155
  90. package/src/demos/README.md +0 -47
  91. package/src/demos/basic/universal-llm-examples.ts +0 -161
  92. package/src/demos/diffusion-gemma/.env +0 -29
  93. package/src/demos/diffusion-gemma/.env.example +0 -27
  94. package/src/demos/diffusion-gemma/CLAUDE.md +0 -95
  95. package/src/demos/diffusion-gemma/README.md +0 -59
  96. package/src/demos/diffusion-gemma/canvas.ts +0 -1606
  97. package/src/demos/diffusion-gemma/docker-compose.yml +0 -29
  98. package/src/demos/diffusion-gemma/probe-stream.ts +0 -51
  99. package/src/demos/diffusion-gemma/probe-tools.ts +0 -55
  100. package/src/demos/diffusion-gemma/server.ts +0 -1205
  101. package/src/demos/diffusion-gemma/start-vllm.sh +0 -98
  102. package/src/demos/mcp/astrid-memory-demo.ts +0 -295
  103. package/src/demos/mcp/astrid-persona-memory.ts +0 -357
  104. package/src/demos/mcp/mcp-mongodb-demo.ts +0 -275
  105. package/src/demos/mcp/simple-astrid-memory.ts +0 -148
  106. package/src/demos/mcp/simple-mcp-demo.ts +0 -68
  107. package/src/demos/mcp/working-mcp-demo.ts +0 -62
  108. package/src/demos/model-alias-demo.ts +0 -0
  109. package/src/demos/tools/RAG_MEMORY_INTEGRATION.md +0 -267
  110. package/src/demos/tools/astrid-memory-demo.ts +0 -270
  111. package/src/demos/tools/astrid-production-memory-clean.ts +0 -785
  112. package/src/demos/tools/astrid-production-memory.ts +0 -558
  113. package/src/demos/tools/basic-translation-test.ts +0 -66
  114. package/src/demos/tools/chromadb-similarity-tuning.ts +0 -390
  115. package/src/demos/tools/clean-multilingual-conversation.ts +0 -209
  116. package/src/demos/tools/clean-translation-test.ts +0 -119
  117. package/src/demos/tools/clean-universal-multilingual-test.ts +0 -131
  118. package/src/demos/tools/complete-rag-demo.ts +0 -369
  119. package/src/demos/tools/complete-tool-demo.ts +0 -132
  120. package/src/demos/tools/demo-tool-calling.ts +0 -124
  121. package/src/demos/tools/dynamic-language-switching-test.ts +0 -251
  122. package/src/demos/tools/hybrid-thinking-test.ts +0 -154
  123. package/src/demos/tools/memory-integration-test.ts +0 -420
  124. package/src/demos/tools/multilingual-memory-system.ts +0 -802
  125. package/src/demos/tools/ondemand-translation-demo.ts +0 -655
  126. package/src/demos/tools/production-tool-demo.ts +0 -245
  127. package/src/demos/tools/revolutionary-multilingual-test.ts +0 -151
  128. package/src/demos/tools/rigorous-language-analysis.ts +0 -218
  129. package/src/demos/tools/test-universal-memory-system.ts +0 -126
  130. package/src/demos/tools/translation-integration-guide.ts +0 -346
  131. package/src/demos/tools/universal-memory-system.ts +0 -560
  132. package/src/gemma-channel.ts +0 -47
  133. package/src/gemma-diffusion.ts +0 -167
  134. package/src/http.ts +0 -261
  135. package/src/index.ts +0 -180
  136. package/src/interfaces.ts +0 -843
  137. package/src/mcp.ts +0 -345
  138. package/src/providers/anthropic.ts +0 -796
  139. package/src/providers/google.ts +0 -840
  140. package/src/providers/index.ts +0 -8
  141. package/src/providers/ollama.ts +0 -503
  142. package/src/providers/openai.ts +0 -587
  143. package/src/router.ts +0 -785
  144. package/src/stream-decoder.ts +0 -535
  145. package/src/structured-output.ts +0 -759
  146. package/src/test-scripts/test-advanced-tools.ts +0 -310
  147. package/src/test-scripts/test-google-deep-research.ts +0 -33
  148. package/src/test-scripts/test-google-streaming-enhanced.ts +0 -147
  149. package/src/test-scripts/test-google-streaming.ts +0 -63
  150. package/src/test-scripts/test-google-system-prompt-comprehensive.ts +0 -189
  151. package/src/test-scripts/test-google-thinking.ts +0 -46
  152. package/src/test-scripts/test-mcp-config.ts +0 -28
  153. package/src/test-scripts/test-mcp-connection.ts +0 -29
  154. package/src/test-scripts/test-system-message-positions.ts +0 -163
  155. package/src/test-scripts/test-system-prompt-improvement-demo.ts +0 -83
  156. package/src/test-scripts/test-tool-calling.ts +0 -231
  157. package/src/test-scripts/test-vllm-qwen36.ts +0 -256
  158. package/src/tests/ai-model.test.ts +0 -1614
  159. package/src/tests/auditor.test.ts +0 -224
  160. package/src/tests/gemma-diffusion.test.ts +0 -115
  161. package/src/tests/http.test.ts +0 -200
  162. package/src/tests/interfaces.test.ts +0 -117
  163. package/src/tests/providers/anthropic.test.ts +0 -118
  164. package/src/tests/providers/google.test.ts +0 -841
  165. package/src/tests/providers/ollama.test.ts +0 -1034
  166. package/src/tests/providers/openai.test.ts +0 -1511
  167. package/src/tests/router.test.ts +0 -254
  168. package/src/tests/stream-decoder.test.ts +0 -263
  169. package/src/tests/structured-output.test.ts +0 -1450
  170. package/src/tests/thinking.test.ts +0 -65
  171. package/src/tests/tools.test.ts +0 -175
  172. package/src/thinking.ts +0 -73
  173. package/src/tools.ts +0 -246
  174. package/src/zod-adapter.ts +0 -72
package/CHANGELOG.md CHANGED
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [4.5.1] - 2026-06-14
9
+
10
+ ### Added
11
+
12
+ - **Automatic vLLM tool-calling fallback (OpenAI-compatible provider)** — when a vLLM / OpenAI-compatible server rejects native tool calling (started without `--enable-auto-tool-choice` / `--tool-call-parser`, surfaced as a `"auto" tool choice requires …` 400), the client now transparently retries with a text-level tool protocol: it drops `tools` / `tool_choice`, injects a `<tool_call>name({…})</tool_call>` instruction, and recovers the emitted calls back into `message.tool_calls` (parsing `<tool_call>`, `<function=…>`, and `name(args)` forms). Works for both `chat()` and `chatStream()`, and emits a one-time warning pointing to the flags needed for native parsing. Tool calling now works against vLLM servers not started with tool-parser flags.
13
+
14
+ ### Changed
15
+
16
+ - **Non-leading system messages normalized for OpenAI-compatible servers** — leading system messages are preserved, but a system message appearing *after* the conversation has started is rewritten to a `user` turn prefixed with `[SYSTEM MESSAGE]` (many OpenAI-compatible servers and chat templates reject mid-conversation system roles). Multimodal content is flattened to text for the prefix.
17
+ - **`chat()` / `chatStream()` no longer auto-attach registered tools** — tools are sent only when explicitly passed via `options.tools` (the `chatWithTools` path already does this). Previously every tool added with `registerTool` was attached to plain `chat()` calls. Pass `{ tools }` explicitly (or use `chatWithTools`) if you relied on the old behavior.
18
+ - **Minimal published package** — the npm tarball now ships only `dist/` (compiled JS + type declarations) plus `README` / `CHANGELOG` / `LICENSE`. `src/` (tests, demos, test-scripts) is no longer published, and the build no longer emits `.js.map` / `.d.ts.map` (they referenced sources that aren't shipped and triggered "missing source" warnings in consumer bundlers). Package size dropped ~78% (357 kB → 80 kB, 175 → 44 files). Because `src/` is no longer whitelisted, a local demo model cache under `src/` can never bloat the published package again.
19
+
8
20
  ## [4.5.0] - 2026-06-14
9
21
 
10
22
  ### Added
package/README.md CHANGED
@@ -1,5 +1,7 @@
1
1
  # universal-llm-client
2
2
 
3
+ [![npm version](https://img.shields.io/npm/v/universal-llm-client.svg)](https://www.npmjs.com/package/universal-llm-client) [![CI](https://github.com/igorls/universal-llm-client/actions/workflows/ci.yml/badge.svg)](https://github.com/igorls/universal-llm-client/actions/workflows/ci.yml) [![npm downloads](https://img.shields.io/npm/dm/universal-llm-client.svg)](https://www.npmjs.com/package/universal-llm-client) [![License: MIT](https://img.shields.io/npm/l/universal-llm-client.svg)](https://github.com/igorls/universal-llm-client/blob/main/LICENSE)
4
+
3
5
  A universal LLM client for JavaScript/TypeScript with **transparent provider failover** and a **provider-agnostic reasoning API** — one set of code across OpenAI, Anthropic, Google Gemini, Ollama, vLLM, and any OpenAI-compatible endpoint. Streaming tool execution, structured output, generation stats, and native observability included.
4
6
 
5
7
  ```typescript
@@ -148,4 +148,3 @@ export declare class AIModel {
148
148
  private createClient;
149
149
  private normalizeType;
150
150
  }
151
- //# sourceMappingURL=ai-model.d.ts.map
package/dist/ai-model.js CHANGED
@@ -290,4 +290,3 @@ export class AIModel {
290
290
  return type.toLowerCase();
291
291
  }
292
292
  }
293
- //# sourceMappingURL=ai-model.js.map
package/dist/auditor.d.ts CHANGED
@@ -79,4 +79,3 @@ export declare class BufferedAuditor implements Auditor {
79
79
  /** Clear all buffered events without flushing */
80
80
  clear(): void;
81
81
  }
82
- //# sourceMappingURL=auditor.d.ts.map
package/dist/auditor.js CHANGED
@@ -110,4 +110,3 @@ export class BufferedAuditor {
110
110
  this.events.length = 0;
111
111
  }
112
112
  }
113
- //# sourceMappingURL=auditor.js.map
package/dist/client.d.ts CHANGED
@@ -86,4 +86,3 @@ export declare abstract class BaseLLMClient {
86
86
  */
87
87
  protected validateStructuredResponse(content: string, config: SchemaConfig<unknown>): void;
88
88
  }
89
- //# sourceMappingURL=client.d.ts.map
package/dist/client.js CHANGED
@@ -297,4 +297,3 @@ export class BaseLLMClient {
297
297
  }
298
298
  }
299
299
  }
300
- //# sourceMappingURL=client.js.map
@@ -11,4 +11,3 @@ export interface GemmaThoughtExtraction {
11
11
  export declare const GEMMA_THOUGHT_OPENERS: readonly ["<|channel>thought", "<|thought"];
12
12
  export declare function extractGemmaThoughtChannels(input: string): GemmaThoughtExtraction;
13
13
  export declare function normalizeGemmaThought(thought: string): string;
14
- //# sourceMappingURL=gemma-channel.d.ts.map
@@ -35,4 +35,3 @@ export function extractGemmaThoughtChannels(input) {
35
35
  export function normalizeGemmaThought(thought) {
36
36
  return thought.replace(/^\s+/, '').replace(/\s+$/, '');
37
37
  }
38
- //# sourceMappingURL=gemma-channel.js.map
@@ -46,4 +46,3 @@ export declare function gemmaArgsToJson(body: string): string;
46
46
  * clean answer text.
47
47
  */
48
48
  export declare function parseGemmaDiffusionOutput(raw: string): GemmaDiffusionParsed;
49
- //# sourceMappingURL=gemma-diffusion.d.ts.map
@@ -144,4 +144,3 @@ export function parseGemmaDiffusionOutput(raw) {
144
144
  toolCalls,
145
145
  };
146
146
  }
147
- //# sourceMappingURL=gemma-diffusion.js.map
package/dist/http.d.ts CHANGED
@@ -50,4 +50,3 @@ export declare function parseSSE(stream: AsyncGenerator<string>): AsyncGenerator
50
50
  * Respects authHeader / authPrefix from config for Azure-style or gateway auth.
51
51
  */
52
52
  export declare function buildHeaders(options: LLMClientOptions): Record<string, string>;
53
- //# sourceMappingURL=http.d.ts.map
package/dist/http.js CHANGED
@@ -197,4 +197,3 @@ export function buildHeaders(options) {
197
197
  }
198
198
  return headers;
199
199
  }
200
- //# sourceMappingURL=http.js.map
package/dist/index.d.ts CHANGED
@@ -15,4 +15,3 @@ export { httpRequest, httpStream, parseNDJSON, parseSSE, buildHeaders, type Http
15
15
  export { isGemmaDiffusionModel, parseGemmaDiffusionOutput, gemmaArgsToJson, type GemmaDiffusionParsed, type GemmaParsedToolCall, } from './gemma-diffusion.js';
16
16
  export { MCPToolBridge, type MCPBridgeConfig, type MCPServerConfig, type MCPTool, } from './mcp.js';
17
17
  export { StructuredOutputError, type StructuredOutputErrorOptions, type StructuredOutputOptions, type StructuredOutputResult, type StructuredOutputSuccess, type StructuredOutputFailure, type JSONSchema, type SchemaProvider, type ProviderSchema, type SchemaConfig, isStructuredOutputSuccess, isStructuredOutputFailure, normalizeJsonSchema, convertToProviderSchema, stripUnsupportedFeatures, getJsonSchema, getJsonSchemaFromConfig, parseStructured, tryParseStructured, validateStructuredOutput, stripJsonFences, StreamingJsonParser, type StreamingStructuredResult, } from './structured-output.js';
18
- //# sourceMappingURL=index.d.ts.map
package/dist/index.js CHANGED
@@ -52,4 +52,3 @@ normalizeJsonSchema, convertToProviderSchema, stripUnsupportedFeatures, getJsonS
52
52
  parseStructured, tryParseStructured, validateStructuredOutput, stripJsonFences,
53
53
  // Streaming parser
54
54
  StreamingJsonParser, } from './structured-output.js';
55
- //# sourceMappingURL=index.js.map
@@ -677,4 +677,3 @@ export declare function hasImages(content: LLMMessageContent): boolean;
677
677
  export declare function audioContent(base64Data: string, mimeType: string): LLMAudioContent;
678
678
  /** Check if message content contains audio */
679
679
  export declare function hasAudio(content: LLMMessageContent): boolean;
680
- //# sourceMappingURL=interfaces.d.ts.map
@@ -74,4 +74,3 @@ export function hasAudio(content) {
74
74
  return false;
75
75
  return content.some(part => part.type === 'audio');
76
76
  }
77
- //# sourceMappingURL=interfaces.js.map
package/dist/mcp.d.ts CHANGED
@@ -82,4 +82,3 @@ export declare class MCPToolBridge {
82
82
  private createToolHandler;
83
83
  private convertInputSchema;
84
84
  }
85
- //# sourceMappingURL=mcp.d.ts.map
package/dist/mcp.js CHANGED
@@ -252,4 +252,3 @@ export class MCPToolBridge {
252
252
  };
253
253
  }
254
254
  }
255
- //# sourceMappingURL=mcp.js.map
@@ -53,4 +53,3 @@ export declare class AnthropicClient extends BaseLLMClient {
53
53
  /** Extract text from multimodal content */
54
54
  private extractText;
55
55
  }
56
- //# sourceMappingURL=anthropic.d.ts.map
@@ -546,4 +546,3 @@ export class AnthropicClient extends BaseLLMClient {
546
546
  .join('');
547
547
  }
548
548
  }
549
- //# sourceMappingURL=anthropic.js.map
@@ -56,4 +56,3 @@ export declare class GoogleClient extends BaseLLMClient {
56
56
  */
57
57
  private fetchWithFlexRetry;
58
58
  }
59
- //# sourceMappingURL=google.d.ts.map
@@ -712,4 +712,3 @@ export class GoogleClient extends BaseLLMClient {
712
712
  throw new Error('Unreachable');
713
713
  }
714
714
  }
715
- //# sourceMappingURL=google.js.map
@@ -5,4 +5,3 @@ export { OllamaClient } from './ollama.js';
5
5
  export { OpenAICompatibleClient } from './openai.js';
6
6
  export { GoogleClient } from './google.js';
7
7
  export { AnthropicClient } from './anthropic.js';
8
- //# sourceMappingURL=index.d.ts.map
@@ -5,4 +5,3 @@ export { OllamaClient } from './ollama.js';
5
5
  export { OpenAICompatibleClient } from './openai.js';
6
6
  export { GoogleClient } from './google.js';
7
7
  export { AnthropicClient } from './anthropic.js';
8
- //# sourceMappingURL=index.js.map
@@ -37,4 +37,3 @@ export declare class OllamaClient extends BaseLLMClient {
37
37
  */
38
38
  private buildFormatParameter;
39
39
  }
40
- //# sourceMappingURL=ollama.d.ts.map
@@ -426,4 +426,3 @@ export class OllamaClient extends BaseLLMClient {
426
426
  return 'json';
427
427
  }
428
428
  }
429
- //# sourceMappingURL=ollama.js.map
@@ -9,6 +9,7 @@ import type { LLMClientOptions, LLMChatMessage, LLMChatResponse, ChatOptions } f
9
9
  import type { DecodedEvent } from '../stream-decoder.js';
10
10
  import type { Auditor } from '../auditor.js';
11
11
  export declare class OpenAICompatibleClient extends BaseLLMClient {
12
+ private warnedVllmToolFallback;
12
13
  /**
13
14
  * DiffusionGemma on trimmed vLLM builds has no server-side reasoning or
14
15
  * tool-call parser — the native channel protocol is handled client-side
@@ -22,6 +23,7 @@ export declare class OpenAICompatibleClient extends BaseLLMClient {
22
23
  */
23
24
  private buildUrl;
24
25
  constructor(options: LLMClientOptions, auditor?: Auditor);
26
+ private warnVllmToolFallback;
25
27
  chat(messages: LLMChatMessage[], options?: ChatOptions): Promise<LLMChatResponse>;
26
28
  chatStream(messages: LLMChatMessage[], options?: ChatOptions): AsyncGenerator<DecodedEvent, LLMChatResponse | void, unknown>;
27
29
  private normalizeToolCall;
@@ -35,4 +37,3 @@ export declare class OpenAICompatibleClient extends BaseLLMClient {
35
37
  */
36
38
  private buildResponseFormat;
37
39
  }
38
- //# sourceMappingURL=openai.d.ts.map