@aexol/spectral 0.9.226 → 0.9.228
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/sdk/agent-core/agent-loop.d.ts.map +1 -1
- package/dist/sdk/agent-core/agent-loop.js +8 -0
- package/dist/sdk/ai/providers/openai-completions.d.ts.map +1 -1
- package/dist/sdk/ai/providers/openai-completions.js +8 -6
- package/dist/sdk/ai/utils/diagnostics.d.ts +19 -0
- package/dist/sdk/ai/utils/diagnostics.d.ts.map +1 -1
- package/dist/sdk/ai/utils/diagnostics.js +73 -0
- package/dist/sdk/ai/utils/image-source.d.ts.map +1 -1
- package/dist/sdk/ai/utils/image-source.js +16 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../../../src/sdk/agent-core/agent-loop.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,WAAW,EAWZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,eAAe,EACf,YAAY,EACZ,SAAS,EACT,aAAa,EAEb,QAAQ,EACT,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAiCzE;;;GAGG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CA2BzC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAkCzC;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,OAAO,CAAC,YAAY,EAAE,CAAC,CAgBzB;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,OAAO,CAAC,YAAY,EAAE,CAAC,CAiBzB;
|
|
1
|
+
{"version":3,"file":"agent-loop.d.ts","sourceRoot":"","sources":["../../../src/sdk/agent-core/agent-loop.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAGL,WAAW,EAWZ,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EACV,YAAY,EACZ,UAAU,EACV,eAAe,EACf,YAAY,EACZ,SAAS,EACT,aAAa,EAEb,QAAQ,EACT,MAAM,YAAY,CAAC;AAEpB,MAAM,MAAM,cAAc,GAAG,CAAC,KAAK,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;AAiCzE;;;GAGG;AACH,wBAAgB,SAAS,CACvB,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CA2BzC;AAED;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,WAAW,CAAC,UAAU,EAAE,YAAY,EAAE,CAAC,CAkCzC;AAED,wBAAsB,YAAY,CAChC,OAAO,EAAE,YAAY,EAAE,EACvB,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,OAAO,CAAC,YAAY,EAAE,CAAC,CAgBzB;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,YAAY,EACrB,MAAM,EAAE,eAAe,EACvB,IAAI,EAAE,cAAc,EACpB,MAAM,CAAC,EAAE,WAAW,EACpB,QAAQ,CAAC,EAAE,QAAQ,GAClB,OAAO,CAAC,YAAY,EAAE,CAAC,CAiBzB;AAkyBD;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,IAAI,EAAE,SAAS,CAAC,GAAG,CAAC,EAAE,QAAQ,EAAE,aAAa,GAAG,OAAO,CAYlG"}
|
|
@@ -177,6 +177,10 @@ async function runLoop(initialContext, newMessages, initialConfig, signal, emit,
|
|
|
177
177
|
rateLimitRetryCount < MAX_RATE_LIMIT_RETRIES) {
|
|
178
178
|
rateLimitRetryCount++;
|
|
179
179
|
const backoffMs = getRateLimitRetryDelayMs(rateLimitRetryCount);
|
|
180
|
+
// Retry decisions are invisible in stderr today — log every
|
|
181
|
+
// attempt with the provider message so failures can be diagnosed
|
|
182
|
+
// after the fact. The UI text_delta below stays the user signal.
|
|
183
|
+
console.error(`[agent-loop] rate limit error (attempt ${rateLimitRetryCount}/${MAX_RATE_LIMIT_RETRIES}, retrying in ${backoffMs}ms): ${errorMsg.slice(0, 600)}`);
|
|
180
184
|
await emit({
|
|
181
185
|
type: "message_update",
|
|
182
186
|
message,
|
|
@@ -213,6 +217,10 @@ async function runLoop(initialContext, newMessages, initialConfig, signal, emit,
|
|
|
213
217
|
if (isTransientError && apiRetryCount < MAX_API_RETRIES) {
|
|
214
218
|
apiRetryCount++;
|
|
215
219
|
const backoffMs = API_RETRY_BASE_MS * Math.pow(2, apiRetryCount - 1); // 1000, 2000, 4000
|
|
220
|
+
// Same as the rate-limit branch: retries leave no stderr trace
|
|
221
|
+
// today. Log each attempt with the (enriched) provider message;
|
|
222
|
+
// the UI text_delta below stays the user-facing signal.
|
|
223
|
+
console.error(`[agent-loop] transient provider error (attempt ${apiRetryCount}/${MAX_API_RETRIES}, retrying in ${backoffMs}ms): ${errorMsg.slice(0, 600)}`);
|
|
216
224
|
await emit({
|
|
217
225
|
type: "message_update",
|
|
218
226
|
message,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"openai-completions.d.ts","sourceRoot":"","sources":["../../../../src/sdk/ai/providers/openai-completions.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAMX,0BAA0B,EAE1B,MAAM,sCAAsC,CAAC;AAI9C,OAAO,KAAK,EAGX,OAAO,EAGP,KAAK,EACL,uBAAuB,EACvB,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAMb,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"openai-completions.d.ts","sourceRoot":"","sources":["../../../../src/sdk/ai/providers/openai-completions.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAMX,0BAA0B,EAE1B,MAAM,sCAAsC,CAAC;AAI9C,OAAO,KAAK,EAGX,OAAO,EAGP,KAAK,EACL,uBAAuB,EACvB,mBAAmB,EAEnB,cAAc,EACd,aAAa,EAMb,MAAM,aAAa,CAAC;AAoErB,MAAM,WAAW,wBAAyB,SAAQ,aAAa;IAC9D,UAAU,CAAC,EACR,MAAM,GACN,MAAM,GACN,UAAU,GACV;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,QAAQ,EAAE;YAAE,IAAI,EAAE,MAAM,CAAA;SAAE,CAAA;KAAE,CAAC;IACpD,eAAe,CAAC,EAAE,SAAS,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,OAAO,CAAC;CAClE;AAED,KAAK,+BAA+B,GAAG,QAAQ,CAAC,uBAAuB,CAAC,CAAC;AAqRzE,eAAO,MAAM,uBAAuB,EAAE,cAAc,CACnD,oBAAoB,EACpB,wBAAwB,CAsexB,CAAC;AAEF,eAAO,MAAM,6BAA6B,EAAE,cAAc,CACzD,oBAAoB,EACpB,mBAAmB,CAyBnB,CAAC;AAkNF,wBAAgB,eAAe,CAC9B,KAAK,EAAE,KAAK,CAAC,oBAAoB,CAAC,EAClC,OAAO,EAAE,OAAO,EAChB,MAAM,EAAE,+BAA+B,GACrC,0BAA0B,EAAE,CA0R9B"}
|
|
@@ -4,6 +4,7 @@ import { getApiUrl, readConfig } from "../../../config.js";
|
|
|
4
4
|
import { getEnvApiKey } from "../env-api-keys.js";
|
|
5
5
|
import { calculateCost, clampThinkingLevel } from "../models.js";
|
|
6
6
|
import { AssistantMessageEventStream } from "../utils/event-stream.js";
|
|
7
|
+
import { enrichProviderErrorMessage } from "../utils/diagnostics.js";
|
|
7
8
|
import { headersToRecord } from "../utils/headers.js";
|
|
8
9
|
import { imageSourceUrlForProvider, resolveImagesForContext } from "../utils/image-source.js";
|
|
9
10
|
import { parseStreamingJson } from "../utils/json-parse.js";
|
|
@@ -687,12 +688,13 @@ export const streamOpenAICompletions = (model, context, options) => {
|
|
|
687
688
|
delete block.streamIndex;
|
|
688
689
|
}
|
|
689
690
|
output.stopReason = options?.signal?.aborted ? "aborted" : "error";
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
//
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
691
|
+
// Enrich with HTTP status + provider error details (code / metadata /
|
|
692
|
+
// message) for diagnostics while keeping the original provider
|
|
693
|
+
// message verbatim at the start — transient / rate-limit classifiers
|
|
694
|
+
// regex-match the beginning of this string. The provider `.error`
|
|
695
|
+
// JSON (including OpenRouter's `metadata.raw`) is summarized inside
|
|
696
|
+
// the ~600-char budget.
|
|
697
|
+
output.errorMessage = enrichProviderErrorMessage(error, 600);
|
|
696
698
|
stream.push({ type: "error", reason: output.stopReason, error: output });
|
|
697
699
|
stream.end();
|
|
698
700
|
}
|
|
@@ -16,4 +16,23 @@ export declare function createAssistantMessageDiagnostic(type: string, error: un
|
|
|
16
16
|
export declare function appendAssistantMessageDiagnostic<T extends {
|
|
17
17
|
diagnostics?: AssistantMessageDiagnostic[];
|
|
18
18
|
}>(message: T, diagnostic: AssistantMessageDiagnostic): void;
|
|
19
|
+
/** Detail budget (chars) for enriched provider error messages. */
|
|
20
|
+
export declare const PROVIDER_ERROR_DETAIL_BUDGET = 600;
|
|
21
|
+
/**
|
|
22
|
+
* Build an enriched provider error message for retry diagnostics:
|
|
23
|
+
*
|
|
24
|
+
* `<original message> | HTTP <status> | code=<code> | type=<type> | requestID=<id> | provider error: <json>`
|
|
25
|
+
*
|
|
26
|
+
* The original message stays verbatim at the BEGINNING so the transient /
|
|
27
|
+
* rate-limit regex classifiers (`isTransientApiError`, `isRateLimitError`)
|
|
28
|
+
* still match it — they regex the message string, so the prefix must remain
|
|
29
|
+
* intact and untruncated. Detail parts come from the OpenAI SDK's APIError
|
|
30
|
+
* shape: `status` (set for HTTP-level failures, undefined for mid-stream SSE
|
|
31
|
+
* error chunks), `.error` (the raw provider JSON body — message / code /
|
|
32
|
+
* type / metadata), plus the top-level `code` / `type` copies and
|
|
33
|
+
* `requestID` the SDK attaches. The detail portion is clamped so the total
|
|
34
|
+
* stays within the ~600-char budget; the original message is never
|
|
35
|
+
* truncated.
|
|
36
|
+
*/
|
|
37
|
+
export declare function enrichProviderErrorMessage(error: unknown, budget?: number): string;
|
|
19
38
|
//# sourceMappingURL=diagnostics.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../../../src/sdk/ai/utils/diagnostics.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,mBAAmB,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAIxD;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CAS1E;AAED,wBAAgB,gCAAgC,CAC/C,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,0BAA0B,CAE5B;AAED,wBAAgB,gCAAgC,CAAC,CAAC,SAAS;IAAE,WAAW,CAAC,EAAE,0BAA0B,EAAE,CAAA;CAAE,EACxG,OAAO,EAAE,CAAC,EACV,UAAU,EAAE,0BAA0B,GACpC,IAAI,CAEN"}
|
|
1
|
+
{"version":3,"file":"diagnostics.d.ts","sourceRoot":"","sources":["../../../../src/sdk/ai/utils/diagnostics.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,mBAAmB;IACnC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,0BAA0B;IAC1C,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,CAAC,EAAE,mBAAmB,CAAC;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CAClC;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,CAIxD;AAED,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,OAAO,GAAG,mBAAmB,CAS1E;AAED,wBAAgB,gCAAgC,CAC/C,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC/B,0BAA0B,CAE5B;AAED,wBAAgB,gCAAgC,CAAC,CAAC,SAAS;IAAE,WAAW,CAAC,EAAE,0BAA0B,EAAE,CAAA;CAAE,EACxG,OAAO,EAAE,CAAC,EACV,UAAU,EAAE,0BAA0B,GACpC,IAAI,CAEN;AAED,kEAAkE;AAClE,eAAO,MAAM,4BAA4B,MAAM,CAAC;AAchD;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,0BAA0B,CACzC,KAAK,EAAE,OAAO,EACd,MAAM,SAA+B,GACnC,MAAM,CA6CR"}
|
|
@@ -22,3 +22,76 @@ export function createAssistantMessageDiagnostic(type, error, details) {
|
|
|
22
22
|
export function appendAssistantMessageDiagnostic(message, diagnostic) {
|
|
23
23
|
message.diagnostics = [...(message.diagnostics ?? []), diagnostic];
|
|
24
24
|
}
|
|
25
|
+
/** Detail budget (chars) for enriched provider error messages. */
|
|
26
|
+
export const PROVIDER_ERROR_DETAIL_BUDGET = 600;
|
|
27
|
+
/** Minimum room (chars) required before details are appended at all. */
|
|
28
|
+
const PROVIDER_ERROR_DETAIL_MIN_ROOM = 20;
|
|
29
|
+
function stringifyErrorDetail(value) {
|
|
30
|
+
if (typeof value === "string")
|
|
31
|
+
return value;
|
|
32
|
+
try {
|
|
33
|
+
return JSON.stringify(value) ?? String(value);
|
|
34
|
+
}
|
|
35
|
+
catch {
|
|
36
|
+
// Circular or otherwise unserializable — fall back to String().
|
|
37
|
+
return String(value);
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Build an enriched provider error message for retry diagnostics:
|
|
42
|
+
*
|
|
43
|
+
* `<original message> | HTTP <status> | code=<code> | type=<type> | requestID=<id> | provider error: <json>`
|
|
44
|
+
*
|
|
45
|
+
* The original message stays verbatim at the BEGINNING so the transient /
|
|
46
|
+
* rate-limit regex classifiers (`isTransientApiError`, `isRateLimitError`)
|
|
47
|
+
* still match it — they regex the message string, so the prefix must remain
|
|
48
|
+
* intact and untruncated. Detail parts come from the OpenAI SDK's APIError
|
|
49
|
+
* shape: `status` (set for HTTP-level failures, undefined for mid-stream SSE
|
|
50
|
+
* error chunks), `.error` (the raw provider JSON body — message / code /
|
|
51
|
+
* type / metadata), plus the top-level `code` / `type` copies and
|
|
52
|
+
* `requestID` the SDK attaches. The detail portion is clamped so the total
|
|
53
|
+
* stays within the ~600-char budget; the original message is never
|
|
54
|
+
* truncated.
|
|
55
|
+
*/
|
|
56
|
+
export function enrichProviderErrorMessage(error, budget = PROVIDER_ERROR_DETAIL_BUDGET) {
|
|
57
|
+
let original;
|
|
58
|
+
if (error instanceof Error)
|
|
59
|
+
original = error.message || error.name;
|
|
60
|
+
else if (typeof error === "string")
|
|
61
|
+
original = error;
|
|
62
|
+
else {
|
|
63
|
+
try {
|
|
64
|
+
original = JSON.stringify(error) ?? String(error);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
original = String(error);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
const err = error;
|
|
71
|
+
const details = [];
|
|
72
|
+
if (err && typeof err.status === "number")
|
|
73
|
+
details.push(`HTTP ${err.status}`);
|
|
74
|
+
if (err && typeof err.code !== "undefined" && err.code !== null) {
|
|
75
|
+
details.push(`code=${stringifyErrorDetail(err.code)}`);
|
|
76
|
+
}
|
|
77
|
+
if (err && typeof err.type === "string" && err.type) {
|
|
78
|
+
details.push(`type=${err.type}`);
|
|
79
|
+
}
|
|
80
|
+
if (err && typeof err.requestID === "string" && err.requestID) {
|
|
81
|
+
details.push(`requestID=${err.requestID}`);
|
|
82
|
+
}
|
|
83
|
+
if (err && err.error != null) {
|
|
84
|
+
const json = stringifyErrorDetail(err.error);
|
|
85
|
+
if (json && json !== "{}")
|
|
86
|
+
details.push(`provider error: ${json}`);
|
|
87
|
+
}
|
|
88
|
+
let suffix = details.join(" | ");
|
|
89
|
+
if (!suffix)
|
|
90
|
+
return original;
|
|
91
|
+
const room = budget - original.length - 3; // " | " separator
|
|
92
|
+
if (room < PROVIDER_ERROR_DETAIL_MIN_ROOM)
|
|
93
|
+
return original;
|
|
94
|
+
if (suffix.length > room)
|
|
95
|
+
suffix = `${suffix.slice(0, room - 1)}…`;
|
|
96
|
+
return `${original} | ${suffix}`;
|
|
97
|
+
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"image-source.d.ts","sourceRoot":"","sources":["../../../../src/sdk/ai/utils/image-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,YAAY,EAAW,MAAM,aAAa,CAAC;AAElE,8EAA8E;AAC9E,eAAO,MAAM,wBAAwB,QAAmB,CAAC;AAEzD,iEAAiE;AACjE,eAAO,MAAM,+BAA+B,QAAS,CAAC;AAEtD,MAAM,WAAW,mBAAmB;IACnC,mEAAmE;IACnE,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mDAAmD;IACnD,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB;;;;;OAKG;IACH,OAAO,CAAC,EAAE,MAAM,GAAG,CAAC,MAAM,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC,CAAC;IAC5E;;;;;;;;;OASG;IACH,gBAAgB,CAAC,EAAE,CAClB,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,WAAW,CAAC;QAAC,SAAS,CAAC,EAAE,MAAM,CAAA;KAAE,KAClD,OAAO,CAAC,MAAM,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;IACxC;;;;;;;OAOG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,MAAM,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IAC3F,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACnC;AAED,MAAM,WAAW,mBAAmB;IACnC,mEAAmE;IACnE,GAAG,EAAE,MAAM,CAAC;IACZ,2DAA2D;IAC3D,OAAO,EAAE,OAAO,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,cAAc,CAAC,EAAE,OAAO,CAAC;CACzB;AAuCD;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAI1D;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAUnF;AAmBD;;;;;;;;;GASG;AACH,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CA4BhE;AAcD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAE3F;AAqBD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,KAAK,IAAI,YAAY,GAAG;IAAE,IAAI,EAAE,MAAM,CAAA;CAAE,CAEhG;AAED,wEAAwE;AACxE,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGtE;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIxD;AAoBD;;;;;;GAMG;AACH,wBAAsB,uBAAuB,CAC5C,KAAK,EAAE,YAAY,EACnB,OAAO,GAAE,mBAAwB,GAC/B,OAAO,CAAC,mBAAmB,GAAG,IAAI,CAAC,
|
|
1
|
+
{"version":3,"file":"image-source.d.ts","sourceRoot":"","sources":["../../../../src/sdk/ai/utils/image-source.ts"],"names":[],"mappings":"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"}
|
|
@@ -290,9 +290,24 @@ export async function resolveImageForProvider(image, options = {}) {
|
|
|
290
290
|
if (hosted && options.resolveHostedUrl) {
|
|
291
291
|
try {
|
|
292
292
|
const resolvedUrl = (await options.resolveHostedUrl(url, { signal: options.signal, timeoutMs: options.timeoutMs }))?.trim();
|
|
293
|
-
if (resolvedUrl) {
|
|
293
|
+
if (resolvedUrl && !isLocalOrPrivateImageUrl(resolvedUrl)) {
|
|
294
294
|
return { url: resolvedUrl, inlined: false, mimeType: image.mimeType, hostedResolved: true };
|
|
295
295
|
}
|
|
296
|
+
if (resolvedUrl) {
|
|
297
|
+
// The backend minted the presigned url on a LOCAL/private endpoint
|
|
298
|
+
// (dev S3 on `http://localhost:9002`) — a remote provider can never
|
|
299
|
+
// fetch it. Do NOT hand over that dead url: fall through to the
|
|
300
|
+
// authenticated inline path below, which downloads the bytes from
|
|
301
|
+
// the backend itself and sends a base64 data URL instead.
|
|
302
|
+
let host = "";
|
|
303
|
+
try {
|
|
304
|
+
host = new URL(resolvedUrl).host;
|
|
305
|
+
}
|
|
306
|
+
catch {
|
|
307
|
+
host = resolvedUrl;
|
|
308
|
+
}
|
|
309
|
+
options.onWarn?.(`Resolved hosted image URL is local/private (${host}); inlining image as base64 instead`);
|
|
310
|
+
}
|
|
296
311
|
}
|
|
297
312
|
catch (error) {
|
|
298
313
|
const reason = error instanceof Error ? error.message : String(error);
|