@arden-hq/loop 0.0.0-stage → 0.1.2
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/LICENSE +202 -0
- package/README.md +121 -2
- package/dist/abort.d.ts +9 -0
- package/dist/abort.d.ts.map +1 -0
- package/dist/abort.js +31 -0
- package/dist/abort.js.map +1 -0
- package/dist/agent/agent.d.ts +48 -0
- package/dist/agent/agent.d.ts.map +1 -0
- package/dist/agent/agent.js +146 -0
- package/dist/agent/agent.js.map +1 -0
- package/dist/agent/background-tools.d.ts +51 -0
- package/dist/agent/background-tools.d.ts.map +1 -0
- package/dist/agent/background-tools.js +257 -0
- package/dist/agent/background-tools.js.map +1 -0
- package/dist/agent/budget.d.ts +5 -0
- package/dist/agent/budget.d.ts.map +1 -0
- package/dist/agent/budget.js +48 -0
- package/dist/agent/budget.js.map +1 -0
- package/dist/agent/config.d.ts +61 -0
- package/dist/agent/config.d.ts.map +1 -0
- package/dist/agent/config.js +99 -0
- package/dist/agent/config.js.map +1 -0
- package/dist/agent/guards.d.ts +10 -0
- package/dist/agent/guards.d.ts.map +1 -0
- package/dist/agent/guards.js +136 -0
- package/dist/agent/guards.js.map +1 -0
- package/dist/agent/history-journal.d.ts +18 -0
- package/dist/agent/history-journal.d.ts.map +1 -0
- package/dist/agent/history-journal.js +87 -0
- package/dist/agent/history-journal.js.map +1 -0
- package/dist/agent/history-projection.d.ts +6 -0
- package/dist/agent/history-projection.d.ts.map +1 -0
- package/dist/agent/history-projection.js +62 -0
- package/dist/agent/history-projection.js.map +1 -0
- package/dist/agent/interactions.d.ts +14 -0
- package/dist/agent/interactions.d.ts.map +1 -0
- package/dist/agent/interactions.js +85 -0
- package/dist/agent/interactions.js.map +1 -0
- package/dist/agent/middleware.d.ts +5 -0
- package/dist/agent/middleware.d.ts.map +1 -0
- package/dist/agent/middleware.js +55 -0
- package/dist/agent/middleware.js.map +1 -0
- package/dist/agent/model-output-projection.d.ts +27 -0
- package/dist/agent/model-output-projection.d.ts.map +1 -0
- package/dist/agent/model-output-projection.js +138 -0
- package/dist/agent/model-output-projection.js.map +1 -0
- package/dist/agent/model-output.d.ts +19 -0
- package/dist/agent/model-output.d.ts.map +1 -0
- package/dist/agent/model-output.js +172 -0
- package/dist/agent/model-output.js.map +1 -0
- package/dist/agent/model-turn.d.ts +29 -0
- package/dist/agent/model-turn.d.ts.map +1 -0
- package/dist/agent/model-turn.js +401 -0
- package/dist/agent/model-turn.js.map +1 -0
- package/dist/agent/policy.d.ts +28 -0
- package/dist/agent/policy.d.ts.map +1 -0
- package/dist/agent/policy.js +109 -0
- package/dist/agent/policy.js.map +1 -0
- package/dist/agent/provider-capabilities.d.ts +12 -0
- package/dist/agent/provider-capabilities.d.ts.map +1 -0
- package/dist/agent/provider-capabilities.js +76 -0
- package/dist/agent/provider-capabilities.js.map +1 -0
- package/dist/agent/recovery.d.ts +8 -0
- package/dist/agent/recovery.d.ts.map +1 -0
- package/dist/agent/recovery.js +21 -0
- package/dist/agent/recovery.js.map +1 -0
- package/dist/agent/replies.d.ts +3 -0
- package/dist/agent/replies.d.ts.map +1 -0
- package/dist/agent/replies.js +24 -0
- package/dist/agent/replies.js.map +1 -0
- package/dist/agent/run-state.d.ts +98 -0
- package/dist/agent/run-state.d.ts.map +1 -0
- package/dist/agent/run-state.js +454 -0
- package/dist/agent/run-state.js.map +1 -0
- package/dist/agent/run.d.ts +6 -0
- package/dist/agent/run.d.ts.map +1 -0
- package/dist/agent/run.js +462 -0
- package/dist/agent/run.js.map +1 -0
- package/dist/agent/streamed-call-history.d.ts +20 -0
- package/dist/agent/streamed-call-history.d.ts.map +1 -0
- package/dist/agent/streamed-call-history.js +71 -0
- package/dist/agent/streamed-call-history.js.map +1 -0
- package/dist/agent/streaming-tools.d.ts +23 -0
- package/dist/agent/streaming-tools.d.ts.map +1 -0
- package/dist/agent/streaming-tools.js +67 -0
- package/dist/agent/streaming-tools.js.map +1 -0
- package/dist/agent/structured-output.d.ts +27 -0
- package/dist/agent/structured-output.d.ts.map +1 -0
- package/dist/agent/structured-output.js +26 -0
- package/dist/agent/structured-output.js.map +1 -0
- package/dist/agent/tool-admission.d.ts +18 -0
- package/dist/agent/tool-admission.d.ts.map +1 -0
- package/dist/agent/tool-admission.js +22 -0
- package/dist/agent/tool-admission.js.map +1 -0
- package/dist/contracts/events.d.ts +236 -0
- package/dist/contracts/events.d.ts.map +1 -0
- package/dist/contracts/events.js +13 -0
- package/dist/contracts/events.js.map +1 -0
- package/dist/contracts/messages.d.ts +234 -0
- package/dist/contracts/messages.d.ts.map +1 -0
- package/dist/contracts/messages.js +11 -0
- package/dist/contracts/messages.js.map +1 -0
- package/dist/contracts/provider.d.ts +177 -0
- package/dist/contracts/provider.d.ts.map +1 -0
- package/dist/contracts/provider.js +26 -0
- package/dist/contracts/provider.js.map +1 -0
- package/dist/contracts/tools.d.ts +217 -0
- package/dist/contracts/tools.d.ts.map +1 -0
- package/dist/contracts/tools.js +16 -0
- package/dist/contracts/tools.js.map +1 -0
- package/dist/errors.d.ts +112 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +190 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +20 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/concurrency.d.ts +11 -0
- package/dist/internal/concurrency.d.ts.map +1 -0
- package/dist/internal/concurrency.js +86 -0
- package/dist/internal/concurrency.js.map +1 -0
- package/dist/internal/stream.d.ts +25 -0
- package/dist/internal/stream.d.ts.map +1 -0
- package/dist/internal/stream.js +97 -0
- package/dist/internal/stream.js.map +1 -0
- package/dist/internal/validate.d.ts +30 -0
- package/dist/internal/validate.d.ts.map +1 -0
- package/dist/internal/validate.js +480 -0
- package/dist/internal/validate.js.map +1 -0
- package/dist/providers/kit/errors.d.ts +40 -0
- package/dist/providers/kit/errors.d.ts.map +1 -0
- package/dist/providers/kit/errors.js +48 -0
- package/dist/providers/kit/errors.js.map +1 -0
- package/dist/providers/kit/index.d.ts +10 -0
- package/dist/providers/kit/index.d.ts.map +1 -0
- package/dist/providers/kit/index.js +10 -0
- package/dist/providers/kit/index.js.map +1 -0
- package/dist/providers/kit/retry.d.ts +43 -0
- package/dist/providers/kit/retry.d.ts.map +1 -0
- package/dist/providers/kit/retry.js +118 -0
- package/dist/providers/kit/retry.js.map +1 -0
- package/dist/providers/kit/sse.d.ts +22 -0
- package/dist/providers/kit/sse.d.ts.map +1 -0
- package/dist/providers/kit/sse.js +70 -0
- package/dist/providers/kit/sse.js.map +1 -0
- package/dist/providers/openai-responses/citations.d.ts +21 -0
- package/dist/providers/openai-responses/citations.d.ts.map +1 -0
- package/dist/providers/openai-responses/citations.js +65 -0
- package/dist/providers/openai-responses/citations.js.map +1 -0
- package/dist/providers/openai-responses/continuation.d.ts +19 -0
- package/dist/providers/openai-responses/continuation.d.ts.map +1 -0
- package/dist/providers/openai-responses/continuation.js +28 -0
- package/dist/providers/openai-responses/continuation.js.map +1 -0
- package/dist/providers/openai-responses/errors.d.ts +28 -0
- package/dist/providers/openai-responses/errors.d.ts.map +1 -0
- package/dist/providers/openai-responses/errors.js +103 -0
- package/dist/providers/openai-responses/errors.js.map +1 -0
- package/dist/providers/openai-responses/history.d.ts +8 -0
- package/dist/providers/openai-responses/history.d.ts.map +1 -0
- package/dist/providers/openai-responses/history.js +93 -0
- package/dist/providers/openai-responses/history.js.map +1 -0
- package/dist/providers/openai-responses/items.d.ts +106 -0
- package/dist/providers/openai-responses/items.d.ts.map +1 -0
- package/dist/providers/openai-responses/items.js +124 -0
- package/dist/providers/openai-responses/items.js.map +1 -0
- package/dist/providers/openai-responses/parameter-schema.d.ts +11 -0
- package/dist/providers/openai-responses/parameter-schema.d.ts.map +1 -0
- package/dist/providers/openai-responses/parameter-schema.js +186 -0
- package/dist/providers/openai-responses/parameter-schema.js.map +1 -0
- package/dist/providers/openai-responses/provider.d.ts +54 -0
- package/dist/providers/openai-responses/provider.d.ts.map +1 -0
- package/dist/providers/openai-responses/provider.js +270 -0
- package/dist/providers/openai-responses/provider.js.map +1 -0
- package/dist/providers/openai-responses/request.d.ts +41 -0
- package/dist/providers/openai-responses/request.d.ts.map +1 -0
- package/dist/providers/openai-responses/request.js +276 -0
- package/dist/providers/openai-responses/request.js.map +1 -0
- package/dist/providers/openai-responses/response.d.ts +7 -0
- package/dist/providers/openai-responses/response.d.ts.map +1 -0
- package/dist/providers/openai-responses/response.js +354 -0
- package/dist/providers/openai-responses/response.js.map +1 -0
- package/dist/providers/openai-responses/stored-items.d.ts +9 -0
- package/dist/providers/openai-responses/stored-items.d.ts.map +1 -0
- package/dist/providers/openai-responses/stored-items.js +133 -0
- package/dist/providers/openai-responses/stored-items.js.map +1 -0
- package/dist/providers/openai-responses/tool-search.d.ts +12 -0
- package/dist/providers/openai-responses/tool-search.d.ts.map +1 -0
- package/dist/providers/openai-responses/tool-search.js +68 -0
- package/dist/providers/openai-responses/tool-search.js.map +1 -0
- package/dist/providers/openai-responses/tools.d.ts +33 -0
- package/dist/providers/openai-responses/tools.d.ts.map +1 -0
- package/dist/providers/openai-responses/tools.js +53 -0
- package/dist/providers/openai-responses/tools.js.map +1 -0
- package/dist/providers/openai-responses/web-search.d.ts +5 -0
- package/dist/providers/openai-responses/web-search.d.ts.map +1 -0
- package/dist/providers/openai-responses/web-search.js +114 -0
- package/dist/providers/openai-responses/web-search.js.map +1 -0
- package/dist/providers/openai-responses/websocket.d.ts +29 -0
- package/dist/providers/openai-responses/websocket.d.ts.map +1 -0
- package/dist/providers/openai-responses/websocket.js +400 -0
- package/dist/providers/openai-responses/websocket.js.map +1 -0
- package/dist/tools/dispatch.d.ts +65 -0
- package/dist/tools/dispatch.d.ts.map +1 -0
- package/dist/tools/dispatch.js +536 -0
- package/dist/tools/dispatch.js.map +1 -0
- package/dist/tools/display-title.d.ts +18 -0
- package/dist/tools/display-title.d.ts.map +1 -0
- package/dist/tools/display-title.js +50 -0
- package/dist/tools/display-title.js.map +1 -0
- package/dist/tools/search.d.ts +36 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +224 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/tool.d.ts +200 -0
- package/dist/tools/tool.d.ts.map +1 -0
- package/dist/tools/tool.js +275 -0
- package/dist/tools/tool.js.map +1 -0
- package/dist/tools/truncate.d.ts +18 -0
- package/dist/tools/truncate.d.ts.map +1 -0
- package/dist/tools/truncate.js +76 -0
- package/dist/tools/truncate.js.map +1 -0
- package/package.json +67 -4
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/** Total connection attempts per request (the pre-emission 401 auth retry is excluded). */
|
|
2
|
+
export declare const DEFAULT_MAX_ATTEMPTS = 5;
|
|
3
|
+
/**
|
|
4
|
+
* A classified failure retries by its own `retryable` (408/429/5xx statuses and
|
|
5
|
+
* transport failures do; semantic rejections and other 4xx do not). An
|
|
6
|
+
* unclassified Error retries when its message names a transport failure
|
|
7
|
+
* (connection resets, timeouts, overload-style fetch errors).
|
|
8
|
+
*/
|
|
9
|
+
export declare const isRetryableFailure: (error: unknown) => boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Delay before retry `attempt` (1-based): response headers win, then the SSE
|
|
12
|
+
* wire `retry:` hint, then exponential backoff.
|
|
13
|
+
*/
|
|
14
|
+
export declare const retryDelayMs: (attempt: number, error: unknown, wireHintMs?: number, random?: number) => number;
|
|
15
|
+
/** Backoff sleep that the abort signal cancels immediately with the loop's AbortError. */
|
|
16
|
+
export declare const backoffSleep: (delayMs: number, signal?: AbortSignal) => Promise<void>;
|
|
17
|
+
/**
|
|
18
|
+
* The one retry decision: the delay before attempt `attempt + 1` when the
|
|
19
|
+
* failure is a transient one and the budget allows another try, else
|
|
20
|
+
* undefined (the failure stands).
|
|
21
|
+
*/
|
|
22
|
+
export declare const nextRetry: (attempt: number, error: unknown, options?: {
|
|
23
|
+
readonly maxAttempts?: number;
|
|
24
|
+
readonly wireHintMs?: number | undefined;
|
|
25
|
+
}) => number | undefined;
|
|
26
|
+
/**
|
|
27
|
+
* `fetch` with the transport retry, for a model endpoint called with one JSON
|
|
28
|
+
* request (embeddings, decision models, a local model server). A dropped
|
|
29
|
+
* connection or a 408/429/5xx answer is tried again under `nextRetry`; the
|
|
30
|
+
* request's own signal bounds every attempt and every wait, so a caller's
|
|
31
|
+
* timeout still holds. The last answer is returned as it came, so the caller
|
|
32
|
+
* reads its status as before. Only a body that can be sent again (none, or a
|
|
33
|
+
* string) is retried.
|
|
34
|
+
*/
|
|
35
|
+
export declare const retryingFetch: (fetch: typeof globalThis.fetch, maxAttempts?: number) => typeof globalThis.fetch;
|
|
36
|
+
/**
|
|
37
|
+
* A one-shot model call with the transport retry: `run` again after a
|
|
38
|
+
* transient failure under `nextRetry`, for a call that is not a plain fetch
|
|
39
|
+
* (a multipart upload over node:http). The signal bounds every attempt and
|
|
40
|
+
* wait. A non-OK answer must throw an HttpStatusError for its status to count.
|
|
41
|
+
*/
|
|
42
|
+
export declare const retrying: <T>(run: () => Promise<T>, signal: AbortSignal | undefined, maxAttempts?: number) => Promise<T>;
|
|
43
|
+
//# sourceMappingURL=retry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../../../src/providers/kit/retry.ts"],"names":[],"mappings":"AAMA,2FAA2F;AAC3F,eAAO,MAAM,oBAAoB,IAAI,CAAA;AAarC;;;;;GAKG;AACH,eAAO,MAAM,kBAAkB,UAAW,OAAO,KAAG,OAGnD,CAAA;AAUD;;;GAGG;AACH,eAAO,MAAM,YAAY,YACd,MAAM,SACR,OAAO,eACD,MAAM,sBAElB,MAKF,CAAA;AAED,0FAA0F;AAC1F,eAAO,MAAM,YAAY,YAAa,MAAM,WAAW,WAAW,KAAG,OAAO,CAAC,IAAI,CAG7E,CAAA;AAEJ;;;;GAIG;AACH,eAAO,MAAM,SAAS,YACX,MAAM,SACR,OAAO,YACL;IAAE,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CAAE,KACnF,MAAM,GAAG,SAGG,CAAA;AAEf;;;;;;;;GAQG;AACH,eAAO,MAAM,aAAa,UAChB,OAAO,UAAU,CAAC,KAAK,2BAAuC,OAAO,UAAU,CAAC,KA2BvF,CAAA;AAEH;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,GAAU,CAAC,OACzB,MAAM,OAAO,CAAC,CAAC,CAAC,UACb,WAAW,GAAG,SAAS,2BAE9B,OAAO,CAAC,CAAC,CAWX,CAAA"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
import { backoffDelayMs, parseRetryAfter, retryAfterHints } from "@arden-hq/std/retry";
|
|
2
|
+
import { sleep } from "@arden-hq/std/sleep";
|
|
3
|
+
import { abortError } from "../../abort.js";
|
|
4
|
+
import { HttpStatusError, ProviderError } from "./errors.js";
|
|
5
|
+
/** Total connection attempts per request (the pre-emission 401 auth retry is excluded). */
|
|
6
|
+
export const DEFAULT_MAX_ATTEMPTS = 5;
|
|
7
|
+
const RETRY_MAX_DELAY_MS = 30_000;
|
|
8
|
+
const BACKOFF = { initialMs: 250, maxMs: RETRY_MAX_DELAY_MS, jitter: 0.25 };
|
|
9
|
+
const RETRYABLE_MESSAGE_PATTERNS = [
|
|
10
|
+
/overloaded|service unavailable|too many requests|rate limit/i,
|
|
11
|
+
/terminated|fetch failed|failed to fetch|network[-_\s]error|connection (?:error|refused|reset|lost)|socket connection was closed|socket hang up|reset before headers|getaddrinfo|enotfound|eai_again|econnrefused|econnreset|etimedout/i,
|
|
12
|
+
/^timeout$|\b(?:request|response|connection|network|stream|read) (?:timeout|timed out|time out)\b/i
|
|
13
|
+
];
|
|
14
|
+
const matchesRetryableMessage = (value) => typeof value === "string" && RETRYABLE_MESSAGE_PATTERNS.some((pattern) => pattern.test(value));
|
|
15
|
+
/**
|
|
16
|
+
* A classified failure retries by its own `retryable` (408/429/5xx statuses and
|
|
17
|
+
* transport failures do; semantic rejections and other 4xx do not). An
|
|
18
|
+
* unclassified Error retries when its message names a transport failure
|
|
19
|
+
* (connection resets, timeouts, overload-style fetch errors).
|
|
20
|
+
*/
|
|
21
|
+
export const isRetryableFailure = (error) => {
|
|
22
|
+
if (error instanceof ProviderError)
|
|
23
|
+
return error.retryable;
|
|
24
|
+
return error instanceof Error && matchesRetryableMessage(error.message);
|
|
25
|
+
};
|
|
26
|
+
const cap = (ms) => Math.min(RETRY_MAX_DELAY_MS, Math.ceil(ms));
|
|
27
|
+
const retryAfterDelayMs = (error) => {
|
|
28
|
+
if (!(error instanceof HttpStatusError))
|
|
29
|
+
return undefined;
|
|
30
|
+
const asked = parseRetryAfter(error);
|
|
31
|
+
return asked === undefined ? undefined : cap(asked);
|
|
32
|
+
};
|
|
33
|
+
/**
|
|
34
|
+
* Delay before retry `attempt` (1-based): response headers win, then the SSE
|
|
35
|
+
* wire `retry:` hint, then exponential backoff.
|
|
36
|
+
*/
|
|
37
|
+
export const retryDelayMs = (attempt, error, wireHintMs, random = Math.random()) => {
|
|
38
|
+
const directed = retryAfterDelayMs(error);
|
|
39
|
+
if (directed !== undefined)
|
|
40
|
+
return directed;
|
|
41
|
+
if (wireHintMs !== undefined)
|
|
42
|
+
return cap(wireHintMs);
|
|
43
|
+
return backoffDelayMs(BACKOFF, attempt, random);
|
|
44
|
+
};
|
|
45
|
+
/** Backoff sleep that the abort signal cancels immediately with the loop's AbortError. */
|
|
46
|
+
export const backoffSleep = (delayMs, signal) => sleep(delayMs, signal).catch(() => {
|
|
47
|
+
throw abortError();
|
|
48
|
+
});
|
|
49
|
+
/**
|
|
50
|
+
* The one retry decision: the delay before attempt `attempt + 1` when the
|
|
51
|
+
* failure is a transient one and the budget allows another try, else
|
|
52
|
+
* undefined (the failure stands).
|
|
53
|
+
*/
|
|
54
|
+
export const nextRetry = (attempt, error, options = {}) => attempt < (options.maxAttempts ?? DEFAULT_MAX_ATTEMPTS) && isRetryableFailure(error)
|
|
55
|
+
? retryDelayMs(attempt, error, options.wireHintMs)
|
|
56
|
+
: undefined;
|
|
57
|
+
/**
|
|
58
|
+
* `fetch` with the transport retry, for a model endpoint called with one JSON
|
|
59
|
+
* request (embeddings, decision models, a local model server). A dropped
|
|
60
|
+
* connection or a 408/429/5xx answer is tried again under `nextRetry`; the
|
|
61
|
+
* request's own signal bounds every attempt and every wait, so a caller's
|
|
62
|
+
* timeout still holds. The last answer is returned as it came, so the caller
|
|
63
|
+
* reads its status as before. Only a body that can be sent again (none, or a
|
|
64
|
+
* string) is retried.
|
|
65
|
+
*/
|
|
66
|
+
export const retryingFetch = (fetch, maxAttempts = DEFAULT_MAX_ATTEMPTS) => async (input, init) => {
|
|
67
|
+
const replayable = !(input instanceof Request) &&
|
|
68
|
+
(init?.body === undefined || init.body === null || typeof init.body === "string");
|
|
69
|
+
for (let attempt = 1;; attempt += 1) {
|
|
70
|
+
let failure;
|
|
71
|
+
try {
|
|
72
|
+
const response = await fetch(input, init);
|
|
73
|
+
if (response.ok || !replayable)
|
|
74
|
+
return response;
|
|
75
|
+
failure = new HttpStatusError(`HTTP ${String(response.status)}`, {
|
|
76
|
+
status: response.status,
|
|
77
|
+
...retryAfterHints(response.headers),
|
|
78
|
+
code: "provider_unavailable"
|
|
79
|
+
});
|
|
80
|
+
const delayMs = nextRetry(attempt, failure, { maxAttempts });
|
|
81
|
+
if (delayMs === undefined)
|
|
82
|
+
return response;
|
|
83
|
+
await response.body?.cancel().catch(() => undefined);
|
|
84
|
+
await backoffSleep(delayMs, init?.signal ?? undefined);
|
|
85
|
+
continue;
|
|
86
|
+
}
|
|
87
|
+
catch (error) {
|
|
88
|
+
if (failure !== undefined || init?.signal?.aborted || !replayable)
|
|
89
|
+
throw error;
|
|
90
|
+
const delayMs = nextRetry(attempt, error, { maxAttempts });
|
|
91
|
+
if (delayMs === undefined)
|
|
92
|
+
throw error;
|
|
93
|
+
await backoffSleep(delayMs, init?.signal ?? undefined);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
/**
|
|
98
|
+
* A one-shot model call with the transport retry: `run` again after a
|
|
99
|
+
* transient failure under `nextRetry`, for a call that is not a plain fetch
|
|
100
|
+
* (a multipart upload over node:http). The signal bounds every attempt and
|
|
101
|
+
* wait. A non-OK answer must throw an HttpStatusError for its status to count.
|
|
102
|
+
*/
|
|
103
|
+
export const retrying = async (run, signal, maxAttempts = DEFAULT_MAX_ATTEMPTS) => {
|
|
104
|
+
for (let attempt = 1;; attempt += 1) {
|
|
105
|
+
try {
|
|
106
|
+
return await run();
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
if (signal?.aborted)
|
|
110
|
+
throw error;
|
|
111
|
+
const delayMs = nextRetry(attempt, error, { maxAttempts });
|
|
112
|
+
if (delayMs === undefined)
|
|
113
|
+
throw error;
|
|
114
|
+
await backoffSleep(delayMs, signal);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
//# sourceMappingURL=retry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"retry.js","sourceRoot":"","sources":["../../../src/providers/kit/retry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export interface SseEvent {
|
|
2
|
+
readonly event: string;
|
|
3
|
+
readonly data: string;
|
|
4
|
+
}
|
|
5
|
+
/** Incremental SSE decoder with the same seam the provider consumed before. */
|
|
6
|
+
export declare class SseParser {
|
|
7
|
+
#private;
|
|
8
|
+
/** Last `retry:` reconnection hint seen on the wire, in milliseconds. */
|
|
9
|
+
retryDelayMs: number | undefined;
|
|
10
|
+
constructor();
|
|
11
|
+
feed(chunk: string): Array<SseEvent>;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Reads `body` as SSE events. `streamName` opens the failure messages
|
|
15
|
+
* ("<streamName> became idle", "<streamName> failed").
|
|
16
|
+
*/
|
|
17
|
+
export declare function readSseEvents(body: ReadableStream<Uint8Array>, parser: SseParser, options: {
|
|
18
|
+
readonly idleTimeoutMs: number;
|
|
19
|
+
readonly streamName: string;
|
|
20
|
+
readonly signal?: AbortSignal;
|
|
21
|
+
}): AsyncGenerator<SseEvent>;
|
|
22
|
+
//# sourceMappingURL=sse.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.d.ts","sourceRoot":"","sources":["../../../src/providers/kit/sse.ts"],"names":[],"mappings":"AASA,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED,+EAA+E;AAC/E,qBAAa,SAAS;;IAGpB,yEAAyE;IACzE,YAAY,EAAE,MAAM,GAAG,SAAS,CAAA;IAEhC,cASC;IAED,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,KAAK,CAAC,QAAQ,CAAC,CAKnC;CACF;AAyBD;;;GAGG;AACH,wBAAuB,aAAa,CAClC,IAAI,EAAE,cAAc,CAAC,UAAU,CAAC,EAChC,MAAM,EAAE,SAAS,EACjB,OAAO,EAAE;IACP,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAC9B,GACA,cAAc,CAAC,QAAQ,CAAC,CAsB1B"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Idleness and network failures surface as RetryableProviderError so the
|
|
3
|
+
* kit's retry policy classifies them; abort errors pass through.
|
|
4
|
+
*/
|
|
5
|
+
import { createParser } from "eventsource-parser";
|
|
6
|
+
import { isAbortError, raceAbort } from "../../abort.js";
|
|
7
|
+
import { RetryableProviderError } from "./errors.js";
|
|
8
|
+
import { errorMessage } from "@arden-hq/std/errors";
|
|
9
|
+
/** Incremental SSE decoder with the same seam the provider consumed before. */
|
|
10
|
+
export class SseParser {
|
|
11
|
+
#events = [];
|
|
12
|
+
#parser;
|
|
13
|
+
/** Last `retry:` reconnection hint seen on the wire, in milliseconds. */
|
|
14
|
+
retryDelayMs;
|
|
15
|
+
constructor() {
|
|
16
|
+
this.#parser = createParser({
|
|
17
|
+
onEvent: (message) => {
|
|
18
|
+
this.#events.push({ event: message.event ?? "message", data: message.data });
|
|
19
|
+
},
|
|
20
|
+
onRetry: (delayMs) => {
|
|
21
|
+
this.retryDelayMs = delayMs;
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
feed(chunk) {
|
|
26
|
+
this.#parser.feed(chunk);
|
|
27
|
+
const events = this.#events;
|
|
28
|
+
this.#events = [];
|
|
29
|
+
return events;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
const asTransportError = (cause, streamName) => isAbortError(cause) || (cause instanceof DOMException && cause.name === "AbortError")
|
|
33
|
+
? cause
|
|
34
|
+
: new RetryableProviderError(errorMessage(cause, `${streamName} failed`));
|
|
35
|
+
const raceIdle = (promise, idleTimeoutMs, streamName) => new Promise((resolve, reject) => {
|
|
36
|
+
const timer = setTimeout(() => reject(new RetryableProviderError(`${streamName} became idle`)), idleTimeoutMs);
|
|
37
|
+
promise.then((value) => {
|
|
38
|
+
clearTimeout(timer);
|
|
39
|
+
resolve(value);
|
|
40
|
+
}, (cause) => {
|
|
41
|
+
clearTimeout(timer);
|
|
42
|
+
reject(cause);
|
|
43
|
+
});
|
|
44
|
+
});
|
|
45
|
+
/**
|
|
46
|
+
* Reads `body` as SSE events. `streamName` opens the failure messages
|
|
47
|
+
* ("<streamName> became idle", "<streamName> failed").
|
|
48
|
+
*/
|
|
49
|
+
export async function* readSseEvents(body, parser, options) {
|
|
50
|
+
const reader = body.getReader();
|
|
51
|
+
const decoder = new TextDecoder();
|
|
52
|
+
try {
|
|
53
|
+
while (true) {
|
|
54
|
+
const read = raceIdle(reader.read().catch((cause) => {
|
|
55
|
+
throw asTransportError(cause, options.streamName);
|
|
56
|
+
}), options.idleTimeoutMs, options.streamName);
|
|
57
|
+
// The abort race can win and abandon the read; observe its late rejection.
|
|
58
|
+
read.catch(() => { });
|
|
59
|
+
const next = await raceAbort(read, options.signal);
|
|
60
|
+
if (next.done)
|
|
61
|
+
break;
|
|
62
|
+
yield* parser.feed(decoder.decode(next.value, { stream: true }));
|
|
63
|
+
}
|
|
64
|
+
yield* parser.feed(decoder.decode());
|
|
65
|
+
}
|
|
66
|
+
finally {
|
|
67
|
+
void reader.cancel().catch(() => { });
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=sse.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sse.js","sourceRoot":"","sources":["../../../src/providers/kit/sse.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Removes OpenAI citation markers from user-visible text.
|
|
3
|
+
*
|
|
4
|
+
* The API emits citations as framed private-use text:
|
|
5
|
+
* `\uE200cite\uE202{source-id}[\uE202{locator}]\uE201`.
|
|
6
|
+
* Applications must resolve the source ids or remove the markers before
|
|
7
|
+
* display. Arden currently presents the resolved turn sources separately, so
|
|
8
|
+
* this filter removes the protocol framing while preserving raw response items
|
|
9
|
+
* for provider replay.
|
|
10
|
+
*
|
|
11
|
+
* @see https://developers.openai.com/api/docs/guides/citation-formatting
|
|
12
|
+
*/
|
|
13
|
+
/** Stateful because a citation marker may span several streamed deltas. */
|
|
14
|
+
export declare class OpenAiCitationFilter {
|
|
15
|
+
private state;
|
|
16
|
+
push(chunk: string): string;
|
|
17
|
+
/** Drops a truncated citation prefix or marker at the end of the response. */
|
|
18
|
+
finish(): void;
|
|
19
|
+
}
|
|
20
|
+
export declare const stripOpenAiCitations: (text: string) => string;
|
|
21
|
+
//# sourceMappingURL=citations.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"citations.d.ts","sourceRoot":"","sources":["../../../src/providers/openai-responses/citations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAYH,2EAA2E;AAC3E,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,KAAK,CAAgC;IAE7C,IAAI,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAmC1B;IAED,8EAA8E;IAC9E,MAAM,IAAI,IAAI,CAEb;CACF;AAED,eAAO,MAAM,oBAAoB,SAAU,MAAM,KAAG,MAKnD,CAAA"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Removes OpenAI citation markers from user-visible text.
|
|
3
|
+
*
|
|
4
|
+
* The API emits citations as framed private-use text:
|
|
5
|
+
* `\uE200cite\uE202{source-id}[\uE202{locator}]\uE201`.
|
|
6
|
+
* Applications must resolve the source ids or remove the markers before
|
|
7
|
+
* display. Arden currently presents the resolved turn sources separately, so
|
|
8
|
+
* this filter removes the protocol framing while preserving raw response items
|
|
9
|
+
* for provider replay.
|
|
10
|
+
*
|
|
11
|
+
* @see https://developers.openai.com/api/docs/guides/citation-formatting
|
|
12
|
+
*/
|
|
13
|
+
const CITATION_START = "\uE200";
|
|
14
|
+
const CITATION_DELIMITER = "\uE202";
|
|
15
|
+
const CITATION_STOP = "\uE201";
|
|
16
|
+
const CITATION_PREFIX = `${CITATION_START}cite${CITATION_DELIMITER}`;
|
|
17
|
+
/** Stateful because a citation marker may span several streamed deltas. */
|
|
18
|
+
export class OpenAiCitationFilter {
|
|
19
|
+
state = { kind: "text" };
|
|
20
|
+
push(chunk) {
|
|
21
|
+
let visible = "";
|
|
22
|
+
for (const character of chunk) {
|
|
23
|
+
if (this.state.kind === "citation") {
|
|
24
|
+
if (character === CITATION_STOP)
|
|
25
|
+
this.state = { kind: "text" };
|
|
26
|
+
continue;
|
|
27
|
+
}
|
|
28
|
+
if (this.state.kind === "prefix") {
|
|
29
|
+
const candidate = `${this.state.value}${character}`;
|
|
30
|
+
if (candidate === CITATION_PREFIX) {
|
|
31
|
+
this.state = { kind: "citation" };
|
|
32
|
+
continue;
|
|
33
|
+
}
|
|
34
|
+
if (CITATION_PREFIX.startsWith(candidate)) {
|
|
35
|
+
this.state = { kind: "prefix", value: candidate };
|
|
36
|
+
continue;
|
|
37
|
+
}
|
|
38
|
+
visible += this.state.value;
|
|
39
|
+
this.state =
|
|
40
|
+
character === CITATION_START ? { kind: "prefix", value: character } : { kind: "text" };
|
|
41
|
+
if (character !== CITATION_START)
|
|
42
|
+
visible += character;
|
|
43
|
+
continue;
|
|
44
|
+
}
|
|
45
|
+
if (character === CITATION_START) {
|
|
46
|
+
this.state = { kind: "prefix", value: character };
|
|
47
|
+
}
|
|
48
|
+
else {
|
|
49
|
+
visible += character;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
return visible;
|
|
53
|
+
}
|
|
54
|
+
/** Drops a truncated citation prefix or marker at the end of the response. */
|
|
55
|
+
finish() {
|
|
56
|
+
this.state = { kind: "text" };
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
export const stripOpenAiCitations = (text) => {
|
|
60
|
+
const filter = new OpenAiCitationFilter();
|
|
61
|
+
const visible = filter.push(text);
|
|
62
|
+
filter.finish();
|
|
63
|
+
return visible;
|
|
64
|
+
};
|
|
65
|
+
//# sourceMappingURL=citations.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"citations.js","sourceRoot":"","sources":["../../../src/providers/openai-responses/citations.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,MAAM,cAAc,GAAG,QAAQ,CAAA;AAC/B,MAAM,kBAAkB,GAAG,QAAQ,CAAA;AACnC,MAAM,aAAa,GAAG,QAAQ,CAAA;AAC9B,MAAM,eAAe,GAAG,GAAG,cAAc,OAAO,kBAAkB,EAAE,CAAA;AAOpE,2EAA2E;AAC3E,MAAM,OAAO,oBAAoB;IACvB,KAAK,GAAgB,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;IAE7C,IAAI,CAAC,KAAa;QAChB,IAAI,OAAO,GAAG,EAAE,CAAA;QAEhB,KAAK,MAAM,SAAS,IAAI,KAAK,EAAE,CAAC;YAC9B,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBACnC,IAAI,SAAS,KAAK,aAAa;oBAAE,IAAI,CAAC,KAAK,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;gBAC9D,SAAQ;YACV,CAAC;YAED,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;gBACjC,MAAM,SAAS,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,SAAS,EAAE,CAAA;gBACnD,IAAI,SAAS,KAAK,eAAe,EAAE,CAAC;oBAClC,IAAI,CAAC,KAAK,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,CAAA;oBACjC,SAAQ;gBACV,CAAC;gBACD,IAAI,eAAe,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;oBAC1C,IAAI,CAAC,KAAK,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;oBACjD,SAAQ;gBACV,CAAC;gBAED,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,KAAK,CAAA;gBAC3B,IAAI,CAAC,KAAK;oBACR,SAAS,KAAK,cAAc,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;gBACxF,IAAI,SAAS,KAAK,cAAc;oBAAE,OAAO,IAAI,SAAS,CAAA;gBACtD,SAAQ;YACV,CAAC;YAED,IAAI,SAAS,KAAK,cAAc,EAAE,CAAC;gBACjC,IAAI,CAAC,KAAK,GAAG,EAAE,IAAI,EAAE,QAAQ,EAAE,KAAK,EAAE,SAAS,EAAE,CAAA;YACnD,CAAC;iBAAM,CAAC;gBACN,OAAO,IAAI,SAAS,CAAA;YACtB,CAAC;QACH,CAAC;QAED,OAAO,OAAO,CAAA;IAChB,CAAC;IAED,8EAA8E;IAC9E,MAAM;QACJ,IAAI,CAAC,KAAK,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,CAAA;IAC/B,CAAC;CACF;AAED,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,IAAY,EAAU,EAAE;IAC3D,MAAM,MAAM,GAAG,IAAI,oBAAoB,EAAE,CAAA;IACzC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;IACjC,MAAM,CAAC,MAAM,EAAE,CAAA;IACf,OAAO,OAAO,CAAA;AAChB,CAAC,CAAA"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ProviderMessage } from "../../contracts/provider.js";
|
|
2
|
+
import type { InputItem } from "./items.js";
|
|
3
|
+
import type { ResponsesPayload } from "./request.js";
|
|
4
|
+
export interface ResponseContinuation {
|
|
5
|
+
readonly responseId: string;
|
|
6
|
+
readonly properties: string;
|
|
7
|
+
readonly input: ReadonlyArray<string>;
|
|
8
|
+
readonly pendingInput: ReadonlyArray<InputItem>;
|
|
9
|
+
}
|
|
10
|
+
/** Canonical replay prefix, with locally answered searches still awaiting submission. */
|
|
11
|
+
export declare const responseContinuation: ({ payload, message, responseId, asyncTools }: {
|
|
12
|
+
readonly payload: ResponsesPayload;
|
|
13
|
+
readonly message: ProviderMessage;
|
|
14
|
+
readonly responseId: string;
|
|
15
|
+
readonly asyncTools: ReadonlySet<string>;
|
|
16
|
+
}) => ResponseContinuation | undefined;
|
|
17
|
+
/** Compaction, edits, or changed request settings start a new full-input chain. */
|
|
18
|
+
export declare const incrementalInput: (payload: ResponsesPayload, previous: ResponseContinuation) => ReadonlyArray<InputItem> | undefined;
|
|
19
|
+
//# sourceMappingURL=continuation.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"continuation.d.ts","sourceRoot":"","sources":["../../../src/providers/openai-responses/continuation.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,6BAA6B,CAAA;AAClE,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAC3C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAA;AAGpD,MAAM,WAAW,oBAAoB;IACnC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;IACrC,QAAQ,CAAC,YAAY,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;CAChD;AAED,yFAAyF;AACzF,eAAO,MAAM,oBAAoB,iDAK9B;IACD,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAA;IAClC,QAAQ,CAAC,OAAO,EAAE,eAAe,CAAA;IACjC,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAA;IAC3B,QAAQ,CAAC,UAAU,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;CACzC,KAAG,oBAAoB,GAAG,SAmB1B,CAAA;AAED,mFAAmF;AACnF,eAAO,MAAM,gBAAgB,YAClB,gBAAgB,YACf,oBAAoB,KAC7B,aAAa,CAAC,SAAS,CAAC,GAAG,SAS7B,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { responseItems } from "./stored-items.js";
|
|
2
|
+
/** Canonical replay prefix, with locally answered searches still awaiting submission. */
|
|
3
|
+
export const responseContinuation = ({ payload, message, responseId, asyncTools }) => {
|
|
4
|
+
const output = responseItems({
|
|
5
|
+
role: "assistant",
|
|
6
|
+
tool_calls: message.tool_calls ?? [],
|
|
7
|
+
...(message.provider_state === undefined ? {} : { provider_state: message.provider_state })
|
|
8
|
+
}, asyncTools);
|
|
9
|
+
if (output === undefined)
|
|
10
|
+
return undefined;
|
|
11
|
+
const { input: _, stream: __, ...properties } = payload;
|
|
12
|
+
return {
|
|
13
|
+
responseId,
|
|
14
|
+
properties: JSON.stringify(properties),
|
|
15
|
+
input: [...payload.input, ...output].map((item) => JSON.stringify(item)),
|
|
16
|
+
pendingInput: output.filter((item) => item.type === "tool_search_output" && item.execution === "client")
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
/** Compaction, edits, or changed request settings start a new full-input chain. */
|
|
20
|
+
export const incrementalInput = (payload, previous) => {
|
|
21
|
+
const { input, stream: _, ...properties } = payload;
|
|
22
|
+
if (JSON.stringify(properties) !== previous.properties ||
|
|
23
|
+
input.length < previous.input.length ||
|
|
24
|
+
previous.input.some((item, index) => item !== JSON.stringify(input[index])))
|
|
25
|
+
return undefined;
|
|
26
|
+
return [...previous.pendingInput, ...input.slice(previous.input.length)];
|
|
27
|
+
};
|
|
28
|
+
//# sourceMappingURL=continuation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"continuation.js","sourceRoot":"","sources":["../../../src/providers/openai-responses/continuation.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAA;AASjD,yFAAyF;AACzF,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,EACnC,OAAO,EACP,OAAO,EACP,UAAU,EACV,UAAU,EAMX,EAAoC,EAAE;IACrC,MAAM,MAAM,GAAG,aAAa,CAC1B;QACE,IAAI,EAAE,WAAW;QACjB,UAAU,EAAE,OAAO,CAAC,UAAU,IAAI,EAAE;QACpC,GAAG,CAAC,OAAO,CAAC,cAAc,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,cAAc,EAAE,OAAO,CAAC,cAAc,EAAE,CAAC;KAC5F,EACD,UAAU,CACX,CAAA;IACD,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,SAAS,CAAA;IAC1C,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,GAAG,UAAU,EAAE,GAAG,OAAO,CAAA;IACvD,OAAO;QACL,UAAU;QACV,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC;QACtC,KAAK,EAAE,CAAC,GAAG,OAAO,CAAC,KAAK,EAAE,GAAG,MAAM,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QACxE,YAAY,EAAE,MAAM,CAAC,MAAM,CACzB,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,oBAAoB,IAAI,IAAI,CAAC,SAAS,KAAK,QAAQ,CAC5E;KACF,CAAA;AACH,CAAC,CAAA;AAED,mFAAmF;AACnF,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,OAAyB,EACzB,QAA8B,EACQ,EAAE;IACxC,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,GAAG,UAAU,EAAE,GAAG,OAAO,CAAA;IACnD,IACE,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,QAAQ,CAAC,UAAU;QAClD,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,MAAM;QACpC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC;QAE3E,OAAO,SAAS,CAAA;IAClB,OAAO,CAAC,GAAG,QAAQ,CAAC,YAAY,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAA;AAC1E,CAAC,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { ProviderErrorCode } from "../../errors.js";
|
|
2
|
+
import { HttpStatusError, ProviderError } from "../kit/index.js";
|
|
3
|
+
/** The public failure type of this provider. Deliberately NOT a LoopError. */
|
|
4
|
+
export declare class OpenAiResponsesProviderError extends ProviderError {
|
|
5
|
+
readonly name = "OpenAiResponsesProviderError";
|
|
6
|
+
constructor(message: string, code?: ProviderErrorCode);
|
|
7
|
+
}
|
|
8
|
+
/** How much of a rejection body is worth carrying into the error message. */
|
|
9
|
+
export declare const MAX_STATUS_DETAIL_CHARS = 600;
|
|
10
|
+
/**
|
|
11
|
+
* The response failures OpenAI names itself, mapped onto the host taxonomy.
|
|
12
|
+
* Membership is also what makes a `response.failed` terminal: anything not
|
|
13
|
+
* listed here is a missing, new, overloaded, or server-side code that spends
|
|
14
|
+
* the retry budget instead.
|
|
15
|
+
*/
|
|
16
|
+
export declare const TERMINAL_RESPONSE_CODES: Readonly<Record<string, ProviderErrorCode>>;
|
|
17
|
+
/** The failure code of a non-OK HTTP status, from the body when one was read. */
|
|
18
|
+
export declare const statusFailureCode: (status: number, detail: string | null) => ProviderErrorCode;
|
|
19
|
+
/**
|
|
20
|
+
* A non-OK HTTP status, carrying the retry-after headers and — when the caller
|
|
21
|
+
* could read one — what the provider actually said. A bare status is nearly
|
|
22
|
+
* useless for a 400: the reason a request was rejected lives only in its body.
|
|
23
|
+
*/
|
|
24
|
+
export declare class StatusError extends HttpStatusError {
|
|
25
|
+
readonly detail: string | null;
|
|
26
|
+
constructor(status: number, retryAfter: string | null, retryAfterMs?: string | null, detail?: string | null);
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../../src/providers/openai-responses/errors.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAGhE,8EAA8E;AAC9E,qBAAa,4BAA6B,SAAQ,aAAa;IAC7D,SAAkB,IAAI,kCAAiC;IAEvD,YAAY,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,iBAAoC,EAEtE;CACF;AAED,6EAA6E;AAC7E,eAAO,MAAM,uBAAuB,MAAM,CAAA;AAE1C;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,iBAAiB,CAAC,CAW/E,CAAA;AA4CD,iFAAiF;AACjF,eAAO,MAAM,iBAAiB,WAAY,MAAM,UAAU,MAAM,GAAG,IAAI,KAAG,iBAgBzE,CAAA;AAED;;;;GAIG;AACH,qBAAa,WAAY,SAAQ,eAAe;IAC9C,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;IAE9B,YACE,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,MAAM,GAAG,IAAI,EACzB,YAAY,GAAE,MAAM,GAAG,IAAW,EAClC,MAAM,GAAE,MAAM,GAAG,IAAW,EAU7B;CACF"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { retryableStatus } from "@arden-hq/std/retry";
|
|
2
|
+
import { clipLine } from "@arden-hq/std/text";
|
|
3
|
+
import { HttpStatusError, ProviderError } from "../kit/index.js";
|
|
4
|
+
import { asRecord, stringValue } from "./items.js";
|
|
5
|
+
/** The public failure type of this provider. Deliberately NOT a LoopError. */
|
|
6
|
+
export class OpenAiResponsesProviderError extends ProviderError {
|
|
7
|
+
name = "OpenAiResponsesProviderError";
|
|
8
|
+
constructor(message, code = "provider_error") {
|
|
9
|
+
super(message, { code, retryable: false });
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
/** How much of a rejection body is worth carrying into the error message. */
|
|
13
|
+
export const MAX_STATUS_DETAIL_CHARS = 600;
|
|
14
|
+
/**
|
|
15
|
+
* The response failures OpenAI names itself, mapped onto the host taxonomy.
|
|
16
|
+
* Membership is also what makes a `response.failed` terminal: anything not
|
|
17
|
+
* listed here is a missing, new, overloaded, or server-side code that spends
|
|
18
|
+
* the retry budget instead.
|
|
19
|
+
*/
|
|
20
|
+
export const TERMINAL_RESPONSE_CODES = {
|
|
21
|
+
bio_policy: "provider_error",
|
|
22
|
+
content_filter: "provider_error",
|
|
23
|
+
context_length_exceeded: "context_length_exceeded",
|
|
24
|
+
cyber_policy: "provider_error",
|
|
25
|
+
insufficient_quota: "rate_limited",
|
|
26
|
+
invalid_prompt: "provider_error",
|
|
27
|
+
invalid_request_error: "request_invalid",
|
|
28
|
+
misalignment_policy_violation: "provider_error",
|
|
29
|
+
model_not_found: "model_unavailable",
|
|
30
|
+
usage_not_included: "provider_error"
|
|
31
|
+
};
|
|
32
|
+
/**
|
|
33
|
+
* A context overflow that a rejection reports only in prose. OpenAI omits the
|
|
34
|
+
* `context_length_exceeded` code on some rejections and says it in the message
|
|
35
|
+
* instead; the host taxonomy still has to see one class, not two.
|
|
36
|
+
*/
|
|
37
|
+
const CONTEXT_OVERFLOW_PROSE = /context (?:length|window)/i;
|
|
38
|
+
/**
|
|
39
|
+
* A refusal of the model itself, in prose. The Codex backend answers a model
|
|
40
|
+
* the ChatGPT sign-in may not use with a bare `{"detail": "The '<model>'
|
|
41
|
+
* model is not supported when using Codex with a ChatGPT account."}`, and the
|
|
42
|
+
* Platform API says "The model `<model>` does not exist or you do not have
|
|
43
|
+
* access to it." Only the provider's own sentence is read, never the request
|
|
44
|
+
* echo around it.
|
|
45
|
+
*/
|
|
46
|
+
const MODEL_UNAVAILABLE_PROSE = /\bmodel\b.{0,80}?\b(?:is not supported|does not exist|is not available|not found)\b/i;
|
|
47
|
+
const rejection = (detail) => {
|
|
48
|
+
const none = { code: undefined, type: undefined, message: undefined };
|
|
49
|
+
if (detail === null)
|
|
50
|
+
return none;
|
|
51
|
+
let decoded;
|
|
52
|
+
try {
|
|
53
|
+
decoded = JSON.parse(detail);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
return none;
|
|
57
|
+
}
|
|
58
|
+
const body = asRecord(decoded);
|
|
59
|
+
const error = asRecord(body?.error);
|
|
60
|
+
return {
|
|
61
|
+
code: stringValue(error?.code) ?? undefined,
|
|
62
|
+
type: stringValue(error?.type) ?? undefined,
|
|
63
|
+
message: stringValue(error?.message) ?? stringValue(body?.detail) ?? undefined
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
/** The failure code of a non-OK HTTP status, from the body when one was read. */
|
|
67
|
+
export const statusFailureCode = (status, detail) => {
|
|
68
|
+
const refused = rejection(detail);
|
|
69
|
+
const declared = TERMINAL_RESPONSE_CODES[refused.code ?? ""];
|
|
70
|
+
if (declared !== undefined)
|
|
71
|
+
return declared;
|
|
72
|
+
if (detail !== null && CONTEXT_OVERFLOW_PROSE.test(detail))
|
|
73
|
+
return "context_length_exceeded";
|
|
74
|
+
if ((status === 400 || status === 403 || status === 404) &&
|
|
75
|
+
refused.message !== undefined &&
|
|
76
|
+
MODEL_UNAVAILABLE_PROSE.test(refused.message))
|
|
77
|
+
return "model_unavailable";
|
|
78
|
+
if (status === 400 && refused.type === "invalid_request_error")
|
|
79
|
+
return "request_invalid";
|
|
80
|
+
if (status === 401 || status === 403)
|
|
81
|
+
return "provider_auth";
|
|
82
|
+
if (status === 429)
|
|
83
|
+
return "rate_limited";
|
|
84
|
+
if (retryableStatus(status))
|
|
85
|
+
return "provider_unavailable";
|
|
86
|
+
return "provider_error";
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* A non-OK HTTP status, carrying the retry-after headers and — when the caller
|
|
90
|
+
* could read one — what the provider actually said. A bare status is nearly
|
|
91
|
+
* useless for a 400: the reason a request was rejected lives only in its body.
|
|
92
|
+
*/
|
|
93
|
+
export class StatusError extends HttpStatusError {
|
|
94
|
+
detail;
|
|
95
|
+
constructor(status, retryAfter, retryAfterMs = null, detail = null) {
|
|
96
|
+
const trimmed = detail === null ? null : clipLine(detail, MAX_STATUS_DETAIL_CHARS) || null;
|
|
97
|
+
super(trimmed === null
|
|
98
|
+
? `OpenAI request failed with status ${status}`
|
|
99
|
+
: `OpenAI request failed with status ${status}: ${trimmed}`, { status, retryAfter, retryAfterMs, code: statusFailureCode(status, trimmed) });
|
|
100
|
+
this.detail = trimmed;
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../../src/providers/openai-responses/errors.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { InputItem } from "./items.js";
|
|
2
|
+
export interface InputBatch {
|
|
3
|
+
readonly items: ReadonlyArray<InputItem>;
|
|
4
|
+
readonly deferWhileCallsPending: boolean;
|
|
5
|
+
}
|
|
6
|
+
/** Reject malformed durable runtime-tool history before it reaches OpenAI. */
|
|
7
|
+
export declare function validateFunctionCallHistory(batches: ReadonlyArray<InputBatch>): ReadonlyArray<InputItem>;
|
|
8
|
+
//# sourceMappingURL=history.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"history.d.ts","sourceRoot":"","sources":["../../../src/providers/openai-responses/history.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAA;AAG3C,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC,SAAS,CAAC,CAAA;IACxC,QAAQ,CAAC,sBAAsB,EAAE,OAAO,CAAA;CACzC;AAED,8EAA8E;AAC9E,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,aAAa,CAAC,UAAU,CAAC,GACjC,aAAa,CAAC,SAAS,CAAC,CA2F1B"}
|