twinclaw 1.2.3 → 1.2.4
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/services/model-router.js +14 -21
- package/package.json +1 -1
|
@@ -526,17 +526,7 @@ export class ModelRouter {
|
|
|
526
526
|
this.recordEvent('attempt', input.config, `Attempting ${input.config.model} (profile=${input.directive.profile}, severity=${input.directive.severity}).`);
|
|
527
527
|
const startedAt = this.nowFn();
|
|
528
528
|
const timeoutMs = 60000; // 60 second timeout
|
|
529
|
-
// For providers that don't support tools well, strip them from the request
|
|
530
|
-
// This includes fallback models that use OpenRouter/StepFun which have tool issues
|
|
531
|
-
const providerId = this.resolveProviderId(input.config);
|
|
532
|
-
const noToolProviders = ['stepfun', 'openrouter', 'unknown'];
|
|
533
|
-
const isFallbackModel = input.config.id === MODEL_SLOT_IDS.FALLBACK_1 || input.config.id === MODEL_SLOT_IDS.FALLBACK_2;
|
|
534
529
|
let payload = input.payload;
|
|
535
|
-
if ((noToolProviders.includes(providerId) || isFallbackModel) && input.payload.tools) {
|
|
536
|
-
payload = { ...input.payload };
|
|
537
|
-
delete payload.tools;
|
|
538
|
-
delete payload.tool_choice;
|
|
539
|
-
}
|
|
540
530
|
try {
|
|
541
531
|
const controller = new AbortController();
|
|
542
532
|
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -670,16 +660,7 @@ export class ModelRouter {
|
|
|
670
660
|
const responseContentParts = [];
|
|
671
661
|
const toolCalls = [];
|
|
672
662
|
// For providers that don't support tools well, strip them from the request
|
|
673
|
-
// This includes fallback models that use OpenRouter/StepFun which have tool issues
|
|
674
|
-
const providerId = this.resolveProviderId(input.config);
|
|
675
|
-
const noToolProviders = ['stepfun', 'openrouter', 'unknown'];
|
|
676
|
-
const isFallbackModel = input.config.id === MODEL_SLOT_IDS.FALLBACK_1 || input.config.id === MODEL_SLOT_IDS.FALLBACK_2;
|
|
677
663
|
let payload = input.payload;
|
|
678
|
-
if ((noToolProviders.includes(providerId) || isFallbackModel) && input.payload.tools) {
|
|
679
|
-
payload = { ...input.payload };
|
|
680
|
-
delete payload.tools;
|
|
681
|
-
delete payload.tool_choice;
|
|
682
|
-
}
|
|
683
664
|
try {
|
|
684
665
|
const controller = new AbortController();
|
|
685
666
|
const timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
@@ -1094,11 +1075,23 @@ export class ModelRouter {
|
|
|
1094
1075
|
apiKeyEnvName: 'MODAL_API_KEY',
|
|
1095
1076
|
});
|
|
1096
1077
|
}
|
|
1097
|
-
|
|
1078
|
+
// Use Groq as fallback (supports tools, fast, cheap)
|
|
1079
|
+
const groqApiKey = getConfigValue('GROQ_API_KEY');
|
|
1080
|
+
if (groqApiKey && !configModels.find((m) => m.id === MODEL_SLOT_IDS.FALLBACK_1)) {
|
|
1081
|
+
const groqInfo = PROVIDER_INFO.groq;
|
|
1082
|
+
configModels.push({
|
|
1083
|
+
id: MODEL_SLOT_IDS.FALLBACK_1,
|
|
1084
|
+
model: 'llama-3.3-70b-versatile',
|
|
1085
|
+
baseURL: groqInfo?.baseURL || 'https://api.groq.com/openai/v1/chat/completions',
|
|
1086
|
+
apiKeyEnvName: 'GROQ_API_KEY',
|
|
1087
|
+
});
|
|
1088
|
+
}
|
|
1089
|
+
else if (openRouterApiKey && !configModels.find((m) => m.id === MODEL_SLOT_IDS.FALLBACK_1)) {
|
|
1090
|
+
// Only use OpenRouter if Groq is not available - use a model that supports tools
|
|
1098
1091
|
const orInfo = PROVIDER_INFO.openrouter;
|
|
1099
1092
|
configModels.push({
|
|
1100
1093
|
id: MODEL_SLOT_IDS.FALLBACK_1,
|
|
1101
|
-
model: '
|
|
1094
|
+
model: 'meta-llama/llama-3.3-70b-instruct',
|
|
1102
1095
|
baseURL: orInfo?.baseURL ? (orInfo.baseURL.endsWith('/chat/completions') ? orInfo.baseURL : `${orInfo.baseURL}/chat/completions`) : 'https://openrouter.ai/api/v1/chat/completions',
|
|
1103
1096
|
apiKeyEnvName: 'OPENROUTER_API_KEY',
|
|
1104
1097
|
});
|