ag-common 0.0.911 → 0.0.913

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.
@@ -1,12 +1,10 @@
1
1
  export * from "./acm";
2
- export * from "./ai";
3
2
  export * from "./api";
4
3
  export * from "./apigw";
5
4
  export * from "./aws";
6
5
  export * from "./cosmos";
7
6
  export * from "./dynamo";
8
7
  export * from "./enforceDynamoProvisionCap";
9
- export * from "./google";
10
8
  export * from "./retryOnError";
11
9
  export * from "./s3";
12
10
  export * from "./ses";
@@ -15,14 +15,12 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./acm"), exports);
18
- __exportStar(require("./ai"), exports);
19
18
  __exportStar(require("./api"), exports);
20
19
  __exportStar(require("./apigw"), exports);
21
20
  __exportStar(require("./aws"), exports);
22
21
  __exportStar(require("./cosmos"), exports);
23
22
  __exportStar(require("./dynamo"), exports);
24
23
  __exportStar(require("./enforceDynamoProvisionCap"), exports);
25
- __exportStar(require("./google"), exports);
26
24
  __exportStar(require("./retryOnError"), exports);
27
25
  __exportStar(require("./s3"), exports);
28
26
  __exportStar(require("./ses"), exports);
@@ -2,7 +2,25 @@ export declare const overloadedMessages: string[];
2
2
  export declare const retryableErrorMessages: string[];
3
3
  export declare const isOverloadedApiKeyError: (error: unknown) => boolean;
4
4
  export declare const isRetryableApiError: (error: unknown) => boolean;
5
+ export type RetryOnErrorOptions = {
6
+ /** Number of retries after the initial attempt. Defaults to 1. */
7
+ retries?: number;
8
+ /** Delay between attempts in ms. Defaults to 2000. */
9
+ errorDelay?: number;
10
+ /** Predicate deciding whether a failure is worth retrying. */
11
+ errorCheck?: (error: unknown) => boolean;
12
+ /** AbortSignal cancelling the backoff sleep and further attempts. */
13
+ signal?: AbortSignal;
14
+ /**
15
+ * Delay before each attempt after the first, in ms. It composes with
16
+ * errorDelay: the attempt waits for initialDelayMs plus errorDelay.
17
+ * Defaults to 0 (no pacing).
18
+ */
19
+ initialDelayMs?: number;
20
+ /** Sleep implementation, overridable in tests. */
21
+ sleepFn?: (ms: number) => Promise<unknown>;
22
+ };
5
23
  export declare function retryOnError<T>(
6
24
  /** so we can log retries with useful info */
7
- debugIdent: string, fn: () => Promise<T>, retries?: number, errorDelay?: number, errorCheck?: (error: unknown) => boolean, signal?: AbortSignal): Promise<T>;
25
+ debugIdent: string, fn: () => Promise<T>, retriesOrOptions?: number | RetryOnErrorOptions, errorDelay?: number, errorCheck?: (error: unknown) => boolean, signal?: AbortSignal): Promise<T>;
8
26
  export declare const sleep: (ms: number) => Promise<unknown>;
@@ -70,19 +70,51 @@ const awaitWithSignal = async (promise, signal) => {
70
70
  });
71
71
  return Promise.race([promise, abort]);
72
72
  };
73
+ const normalizeRetryOnErrorOptions = (retriesOrOptions, errorDelay, errorCheck, signal) => ({
74
+ retries: typeof retriesOrOptions === "number" ? retriesOrOptions : (retriesOrOptions?.retries ?? 1),
75
+ errorDelay: typeof retriesOrOptions === "number"
76
+ ? (errorDelay ?? 2000)
77
+ : (retriesOrOptions?.errorDelay ?? 2000),
78
+ errorCheck: typeof retriesOrOptions === "number"
79
+ ? (errorCheck ?? exports.isRetryableApiError)
80
+ : (retriesOrOptions?.errorCheck ?? exports.isRetryableApiError),
81
+ signal: typeof retriesOrOptions === "number" ? signal : (retriesOrOptions?.signal ?? signal),
82
+ initialDelayMs: typeof retriesOrOptions === "number" ? 0 : Math.max(0, retriesOrOptions?.initialDelayMs ?? 0),
83
+ sleepFn: typeof retriesOrOptions === "number" ? undefined : retriesOrOptions?.sleepFn,
84
+ });
73
85
  async function retryOnError(
74
86
  /** so we can log retries with useful info */
75
- debugIdent, fn, retries = 1, errorDelay = 2000, errorCheck = exports.isRetryableApiError, signal) {
87
+ debugIdent, fn, retriesOrOptions, errorDelay, errorCheck = exports.isRetryableApiError, signal) {
88
+ const options = normalizeRetryOnErrorOptions(retriesOrOptions, errorDelay, errorCheck, signal);
89
+ const sleepWithSignal = async (ms) => {
90
+ if (ms <= 0)
91
+ return;
92
+ if (options.sleepFn !== undefined) {
93
+ await options.sleepFn(ms);
94
+ return;
95
+ }
96
+ await awaitWithSignal((0, exports.sleep)(ms), options.signal);
97
+ };
98
+ // Pacing delay before attempts after the first: it spreads bursty fan-out
99
+ // (e.g. nightly jobs hitting a low free-tier quota) without changing the
100
+ // retry semantics for direct callers.
101
+ await sleepWithSignal(options.initialDelayMs);
76
102
  try {
77
103
  const result = await fn();
78
104
  return result;
79
105
  }
80
106
  catch (error) {
81
107
  const message = error instanceof Error ? error.message : String(error);
82
- if (retries > 0 && errorCheck(error)) {
83
- (0, log_1.info)(`Operation ${debugIdent} failed. Retrying after ${errorDelay}ms...`, message);
84
- await awaitWithSignal((0, exports.sleep)(errorDelay), signal);
85
- return retryOnError(debugIdent, fn, retries - 1, errorDelay, errorCheck, signal);
108
+ if (options.retries > 0 && options.errorCheck(error)) {
109
+ (0, log_1.info)(`Operation ${debugIdent} failed. Retrying after ${options.errorDelay}ms...`, message);
110
+ await sleepWithSignal(options.errorDelay);
111
+ return retryOnError(debugIdent, fn, {
112
+ retries: options.retries - 1,
113
+ errorDelay: options.errorDelay,
114
+ errorCheck: options.errorCheck,
115
+ signal: options.signal,
116
+ sleepFn: options.sleepFn,
117
+ });
86
118
  }
87
119
  throw error;
88
120
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ag-common",
3
- "version": "0.0.911",
3
+ "version": "0.0.913",
4
4
  "license": "ISC",
5
5
  "author": "admin@gec.dev",
6
6
  "repository": {
@@ -1,12 +0,0 @@
1
- import type { AIClientDependencies, AIEndpoint, AIModel, AIRequest, GenerationResult } from "../types";
2
- export type CodexAdapterConfig = {
3
- endpoint: AIEndpoint;
4
- dependencies?: AIClientDependencies;
5
- timeoutMs?: number;
6
- pollIntervalMs?: number;
7
- maxPollIntervalMs?: number;
8
- };
9
- /** Validate and normalize the direct private LAN endpoint used by Codex. */
10
- export declare const normalizeCodexEndpoint: (endpoint: AIEndpoint) => AIEndpoint;
11
- export declare const generateCodex: (request: AIRequest, config: CodexAdapterConfig) => Promise<GenerationResult>;
12
- export declare const listCodexModels: (endpoint: AIEndpoint, dependencies?: AIClientDependencies) => Promise<AIModel[]>;