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.
- package/CHANGELOG.md +27 -24
- package/README.md +60 -11
- package/dist/ai-model.d.ts +12 -1
- package/dist/ai-model.d.ts.map +1 -1
- package/dist/ai-model.js +36 -1
- package/dist/ai-model.js.map +1 -1
- package/dist/auditor.js.map +1 -1
- package/dist/client.js.map +1 -1
- package/dist/gemma-channel.d.ts +14 -0
- package/dist/gemma-channel.d.ts.map +1 -0
- package/dist/gemma-channel.js +38 -0
- package/dist/gemma-channel.js.map +1 -0
- package/dist/gemma-diffusion.d.ts +49 -0
- package/dist/gemma-diffusion.d.ts.map +1 -0
- package/dist/gemma-diffusion.js +147 -0
- package/dist/gemma-diffusion.js.map +1 -0
- package/dist/http.d.ts +4 -0
- package/dist/http.d.ts.map +1 -1
- package/dist/http.js +14 -1
- package/dist/http.js.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/interfaces.d.ts +163 -7
- package/dist/interfaces.d.ts.map +1 -1
- package/dist/interfaces.js.map +1 -1
- package/dist/mcp.js.map +1 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +28 -3
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/google.d.ts +22 -1
- package/dist/providers/google.d.ts.map +1 -1
- package/dist/providers/google.js +223 -13
- package/dist/providers/google.js.map +1 -1
- package/dist/providers/index.js.map +1 -1
- package/dist/providers/ollama.d.ts +2 -0
- package/dist/providers/ollama.d.ts.map +1 -1
- package/dist/providers/ollama.js +59 -30
- package/dist/providers/ollama.js.map +1 -1
- package/dist/providers/openai.d.ts +14 -0
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +200 -22
- package/dist/providers/openai.js.map +1 -1
- package/dist/router.d.ts +2 -0
- package/dist/router.d.ts.map +1 -1
- package/dist/router.js +4 -0
- package/dist/router.js.map +1 -1
- package/dist/stream-decoder.d.ts +12 -0
- package/dist/stream-decoder.d.ts.map +1 -1
- package/dist/stream-decoder.js +182 -5
- package/dist/stream-decoder.js.map +1 -1
- package/dist/structured-output.js.map +1 -1
- package/dist/thinking.d.ts +36 -0
- package/dist/thinking.d.ts.map +1 -0
- package/dist/thinking.js +52 -0
- package/dist/thinking.js.map +1 -0
- package/dist/tools.js.map +1 -1
- package/dist/zod-adapter.js.map +1 -1
- package/package.json +4 -1
- package/src/ai-model.ts +400 -0
- package/src/auditor.ts +213 -0
- package/src/client.ts +402 -0
- package/src/debug/debug-google-streaming.ts +97 -0
- package/src/debug/debug-tool-execution.ts +86 -0
- package/src/debug/test-lmstudio-tools.ts +155 -0
- package/src/demos/README.md +47 -0
- package/src/demos/basic/universal-llm-examples.ts +161 -0
- package/src/demos/diffusion-gemma/.env +29 -0
- package/src/demos/diffusion-gemma/.env.example +27 -0
- package/src/demos/diffusion-gemma/CLAUDE.md +95 -0
- package/src/demos/diffusion-gemma/README.md +59 -0
- package/src/demos/diffusion-gemma/canvas.ts +1606 -0
- package/src/demos/diffusion-gemma/docker-compose.yml +29 -0
- package/src/demos/diffusion-gemma/probe-stream.ts +51 -0
- package/src/demos/diffusion-gemma/probe-tools.ts +55 -0
- package/src/demos/diffusion-gemma/server.ts +1205 -0
- package/src/demos/diffusion-gemma/start-vllm.sh +98 -0
- package/src/demos/mcp/astrid-memory-demo.ts +295 -0
- package/src/demos/mcp/astrid-persona-memory.ts +357 -0
- package/src/demos/mcp/mcp-mongodb-demo.ts +275 -0
- package/src/demos/mcp/simple-astrid-memory.ts +148 -0
- package/src/demos/mcp/simple-mcp-demo.ts +68 -0
- package/src/demos/mcp/working-mcp-demo.ts +62 -0
- package/src/demos/model-alias-demo.ts +0 -0
- package/src/demos/tools/RAG_MEMORY_INTEGRATION.md +267 -0
- package/src/demos/tools/astrid-memory-demo.ts +270 -0
- package/src/demos/tools/astrid-production-memory-clean.ts +785 -0
- package/src/demos/tools/astrid-production-memory.ts +558 -0
- package/src/demos/tools/basic-translation-test.ts +66 -0
- package/src/demos/tools/chromadb-similarity-tuning.ts +390 -0
- package/src/demos/tools/clean-multilingual-conversation.ts +209 -0
- package/src/demos/tools/clean-translation-test.ts +119 -0
- package/src/demos/tools/clean-universal-multilingual-test.ts +131 -0
- package/src/demos/tools/complete-rag-demo.ts +369 -0
- package/src/demos/tools/complete-tool-demo.ts +132 -0
- package/src/demos/tools/demo-tool-calling.ts +124 -0
- package/src/demos/tools/dynamic-language-switching-test.ts +251 -0
- package/src/demos/tools/hybrid-thinking-test.ts +154 -0
- package/src/demos/tools/memory-integration-test.ts +420 -0
- package/src/demos/tools/multilingual-memory-system.ts +802 -0
- package/src/demos/tools/ondemand-translation-demo.ts +655 -0
- package/src/demos/tools/production-tool-demo.ts +245 -0
- package/src/demos/tools/revolutionary-multilingual-test.ts +151 -0
- package/src/demos/tools/rigorous-language-analysis.ts +218 -0
- package/src/demos/tools/test-universal-memory-system.ts +126 -0
- package/src/demos/tools/translation-integration-guide.ts +346 -0
- package/src/demos/tools/universal-memory-system.ts +560 -0
- package/src/gemma-channel.ts +47 -0
- package/src/gemma-diffusion.ts +167 -0
- package/src/http.ts +261 -0
- package/src/index.ts +180 -0
- package/src/interfaces.ts +843 -0
- package/src/mcp.ts +345 -0
- package/src/providers/anthropic.ts +796 -0
- package/src/providers/google.ts +840 -0
- package/src/providers/index.ts +8 -0
- package/src/providers/ollama.ts +503 -0
- package/src/providers/openai.ts +587 -0
- package/src/router.ts +785 -0
- package/src/stream-decoder.ts +535 -0
- package/src/structured-output.ts +759 -0
- package/src/test-scripts/test-advanced-tools.ts +310 -0
- package/src/test-scripts/test-google-deep-research.ts +33 -0
- package/src/test-scripts/test-google-streaming-enhanced.ts +147 -0
- package/src/test-scripts/test-google-streaming.ts +63 -0
- package/src/test-scripts/test-google-system-prompt-comprehensive.ts +189 -0
- package/src/test-scripts/test-google-thinking.ts +46 -0
- package/src/test-scripts/test-mcp-config.ts +28 -0
- package/src/test-scripts/test-mcp-connection.ts +29 -0
- package/src/test-scripts/test-system-message-positions.ts +163 -0
- package/src/test-scripts/test-system-prompt-improvement-demo.ts +83 -0
- package/src/test-scripts/test-tool-calling.ts +231 -0
- package/src/test-scripts/test-vllm-qwen36.ts +256 -0
- package/src/tests/ai-model.test.ts +1614 -0
- package/src/tests/auditor.test.ts +224 -0
- package/src/tests/gemma-diffusion.test.ts +115 -0
- package/src/tests/http.test.ts +200 -0
- package/src/tests/interfaces.test.ts +117 -0
- package/src/tests/providers/anthropic.test.ts +118 -0
- package/src/tests/providers/google.test.ts +841 -0
- package/src/tests/providers/ollama.test.ts +1034 -0
- package/src/tests/providers/openai.test.ts +1511 -0
- package/src/tests/router.test.ts +254 -0
- package/src/tests/stream-decoder.test.ts +263 -0
- package/src/tests/structured-output.test.ts +1450 -0
- package/src/tests/thinking.test.ts +65 -0
- package/src/tests/tools.test.ts +175 -0
- package/src/thinking.ts +73 -0
- package/src/tools.ts +246 -0
- package/src/zod-adapter.ts +72 -0
package/dist/providers/openai.js
CHANGED
|
@@ -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
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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 =
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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:
|
|
338
|
+
content: cleanContent,
|
|
203
339
|
tool_calls: finalToolCalls,
|
|
204
340
|
},
|
|
205
|
-
reasoning
|
|
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 =
|
|
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 =
|
|
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.
|
package/dist/router.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../src/router.ts"],"names":[],"mappings":"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"}
|
|
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,
|