@north-light/crouter 0.3.341 → 0.3.343
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.
|
@@ -435,7 +435,7 @@ async function streamProviderAttempt(state, providerId, model, context, options,
|
|
|
435
435
|
},
|
|
436
436
|
};
|
|
437
437
|
const provider = state.runtimeContext?.modelRegistry.getProvider?.(model.provider);
|
|
438
|
-
const inner =
|
|
438
|
+
const inner = isManagedProvider(providerId)
|
|
439
439
|
? streamForProvider(model, context, streamOptions)
|
|
440
440
|
: state.delegatedProviderStreams.get(providerId)?.(model, context, streamOptions)
|
|
441
441
|
?? provider?.streamSimple(model, context, streamOptions)
|
|
@@ -598,7 +598,14 @@ async function runManagedProvider(state, model, context, options, stream) {
|
|
|
598
598
|
const isLiveRoute = (candidate) => candidate.providerId === model.provider && candidate.model.id === model.id && candidate.thinkingLevel === liveThinking;
|
|
599
599
|
// A cooling or unauthenticated managed route contributes its diagnostic and may
|
|
600
600
|
// later re-enter when a credential becomes ready, but it is never selected now.
|
|
601
|
-
const candidates = routeCandidates.filter((candidate) =>
|
|
601
|
+
const candidates = routeCandidates.filter((candidate) => {
|
|
602
|
+
if (isLiveRoute(candidate) || !isManagedProvider(candidate.providerId))
|
|
603
|
+
return true;
|
|
604
|
+
const pool = readSubscriptionPool(candidate.providerId);
|
|
605
|
+
return pool.length === 0
|
|
606
|
+
? state.runtimeContext.modelRegistry.hasConfiguredAuth(candidate.model)
|
|
607
|
+
: pool.some((entry) => entry.authFailure === undefined && (entry.rateLimitedUntil || 0) <= Date.now());
|
|
608
|
+
});
|
|
602
609
|
if (!candidates.some(isLiveRoute)) {
|
|
603
610
|
candidates.unshift({ routeId: `live:${model.provider}/${model.id}`, credentialSource: 'live', rank: liveRank, providerId: model.provider, model, thinkingLevel: liveThinking });
|
|
604
611
|
}
|
|
@@ -625,8 +632,25 @@ async function runManagedProvider(state, model, context, options, stream) {
|
|
|
625
632
|
emitTerminalError(stream, candidateModel, `Provider route ${routeId} is unavailable: failed to select ${providerId}/${candidateModel.id}`);
|
|
626
633
|
return;
|
|
627
634
|
}
|
|
628
|
-
|
|
629
|
-
|
|
635
|
+
const rawPool = isManagedProvider(providerId) ? readSubscriptionPool(providerId) : [];
|
|
636
|
+
if (!isManagedProvider(providerId) || rawPool.length === 0) {
|
|
637
|
+
const liveKey = isLiveRoute(candidate) ? options?.apiKey : undefined;
|
|
638
|
+
if (isManagedProvider(providerId) && !liveKey && !state.runtimeContext.modelRegistry.hasConfiguredAuth(candidateModel))
|
|
639
|
+
continue;
|
|
640
|
+
const auth = isManagedProvider(providerId) && !liveKey
|
|
641
|
+
? await state.runtimeContext.modelRegistry.getApiKeyAndHeaders(candidateModel)
|
|
642
|
+
: undefined;
|
|
643
|
+
if (isManagedProvider(providerId) && !liveKey && (!auth?.ok || !auth.apiKey))
|
|
644
|
+
continue;
|
|
645
|
+
const headers = { ...options?.headers };
|
|
646
|
+
for (const [name, value] of Object.entries(auth?.ok ? auth.headers ?? {} : {})) {
|
|
647
|
+
for (const existing of Object.keys(headers))
|
|
648
|
+
if (existing.toLowerCase() === name.toLowerCase())
|
|
649
|
+
delete headers[existing];
|
|
650
|
+
headers[name] = value;
|
|
651
|
+
}
|
|
652
|
+
const attemptOptions = auth?.ok ? { ...options, apiKey: auth.apiKey, headers } : options;
|
|
653
|
+
const result = await streamProviderAttempt(state, providerId, candidateModel, context, attemptOptions, undefined, stream);
|
|
630
654
|
if (result.result === 'success' || result.result === 'fatal') {
|
|
631
655
|
state.transportOnlyExhaustedPasses = 0;
|
|
632
656
|
stream.end();
|
|
@@ -641,7 +665,6 @@ async function runManagedProvider(state, model, context, options, stream) {
|
|
|
641
665
|
logRouteQueueAdvance(candidate, candidates[0], result);
|
|
642
666
|
continue;
|
|
643
667
|
}
|
|
644
|
-
const rawPool = readSubscriptionPool(providerId);
|
|
645
668
|
for (const entry of rawPool)
|
|
646
669
|
if (entry.authFailure === 'invalid_grant')
|
|
647
670
|
authFailures.add(`${providerId}/${entry.label}`);
|
|
@@ -600,7 +600,7 @@ async function streamProviderAttempt(
|
|
|
600
600
|
},
|
|
601
601
|
};
|
|
602
602
|
const provider = state.runtimeContext?.modelRegistry.getProvider?.(model.provider);
|
|
603
|
-
const inner =
|
|
603
|
+
const inner = isManagedProvider(providerId)
|
|
604
604
|
? streamForProvider(model, context, streamOptions)
|
|
605
605
|
: state.delegatedProviderStreams.get(providerId)?.(model, context, streamOptions)
|
|
606
606
|
?? provider?.streamSimple(model, context, streamOptions)
|
|
@@ -802,7 +802,13 @@ async function runManagedProvider(
|
|
|
802
802
|
candidate.providerId === model.provider && candidate.model.id === model.id && candidate.thinkingLevel === liveThinking;
|
|
803
803
|
// A cooling or unauthenticated managed route contributes its diagnostic and may
|
|
804
804
|
// later re-enter when a credential becomes ready, but it is never selected now.
|
|
805
|
-
const candidates = routeCandidates.filter((candidate) =>
|
|
805
|
+
const candidates = routeCandidates.filter((candidate) => {
|
|
806
|
+
if (isLiveRoute(candidate) || !isManagedProvider(candidate.providerId)) return true;
|
|
807
|
+
const pool = readSubscriptionPool(candidate.providerId);
|
|
808
|
+
return pool.length === 0
|
|
809
|
+
? state.runtimeContext!.modelRegistry.hasConfiguredAuth(candidate.model)
|
|
810
|
+
: pool.some((entry) => entry.authFailure === undefined && (entry.rateLimitedUntil || 0) <= Date.now());
|
|
811
|
+
});
|
|
806
812
|
if (!candidates.some(isLiveRoute)) {
|
|
807
813
|
candidates.unshift({ routeId: `live:${model.provider}/${model.id}`, credentialSource: 'live', rank: liveRank, providerId: model.provider, model, thinkingLevel: liveThinking });
|
|
808
814
|
}
|
|
@@ -833,8 +839,21 @@ async function runManagedProvider(
|
|
|
833
839
|
return;
|
|
834
840
|
}
|
|
835
841
|
|
|
836
|
-
|
|
837
|
-
|
|
842
|
+
const rawPool = isManagedProvider(providerId) ? readSubscriptionPool(providerId) : [];
|
|
843
|
+
if (!isManagedProvider(providerId) || rawPool.length === 0) {
|
|
844
|
+
const liveKey = isLiveRoute(candidate) ? options?.apiKey : undefined;
|
|
845
|
+
if (isManagedProvider(providerId) && !liveKey && !state.runtimeContext!.modelRegistry.hasConfiguredAuth(candidateModel)) continue;
|
|
846
|
+
const auth = isManagedProvider(providerId) && !liveKey
|
|
847
|
+
? await state.runtimeContext!.modelRegistry.getApiKeyAndHeaders(candidateModel)
|
|
848
|
+
: undefined;
|
|
849
|
+
if (isManagedProvider(providerId) && !liveKey && (!auth?.ok || !auth.apiKey)) continue;
|
|
850
|
+
const headers = { ...options?.headers };
|
|
851
|
+
for (const [name, value] of Object.entries(auth?.ok ? auth.headers ?? {} : {})) {
|
|
852
|
+
for (const existing of Object.keys(headers)) if (existing.toLowerCase() === name.toLowerCase()) delete headers[existing];
|
|
853
|
+
headers[name] = value;
|
|
854
|
+
}
|
|
855
|
+
const attemptOptions = auth?.ok ? { ...options, apiKey: auth.apiKey, headers } : options;
|
|
856
|
+
const result = await streamProviderAttempt(state, providerId, candidateModel, context, attemptOptions, undefined, stream);
|
|
838
857
|
if (result.result === 'success' || result.result === 'fatal') { state.transportOnlyExhaustedPasses = 0; stream.end(); return; }
|
|
839
858
|
if (result.result === 'rate_limited' || result.classification?.status !== undefined || result.classification?.hadRetryAfterHeader === true) sawHttpEvidence = true;
|
|
840
859
|
const cooldownMs = result.result === 'rate_limited' ? result.retryAfterMs ?? DEFAULT_RATE_LIMIT_BACKOFF_MS : TRANSIENT_ROTATE_COOLDOWN_MS;
|
|
@@ -843,8 +862,6 @@ async function runManagedProvider(
|
|
|
843
862
|
logRouteQueueAdvance(candidate, candidates[0], result);
|
|
844
863
|
continue;
|
|
845
864
|
}
|
|
846
|
-
|
|
847
|
-
const rawPool = readSubscriptionPool(providerId);
|
|
848
865
|
for (const entry of rawPool) if (entry.authFailure === 'invalid_grant') authFailures.add(`${providerId}/${entry.label}`);
|
|
849
866
|
const available = rawPool.filter((entry) => entry.authFailure === undefined && (!entry.rateLimitedUntil || entry.rateLimitedUntil <= Date.now()));
|
|
850
867
|
const seenLabels = seenReadyLabels.get(routeId) ?? new Set<string>();
|