Skip to content

Commit d8692c4

Browse files
committed
refactor: resolve request defaults once in embedTexts
1 parent fbb8e75 commit d8692c4

2 files changed

Lines changed: 21 additions & 17 deletions

File tree

‎src/embed.ts‎

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,16 @@
11
import { type } from "arktype";
22
import {
33
classifyProtocolMismatch,
4+
createDefaultRetryPolicy,
45
createDefaultScheduler,
56
type BuiltRequest,
67
} from "@intx/inference";
78
import type { RetryPolicy } from "@intx/types/runtime";
89

910
import {
11+
DEFAULT_TIMEOUT_MS,
1012
EmbeddingRequestError,
13+
extractRetryAfterMs,
1114
runJSONRequest,
1215
type RequestDependencies,
1316
type RetryAfterExtractor,
@@ -58,10 +61,12 @@ const PROBE_TEXT = "embedding dimension probe";
5861
export type EmbedOptions = {
5962
/** Defaults to global `fetch` and Interchange's default scheduler. */
6063
deps?: RequestDependencies;
64+
/** Defaults to Interchange's policy: back off retryables, abort the rest. */
6165
retryPolicy?: RetryPolicy;
6266
/**
6367
* Reads `Retry-After` off a failed response, for a provider that signals
64-
* pacing its own way. Named after `ProviderAdapter.extractRetryAfterMs`.
68+
* pacing its own way. Defaults to seconds or HTTP-date parsing. Named
69+
* after `ProviderAdapter.extractRetryAfterMs`.
6570
* There is no adapter object here because every provider serves the one
6671
* `/v1/embeddings` shape, so this hangs off the options instead.
6772
*/
@@ -187,13 +192,17 @@ export async function embedTexts(
187192
scheduler: createDefaultScheduler(),
188193
};
189194

195+
const retryPolicy = options.retryPolicy ?? createDefaultRetryPolicy();
196+
const timeoutMs = valid.timeoutMs ?? DEFAULT_TIMEOUT_MS;
197+
const extractRetryAfter = options.extractRetryAfterMs ?? extractRetryAfterMs;
198+
190199
const vectors: number[][] = [];
191200
for (const batch of batches(texts, valid.batchSize ?? DEFAULT_BATCH_SIZE)) {
192201
const request = buildRequest(valid, batch);
193202
const body = await runJSONRequest(request, deps, {
194-
retryPolicy: options.retryPolicy,
195-
timeoutMs: valid.timeoutMs,
196-
extractRetryAfterMs: options.extractRetryAfterMs,
203+
retryPolicy,
204+
timeoutMs,
205+
extractRetryAfterMs: extractRetryAfter,
197206
signal: options.signal,
198207
});
199208
vectors.push(...parseResponse(body, request.url, batch.length));

‎src/request.ts‎

Lines changed: 8 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import {
33
classifyHTTPError,
44
classifyNetworkError,
55
classifyProtocolMismatch,
6-
createDefaultRetryPolicy,
76
type BuiltRequest,
87
type Dependencies,
98
} from "@intx/inference";
@@ -43,28 +42,26 @@ export class EmbeddingRequestError extends Error {
4342
export type RetryAfterExtractor = (headers: Headers) => number | undefined;
4443

4544
type RunRequestOptions = {
46-
/** Defaults to Interchange's policy: back off retryables, abort the rest. */
47-
retryPolicy: RetryPolicy | undefined;
45+
retryPolicy: RetryPolicy;
4846
/**
4947
* Per-attempt ceiling, enforced alongside any caller `signal` rather than
5048
* instead of it. A cold local model can take a while to page in.
5149
*/
52-
timeoutMs: number | undefined;
50+
timeoutMs: number;
5351
/**
5452
* Reads `Retry-After` off a failed response. Mirrors `ProviderAdapter`'s
5553
* member of the same name, so a provider that signals pacing its own way can
56-
* override without touching the transport. Defaults to
57-
* {@link extractRetryAfterMs}.
54+
* override without touching the transport.
5855
*/
59-
extractRetryAfterMs: RetryAfterExtractor | undefined;
56+
extractRetryAfterMs: RetryAfterExtractor;
6057
signal: AbortSignal | undefined;
6158
};
6259

6360
type Attempt =
6461
| { ok: true; body: unknown }
6562
| { ok: false; error: InferenceError };
6663

67-
const DEFAULT_TIMEOUT_MS = 30_000;
64+
export const DEFAULT_TIMEOUT_MS = 30_000;
6865

6966
/**
7067
* `Retry-After` in seconds or as an HTTP date; undefined when absent.
@@ -77,7 +74,7 @@ const DEFAULT_TIMEOUT_MS = 30_000;
7774
* absolute instant, so it cannot be resolved against the harness scheduler's
7875
* virtual clock. Upstream's extractor has the same constraint.
7976
*/
80-
const extractRetryAfterMs: RetryAfterExtractor = (headers) => {
77+
export const extractRetryAfterMs: RetryAfterExtractor = (headers) => {
8178
const header = headers.get("retry-after")?.trim();
8279
if (header === undefined || header === "") return undefined;
8380

@@ -194,10 +191,8 @@ export async function runJSONRequest(
194191
deps: RequestDependencies,
195192
options: RunRequestOptions,
196193
): Promise<unknown> {
197-
const { signal } = options;
198-
const policy = options.retryPolicy ?? createDefaultRetryPolicy();
199-
const timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
200-
const extractRetryAfter = options.extractRetryAfterMs ?? extractRetryAfterMs;
194+
const { retryPolicy: policy, timeoutMs, signal } = options;
195+
const extractRetryAfter = options.extractRetryAfterMs;
201196

202197
// Time comes from the harness scheduler, not globals, so a virtual-clock
203198
// test scheduler drives the retry loop deterministically.

0 commit comments

Comments
 (0)