docs: document memory batch helpers

This commit is contained in:
Peter Steinberger
2026-06-04 01:31:52 -04:00
parent 8b6bed9c9c
commit c40dd6ff5c
8 changed files with 40 additions and 0 deletions

View File

@@ -1,5 +1,8 @@
import { formatErrorMessage } from "./error-utils.js";
// Extracts provider batch error text from output and unavailable error files.
/** Minimal batch output line shape that can carry provider error messages. */
type BatchOutputErrorLike = {
error?: { message?: string };
response?: {
@@ -11,6 +14,7 @@ type BatchOutputErrorLike = {
};
};
/** Pull a nested response error message without assuming a fixed provider body shape. */
function getResponseErrorMessage(line: BatchOutputErrorLike | undefined): string | undefined {
const body = line?.response?.body;
if (typeof body === "string") {
@@ -22,11 +26,13 @@ function getResponseErrorMessage(line: BatchOutputErrorLike | undefined): string
return typeof body.error?.message === "string" ? body.error.message : undefined;
}
/** Return the first useful error message from batch output lines. */
export function extractBatchErrorMessage(lines: BatchOutputErrorLike[]): string | undefined {
const first = lines.find((line) => line.error?.message || getResponseErrorMessage(line));
return first?.error?.message ?? getResponseErrorMessage(first);
}
/** Format a failed error-file read without hiding the underlying read problem. */
export function formatUnavailableBatchError(err: unknown): string | undefined {
const message = formatErrorMessage(err);
return message ? `error file unavailable: ${message}` : undefined;

View File

@@ -2,6 +2,9 @@ import { postJson } from "./post-json.js";
import { retryAsync } from "./retry-utils.js";
import type { SsrFPolicy } from "./ssrf-policy.js";
// JSON POST helper for batch APIs with provider-style transient retry.
/** POST JSON and retry provider 429/5xx failures with bounded backoff. */
export async function postJsonWithRetry<T>(params: {
url: string;
headers: Record<string, string>;

View File

@@ -1,3 +1,6 @@
// Parses provider batch output lines into the custom-id embedding map.
/** Minimal OpenAI-compatible embedding batch output line. */
export type EmbeddingBatchOutputLine = {
custom_id?: string;
error?: { message?: string };
@@ -14,6 +17,7 @@ export type EmbeddingBatchOutputLine = {
};
};
/** Apply one output line, collecting errors and successful embeddings by custom id. */
export function applyEmbeddingBatchOutputLine(params: {
line: EmbeddingBatchOutputLine;
remaining: Set<string>;

View File

@@ -1,5 +1,8 @@
import type { EmbeddingBatchOutputLine } from "./batch-output.js";
// Common OpenAI-compatible batch shapes shared by remote embedding providers.
/** Minimal provider batch status payload used by polling code. */
export type EmbeddingBatchStatus = {
id?: string;
status?: string;
@@ -7,6 +10,8 @@ export type EmbeddingBatchStatus = {
error_file_id?: string | null;
};
/** Provider output line after an embedding batch file is read. */
export type ProviderBatchOutputLine = EmbeddingBatchOutputLine;
/** OpenAI-compatible endpoint used inside embedding batch request lines. */
export const EMBEDDING_BATCH_ENDPOINT = "/v1/embeddings";

View File

@@ -2,6 +2,9 @@ import { resolveSafeTimeoutDelayMs } from "../../../gateway-client/src/timeouts.
import { splitBatchRequests } from "./batch-utils.js";
import { runWithConcurrency } from "./internal.js";
// Shared runner for splitting and executing remote embedding batch groups.
/** Execution controls for provider embedding batch submissions and polling. */
export type EmbeddingBatchExecutionParams = {
wait: boolean;
pollIntervalMs: number;
@@ -10,6 +13,7 @@ export type EmbeddingBatchExecutionParams = {
debug?: (message: string, data?: Record<string, unknown>) => void;
};
/** Clamp polling to both configured poll interval and total timeout budget. */
function resolveEmbeddingBatchPollIntervalMs(params: {
pollIntervalMs: number;
timeoutMs: number;
@@ -24,6 +28,7 @@ function resolveEmbeddingBatchPollIntervalMs(params: {
return Math.min(safePollIntervalMs, safeTimeoutMs);
}
/** Run request groups with bounded concurrency and return embeddings by custom id. */
export async function runEmbeddingBatchGroups<TRequest>(params: {
requests: TRequest[];
maxRequests: number;
@@ -72,6 +77,7 @@ export async function runEmbeddingBatchGroups<TRequest>(params: {
return byCustomId;
}
/** Build normalized batch-group options for provider-specific runners. */
export function buildEmbeddingBatchGroupOptions<TRequest>(
params: { requests: TRequest[] } & EmbeddingBatchExecutionParams,
options: { maxRequests: number; debugLabel: string },

View File

@@ -1,5 +1,8 @@
// Batch status helpers shared by remote embedding providers.
const TERMINAL_FAILURE_STATES = new Set(["failed", "expired", "cancelled", "canceled"]);
/** Minimal provider batch status used for completion and terminal-failure checks. */
type BatchStatusLike = {
id?: string;
status?: string;
@@ -7,11 +10,13 @@ type BatchStatusLike = {
error_file_id?: string | null;
};
/** File ids returned once a batch has completed. */
export type BatchCompletionResult = {
outputFileId: string;
errorFileId?: string;
};
/** Convert a completed provider status payload into output/error file ids. */
export function resolveBatchCompletionFromStatus(params: {
provider: string;
batchId: string;
@@ -26,6 +31,7 @@ export function resolveBatchCompletionFromStatus(params: {
};
}
/** Throw when a provider reports a terminal failure, including error-file detail if available. */
export async function throwIfBatchTerminalFailure(params: {
provider: string;
status: BatchStatusLike;
@@ -42,6 +48,7 @@ export async function throwIfBatchTerminalFailure(params: {
throw new Error(`${params.provider} batch ${params.status.id ?? "<unknown>"} ${state}${suffix}`);
}
/** Resolve the completed batch files, optionally waiting according to caller policy. */
export async function resolveCompletedBatchResult(params: {
provider: string;
status: BatchStatusLike;

View File

@@ -7,6 +7,9 @@ import { hashText } from "./hash.js";
import { withRemoteHttpResponse } from "./remote-http.js";
import { readResponseJsonWithLimit, readResponseTextSnippet } from "./response-snippet.js";
// Uploads provider batch JSONL payloads through the shared remote HTTP guard.
/** Upload embedding batch requests and return the provider file id. */
export async function uploadBatchJsonlFile(params: {
client: BatchHttpClientConfig;
requests: unknown[];

View File

@@ -1,15 +1,20 @@
import type { SsrFPolicy } from "./ssrf-policy.js";
// Common HTTP and grouping helpers for remote embedding batch clients.
/** Minimal HTTP client config needed by batch providers. */
export type BatchHttpClientConfig = {
baseUrl?: string;
headers?: Record<string, string>;
ssrfPolicy?: SsrFPolicy;
};
/** Normalize batch API base URLs by removing one trailing slash. */
export function normalizeBatchBaseUrl(client: BatchHttpClientConfig): string {
return client.baseUrl?.replace(/\/$/, "") ?? "";
}
/** Build request headers, preserving caller auth and controlling JSON/form content type. */
export function buildBatchHeaders(
client: Pick<BatchHttpClientConfig, "headers">,
params: { json: boolean },
@@ -26,6 +31,7 @@ export function buildBatchHeaders(
return headers;
}
/** Split provider requests into max-sized groups while preserving order. */
export function splitBatchRequests<T>(requests: T[], maxRequests: number): T[][] {
if (requests.length <= maxRequests) {
return [requests];