modelmix 4.4.20 → 4.4.22
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/index.js +46 -4
- package/package.json +1 -1
- package/.claude/settings.local.json +0 -12
package/index.js
CHANGED
|
@@ -1334,7 +1334,34 @@ class MixCustom {
|
|
|
1334
1334
|
}
|
|
1335
1335
|
|
|
1336
1336
|
static extractMessage(data) {
|
|
1337
|
-
const
|
|
1337
|
+
const choice = data?.choices?.[0] || {};
|
|
1338
|
+
const messageObj = choice.message || {};
|
|
1339
|
+
const finishReason = choice.finish_reason;
|
|
1340
|
+
|
|
1341
|
+
if (typeof messageObj.refusal === 'string' && messageObj.refusal.trim().length > 0) {
|
|
1342
|
+
throw new Error(`OpenAI model refused to process this request: ${messageObj.refusal}`);
|
|
1343
|
+
}
|
|
1344
|
+
|
|
1345
|
+
if (finishReason === 'content_filter') {
|
|
1346
|
+
throw new Error('OpenAI response was blocked by content_filter.');
|
|
1347
|
+
}
|
|
1348
|
+
|
|
1349
|
+
let message = '';
|
|
1350
|
+
if (typeof messageObj.content === 'string') {
|
|
1351
|
+
message = messageObj.content.trim();
|
|
1352
|
+
} else if (Array.isArray(messageObj.content)) {
|
|
1353
|
+
const refusalPart = messageObj.content.find(part => part?.type === 'refusal' || (typeof part?.refusal === 'string' && part.refusal.trim().length > 0));
|
|
1354
|
+
if (refusalPart) {
|
|
1355
|
+
const refusalText = typeof refusalPart.refusal === 'string' ? refusalPart.refusal : 'No refusal text provided.';
|
|
1356
|
+
throw new Error(`OpenAI model refused to process this request: ${refusalText}`);
|
|
1357
|
+
}
|
|
1358
|
+
message = messageObj.content
|
|
1359
|
+
.filter(part => typeof part?.text === 'string')
|
|
1360
|
+
.map(part => part.text)
|
|
1361
|
+
.join('')
|
|
1362
|
+
.trim();
|
|
1363
|
+
}
|
|
1364
|
+
|
|
1338
1365
|
const endTagIndex = message.indexOf('</think>');
|
|
1339
1366
|
if (message.startsWith('<think>') && endTagIndex !== -1) {
|
|
1340
1367
|
return message.substring(endTagIndex + 8).trim();
|
|
@@ -2020,10 +2047,25 @@ class MixAnthropic extends MixCustom {
|
|
|
2020
2047
|
}
|
|
2021
2048
|
|
|
2022
2049
|
static extractMessage(data) {
|
|
2023
|
-
|
|
2024
|
-
|
|
2050
|
+
const content = Array.isArray(data?.content) ? data.content : [];
|
|
2051
|
+
|
|
2052
|
+
// Anthropic can return text in different positions depending on thinking/tool blocks.
|
|
2053
|
+
const textBlock = content.find(block => typeof block?.text === 'string' && block.text.trim().length > 0);
|
|
2054
|
+
if (textBlock) {
|
|
2055
|
+
return textBlock.text;
|
|
2056
|
+
}
|
|
2057
|
+
|
|
2058
|
+
// Empty/non-text content is often due to safety refusal or token limits.
|
|
2059
|
+
const stopReason = data?.stop_reason;
|
|
2060
|
+
const contentTypes = content.map(block => block?.type || 'unknown').join(', ') || 'none';
|
|
2061
|
+
|
|
2062
|
+
if (stopReason === 'refusal') {
|
|
2063
|
+
throw new Error('Anthropic refused to process this request (content policy). Try different wording or a fallback model.');
|
|
2064
|
+
}
|
|
2065
|
+
if (!content.length) {
|
|
2066
|
+
throw new Error(`Anthropic returned empty content (stop_reason: ${stopReason ?? 'unknown'}).`);
|
|
2025
2067
|
}
|
|
2026
|
-
|
|
2068
|
+
throw new Error(`Anthropic content blocks are missing .text (stop_reason: ${stopReason ?? 'unknown'}, content_types: ${contentTypes}).`);
|
|
2027
2069
|
}
|
|
2028
2070
|
|
|
2029
2071
|
static extractThink(data) {
|
package/package.json
CHANGED