@wrongstack/providers 0.257.2 → 0.264.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/dist/index.d.ts +20 -0
- package/dist/index.js +6 -5
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.d.ts
CHANGED
|
@@ -164,6 +164,26 @@ interface ConvertOptions {
|
|
|
164
164
|
flattenContentToString?: boolean | undefined;
|
|
165
165
|
stripCacheControl?: boolean | undefined;
|
|
166
166
|
systemAsMessage?: boolean | undefined;
|
|
167
|
+
/**
|
|
168
|
+
* What to write as the assistant message's `content` field when the
|
|
169
|
+
* message has tool_calls but no prose. Two values:
|
|
170
|
+
*
|
|
171
|
+
* - `'empty_string'` (default): writes `content: ''`. This is the
|
|
172
|
+
* OpenAI 2024-2025 wire-format contract. Vanilla OpenAI, K2P7,
|
|
173
|
+
* strict Mistral / OpenRouter / DeepSeek proxies all reject
|
|
174
|
+
* requests where `content` is missing or `null` on a tool_call
|
|
175
|
+
* assistant message.
|
|
176
|
+
*
|
|
177
|
+
* - `'null'`: writes `content: null` explicitly. Some older or
|
|
178
|
+
* permissive proxies (e.g. certain vLLM builds, local llama.cpp
|
|
179
|
+
* servers) prefer this. Set this only if a specific provider
|
|
180
|
+
* rejects the empty-string form.
|
|
181
|
+
*
|
|
182
|
+
* The default is `'empty_string'` (NOT undefined) because omitting
|
|
183
|
+
* `content` entirely (the pre-2024 behaviour) breaks too many
|
|
184
|
+
* providers to be the safe default in 2025. Callers that need the
|
|
185
|
+
* old behaviour can opt in with `emptyToolCallContent: 'null'`.
|
|
186
|
+
*/
|
|
167
187
|
emptyToolCallContent?: 'null' | 'empty_string' | undefined;
|
|
168
188
|
}
|
|
169
189
|
declare function messagesToOpenAI(system: TextBlock[] | undefined, messages: Message[], opts?: ConvertOptions): OpenAIMessage[];
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { expectDefined, ProviderError, StreamHangError, safeParse, sanitizeJsonString, WrongStackError, ERROR_CODES } from '@wrongstack/core';
|
|
2
2
|
import { Readable } from 'stream';
|
|
3
|
+
import { toErrorMessage } from '@wrongstack/core/utils';
|
|
3
4
|
import { randomUUID } from 'crypto';
|
|
4
5
|
|
|
5
6
|
var __defProp = Object.defineProperty;
|
|
@@ -657,9 +658,9 @@ var WireAdapter = class {
|
|
|
657
658
|
httpRes = raw;
|
|
658
659
|
} catch (err) {
|
|
659
660
|
if (opts.signal.aborted) throw err;
|
|
660
|
-
throw new ProviderError(
|
|
661
|
+
throw new ProviderError(toErrorMessage(err), 0, true, this.id, {
|
|
661
662
|
cause: err,
|
|
662
|
-
body: { message:
|
|
663
|
+
body: { message: toErrorMessage(err) }
|
|
663
664
|
});
|
|
664
665
|
}
|
|
665
666
|
if (!httpRes.ok) {
|
|
@@ -1209,6 +1210,7 @@ function toolsToOpenAI(tools) {
|
|
|
1209
1210
|
}));
|
|
1210
1211
|
}
|
|
1211
1212
|
function messagesToOpenAI(system, messages, opts = {}) {
|
|
1213
|
+
const emptyContentMode = opts.emptyToolCallContent ?? "empty_string";
|
|
1212
1214
|
const out = [];
|
|
1213
1215
|
if (system && system.length > 0) {
|
|
1214
1216
|
const sysText = system.map((b) => b.text).join("\n\n");
|
|
@@ -1255,7 +1257,6 @@ function messagesToOpenAI(system, messages, opts = {}) {
|
|
|
1255
1257
|
if (text) {
|
|
1256
1258
|
message.content = text;
|
|
1257
1259
|
} else {
|
|
1258
|
-
const emptyContentMode = opts.emptyToolCallContent ?? "empty_string";
|
|
1259
1260
|
message.content = emptyContentMode === "null" ? null : "";
|
|
1260
1261
|
}
|
|
1261
1262
|
} else {
|
|
@@ -1627,7 +1628,7 @@ var mistralWireFormat = defineWireFormat({
|
|
|
1627
1628
|
buildBody: (req) => {
|
|
1628
1629
|
const body = {
|
|
1629
1630
|
model: req.model,
|
|
1630
|
-
messages: messagesToOpenAI(stripCacheControl(req.system), req.messages
|
|
1631
|
+
messages: messagesToOpenAI(stripCacheControl(req.system), req.messages),
|
|
1631
1632
|
max_tokens: req.maxTokens,
|
|
1632
1633
|
stream: true
|
|
1633
1634
|
};
|
|
@@ -1908,7 +1909,7 @@ var openaiWireFormat = defineWireFormat({
|
|
|
1908
1909
|
buildBody: (req) => {
|
|
1909
1910
|
const body = {
|
|
1910
1911
|
model: req.model,
|
|
1911
|
-
messages: messagesToOpenAI(stripCacheControl2(req.system), req.messages
|
|
1912
|
+
messages: messagesToOpenAI(stripCacheControl2(req.system), req.messages),
|
|
1912
1913
|
// Real OpenAI requires `max_completion_tokens`; newer model families
|
|
1913
1914
|
// (gpt-4o, o1/o3/o4) 400 on the deprecated `max_tokens`. See issue #10.
|
|
1914
1915
|
max_completion_tokens: req.maxTokens,
|