@vymalo/opencode-ratelimit 0.12.0 → 0.14.1

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/logging.js CHANGED
@@ -1,72 +1,68 @@
1
1
  export const LOG_LEVEL_PRIORITY = {
2
- trace: 5,
3
- debug: 10,
4
- info: 20,
5
- warn: 30,
6
- error: 40
2
+ trace: 5,
3
+ debug: 10,
4
+ info: 20,
5
+ warn: 30,
6
+ error: 40
7
7
  };
8
8
  export const DEFAULT_LOG_LEVEL = "info";
9
9
  function redactFields(fields) {
10
- if (!fields) {
11
- return undefined;
12
- }
13
- const redacted = {};
14
- for (const [key, value] of Object.entries(fields)) {
15
- if (/token|secret|password|authorization/i.test(key)) {
16
- redacted[key] = "[redacted]";
17
- continue;
18
- }
19
- redacted[key] = value;
20
- }
21
- return redacted;
10
+ if (!fields) {
11
+ return undefined;
12
+ }
13
+ const redacted = {};
14
+ for (const [key, value] of Object.entries(fields)) {
15
+ if (/token|secret|password|authorization/i.test(key)) {
16
+ redacted[key] = "[redacted]";
17
+ continue;
18
+ }
19
+ redacted[key] = value;
20
+ }
21
+ return redacted;
22
22
  }
23
23
  export function createJsonConsoleLogger(minLevel = DEFAULT_LOG_LEVEL) {
24
- const minPriority = LOG_LEVEL_PRIORITY[minLevel];
25
- const write = (level, event, fields) => {
26
- if (LOG_LEVEL_PRIORITY[level] < minPriority) {
27
- return;
28
- }
29
- const payload = {
30
- ts: new Date().toISOString(),
31
- level,
32
- event,
33
- ...(redactFields(fields) ?? {})
34
- };
35
- const line = JSON.stringify(payload);
36
- if (level === "error") {
37
- console.error(line);
38
- return;
39
- }
40
- if (level === "warn") {
41
- console.warn(line);
42
- return;
43
- }
44
- console.log(line);
45
- };
46
- return {
47
- trace: (event, fields) => write("trace", event, fields),
48
- debug: (event, fields) => write("debug", event, fields),
49
- info: (event, fields) => write("info", event, fields),
50
- warn: (event, fields) => write("warn", event, fields),
51
- error: (event, fields) => write("error", event, fields)
52
- };
24
+ const minPriority = LOG_LEVEL_PRIORITY[minLevel];
25
+ const write = (level, event, fields) => {
26
+ if (LOG_LEVEL_PRIORITY[level] < minPriority) {
27
+ return;
28
+ }
29
+ const payload = {
30
+ ts: new Date().toISOString(),
31
+ level,
32
+ event,
33
+ ...redactFields(fields) ?? {}
34
+ };
35
+ const line = JSON.stringify(payload);
36
+ if (level === "error") {
37
+ console.error(line);
38
+ return;
39
+ }
40
+ if (level === "warn") {
41
+ console.warn(line);
42
+ return;
43
+ }
44
+ console.log(line);
45
+ };
46
+ return {
47
+ trace: (event, fields) => write("trace", event, fields),
48
+ debug: (event, fields) => write("debug", event, fields),
49
+ info: (event, fields) => write("info", event, fields),
50
+ warn: (event, fields) => write("warn", event, fields),
51
+ error: (event, fields) => write("error", event, fields)
52
+ };
53
53
  }
54
54
  export function fromOpenCodeLogLevel(value) {
55
- if (typeof value !== "string") {
56
- return undefined;
57
- }
58
- switch (value.toUpperCase()) {
59
- // DEBUG unlocks the most-verbose `trace` tier (host has no finer level).
60
- case "DEBUG":
61
- return "trace";
62
- case "INFO":
63
- return "info";
64
- case "WARN":
65
- return "warn";
66
- case "ERROR":
67
- return "error";
68
- default:
69
- return undefined;
70
- }
55
+ if (typeof value !== "string") {
56
+ return undefined;
57
+ }
58
+ switch (value.toUpperCase()) {
59
+ // DEBUG unlocks the most-verbose `trace` tier (host has no finer level).
60
+ case "DEBUG": return "trace";
61
+ case "INFO": return "info";
62
+ case "WARN": return "warn";
63
+ case "ERROR": return "error";
64
+ default: return undefined;
65
+ }
71
66
  }
