universal-llm-client 4.3.0 → 4.5.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 (151) hide show
  1. package/CHANGELOG.md +27 -24
  2. package/README.md +60 -11
  3. package/dist/ai-model.d.ts +12 -1
  4. package/dist/ai-model.d.ts.map +1 -1
  5. package/dist/ai-model.js +36 -1
  6. package/dist/ai-model.js.map +1 -1
  7. package/dist/auditor.js.map +1 -1
  8. package/dist/client.js.map +1 -1
  9. package/dist/gemma-channel.d.ts +14 -0
  10. package/dist/gemma-channel.d.ts.map +1 -0
  11. package/dist/gemma-channel.js +38 -0
  12. package/dist/gemma-channel.js.map +1 -0
  13. package/dist/gemma-diffusion.d.ts +49 -0
  14. package/dist/gemma-diffusion.d.ts.map +1 -0
  15. package/dist/gemma-diffusion.js +147 -0
  16. package/dist/gemma-diffusion.js.map +1 -0
  17. package/dist/http.d.ts +4 -0
  18. package/dist/http.d.ts.map +1 -1
  19. package/dist/http.js +14 -1
  20. package/dist/http.js.map +1 -1
  21. package/dist/index.d.ts +2 -1
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +4 -0
  24. package/dist/index.js.map +1 -1
  25. package/dist/interfaces.d.ts +163 -7
  26. package/dist/interfaces.d.ts.map +1 -1
  27. package/dist/interfaces.js.map +1 -1
  28. package/dist/mcp.js.map +1 -1
  29. package/dist/providers/anthropic.d.ts.map +1 -1
  30. package/dist/providers/anthropic.js +28 -3
  31. package/dist/providers/anthropic.js.map +1 -1
  32. package/dist/providers/google.d.ts +22 -1
  33. package/dist/providers/google.d.ts.map +1 -1
  34. package/dist/providers/google.js +223 -13
  35. package/dist/providers/google.js.map +1 -1
  36. package/dist/providers/index.js.map +1 -1
  37. package/dist/providers/ollama.d.ts +2 -0
  38. package/dist/providers/ollama.d.ts.map +1 -1
  39. package/dist/providers/ollama.js +59 -30
  40. package/dist/providers/ollama.js.map +1 -1
  41. package/dist/providers/openai.d.ts +14 -0
  42. package/dist/providers/openai.d.ts.map +1 -1
  43. package/dist/providers/openai.js +200 -22
  44. package/dist/providers/openai.js.map +1 -1
  45. package/dist/router.d.ts +2 -0
  46. package/dist/router.d.ts.map +1 -1
  47. package/dist/router.js +4 -0
  48. package/dist/router.js.map +1 -1
  49. package/dist/stream-decoder.d.ts +12 -0
  50. package/dist/stream-decoder.d.ts.map +1 -1
  51. package/dist/stream-decoder.js +182 -5
  52. package/dist/stream-decoder.js.map +1 -1
  53. package/dist/structured-output.js.map +1 -1
  54. package/dist/thinking.d.ts +36 -0
  55. package/dist/thinking.d.ts.map +1 -0
  56. package/dist/thinking.js +52 -0
  57. package/dist/thinking.js.map +1 -0
  58. package/dist/tools.js.map +1 -1
  59. package/dist/zod-adapter.js.map +1 -1
  60. package/package.json +4 -1
  61. package/src/ai-model.ts +400 -0
  62. package/src/auditor.ts +213 -0
  63. package/src/client.ts +402 -0
  64. package/src/debug/debug-google-streaming.ts +97 -0
  65. package/src/debug/debug-tool-execution.ts +86 -0
  66. package/src/debug/test-lmstudio-tools.ts +155 -0
  67. package/src/demos/README.md +47 -0
  68. package/src/demos/basic/universal-llm-examples.ts +161 -0
  69. package/src/demos/diffusion-gemma/.env +29 -0
  70. package/src/demos/diffusion-gemma/.env.example +27 -0
  71. package/src/demos/diffusion-gemma/CLAUDE.md +95 -0
  72. package/src/demos/diffusion-gemma/README.md +59 -0
  73. package/src/demos/diffusion-gemma/canvas.ts +1606 -0
  74. package/src/demos/diffusion-gemma/docker-compose.yml +29 -0
  75. package/src/demos/diffusion-gemma/probe-stream.ts +51 -0
  76. package/src/demos/diffusion-gemma/probe-tools.ts +55 -0
  77. package/src/demos/diffusion-gemma/server.ts +1205 -0
  78. package/src/demos/diffusion-gemma/start-vllm.sh +98 -0
  79. package/src/demos/mcp/astrid-memory-demo.ts +295 -0
  80. package/src/demos/mcp/astrid-persona-memory.ts +357 -0
  81. package/src/demos/mcp/mcp-mongodb-demo.ts +275 -0
  82. package/src/demos/mcp/simple-astrid-memory.ts +148 -0
  83. package/src/demos/mcp/simple-mcp-demo.ts +68 -0
  84. package/src/demos/mcp/working-mcp-demo.ts +62 -0
  85. package/src/demos/model-alias-demo.ts +0 -0
  86. package/src/demos/tools/RAG_MEMORY_INTEGRATION.md +267 -0
  87. package/src/demos/tools/astrid-memory-demo.ts +270 -0
  88. package/src/demos/tools/astrid-production-memory-clean.ts +785 -0
  89. package/src/demos/tools/astrid-production-memory.ts +558 -0
  90. package/src/demos/tools/basic-translation-test.ts +66 -0
  91. package/src/demos/tools/chromadb-similarity-tuning.ts +390 -0
  92. package/src/demos/tools/clean-multilingual-conversation.ts +209 -0
  93. package/src/demos/tools/clean-translation-test.ts +119 -0
  94. package/src/demos/tools/clean-universal-multilingual-test.ts +131 -0
  95. package/src/demos/tools/complete-rag-demo.ts +369 -0
  96. package/src/demos/tools/complete-tool-demo.ts +132 -0
  97. package/src/demos/tools/demo-tool-calling.ts +124 -0
  98. package/src/demos/tools/dynamic-language-switching-test.ts +251 -0
  99. package/src/demos/tools/hybrid-thinking-test.ts +154 -0
  100. package/src/demos/tools/memory-integration-test.ts +420 -0
  101. package/src/demos/tools/multilingual-memory-system.ts +802 -0
  102. package/src/demos/tools/ondemand-translation-demo.ts +655 -0
  103. package/src/demos/tools/production-tool-demo.ts +245 -0
  104. package/src/demos/tools/revolutionary-multilingual-test.ts +151 -0
  105. package/src/demos/tools/rigorous-language-analysis.ts +218 -0
  106. package/src/demos/tools/test-universal-memory-system.ts +126 -0
  107. package/src/demos/tools/translation-integration-guide.ts +346 -0
  108. package/src/demos/tools/universal-memory-system.ts +560 -0
  109. package/src/gemma-channel.ts +47 -0
  110. package/src/gemma-diffusion.ts +167 -0
  111. package/src/http.ts +261 -0
  112. package/src/index.ts +180 -0
  113. package/src/interfaces.ts +843 -0
  114. package/src/mcp.ts +345 -0
  115. package/src/providers/anthropic.ts +796 -0
  116. package/src/providers/google.ts +840 -0
  117. package/src/providers/index.ts +8 -0
  118. package/src/providers/ollama.ts +503 -0
  119. package/src/providers/openai.ts +587 -0
  120. package/src/router.ts +785 -0
  121. package/src/stream-decoder.ts +535 -0
  122. package/src/structured-output.ts +759 -0
  123. package/src/test-scripts/test-advanced-tools.ts +310 -0
  124. package/src/test-scripts/test-google-deep-research.ts +33 -0
  125. package/src/test-scripts/test-google-streaming-enhanced.ts +147 -0
  126. package/src/test-scripts/test-google-streaming.ts +63 -0
  127. package/src/test-scripts/test-google-system-prompt-comprehensive.ts +189 -0
  128. package/src/test-scripts/test-google-thinking.ts +46 -0
  129. package/src/test-scripts/test-mcp-config.ts +28 -0
  130. package/src/test-scripts/test-mcp-connection.ts +29 -0
  131. package/src/test-scripts/test-system-message-positions.ts +163 -0
  132. package/src/test-scripts/test-system-prompt-improvement-demo.ts +83 -0
  133. package/src/test-scripts/test-tool-calling.ts +231 -0
  134. package/src/test-scripts/test-vllm-qwen36.ts +256 -0
  135. package/src/tests/ai-model.test.ts +1614 -0
  136. package/src/tests/auditor.test.ts +224 -0
  137. package/src/tests/gemma-diffusion.test.ts +115 -0
  138. package/src/tests/http.test.ts +200 -0
  139. package/src/tests/interfaces.test.ts +117 -0
  140. package/src/tests/providers/anthropic.test.ts +118 -0
  141. package/src/tests/providers/google.test.ts +841 -0
  142. package/src/tests/providers/ollama.test.ts +1034 -0
  143. package/src/tests/providers/openai.test.ts +1511 -0
  144. package/src/tests/router.test.ts +254 -0
  145. package/src/tests/stream-decoder.test.ts +263 -0
  146. package/src/tests/structured-output.test.ts +1450 -0
  147. package/src/tests/thinking.test.ts +65 -0
  148. package/src/tests/tools.test.ts +175 -0
  149. package/src/thinking.ts +73 -0
  150. package/src/tools.ts +246 -0
  151. package/src/zod-adapter.ts +72 -0
