@diegopetrucci/pi-oracle 0.1.12 → 0.1.13
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.ts +41 -0
- package/package.json +1 -1
package/index.ts
CHANGED
|
@@ -557,6 +557,26 @@ function extractTextFromContent(content: unknown): string {
|
|
|
557
557
|
return parts.join("\n\n").trim();
|
|
558
558
|
}
|
|
559
559
|
|
|
560
|
+
// Errors that typically resolve on retry: provider overload, rate limiting,
|
|
561
|
+
// transient 5xx, gateway/network failures, and request timeouts. Keep this list
|
|
562
|
+
// pattern-based so we recognize variants across providers without enumerating them.
|
|
563
|
+
const TRANSIENT_ERROR_PATTERN =
|
|
564
|
+
/\b(overload(?:ed)?|rate[ _-]?limit(?:ed)?|too many requests|429|500|502|503|504|bad gateway|service unavailable|gateway timeout|temporarily unavailable|timed?[ _-]?out|timeout|econnreset|econnrefused|etimedout|enetunreach|socket hang up|fetch failed)\b/i;
|
|
565
|
+
|
|
566
|
+
function isTransientErrorMessage(message: string): boolean {
|
|
567
|
+
return TRANSIENT_ERROR_PATTERN.test(message);
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
function formatOracleModelError(stopReason: "error" | "aborted", errorMessage: string | undefined): string {
|
|
571
|
+
const trimmed = errorMessage?.trim();
|
|
572
|
+
if (stopReason === "aborted") {
|
|
573
|
+
return trimmed ? `Oracle model turn aborted: ${trimmed}` : "Oracle model turn aborted.";
|
|
574
|
+
}
|
|
575
|
+
if (!trimmed) return "Oracle model error (no detail provided by provider).";
|
|
576
|
+
const base = `Oracle model error: ${trimmed}`;
|
|
577
|
+
return isTransientErrorMessage(trimmed) ? `${base} (transient; retry may succeed)` : base;
|
|
578
|
+
}
|
|
579
|
+
|
|
560
580
|
function parseVersionScore(text: string): number {
|
|
561
581
|
const matches = text.match(/\d+(?:\.\d+){0,2}/g) ?? [];
|
|
562
582
|
let best = 0;
|
|
@@ -817,6 +837,9 @@ async function runOracle(
|
|
|
817
837
|
let finalOutput = "";
|
|
818
838
|
let stderr = "";
|
|
819
839
|
|
|
840
|
+
let lastStopReason: string | undefined;
|
|
841
|
+
let lastErrorMessage: string | undefined;
|
|
842
|
+
|
|
820
843
|
const details: OracleDetails = {
|
|
821
844
|
...selection,
|
|
822
845
|
includeBash,
|
|
@@ -888,6 +911,11 @@ async function runOracle(
|
|
|
888
911
|
if (text) finalOutput = text;
|
|
889
912
|
currentText = "";
|
|
890
913
|
|
|
914
|
+
const stopReason = event.message.stopReason;
|
|
915
|
+
lastStopReason = typeof stopReason === "string" ? stopReason : undefined;
|
|
916
|
+
const errorMessageField = event.message.errorMessage;
|
|
917
|
+
lastErrorMessage = typeof errorMessageField === "string" ? errorMessageField : undefined;
|
|
918
|
+
|
|
891
919
|
const messageUsage = event.message.usage;
|
|
892
920
|
if (messageUsage) {
|
|
893
921
|
usage.turns += 1;
|
|
@@ -946,6 +974,19 @@ async function runOracle(
|
|
|
946
974
|
return { ok: false, error: "Oracle was aborted.", details };
|
|
947
975
|
}
|
|
948
976
|
|
|
977
|
+
// The pi subprocess in `--mode json` does not promote an errored assistant
|
|
978
|
+
// turn to a non-zero exit code or stderr; the error is only carried on the
|
|
979
|
+
// streamed assistant message via stopReason/errorMessage. Surface that here
|
|
980
|
+
// so callers can distinguish transient provider errors from a genuinely
|
|
981
|
+
// empty response.
|
|
982
|
+
if (lastStopReason === "error" || lastStopReason === "aborted") {
|
|
983
|
+
return {
|
|
984
|
+
ok: false,
|
|
985
|
+
error: formatOracleModelError(lastStopReason, lastErrorMessage),
|
|
986
|
+
details,
|
|
987
|
+
};
|
|
988
|
+
}
|
|
989
|
+
|
|
949
990
|
if (exitCode !== 0) {
|
|
950
991
|
return {
|
|
951
992
|
ok: false,
|
package/package.json
CHANGED