67
+
72
68
  //# sourceMappingURL=logging.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"logging.js","sourceRoot":"","sources":["../src/logging.ts"],"names":[],"mappings":"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"}
1
+ {"mappings":"AAIA,OAAO,MAAM,qBAA+C;CAC1D,OAAO;CACP,OAAO;CACP,MAAM;CACN,MAAM;CACN,OAAO;AACT;AAEA,OAAO,MAAM,oBAA8B;AAc3C,SAAS,aAAa,QAA2C;CAC/D,IAAI,CAAC,QAAQ;EACX,OAAO;CACT;CACA,MAAM,WAAsB,CAAC;CAC7B,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,MAAM,GAAG;EACjD,IAAI,uCAAuC,KAAK,GAAG,GAAG;GACpD,SAAS,OAAO;GAChB;EACF;EACA,SAAS,OAAO;CAClB;CACA,OAAO;AACT;AAEA,OAAO,SAAS,wBAAwB,WAAqB,mBAA2B;CACtF,MAAM,cAAc,mBAAmB;CAEvC,MAAM,SAAS,OAAiB,OAAe,WAA6B;EAC1E,IAAI,mBAAmB,SAAS,aAAa;GAC3C;EACF;EACA,MAAM,UAAU;GACd,IAAI,IAAI,KAAK,CAAC,CAAC,YAAY;GAC3B;GACA;GACA,GAAI,aAAa,MAAM,KAAK,CAAC;EAC/B;EACA,MAAM,OAAO,KAAK,UAAU,OAAO;EACnC,IAAI,UAAU,SAAS;GACrB,QAAQ,MAAM,IAAI;GAClB;EACF;EACA,IAAI,UAAU,QAAQ;GACpB,QAAQ,KAAK,IAAI;GACjB;EACF;EACA,QAAQ,IAAI,IAAI;CAClB;CAEA,OAAO;EACL,QAAQ,OAAO,WAAW,MAAM,SAAS,OAAO,MAAM;EACtD,QAAQ,OAAO,WAAW,MAAM,SAAS,OAAO,MAAM;EACtD,OAAO,OAAO,WAAW,MAAM,QAAQ,OAAO,MAAM;EACpD,OAAO,OAAO,WAAW,MAAM,QAAQ,OAAO,MAAM;EACpD,QAAQ,OAAO,WAAW,MAAM,SAAS,OAAO,MAAM;CACxD;AACF;AAEA,OAAO,SAAS,qBAAqB,OAAsC;CACzE,IAAI,OAAO,UAAU,UAAU;EAC7B,OAAO;CACT;CACA,QAAQ,MAAM,YAAY,GAA1B;;EAEE,KAAK,SACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,KAAK,QACH,OAAO;EACT,KAAK,SACH,OAAO;EACT,SACE,OAAO;CACX;AACF","names":[],"sources":["../src/logging.ts"],"version":3,"file":"logging.js","sourceRoot":""}
@@ -1,10 +1,10 @@
1
1
  import type { Plugin } from "@opencode-ai/plugin";
2
2
  import { type Logger } from "./logging.js";
3
3
  export interface OpenCodePluginFactoryOptions {
4
- logger?: Logger;
5
- fetchImpl?: typeof fetch;
6
- now?: () => number;
7
- sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
4
+ logger?: Logger;
5
+ fetchImpl?: typeof fetch;
6
+ now?: () => number;
7
+ sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
8
8
  }
