oira666_pi-limits-wait 0.4.3 → 0.4.5
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/package.json +1 -1
- package/src/index.ts +56 -20
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -316,6 +316,25 @@ function rememberNonRetryableFailure(model: Model<Api>, errorMessage: string): v
|
|
|
316
316
|
ensureRateLimitedModelsStatus();
|
|
317
317
|
}
|
|
318
318
|
|
|
319
|
+
function isAbortMessage(msg: string): boolean {
|
|
320
|
+
const lower = msg.toLowerCase();
|
|
321
|
+
return (
|
|
322
|
+
lower.includes("operation aborted") ||
|
|
323
|
+
lower.includes("request aborted") ||
|
|
324
|
+
lower.includes("aborterror") ||
|
|
325
|
+
/\baborted\b/.test(lower)
|
|
326
|
+
);
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
function isAbortErrorEvent(event: AssistantMessageEvent, signal?: AbortSignal): boolean {
|
|
330
|
+
if (signal?.aborted) return true;
|
|
331
|
+
if (event.type !== "error") return false;
|
|
332
|
+
const reason = "reason" in event ? String(event.reason) : "";
|
|
333
|
+
const stopReason = event.error.stopReason ? String(event.error.stopReason) : "";
|
|
334
|
+
const message = event.error.errorMessage ?? "";
|
|
335
|
+
return reason === "aborted" || stopReason === "aborted" || isAbortMessage(message);
|
|
336
|
+
}
|
|
337
|
+
|
|
319
338
|
function earliestCandidateDeadline(current: Model<Api>): number | undefined {
|
|
320
339
|
const deadlines = candidateOrder(current)
|
|
321
340
|
.map((entry) => activeLimit(entry.model)?.deadline ?? activeNonRetryableFailure(entry.model)?.deadline)
|
|
@@ -636,7 +655,7 @@ type StreamSimpleFn = (
|
|
|
636
655
|
model: Model<Api>,
|
|
637
656
|
context: Context,
|
|
638
657
|
options?: SimpleStreamOptions,
|
|
639
|
-
) => AssistantMessageEventStream
|
|
658
|
+
) => AssistantMessageEventStream | Promise<AssistantMessageEventStream>;
|
|
640
659
|
|
|
641
660
|
export function __configureFallbackModelsForTests(
|
|
642
661
|
models: FallbackModel[],
|
|
@@ -712,12 +731,28 @@ export function streamWithLimitsRetry(
|
|
|
712
731
|
: builtinStreamSimpleByApi.get(attempt.model.api)
|
|
713
732
|
?? getApiProviders().find((provider) => provider.api === attempt.model.api)?.streamSimple;
|
|
714
733
|
if (!attemptDelegate) throw new Error(`No stream handler registered for API ${attempt.model.api}.`);
|
|
715
|
-
const inner = attemptDelegate(attempt.model, context, attemptOptions);
|
|
734
|
+
const inner = await attemptDelegate(attempt.model, context, attemptOptions);
|
|
716
735
|
for await (const event of inner) {
|
|
717
736
|
if (!committed) {
|
|
718
737
|
if (event.type === "error") {
|
|
719
738
|
const errMsg = event.error.errorMessage ?? "";
|
|
720
|
-
|
|
739
|
+
|
|
740
|
+
if (isAbortErrorEvent(event, options?.signal)) {
|
|
741
|
+
if (buffer.length > 0) {
|
|
742
|
+
flush(buffer);
|
|
743
|
+
} else {
|
|
744
|
+
output.push({ type: "start", partial: freshMessage(attempt.model) });
|
|
745
|
+
committed = true;
|
|
746
|
+
}
|
|
747
|
+
const error = freshMessage(attempt.model);
|
|
748
|
+
error.stopReason = "aborted";
|
|
749
|
+
error.errorMessage = errMsg || "Operation aborted";
|
|
750
|
+
output.push({ type: "error", reason: "aborted", error });
|
|
751
|
+
output.end();
|
|
752
|
+
return;
|
|
753
|
+
}
|
|
754
|
+
|
|
755
|
+
retryable = getRetryableError(errMsg);
|
|
721
756
|
if (retryable) break;
|
|
722
757
|
|
|
723
758
|
if (allowFallback) {
|
|
@@ -767,26 +802,27 @@ export function streamWithLimitsRetry(
|
|
|
767
802
|
}
|
|
768
803
|
} catch (err) {
|
|
769
804
|
const errMsg = err instanceof Error ? err.message : String(err);
|
|
770
|
-
|
|
805
|
+
const aborted = Boolean(options?.signal?.aborted) || isAbortMessage(errMsg);
|
|
806
|
+
retryable = !aborted ? getRetryableError(errMsg) : undefined;
|
|
771
807
|
if (!retryable) {
|
|
772
|
-
if (allowFallback && !
|
|
808
|
+
if (allowFallback && !aborted) {
|
|
773
809
|
nonRetryableError = { message: errMsg };
|
|
774
810
|
} else {
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
811
|
+
if (!committed) {
|
|
812
|
+
// Synthetic start+error so the stream protocol stays valid.
|
|
813
|
+
output.push({ type: "start", partial: freshMessage(attempt.model) });
|
|
814
|
+
committed = true;
|
|
815
|
+
}
|
|
816
|
+
const error = freshMessage(attempt.model);
|
|
817
|
+
error.stopReason = aborted ? "aborted" : "error";
|
|
818
|
+
error.errorMessage = errMsg;
|
|
819
|
+
output.push({
|
|
820
|
+
type: "error",
|
|
821
|
+
reason: error.stopReason as "error" | "aborted",
|
|
822
|
+
error,
|
|
823
|
+
});
|
|
824
|
+
output.end();
|
|
825
|
+
return;
|
|
790
826
|
}
|
|
791
827
|
}
|
|
792
828
|
}
|