@@ -5,24 +5,67 @@
5
5
  * Works with: OpenAI, OpenRouter, LM Studio, LlamaCpp, vLLM, Groq, Together.
6
6
  */
7
7
  import { BaseLLMClient } from '../client.js';
8
+ import { resolveThinking, isOpenAIReasoningModel } from '../thinking.js';
8
9
  import { httpRequest, httpStream, parseSSE, buildHeaders } from '../http.js';
9
10
  import { StandardChatDecoder } from '../stream-decoder.js';
10
11
  import { normalizeJsonSchema, getJsonSchemaFromConfig, } from '../structured-output.js';
12
+ import { isGemmaDiffusionModel, parseGemmaDiffusionOutput } from '../gemma-diffusion.js';
11
13
  export class OpenAICompatibleClient extends BaseLLMClient {
14
+ /**
15
+ * DiffusionGemma on trimmed vLLM builds has no server-side reasoning or
16
+ * tool-call parser — the native channel protocol is handled client-side
17
+ * (see gemma-diffusion.ts). Auto-detected from the model name; override
18
+ * with `gemmaNativeProtocol` in LLMClientOptions.
19
+ */
20
+ get gemmaNative() {
21
+ return this.options.gemmaNativeProtocol ?? isGemmaDiffusionModel(this.options.model);
22
+ }
23
+ /**
24
+ * Build a full endpoint URL, respecting apiBasePath (already baked into this.options.url)
25
+ * and any queryParams provided at the provider config level.
26
+ */
27
+ buildUrl(suffix) {
28
+ const raw = this.options.url.replace(/\/+$/, '');
29
+ // Split off any query string already on the configured base URL so the
30
+ // path is inserted before it (avoids `host/v1?k=v/chat/completions`).
31
+ const qIdx = raw.indexOf('?');
32
+ const basePath = (qIdx === -1 ? raw : raw.slice(0, qIdx)).replace(/\/+$/, '');
33
+ const existingQuery = qIdx === -1 ? '' : raw.slice(qIdx + 1);
34
+ const path = suffix.startsWith('/') ? suffix : '/' + suffix;
35
+ const search = new URLSearchParams(existingQuery);
36
+ const qp = this.options.queryParams;
37
+ if (qp) {
38
+ for (const [k, v] of Object.entries(qp)) {
39
+ if (v != null)
40
+ search.set(k, String(v));
41
+ }
42
+ }
43
+ const qs = search.toString();
44
+ return basePath + path + (qs ? `?${qs}` : '');
45
+ }
12
46
  constructor(options, auditor) {
13
- // Ensure URL ends with /v1 for standard endpoints
14
- let url = (options.url || 'https://api.openai.com').replace(/\/+$/, '');
15
- if (!url.endsWith('/v1')) {
16
- url += '/v1';
47
+ let base = (options.url || 'https://api.openai.com').replace(/\/+$/, '');
48
+ // Respect apiBasePath (from ProviderConfig.apiBasePath). Default "/v1" for broad compatibility.
49
+ // Set apiBasePath: '' (or '/') when you are supplying a *complete* path already
50
+ // (e.g. full Azure ".../deployments/my-model" URL) or for non-/v1 OpenAI-compatible servers.
51
+ const desired = options.apiBasePath;
52
+ const shouldAppend = desired !== '' && desired !== '/';
53
+ if (shouldAppend) {
54
+ // Normalize to exactly one leading slash and no trailing slash
55
+ // (so 'v1', '/v1', '//v1' and '/v1/' all become '/v1').
56
+ const basePath = ('/' + (desired || '/v1').replace(/^\/+/, '')).replace(/\/+$/, '');
57
+ if (!base.endsWith(basePath)) {
58
+ base += basePath;
59
+ }
17
60
  }
18
- super({ ...options, url }, auditor);
61
+ super({ ...options, url: base }, auditor);
19
62
  }
20
63
  // ========================================================================
21
64
  // Chat
22
65
  // ========================================================================
23
66
  async chat(messages, options) {
24
67
  // Structured output and tools can now be used together.\n // The provider sends both response_format and tools in the request.\n // The Router handles skipping validation when the response contains tool calls.
25
- const url = `${this.options.url}/chat/completions`;
68
+ const url = this.buildUrl('/chat/completions');
26
69
  const tools = options?.tools ?? (Object.keys(this.toolRegistry).length > 0 ? this.getToolDefinitions() : undefined);
27
70
  const body = {
28
71
  model: this.options.model,
@@ -43,6 +86,13 @@ export class OpenAICompatibleClient extends BaseLLMClient {
43
86
  body['tool_choice'] = options.toolChoice;
44
87
  }
45
88
  }
89
+ if (this.gemmaNative) {
90
+ // Markers must survive decoding for client-side parsing,
91
+ // and request-level tool parsing is unavailable server-side.
92
+ body['skip_special_tokens'] = false;
93
+ if (tools?.length)
94
+ body['tool_choice'] = 'none';
95
+ }
46
96
  const start = Date.now();
47
97
  this.auditor.record({
48
98
  timestamp: start,
@@ -61,27 +111,54 @@ export class OpenAICompatibleClient extends BaseLLMClient {
61
111
  if (!choice) {
62
112
  throw new Error('No choices returned from OpenAI API');
63
113
  }
114
+ // vLLM / OpenAI-compatible `usage` carries no timing, so derive decode
115
+ // throughput from the client-measured wall-clock duration.
116
+ const durationMs = Date.now() - start;
64
117
  const usage = data.usage
65
118
  ? {
66
119
  inputTokens: data.usage.prompt_tokens,
67
120
  outputTokens: data.usage.completion_tokens,
68
121
  totalTokens: data.usage.total_tokens,
69
122
  cachedTokens: data.usage.prompt_tokens_details?.cached_tokens,
123
+ durationMs,
124
+ tokensPerSecond: durationMs > 0
125
+ ? data.usage.completion_tokens / (durationMs / 1000)
126
+ : undefined,
70
127
  }
71
128
  : undefined;
72
- // Normalize tool calls (ensure IDs exist)
73
- const toolCalls = choice.message.tool_calls?.map(tc => ({
74
- ...tc,
75
- id: tc.id || this.generateToolCallId(),
76
- }));
129
+ // Normalize tool calls (ensure IDs and JSON-parseable empty args exist).
130
+ let toolCalls = choice.message.tool_calls?.map(tc => this.normalizeToolCall(tc));
77
131
  // Get content, handling null case
78
- const content = choice.message.content || '';
132
+ let content = choice.message.content || '';
133
+ let reasoning;
134
+ // Reasoning models served over the OpenAI-compatible API (vLLM
135
+ // `--reasoning-parser`, DeepSeek-R1, etc.) return the chain-of-thought
136
+ // in a dedicated field instead of inline <think> tags. vLLM uses
137
+ // `reasoning_content`; some gateways use `reasoning`.
138
+ const serverReasoning = choice.message.reasoning ?? choice.message.reasoning_content;
139
+ if (typeof serverReasoning === 'string' && serverReasoning.length > 0) {
140
+ reasoning = serverReasoning;
141
+ }
142
+ if (this.gemmaNative && content) {
143
+ const parsed = parseGemmaDiffusionOutput(content);
144
+ content = parsed.content;
145
+ if (parsed.reasoning)
146
+ reasoning = parsed.reasoning;
147
+ if (!toolCalls?.length && parsed.toolCalls.length) {
148
+ toolCalls = parsed.toolCalls.map(tc => ({
149
+ id: this.generateToolCallId(),
150
+ type: 'function',
151
+ function: { name: tc.name, arguments: tc.argumentsJson },
152
+ }));
153
+ }
154
+ }
79
155
  const result = {
80
156
  message: {
81
157
  role: 'assistant',
82
158
  content,
83
159
  tool_calls: toolCalls,
84
160
  },
161
+ ...(reasoning !== undefined && { reasoning }),
85
162
  usage,
86
163
  provider: 'openai',
87
164
  };
@@ -99,7 +176,7 @@ export class OpenAICompatibleClient extends BaseLLMClient {
99
176
  // Streaming
100
177
  // ========================================================================
101
178
  async *chatStream(messages, options) {
102
- const url = `${this.options.url}/chat/completions`;
179
+ const url = this.buildUrl('/chat/completions');
103
180
  const tools = options?.tools ?? (Object.keys(this.toolRegistry).length > 0 ? this.getToolDefinitions() : undefined);
104
181
  const body = {
105
182
  model: this.options.model,
@@ -113,6 +190,11 @@ export class OpenAICompatibleClient extends BaseLLMClient {
113
190
  body['tool_choice'] = options.toolChoice;
114
191
  }
115
192
  }
193
+ if (this.gemmaNative) {
194
+ body['skip_special_tokens'] = false;
195
+ if (tools?.length)
196
+ body['tool_choice'] = 'none';
197
+ }
116
198
  const start = Date.now();
117
199
  this.auditor.record({
118
200
  timestamp: start,
@@ -120,7 +202,10 @@ export class OpenAICompatibleClient extends BaseLLMClient {
120
202
  provider: 'openai',
121
203
  model: this.options.model,
122
204
  });
123
- const decoder = new StandardChatDecoder(() => { });
205
+ // In gemma-native mode the decoder classifies thought-channel content,
206
+ // so we yield ITS events (thinking vs text) instead of the raw deltas.
207
+ const decoderEvents = [];
208
+ const decoder = new StandardChatDecoder(this.gemmaNative ? e => decoderEvents.push(e) : () => { });
124
209
  // Track accumulated tool calls across chunks
125
210
  const toolCallAccum = new Map();
126
211
  const stream = httpStream(url, {
@@ -130,6 +215,9 @@ export class OpenAICompatibleClient extends BaseLLMClient {
130
215
  timeout: this.options.timeout ?? 120000,
131
216
  });
132
217
  let usage;
218
+ // Accumulates reasoning deltas from servers that stream a dedicated
219
+ // `reasoning` / `reasoning_content` field (vLLM, DeepSeek-R1, etc.).
220
+ let reasoningBuffer = '';
133
221
  for await (const { data } of parseSSE(stream)) {
134
222
  try {
135
223
  const parsed = JSON.parse(data);
@@ -144,9 +232,21 @@ export class OpenAICompatibleClient extends BaseLLMClient {
144
232
  const delta = parsed.choices?.[0]?.delta;
145
233
  if (!delta)
146
234
  continue;
235
+ // Surface server-side reasoning deltas as thinking events.
236
+ const reasoningDelta = delta.reasoning ?? delta.reasoning_content;
237
+ if (reasoningDelta) {
238
+ reasoningBuffer += reasoningDelta;
239
+ yield { type: 'thinking', content: reasoningDelta };
240
+ }
147
241
  if (delta.content) {
148
242
  decoder.push(delta.content);
149
- yield { type: 'text', content: delta.content };
243
+ if (this.gemmaNative) {
244
+ while (decoderEvents.length)
245
+ yield decoderEvents.shift();
246
+ }
247
+ else {
248
+ yield { type: 'text', content: delta.content };
249
+ }
150
250
  }
151
251
  // Accumulate streamed tool calls
152
252
  if (delta.tool_calls) {
@@ -175,7 +275,8 @@ export class OpenAICompatibleClient extends BaseLLMClient {
175
275
  // Emit tool calls when stream finishes
176
276
  if (parsed.choices?.[0]?.finish_reason === 'tool_calls' || parsed.choices?.[0]?.finish_reason === 'stop') {
177
277
  if (toolCallAccum.size > 0) {
178
- const calls = Array.from(toolCallAccum.values());
278
+ const calls = Array.from(toolCallAccum.values())
279
+ .map(tc => this.normalizeToolCall(tc));
179
280
  yield { type: 'tool_call', calls };
180
281
  }
181
282
  }
@@ -185,6 +286,21 @@ export class OpenAICompatibleClient extends BaseLLMClient {
185
286
  }
186
287
  }
187
288
  decoder.flush();
289
+ if (this.gemmaNative) {
290
+ while (decoderEvents.length)
291
+ yield decoderEvents.shift();
292
+ }
293
+ // Augment usage with client-measured timing (vLLM streams no timing).
294
+ if (usage) {
295
+ const durationMs = Date.now() - start;
296
+ usage = {
297
+ ...usage,
298
+ durationMs,
299
+ tokensPerSecond: durationMs > 0
300
+ ? usage.outputTokens / (durationMs / 1000)
301
+ : undefined,
302
+ };
303
+ }
188
304
  this.auditor.record({
189
305
  timestamp: Date.now(),
190
306
  type: 'stream_end',
@@ -193,25 +309,66 @@ export class OpenAICompatibleClient extends BaseLLMClient {
193
309
  duration: Date.now() - start,
194
310
  usage,
195
311
  });
196
- const finalToolCalls = toolCallAccum.size > 0
197
- ? Array.from(toolCallAccum.values())
312
+ let finalToolCalls = toolCallAccum.size > 0
313
+ ? Array.from(toolCallAccum.values()).map(tc => this.normalizeToolCall(tc))
198
314
  : undefined;
315
+ let cleanContent = decoder.getCleanContent();
316
+ // Prefer the server's dedicated reasoning field; fall back to <think>
317
+ // tags parsed from the content stream by the decoder.
318
+ let reasoning = reasoningBuffer || decoder.getReasoning();
319
+ if (this.gemmaNative) {
320
+ // Native tool-call blocks live in the text channel; extract them.
321
+ const parsed = parseGemmaDiffusionOutput(cleanContent);
322
+ cleanContent = parsed.content;
323
+ if (parsed.reasoning) {
324
+ reasoning = reasoning ? `${reasoning}\n\n${parsed.reasoning}` : parsed.reasoning;
325
+ }
326
+ if (!finalToolCalls?.length && parsed.toolCalls.length) {
327
+ finalToolCalls = parsed.toolCalls.map(tc => ({
328
+ id: this.generateToolCallId(),
329
+ type: 'function',
330
+ function: { name: tc.name, arguments: tc.argumentsJson },
331
+ }));
332
+ yield { type: 'tool_call', calls: finalToolCalls };
333
+ }
334
+ }
199
335
  return {
200
336
  message: {
201
337
  role: 'assistant',
202
- content: decoder.getCleanContent(),
338
+ content: cleanContent,
203
339
  tool_calls: finalToolCalls,
204
340
  },
205
- reasoning: decoder.getReasoning(),
341
+ reasoning,
206
342
  usage,
207
343
  provider: 'openai',
208
344
  };
209
345
  }
346
+ normalizeToolCall(toolCall) {
347
+ return {
348
+ ...toolCall,
349
+ id: toolCall.id || this.generateToolCallId(),
350
+ type: 'function',
351
+ function: {
352
+ ...toolCall.function,
353
+ name: toolCall.function?.name || '',
354
+ arguments: this.normalizeToolArguments(toolCall.function?.arguments),
355
+ },
356
+ };
357
+ }
358
+ normalizeToolArguments(args) {
359
+ if (typeof args === 'string') {
360
+ return args.trim().length > 0 ? args : '{}';
361
+ }
362
+ if (args == null) {
363
+ return '{}';
364
+ }
365
+ return JSON.stringify(args) ?? '{}';
366
+ }
210
367
  // ========================================================================
211
368
  // Embeddings
212
369
  // ========================================================================
213
370
  async embed(text) {
214
- const url = `${this.options.url}/embeddings`;
371
+ const url = this.buildUrl('/embeddings');
215
372
  const response = await httpRequest(url, {
216
373
  method: 'POST',
217
374
  headers: buildHeaders(this.options),
@@ -227,7 +384,7 @@ export class OpenAICompatibleClient extends BaseLLMClient {
227
384
  // Model Discovery
228
385
  // ========================================================================
229
386
  async getModels() {
230
- const url = `${this.options.url}/models`;
387
+ const url = this.buildUrl('/models');
231
388
  try {
232
389
  const response = await httpRequest(url, {
233
390
  headers: buildHeaders(this.options),
@@ -259,6 +416,27 @@ export class OpenAICompatibleClient extends BaseLLMClient {
259
416
  params['temperature'] = options.temperature;
260
417
  if (options?.maxTokens !== undefined)
261
418
  params['max_tokens'] = options.maxTokens;
419
+ // Unified thinking flag. Per-call overrides model config; only emitted
420
+ // when explicitly set, so servers that reject unknown fields are
421
+ // unaffected by default. OpenAI reasoning models (o-series / GPT-5) use
422
+ // `reasoning_effort`; vLLM / Qwen use `chat_template_kwargs.enable_thinking`.
423
+ // A user-supplied value (via parameters) always wins.
424
+ const thinking = resolveThinking(options?.thinking, this.options.thinking);
425
+ if (thinking) {
426
+ const isOfficialOpenAI = (this.options.url ?? '').includes('api.openai.com');
427
+ if (isOpenAIReasoningModel(this.options.model)) {
428
+ if (params['reasoning_effort'] === undefined) {
429
+ params['reasoning_effort'] = thinking.enabled ? (thinking.level ?? 'medium') : 'minimal';
430
+ }
431
+ }
432
+ else if (!isOfficialOpenAI) {
433
+ // `chat_template_kwargs` is a vLLM/Qwen extension. Official OpenAI
434
+ // rejects unknown body fields (and gpt-4o has no thinking toggle),
435
+ // so only send it to self-hosted / compatible gateways.
436
+ const existing = params['chat_template_kwargs'] ?? {};
437
+ params['chat_template_kwargs'] = { enable_thinking: thinking.enabled, ...existing };
438
+ }
439
+ }
262
440
  return params;
263
441
  }
264
442
  // ========================================================================
@@ -1 +1 @@
1
- {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"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","sourcesContent":["/**\r\n * Universal LLM Client v3 — OpenAI-Compatible Provider\r\n *\r\n * Implements BaseLLMClient for OpenAI-compatible APIs.\r\n * Works with: OpenAI, OpenRouter, LM Studio, LlamaCpp, vLLM, Groq, Together.\r\n */\r\n\r\nimport { BaseLLMClient } from '../client.js';\r\nimport { httpRequest, httpStream, parseSSE, buildHeaders } from '../http.js';\r\nimport { StandardChatDecoder } from '../stream-decoder.js';\r\nimport {\r\n normalizeJsonSchema,\r\n getJsonSchemaFromConfig,\r\n type JSONSchema,\r\n type StructuredOutputOptions,\r\n} from '../structured-output.js';\r\nimport type {\r\n LLMClientOptions,\r\n LLMChatMessage,\r\n LLMChatResponse,\r\n ChatOptions,\r\n OpenAIResponse,\r\n OpenAIModelInfo,\r\n TokenUsageInfo,\r\n} from '../interfaces.js';\r\nimport type { DecodedEvent } from '../stream-decoder.js';\r\nimport type { Auditor } from '../auditor.js';\r\n\r\nexport class OpenAICompatibleClient extends BaseLLMClient {\r\n constructor(options: LLMClientOptions, auditor?: Auditor) {\r\n // Ensure URL ends with /v1 for standard endpoints\r\n let url = (options.url || 'https://api.openai.com').replace(/\\/+$/, '');\r\n if (!url.endsWith('/v1')) {\r\n url += '/v1';\r\n }\r\n super({ ...options, url }, auditor);\r\n }\r\n\r\n // ========================================================================\r\n // Chat\r\n // ========================================================================\r\n\r\n async chat(\r\n messages: LLMChatMessage[],\r\n options?: ChatOptions,\r\n ): Promise<LLMChatResponse> {\r\n // Structured output and tools can now be used together.\\n // The provider sends both response_format and tools in the request.\\n // The Router handles skipping validation when the response contains tool calls.\r\n\r\n const url = `${this.options.url}/chat/completions`;\r\n const tools = options?.tools ?? (Object.keys(this.toolRegistry).length > 0 ? this.getToolDefinitions() : undefined);\r\n\r\n const body: Record<string, unknown> = {\r\n model: this.options.model,\r\n messages: this.convertMessages(messages),\r\n ...this.buildRequestParams(options),\r\n };\r\n\r\n // Handle structured output\r\n const schemaOptions = this.extractSchemaOptions(options);\r\n if (schemaOptions) {\r\n body['response_format'] = this.buildResponseFormat(schemaOptions);\r\n } else if (options?.responseFormat) {\r\n body['response_format'] = options.responseFormat;\r\n }\r\n\r\n if (tools?.length) {\r\n body['tools'] = tools;\r\n if (options?.toolChoice) {\r\n body['tool_choice'] = options.toolChoice;\r\n }\r\n }\r\n\r\n const start = Date.now();\r\n this.auditor.record({\r\n timestamp: start,\r\n type: 'request',\r\n provider: 'openai',\r\n model: this.options.model,\r\n });\r\n\r\n const response = await httpRequest<OpenAIResponse>(url, {\r\n method: 'POST',\r\n headers: buildHeaders(this.options),\r\n body,\r\n timeout: this.options.timeout ?? 30000,\r\n });\r\n\r\n const data = response.data;\r\n const choice = data.choices[0];\r\n\r\n if (!choice) {\r\n throw new Error('No choices returned from OpenAI API');\r\n }\r\n\r\n const usage: TokenUsageInfo | undefined = data.usage\r\n ? {\r\n inputTokens: data.usage.prompt_tokens,\r\n outputTokens: data.usage.completion_tokens,\r\n totalTokens: data.usage.total_tokens,\r\n cachedTokens: data.usage.prompt_tokens_details?.cached_tokens,\r\n }\r\n : undefined;\r\n\r\n // Normalize tool calls (ensure IDs exist)\r\n const toolCalls = choice.message.tool_calls?.map(tc => ({\r\n ...tc,\r\n id: tc.id || this.generateToolCallId(),\r\n }));\r\n\r\n // Get content, handling null case\r\n const content = choice.message.content || '';\r\n\r\n const result: LLMChatResponse = {\r\n message: {\r\n role: 'assistant',\r\n content,\r\n tool_calls: toolCalls,\r\n },\r\n usage,\r\n provider: 'openai',\r\n };\r\n\r\n this.auditor.record({\r\n timestamp: Date.now(),\r\n type: 'response',\r\n provider: 'openai',\r\n model: this.options.model,\r\n duration: Date.now() - start,\r\n usage,\r\n });\r\n\r\n return result;\r\n }\r\n\r\n // ========================================================================\r\n // Streaming\r\n // ========================================================================\r\n\r\n async *chatStream(\r\n messages: LLMChatMessage[],\r\n options?: ChatOptions,\r\n ): AsyncGenerator<DecodedEvent, LLMChatResponse | void, unknown> {\r\n const url = `${this.options.url}/chat/completions`;\r\n const tools = options?.tools ?? (Object.keys(this.toolRegistry).length > 0 ? this.getToolDefinitions() : undefined);\r\n\r\n const body: Record<string, unknown> = {\r\n model: this.options.model,\r\n messages: this.convertMessages(messages),\r\n stream: true,\r\n ...this.buildRequestParams(options),\r\n };\r\n\r\n if (tools?.length) {\r\n body['tools'] = tools;\r\n if (options?.toolChoice) {\r\n body['tool_choice'] = options.toolChoice;\r\n }\r\n }\r\n\r\n const start = Date.now();\r\n this.auditor.record({\r\n timestamp: start,\r\n type: 'stream_start',\r\n provider: 'openai',\r\n model: this.options.model,\r\n });\r\n\r\n const decoder = new StandardChatDecoder(() => {});\r\n\r\n // Track accumulated tool calls across chunks\r\n const toolCallAccum: Map<number, {\r\n id: string;\r\n type: 'function';\r\n function: { name: string; arguments: string };\r\n }> = new Map();\r\n\r\n const stream = httpStream(url, {\r\n method: 'POST',\r\n headers: buildHeaders(this.options),\r\n body,\r\n timeout: this.options.timeout ?? 120000,\r\n });\r\n\r\n let usage: TokenUsageInfo | undefined;\r\n\r\n for await (const { data } of parseSSE(stream)) {\r\n try {\r\n const parsed = JSON.parse(data) as {\r\n choices?: Array<{\r\n delta?: {\r\n content?: string;\r\n tool_calls?: Array<{\r\n index: number;\r\n id?: string;\r\n type?: string;\r\n function?: { name?: string; arguments?: string };\r\n }>;\r\n };\r\n finish_reason?: string;\r\n }>;\r\n usage?: {\r\n prompt_tokens: number;\r\n completion_tokens: number;\r\n total_tokens: number;\r\n prompt_tokens_details?: {\r\n cached_tokens?: number;\r\n };\r\n };\r\n };\r\n\r\n if (parsed.usage) {\r\n usage = {\r\n inputTokens: parsed.usage.prompt_tokens,\r\n outputTokens: parsed.usage.completion_tokens,\r\n totalTokens: parsed.usage.total_tokens,\r\n cachedTokens: parsed.usage.prompt_tokens_details?.cached_tokens,\r\n };\r\n }\r\n\r\n const delta = parsed.choices?.[0]?.delta;\r\n if (!delta) continue;\r\n\r\n if (delta.content) {\r\n decoder.push(delta.content);\r\n yield { type: 'text', content: delta.content };\r\n }\r\n\r\n // Accumulate streamed tool calls\r\n if (delta.tool_calls) {\r\n for (const tc of delta.tool_calls) {\r\n const existing = toolCallAccum.get(tc.index);\r\n if (!existing) {\r\n toolCallAccum.set(tc.index, {\r\n id: tc.id || this.generateToolCallId(),\r\n type: 'function',\r\n function: {\r\n name: tc.function?.name || '',\r\n arguments: tc.function?.arguments || '',\r\n },\r\n });\r\n } else {\r\n if (tc.function?.arguments) {\r\n existing.function.arguments += tc.function.arguments;\r\n }\r\n if (tc.function?.name) {\r\n existing.function.name += tc.function.name;\r\n }\r\n }\r\n }\r\n }\r\n\r\n // Emit tool calls when stream finishes\r\n if (parsed.choices?.[0]?.finish_reason === 'tool_calls' || parsed.choices?.[0]?.finish_reason === 'stop') {\r\n if (toolCallAccum.size > 0) {\r\n const calls = Array.from(toolCallAccum.values());\r\n yield { type: 'tool_call', calls };\r\n }\r\n }\r\n } catch {\r\n // Skip unparseable SSE data\r\n }\r\n }\r\n\r\n decoder.flush();\r\n\r\n this.auditor.record({\r\n timestamp: Date.now(),\r\n type: 'stream_end',\r\n provider: 'openai',\r\n model: this.options.model,\r\n duration: Date.now() - start,\r\n usage,\r\n });\r\n\r\n const finalToolCalls = toolCallAccum.size > 0\r\n ? Array.from(toolCallAccum.values())\r\n : undefined;\r\n\r\n return {\r\n message: {\r\n role: 'assistant',\r\n content: decoder.getCleanContent(),\r\n tool_calls: finalToolCalls,\r\n },\r\n reasoning: decoder.getReasoning(),\r\n usage,\r\n provider: 'openai',\r\n };\r\n }\r\n\r\n // ========================================================================\r\n // Embeddings\r\n // ========================================================================\r\n\r\n async embed(text: string): Promise<number[]> {\r\n const url = `${this.options.url}/embeddings`;\r\n const response = await httpRequest<{\r\n data: Array<{ embedding: number[] }>;\r\n }>(url, {\r\n method: 'POST',\r\n headers: buildHeaders(this.options),\r\n body: {\r\n model: this.options.model,\r\n input: text,\r\n },\r\n timeout: this.options.timeout ?? 30000,\r\n });\r\n return response.data.data[0]?.embedding ?? [];\r\n }\r\n\r\n // ========================================================================\r\n // Model Discovery\r\n // ========================================================================\r\n\r\n async getModels(): Promise<string[]> {\r\n const url = `${this.options.url}/models`;\r\n try {\r\n const response = await httpRequest<{\r\n data: OpenAIModelInfo[];\r\n }>(url, {\r\n headers: buildHeaders(this.options),\r\n timeout: 5000,\r\n });\r\n return response.data.data.map(m => m.id);\r\n } catch {\r\n return [];\r\n }\r\n }\r\n\r\n // ========================================================================\r\n // Internals\r\n // ========================================================================\r\n\r\n private convertMessages(messages: LLMChatMessage[]): LLMChatMessage[] {\r\n // OpenAI format is our canonical format, minimal conversion needed\r\n return messages.map(msg => ({\r\n ...msg,\r\n // Ensure content is never null/undefined\r\n content: msg.content ?? '',\r\n }));\r\n }\r\n\r\n private buildRequestParams(options?: ChatOptions): Record<string, unknown> {\r\n const params: Record<string, unknown> = {\r\n ...this.options.defaultParameters,\r\n ...options?.parameters,\r\n };\r\n if (options?.temperature !== undefined) params['temperature'] = options.temperature;\r\n if (options?.maxTokens !== undefined) params['max_tokens'] = options.maxTokens;\r\n return params;\r\n }\r\n\r\n // ========================================================================\r\n // Structured Output Helpers\r\n // ========================================================================\r\n\r\n /**\r\n * Build OpenAI response_format for structured output.\r\n */\r\n private buildResponseFormat(options: StructuredOutputOptions<unknown> & { strict?: boolean }): Record<string, unknown> {\r\n let jsonSchema: JSONSchema;\r\n let name: string;\r\n let description: string | undefined;\r\n\r\n // Prefer jsonSchema if provided (handles raw JSON Schema case)\r\n if (options.jsonSchema) {\r\n // Use raw JSON Schema\r\n jsonSchema = normalizeJsonSchema(options.jsonSchema);\r\n name = options.name || 'response';\r\n description = options.description;\r\n } else if (options.schemaConfig) {\r\n // Use SchemaConfig's embedded JSON Schema\r\n jsonSchema = getJsonSchemaFromConfig(options.schemaConfig);\r\n name = options.name || options.schemaConfig.name || 'response';\r\n description = options.description || options.schemaConfig.description;\r\n } else {\r\n // Should not happen - we check this in extractSchemaOptions\r\n throw new Error('Either schemaConfig or jsonSchema must be provided');\r\n }\r\n\r\n // OpenAI strict mode — configurable, defaults to true for reliable structured output\r\n return {\r\n type: 'json_schema',\r\n json_schema: {\r\n name,\r\n ...(description && { description }),\r\n schema: jsonSchema,\r\n strict: options.strict ?? true,\r\n },\r\n };\r\n }\r\n}\r\n"]}
1
+ {"version":3,"file":"openai.js","sourceRoot":"","sources":["../../src/providers/openai.ts"],"names":[],"mappings":"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"}
package/dist/router.d.ts CHANGED
@@ -52,6 +52,8 @@ export declare class Router {
52
52
  addProvider(entry: ProviderEntry): void;
53
53
  removeProvider(id: string): void;
54
54
  setAuditor(auditor: Auditor): void;
55
+ /** All registered provider clients, in priority order. */
56
+ getClients(): BaseLLMClient[];
55
57
  getStatus(): ProviderStatus[];
56
58
  /**
57
59
  * Execute a function against providers with automatic failover.
@@ -1 +1 @@
1
- {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAE5C,OAAO,KAAK,EACR,cAAc,EACd,eAAe,EACf,WAAW,EACX,aAAa,EAEhB,MAAM,iBAAiB,CAAC;AACzB,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACxD,OAAO,EAKH,KAAK,YAAY,EACjB,KAAK,sBAAsB,EAC9B,MAAM,wBAAwB,CAAC;AAMhC,MAAM,WAAW,aAAa;IAC1B,gDAAgD;IAChD,EAAE,EAAE,MAAM,CAAC;IACX,gCAAgC;IAChC,MAAM,EAAE,aAAa,CAAC;IACtB,kEAAkE;IAClE,QAAQ,EAAE,MAAM,CAAC;IACjB,4CAA4C;IAC5C,aAAa,CAAC,EAAE,MAAM,CAAC;CAC1B;AASD,MAAM,WAAW,YAAY;IACzB,4DAA4D;IAC5D,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,qEAAqE;IACrE,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,qEAAqE;IACrE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,gCAAgC;IAChC,OAAO,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,MAAM,CAAC;CACjB;AAMD,qBAAa,MAAM;IACf,OAAO,CAAC,SAAS,CAAuB;IACxC,OAAO,CAAC,MAAM,CAA0C;IACxD,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,MAAM,CAA0C;gBAE5C,MAAM,GAAE,YAAiB;IAarC,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI;IAUvC,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI;IAKhC,UAAU,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI;IAIlC,SAAS,IAAI,cAAc,EAAE;IAe7B;;;OAGG;IACG,OAAO,CAAC,CAAC,EACX,EAAE,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,OAAO,CAAC,CAAC,CAAC,EACzC,OAAO,GAAE,MAAkB,GAC5B,OAAO,CAAC,CAAC,CAAC;IA6Db;;;OAGG;IACI,aAAa,CAChB,EAAE,EAAE,CAAC,MAAM,EAAE,aAAa,KAAK,cAAc,CAAC,YAAY,EAAE,eAAe,GAAG,IAAI,EAAE,OAAO,CAAC,EAC5F,OAAO,GAAE,MAAiB,GAC3B,cAAc,CAAC,YAAY,EAAE,eAAe,GAAG,IAAI,EAAE,OAAO,CAAC;IAiDhE;;OAEG;IACH,OAAO,CAAC,sBAAsB;IAI9B;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAkBrB,IAAI,CAAC,QAAQ,EAAE,cAAc,EAAE,EAAE,OAAO,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC;IAgBvF;;;OAGG;YACW,wBAAwB;IAwHhC,aAAa,CACf,QAAQ,EAAE,cAAc,EAAE,EAC1B,OAAO,CAAC,EAAE,WAAW,GAAG;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,GACnD,OAAO,CAAC,eAAe,CAAC;IAOpB,UAAU,CACb,QAAQ,EAAE,cAAc,EAAE,EAC1B,OAAO,CAAC,EAAE,WAAW,GACtB,cAAc,CAAC,YAAY,EAAE,eAAe,GAAG,IAAI,EAAE,OAAO,CAAC;IAgB1D,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;IAOtC,UAAU,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC;IAOhD,SAAS,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;IAc9B,YAAY,IAAI,OAAO,CAAC,aAAa,CAAC;IAW5C;;;;;;;;;;;OAWG;IACG,kBAAkB,CAAC,CAAC,EACtB,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACvB,QAAQ,EAAE,cAAc,EAAE,EAC1B,OAAO,CAAC,EAAE,WAAW,GACtB,OAAO,CAAC,CAAC,CAAC;IA6Db;;;;;;;;OAQG;IACG,kBAAkB,CAAC,CAAC,EACtB,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACvB,QAAQ,EAAE,cAAc,EAAE,EAC1B,OAAO,CAAC,EAAE,WAAW,GACtB,OAAO,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;IAmBrC;;;;;;;;;;OAUG;IACI,wBAAwB,CAAC,CAAC,EAC7B,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC,EACvB,QAAQ,EAAE,cAAc,EAAE,EAC1B,OAAO,CAAC,EAAE,WAAW,GACtB,cAAc,CAAC,CAAC,EAAE,CAAC,EAAE,OAAO,CAAC;IAoFhC,YAAY,CACR,IAAI,EAAE,MAAM,EACZ,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,OAAO,iBAAiB,EAAE,WAAW,CAAC,YAAY,CAAC,EAC/D,OAAO,EAAE,OAAO,iBAAiB,EAAE,WAAW,GAC/C,IAAI;IAMP,aAAa,CACT,KAAK,EAAE,KAAK,CAAC;QACT,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,OAAO,iBAAiB,EAAE,WAAW,CAAC,YAAY,CAAC,CAAC;QAChE,OAAO,EAAE,OAAO,iBAAiB,EAAE,WAAW,CAAC;KAClD,CAAC,GACH,IAAI;IAUP,OAAO,CAAC,WAAW;IAenB,OAAO,CAAC,qBAAqB;IAI7B,OAAO,CAAC,qBAAqB;IAU7B,OAAO,CAAC,aAAa;IASrB,OAAO,CAAC,aAAa;CAYxB"}
1
+ {"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
package/dist/router.js CHANGED
@@ -47,6 +47,10 @@ export class Router {
47
47
  setAuditor(auditor) {
48
48
  this.auditor = auditor;
49
49
  }
50
+ /** All registered provider clients, in priority order. */
51
+ getClients() {
52
+ return this.providers.map(p => p.client);
53
+ }
50
54
  getStatus() {
51
55
  return this.providers.map(p => ({
52
56
  id: p.id,