9
9
  export declare function createOpencodeRatelimitPlugin(factoryOptions?: OpenCodePluginFactoryOptions): Plugin;
10
10
  export declare const OpencodeRatelimitPlugin: Plugin;
package/dist/opencode.js CHANGED
@@ -2,66 +2,61 @@ import { createJsonConsoleLogger, DEFAULT_LOG_LEVEL, fromOpenCodeLogLevel, LOG_L
2
2
  import { installRateLimiter } from "./plugin.js";
3
3
  const PLUGIN_SERVICE_NAME = "opencode-ratelimit-plugin";
4
4
  /**
5
- * Pipe plugin logs through OpenCode's `client.app.log` so they show up in the
6
- * host's structured log stream, with the JSON console as a reliable fallback.
7
- * Mirrors the pattern used by `@vymalo/opencode-oauth2` and `-models-info`.
8
- */
5
+ * Pipe plugin logs through OpenCode's `client.app.log` so they show up in the
6
+ * host's structured log stream, with the JSON console as a reliable fallback.
7
+ * Mirrors the pattern used by `@vymalo/opencode-oauth2` and `-models-info`.
8
+ */
9
9
  function createOpenCodeLogger(client, getMinLevel) {
10
- const fallback = createJsonConsoleLogger("debug");
11
- // OpenCode already captures plugin logs via client.app.log (and filters them
12
- // by its own log level). Mirroring every event to stdout on top of that just
13
- // floods the terminal, so only mirror warn/error to the JSON console by
14
- // default; set VYMALO_PLUGIN_CONSOLE_LOG=1 to restore full console output.
15
- const consoleAll = /^(1|true|yes|on)$/i.test(process.env.VYMALO_PLUGIN_CONSOLE_LOG ?? "");
16
- const write = (level, event, fields) => {
17
- if (LOG_LEVEL_PRIORITY[level] < LOG_LEVEL_PRIORITY[getMinLevel()]) {
18
- return;
19
- }
20
- if (consoleAll || level === "warn" || level === "error") {
21
- fallback[level](event, fields);
22
- }
23
- // The host's log API has no `trace` level — fold it onto `debug` so the most
24
- // verbose tier still reaches the structured stream (it's already gated above
25
- // by `getMinLevel`, which DEBUG maps to `trace`).
26
- const hostLevel = level === "trace" ? "debug" : level;
27
- void client.app
28
- .log({
29
- body: {
30
- service: PLUGIN_SERVICE_NAME,
31
- level: hostLevel,
32
- message: event,
33
- extra: fields
34
- }
35
- })
36
- .catch(() => {
37
- /* best-effort */
38
- });
39
- };
40
- return {
41
- trace: (event, fields) => write("trace", event, fields),
42
- debug: (event, fields) => write("debug", event, fields),
43
- info: (event, fields) => write("info", event, fields),
44
- warn: (event, fields) => write("warn", event, fields),
45
- error: (event, fields) => write("error", event, fields)
46
- };
10
+ const fallback = createJsonConsoleLogger("debug");
11
+ // OpenCode already captures plugin logs via client.app.log (and filters them
12
+ // by its own log level). Mirroring every event to stdout on top of that just
13
+ // floods the terminal, so only mirror warn/error to the JSON console by
14
+ // default; set VYMALO_PLUGIN_CONSOLE_LOG=1 to restore full console output.
15
+ const consoleAll = /^(1|true|yes|on)$/i.test(process.env.VYMALO_PLUGIN_CONSOLE_LOG ?? "");
16
+ const write = (level, event, fields) => {
17
+ if (LOG_LEVEL_PRIORITY[level] < LOG_LEVEL_PRIORITY[getMinLevel()]) {
18
+ return;
19
+ }
20
+ if (consoleAll || level === "warn" || level === "error") {
21
+ fallback[level](event, fields);
22
+ }
23
+ // The host's log API has no `trace` level — fold it onto `debug` so the most
24
+ // verbose tier still reaches the structured stream (it's already gated above
25
+ // by `getMinLevel`, which DEBUG maps to `trace`).
26
+ const hostLevel = level === "trace" ? "debug" : level;
27
+ void client.app.log({ body: {
28
+ service: PLUGIN_SERVICE_NAME,
29
+ level: hostLevel,
30
+ message: event,
31
+ extra: fields
32
+ } }).catch(() => {
33
+ /* best-effort */
34
+ });
35
+ };
36
+ return {
37
+ trace: (event, fields) => write("trace", event, fields),
38
+ debug: (event, fields) => write("debug", event, fields),
39
+ info: (event, fields) => write("info", event, fields),
40
+ warn: (event, fields) => write("warn", event, fields),
41
+ error: (event, fields) => write("error", event, fields)
42
+ };
47
43
  }
48
44
  export function createOpencodeRatelimitPlugin(factoryOptions = {}) {
49
- return async ({ client }) => {
50
- let currentLogLevel = DEFAULT_LOG_LEVEL;
51
- const logger = factoryOptions.logger ?? createOpenCodeLogger(client, () => currentLogLevel);
52
- return {
53
- config: async (config) => {
54
- currentLogLevel = fromOpenCodeLogLevel(config.logLevel) ?? DEFAULT_LOG_LEVEL;
55
- installRateLimiter(config, {
56
- logger,
57
- fetchImpl: factoryOptions.fetchImpl,
58
- now: factoryOptions.now,
59
- sleep: factoryOptions.sleep
60
- });
61
- }
62
- };
63
- };
45
+ return async ({ client }) => {
46
+ let currentLogLevel = DEFAULT_LOG_LEVEL;
47
+ const logger = factoryOptions.logger ?? createOpenCodeLogger(client, () => currentLogLevel);
48
+ return { config: async (config) => {
49
+ currentLogLevel = fromOpenCodeLogLevel(config.logLevel) ?? DEFAULT_LOG_LEVEL;
50
+ installRateLimiter(config, {
51
+ logger,
52
+ fetchImpl: factoryOptions.fetchImpl,
53
+ now: factoryOptions.now,
54
+ sleep: factoryOptions.sleep
55
+ });
56
+ } };
57
+ };
64
58
  }
65
59
  export const OpencodeRatelimitPlugin = createOpencodeRatelimitPlugin();
66
60
  export default OpencodeRatelimitPlugin;
61
+
67
62
  //# sourceMappingURL=opencode.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"opencode.js","sourceRoot":"","sources":["../src/opencode.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,oBAAoB,EAEpB,kBAAkB,EAGnB,MAAM,cAAc,CAAC;AACtB,OAAO,EAA2B,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAE1E,MAAM,mBAAmB,GAAG,2BAA2B,CAAC;AAWxD;;;;GAIG;AACH,SAAS,oBAAoB,CAAC,MAA6B,EAAE,WAA2B;IACtF,MAAM,QAAQ,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAC;IAClD,6EAA6E;IAC7E,6EAA6E;IAC7E,wEAAwE;IACxE,2EAA2E;IAC3E,MAAM,UAAU,GAAG,oBAAoB,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,IAAI,EAAE,CAAC,CAAC;IAE1F,MAAM,KAAK,GAAG,CAAC,KAAe,EAAE,KAAa,EAAE,MAAkB,EAAE,EAAE;QACnE,IAAI,kBAAkB,CAAC,KAAK,CAAC,GAAG,kBAAkB,CAAC,WAAW,EAAE,CAAC,EAAE,CAAC;YAClE,OAAO;QACT,CAAC;QACD,IAAI,UAAU,IAAI,KAAK,KAAK,MAAM,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;YACxD,QAAQ,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QACjC,CAAC;QACD,6EAA6E;QAC7E,6EAA6E;QAC7E,kDAAkD;QAClD,MAAM,SAAS,GAAG,KAAK,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC;QACtD,KAAK,MAAM,CAAC,GAAG;aACZ,GAAG,CAAC;YACH,IAAI,EAAE;gBACJ,OAAO,EAAE,mBAAmB;gBAC5B,KAAK,EAAE,SAAS;gBAChB,OAAO,EAAE,KAAK;gBACd,KAAK,EAAE,MAAM;aACd;SACF,CAAC;aACD,KAAK,CAAC,GAAG,EAAE;YACV,iBAAiB;QACnB,CAAC,CAAC,CAAC;IACP,CAAC,CAAC;IAEF,OAAO;QACL,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC;QACvD,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC;QACvD,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC;QACrD,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,KAAK,EAAE,MAAM,CAAC;QACrD,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC;KACxD,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,6BAA6B,CAC3C,iBAA+C,EAAE;IAEjD,OAAO,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;QAC1B,IAAI,eAAe,GAAa,iBAAiB,CAAC;QAClD,MAAM,MAAM,GAAG,cAAc,CAAC,MAAM,IAAI,oBAAoB,CAAC,MAAM,EAAE,GAAG,EAAE,CAAC,eAAe,CAAC,CAAC;QAE5F,OAAO;YACL,MAAM,EAAE,KAAK,EAAE,MAAsB,EAAE,EAAE;gBACvC,eAAe,GAAG,oBAAoB,CAAC,MAAM,CAAC,QAAQ,CAAC,IAAI,iBAAiB,CAAC;gBAC7E,kBAAkB,CAAC,MAA4B,EAAE;oBAC/C,MAAM;oBACN,SAAS,EAAE,cAAc,CAAC,SAAS;oBACnC,GAAG,EAAE,cAAc,CAAC,GAAG;oBACvB,KAAK,EAAE,cAAc,CAAC,KAAK;iBAC5B,CAAC,CAAC;YACL,CAAC;SACF,CAAC;IACJ,CAAC,CAAC;AACJ,CAAC;AAED,MAAM,CAAC,MAAM,uBAAuB,GAAG,6BAA6B,EAAE,CAAC;AAEvE,eAAe,uBAAuB,CAAC"}
1
+ {"mappings":"AAEA,SACE,yBACA,mBACA,sBAEA,0BAGK;AACP,SAAkC,0BAA0B;AAE5D,MAAM,sBAAsB;;;;;;AAgB5B,SAAS,qBAAqB,QAA+B,aAAqC;CAChG,MAAM,WAAW,wBAAwB,OAAO;;;;;CAKhD,MAAM,aAAa,qBAAqB,KAAK,QAAQ,IAAI,6BAA6B,EAAE;CAExF,MAAM,SAAS,OAAiB,OAAe,WAAuB;EACpE,IAAI,mBAAmB,SAAS,mBAAmB,YAAY,IAAI;GACjE;EACF;EACA,IAAI,cAAc,UAAU,UAAU,UAAU,SAAS;GACvD,SAAS,MAAM,CAAC,OAAO,MAAM;EAC/B;;;;EAIA,MAAM,YAAY,UAAU,UAAU,UAAU;EAChD,KAAK,OAAO,IACT,IAAI,EACH,MAAM;GACJ,SAAS;GACT,OAAO;GACP,SAAS;GACT,OAAO;EACT,EACF,CAAC,CAAC,CACD,YAAY;;EAEb,CAAC;CACL;CAEA,OAAO;EACL,QAAQ,OAAO,WAAW,MAAM,SAAS,OAAO,MAAM;EACtD,QAAQ,OAAO,WAAW,MAAM,SAAS,OAAO,MAAM;EACtD,OAAO,OAAO,WAAW,MAAM,QAAQ,OAAO,MAAM;EACpD,OAAO,OAAO,WAAW,MAAM,QAAQ,OAAO,MAAM;EACpD,QAAQ,OAAO,WAAW,MAAM,SAAS,OAAO,MAAM;CACxD;AACF;AAEA,OAAO,SAAS,8BACd,iBAA+C,CAAC,GACxC;CACR,OAAO,OAAO,EAAE,aAAa;EAC3B,IAAI,kBAA4B;EAChC,MAAM,SAAS,eAAe,UAAU,qBAAqB,cAAc,eAAe;EAE1F,OAAO,EACL,QAAQ,OAAO,WAA2B;GACxC,kBAAkB,qBAAqB,OAAO,QAAQ,KAAK;GAC3D,mBAAmB,QAA8B;IAC/C;IACA,WAAW,eAAe;IAC1B,KAAK,eAAe;IACpB,OAAO,eAAe;GACxB,CAAC;EACH,EACF;CACF;AACF;AAEA,OAAO,MAAM,0BAAkC,8BAA8B;AAE7E,eAAe","names":[],"sources":["../src/opencode.ts"],"version":3,"file":"opencode.js","sourceRoot":""}
package/dist/plugin.d.ts CHANGED
@@ -1,68 +1,68 @@
1
1
  import type { Logger } from "./logging.js";
2
2
  import type { RateLimitOptions } from "./types.js";
3
3
  /** Fallback backoff when a 429 carries no `x-ratelimit-reset` and no `Retry-After`. */
4
- export declare const DEFAULT_BACKOFF_MS = 1000;
4
+ export declare const DEFAULT_BACKOFF_MS = 1e3;
5
5
  /**
6
- * Mutable, in-memory rate-limit state for a single bucket (a provider, or a
7
- * `(provider, model)` pair when `scope: "model"`). Lives for the process
8
- * lifetime in the provider's state store. Never persisted — a reset window is
9
- * measured in seconds, so survival across process boots is pointless.
10
- */
6
+ * Mutable, in-memory rate-limit state for a single bucket (a provider, or a
7
+ * `(provider, model)` pair when `scope: "model"`). Lives for the process
8
+ * lifetime in the provider's state store. Never persisted — a reset window is
9
+ * measured in seconds, so survival across process boots is pointless.
10
+ */
11
11
  export interface ProviderRateState {
12
- /**
13
- * Epoch ms until which new requests should be held back. 0 = no cooldown.
14
- * The sole gate driver — set from a response's `x-ratelimit-reset` (when
15
- * `remaining` hits 0, and the matched tier is `"wait"`) or from a 429 backoff.
16
- */
17
- cooldownUntilMs: number;
18
- /** The `maxWaitMs` of the tier that armed the current cooldown (0 = unlimited). */
19
- cooldownMaxWaitMs: number;
20
- /** A single in-flight wait shared by every caller during a cooldown window. */
21
- cooldownPromise?: Promise<void>;
22
- /**
23
- * Epoch ms at which {@link cooldownPromise} is scheduled to resolve. Lets a
24
- * caller that needs a shorter wait detect a too-long shared timer and fall
25
- * back to its own sleep, so it never waits past its required time / `maxWaitMs`.
26
- */
27
- cooldownPromiseUntilMs?: number;
12
+ /**
13
+ * Epoch ms until which new requests should be held back. 0 = no cooldown.
14
+ * The sole gate driver — set from a response's `x-ratelimit-reset` (when
15
+ * `remaining` hits 0, and the matched tier is `"wait"`) or from a 429 backoff.
16
+ */
17
+ cooldownUntilMs: number;
18
+ /** The `maxWaitMs` of the tier that armed the current cooldown (0 = unlimited). */
19
+ cooldownMaxWaitMs: number;
20
+ /** A single in-flight wait shared by every caller during a cooldown window. */
21
+ cooldownPromise?: Promise<void>;
22
+ /**
23
+ * Epoch ms at which {@link cooldownPromise} is scheduled to resolve. Lets a
24
+ * caller that needs a shorter wait detect a too-long shared timer and fall
25
+ * back to its own sleep, so it never waits past its required time / `maxWaitMs`.
26
+ */
27
+ cooldownPromiseUntilMs?: number;
28
28
  }
29
29
  export declare function createProviderState(): ProviderRateState;
30
30
  export interface RateLimitDeps {
31
- logger: Logger;
32
- /** Defaults to `Date.now`. */
33
- now?: () => number;
34
- /** Defaults to a real `setTimeout`-based, abort-aware sleep. */
35
- sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
36
- /** Underlying fetch when a provider has no pre-existing `options.fetch`. Defaults to `globalThis.fetch`. */
37
- fetchImpl?: typeof fetch;
31
+ logger: Logger;
32
+ /** Defaults to `Date.now`. */
33
+ now?: () => number;
34
+ /** Defaults to a real `setTimeout`-based, abort-aware sleep. */
35
+ sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
36
+ /** Underlying fetch when a provider has no pre-existing `options.fetch`. Defaults to `globalThis.fetch`. */
37
+ fetchImpl?: typeof fetch;
38
38
  }
39
39
  export interface ProviderConfigLike {
40
- options?: Record<string, unknown>;
40
+ options?: Record<string, unknown>;
41
41
  }
42
42
  export interface InstallConfigInput {
43
- provider?: Record<string, ProviderConfigLike | undefined>;
43
+ provider?: Record<string, ProviderConfigLike | undefined>;
44
44
  }
45
45
  /** A per-bucket state store (key = provider id, or `${providerId}\0${model}`). */
46
46
  export type RateStateStore = Map<string, ProviderRateState>;
47
47
  /**
48
- * Walk every provider in the assembled OpenCode config; for each one that has
49
- * opted in via `options.meta.rateLimit`, wrap its `options.fetch` with a
50
- * rate-limit-aware fetch. Synchronous — all real work happens lazily inside the
51
- * wrapper at request time.
52
- */
48
+ * Walk every provider in the assembled OpenCode config; for each one that has
49
+ * opted in via `options.meta.rateLimit`, wrap its `options.fetch` with a
50
+ * rate-limit-aware fetch. Synchronous — all real work happens lazily inside the
51
+ * wrapper at request time.
52
+ */
53
53
  export declare function installRateLimiter(input: InstallConfigInput, deps: RateLimitDeps): void;
54
54
  /**
55
- * Build the fetch wrapper for one provider. The wrapper:
56
- * 1. Resolves the bucket (provider, or `(provider, model)` under `scope: "model"`).
57
- * 2. Pre-request gate: if that bucket's cooldown is armed, waits until it clears.
58
- * 3. Sends the request via the underlying fetch.
59
- * 4. Reads the rate-limit headers; selects the policy tier by reset magnitude.
60
- * On `remaining: 0` it arms the gate for the next callers (only when the
61
- * matched tier is `"wait"`).
62
- * 5. On a 429: a `"wait"` tier waits the reset window and retries (up to the
63
- * tier's `maxRetries`); an `"error"` tier surfaces the 429 immediately.
64
- *
65
- * The Response is returned untouched (no `.clone()`) — we only read `status`
66
- * and `headers`, so the body stream is delivered to OpenCode intact.
67
- */
55
+ * Build the fetch wrapper for one provider. The wrapper:
56
+ * 1. Resolves the bucket (provider, or `(provider, model)` under `scope: "model"`).
57
+ * 2. Pre-request gate: if that bucket's cooldown is armed, waits until it clears.
58
+ * 3. Sends the request via the underlying fetch.
59
+ * 4. Reads the rate-limit headers; selects the policy tier by reset magnitude.
60
+ * On `remaining: 0` it arms the gate for the next callers (only when the
61
+ * matched tier is `"wait"`).
62
+ * 5. On a 429: a `"wait"` tier waits the reset window and retries (up to the
63
+ * tier's `maxRetries`); an `"error"` tier surfaces the 429 immediately.
64
+ *
65
+ * The Response is returned untouched (no `.clone()`) — we only read `status`
66
+ * and `headers`, so the body stream is delivered to OpenCode intact.
67
+ */
68
68
  export declare function makeRateLimitFetch(providerId: string, opts: RateLimitOptions, store: RateStateStore, deps: RateLimitDeps, delegate?: typeof fetch): typeof fetch;