@alexanderfortin/pi-tavily-tools 0.5.5 → 0.5.6

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/CHANGELOG.md CHANGED
@@ -1,8 +1,8 @@
1
- ## [0.5.5](https://github.com/shaftoe/pi-tavily-tools/compare/v0.5.4...v0.5.5) (2026-04-09)
1
+ ## [0.5.6](https://github.com/shaftoe/pi-tavily-tools/compare/v0.5.5...v0.5.6) (2026-04-09)
2
2
 
3
3
  ### Bug Fixes
4
4
 
5
- - remove doulbe counting in status when paygo is enabled ([9e4f630](https://github.com/shaftoe/pi-tavily-tools/commit/9e4f63056a887636541ee65e6604a48b58b599ab))
5
+ - handle 429 rate limit errors on Tavily usage endpoint ([#13](https://github.com/shaftoe/pi-tavily-tools/issues/13)) ([24304df](https://github.com/shaftoe/pi-tavily-tools/commit/24304dfe9ae5eb30812c789ad63e966ea0e955b5))
6
6
 
7
7
  # Changelog
8
8
 
@@ -12,7 +12,13 @@ This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html)
12
12
  uses [semantic-release](https://semantic-release.gitbook.io/) for automated releases.
13
13
  The format is based on [Keep a Changelog](https://keepachangelog.org/en/1.1.0/).
14
14
 
15
- ## [unreleased]
15
+ ## [Unreleased]
16
+
17
+ ## [0.5.5](https://github.com/shaftoe/pi-tavily-tools/compare/v0.5.4...v0.5.5) (2026-04-09)
18
+
19
+ ### Bug Fixes
20
+
21
+ - remove doulbe counting in status when paygo is enabled ([9e4f630](https://github.com/shaftoe/pi-tavily-tools/commit/9e4f63056a887636541ee65e6604a48b58b599ab))
16
22
 
17
23
  ## [0.5.4](https://github.com/shaftoe/pi-tavily-tools/compare/v0.5.3...v0.5.4) (2026-04-08)
18
24
 
@@ -1 +1 @@
1
- {"version":3,"file":"truncation.d.ts","sourceRoot":"","sources":["../../../src/tools/shared/truncation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAML,KAAK,gBAAgB,EACtB,MAAM,+BAA+B,CAAC;AAMvC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/D;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,CAAC,CAwC1B"}
1
+ {"version":3,"file":"truncation.d.ts","sourceRoot":"","sources":["../../../src/tools/shared/truncation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAML,KAAK,gBAAgB,EACtB,MAAM,+BAA+B,CAAC;AAOvC,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,gBAAgB,CAAC;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAE9C;AAED;;GAEG;AACH,wBAAsB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAG/D;AAED;;GAEG;AACH,wBAAsB,eAAe,CACnC,UAAU,EAAE,MAAM,EAClB,GAAG,EAAE,MAAM,EACX,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,eAAe,CAAC,CAwC1B"}
@@ -2,6 +2,7 @@
2
2
  * Shared truncation utilities
3
3
  */
4
4
  import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, formatSize, truncateHead, withFileMutationQueue, } from "@mariozechner/pi-coding-agent";
5
+ import { Temporal } from "temporal-polyfill";
5
6
  /**
6
7
  * Get the temp directory path used for storing truncated output files.
7
8
  */
@@ -27,7 +28,7 @@ export async function applyTruncation(fullOutput, cwd, toolName) {
27
28
  // Save full output to temp file if truncated
28
29
  if (truncation.truncated) {
29
30
  const tempDir = getTempDir(cwd);
30
- const timestamp = Date.now();
31
+ const timestamp = Temporal.Now.instant().epochMilliseconds;
31
32
  const tempFile = `${tempDir}/${toolName}-${timestamp}.txt`;
32
33
  await withFileMutationQueue(tempFile, async () => {
33
34
  const { writeFile, mkdir } = await import("node:fs/promises");
@@ -1 +1 @@
1
- {"version":3,"file":"truncation.js","sourceRoot":"","sources":["../../../src/tools/shared/truncation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,qBAAqB,GAEtB,MAAM,+BAA+B,CAAC;AAYvC;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,OAAO,GAAG,GAAG,kBAAkB,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW;IAC9C,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAChD,MAAM,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAkB,EAClB,GAAW,EACX,QAAgB;IAEhB,MAAM,UAAU,GAAG,YAAY,CAAC,UAAU,EAAE;QAC1C,QAAQ,EAAE,iBAAiB;QAC3B,QAAQ,EAAE,iBAAiB;KAC5B,CAAC,CAAC;IAEH,IAAI,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;IAEjC,6CAA6C;IAC7C,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,QAAQ,GAAG,GAAG,OAAO,IAAI,QAAQ,IAAI,SAAS,MAAM,CAAC;QAE3D,MAAM,qBAAqB,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;YAC/C,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;YAC9D,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1C,MAAM,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,wBAAwB;QACxB,MAAM,cAAc,GAAG,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC;QACtE,MAAM,cAAc,GAAG,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC;QAEtE,OAAO,IAAI,MAAM,CAAC;QAClB,OAAO,IAAI,qBAAqB,CAAC;QACjC,OAAO,IAAI,WAAW,UAAU,CAAC,WAAW,OAAO,UAAU,CAAC,UAAU,UAAU,CAAC;QACnF,OAAO,IAAI,IAAI,UAAU,CAAC,UAAU,CAAC,WAAW,CAAC,OAAO,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC;QAC/F,OAAO,IAAI,GAAG,cAAc,WAAW,UAAU,CAAC,cAAc,CAAC,aAAa,CAAC;QAC/E,OAAO,IAAI,yBAAyB,QAAQ,IAAI,CAAC;QACjD,OAAO,IAAI,4DAA4D,CAAC;QAExE,OAAO;YACL,OAAO;YACP,UAAU;YACV,cAAc,EAAE,QAAQ;SACzB,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC"}
1
+ {"version":3,"file":"truncation.js","sourceRoot":"","sources":["../../../src/tools/shared/truncation.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EACL,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,YAAY,EACZ,qBAAqB,GAEtB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAY7C;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,GAAW;IACpC,OAAO,GAAG,GAAG,kBAAkB,CAAC;AAClC,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,GAAW;IAC9C,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;IAChD,MAAM,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAC9D,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,UAAkB,EAClB,GAAW,EACX,QAAgB;IAEhB,MAAM,UAAU,GAAG,YAAY,CAAC,UAAU,EAAE;QAC1C,QAAQ,EAAE,iBAAiB;QAC3B,QAAQ,EAAE,iBAAiB;KAC5B,CAAC,CAAC;IAEH,IAAI,OAAO,GAAG,UAAU,CAAC,OAAO,CAAC;IAEjC,6CAA6C;IAC7C,IAAI,UAAU,CAAC,SAAS,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;QAChC,MAAM,SAAS,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,iBAAiB,CAAC;QAC3D,MAAM,QAAQ,GAAG,GAAG,OAAO,IAAI,QAAQ,IAAI,SAAS,MAAM,CAAC;QAE3D,MAAM,qBAAqB,CAAC,QAAQ,EAAE,KAAK,IAAI,EAAE;YAC/C,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,MAAM,MAAM,CAAC,kBAAkB,CAAC,CAAC;YAC9D,MAAM,KAAK,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YAC1C,MAAM,SAAS,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,CAAC,CAAC;QAChD,CAAC,CAAC,CAAC;QAEH,wBAAwB;QACxB,MAAM,cAAc,GAAG,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC;QACtE,MAAM,cAAc,GAAG,UAAU,CAAC,UAAU,GAAG,UAAU,CAAC,WAAW,CAAC;QAEtE,OAAO,IAAI,MAAM,CAAC;QAClB,OAAO,IAAI,qBAAqB,CAAC;QACjC,OAAO,IAAI,WAAW,UAAU,CAAC,WAAW,OAAO,UAAU,CAAC,UAAU,UAAU,CAAC;QACnF,OAAO,IAAI,IAAI,UAAU,CAAC,UAAU,CAAC,WAAW,CAAC,OAAO,UAAU,CAAC,UAAU,CAAC,UAAU,CAAC,KAAK,CAAC;QAC/F,OAAO,IAAI,GAAG,cAAc,WAAW,UAAU,CAAC,cAAc,CAAC,aAAa,CAAC;QAC/E,OAAO,IAAI,yBAAyB,QAAQ,IAAI,CAAC;QACjD,OAAO,IAAI,4DAA4D,CAAC;QAExE,OAAO;YACL,OAAO;YACP,UAAU;YACV,cAAc,EAAE,QAAQ;SACzB,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,OAAO,EAAE,CAAC;AACrB,CAAC"}
@@ -4,6 +4,13 @@
4
4
  * Fetches usage data from the Tavily usage endpoint.
5
5
  * @see https://docs.tavily.com/documentation/api-reference/endpoint/usage
6
6
  */
7
+ /** Default retry-after duration in milliseconds (5 minutes) */
8
+ export declare const DEFAULT_RETRY_AFTER_MS = 300000;
9
+ /** Error thrown when the Tavily usage API rate limit is exceeded */
10
+ export declare class RateLimitError extends Error {
11
+ readonly retryAfterMs: number;
12
+ constructor(retryAfterMs: number);
13
+ }
7
14
  export interface TavilyUsageKeySection {
8
15
  usage: number;
9
16
  limit: number;
@@ -1 +1 @@
1
- {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/usage/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,yBAAyB;IACxC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,qBAAqB,CAAC;IAC3B,OAAO,EAAE,yBAAyB,CAAC;CACpC;AAED,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAMD;;;GAGG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAwC7E"}
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../../src/usage/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,+DAA+D;AAC/D,eAAO,MAAM,sBAAsB,SAAU,CAAC;AAM9C,oEAAoE;AACpE,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;gBAElB,YAAY,EAAE,MAAM;CAKjC;AAuBD,MAAM,WAAW,qBAAqB;IACpC,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,yBAAyB;IACxC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC,GAAG,EAAE,qBAAqB,CAAC;IAC3B,OAAO,EAAE,yBAAyB,CAAC;CACpC;AAED,MAAM,WAAW,eAAe;IAC9B,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,iCAAiC;IACjC,UAAU,EAAE,MAAM,CAAC;IACnB,sCAAsC;IACtC,UAAU,EAAE,MAAM,CAAC;IACnB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,wBAAwB;IACxB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAMD;;;GAGG;AACH,wBAAsB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CA6C7E"}
package/dist/usage/api.js CHANGED
@@ -5,6 +5,34 @@
5
5
  * @see https://docs.tavily.com/documentation/api-reference/endpoint/usage
6
6
  */
7
7
  const TAVILY_USAGE_API_URL = "https://api.tavily.com/usage";
8
+ /** Default retry-after duration in milliseconds (5 minutes) */
9
+ export const DEFAULT_RETRY_AFTER_MS = 300_000;
10
+ // ============================================================================
11
+ // Errors
12
+ // ============================================================================
13
+ /** Error thrown when the Tavily usage API rate limit is exceeded */
14
+ export class RateLimitError extends Error {
15
+ retryAfterMs;
16
+ constructor(retryAfterMs) {
17
+ super(`Tavily usage API rate limited; retry after ${retryAfterMs}ms`);
18
+ this.name = "RateLimitError";
19
+ this.retryAfterMs = retryAfterMs;
20
+ }
21
+ }
22
+ // ============================================================================
23
+ // Utilities
24
+ // ============================================================================
25
+ /**
26
+ * Parse the HTTP Retry-After header to milliseconds.
27
+ * Tavily returns the value as decimal integer seconds (e.g., "60").
28
+ */
29
+ function parseRetryAfter(retryAfterHeader) {
30
+ if (!retryAfterHeader) {
31
+ return DEFAULT_RETRY_AFTER_MS;
32
+ }
33
+ const seconds = parseInt(retryAfterHeader.trim(), 10);
34
+ return isNaN(seconds) ? DEFAULT_RETRY_AFTER_MS : Math.max(seconds * 1000, 0);
35
+ }
8
36
  // ============================================================================
9
37
  // API Client
10
38
  // ============================================================================
@@ -22,6 +50,11 @@ export async function getTavilyUsage(apiKey) {
22
50
  },
23
51
  });
24
52
  if (!response.ok) {
53
+ if (response.status === 429) {
54
+ const retryAfterHeader = response.headers.get("retry-after");
55
+ const retryAfterMs = parseRetryAfter(retryAfterHeader);
56
+ throw new RateLimitError(retryAfterMs);
57
+ }
25
58
  throw new Error(`Tavily usage API request failed with status ${response.status}`);
26
59
  }
27
60
  const data = (await response.json());
@@ -1 +1 @@
1
- {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/usage/api.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,oBAAoB,GAAG,8BAA8B,CAAC;AAmD5D,+EAA+E;AAC/E,aAAa;AACb,+EAA+E;AAE/E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,MAAc;IACjD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,KAAK,CACb,6BAA6B,GAAG,0DAA0D,CAC3F,CAAC;IACJ,CAAC;IAED,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,oBAAoB,EAAE;QACjD,OAAO,EAAE;YACP,aAAa,EAAE,UAAU,MAAM,EAAE;SAClC;KACF,CAAC,CAAC;IAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,+CAA+C,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;IACpF,CAAC;IAED,MAAM,IAAI,GAAG,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAwB,CAAC;IAE5D,IAAI,CAAC,IAAI,CAAC,OAAO,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QACjE,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;IACtF,CAAC;IAED,IAAI,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,KAAK,QAAQ,EAAE,CAAC;QAChD,MAAM,IAAI,KAAK,CAAC,kEAAkE,CAAC,CAAC;IACtF,CAAC;IAED,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC;IAC3C,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC;IAC7E,MAAM,UAAU,GAAG,CAAC,UAAU,GAAG,CAAC,UAAU,IAAI,CAAC,CAAC,CAAC,GAAG,GAAG,CAAC;IAE1D,OAAO;QACL,UAAU;QACV,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;QAClC,SAAS,EAAE,IAAI,CAAC,OAAO,CAAC,UAAU;QAClC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC;QACzC,UAAU,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,IAAI,CAAC;QACzC,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC;QAC9B,QAAQ,EAAE,IAAI,CAAC,GAAG,EAAE,KAAK,IAAI,CAAC;KAC/B,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"api.js","sourceRoot":"","sources":["../../src/usage/api.ts"],"names":[],"mappings":"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"}
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Tavily Usage Cache
3
3
  */
4
- export { getTavilyUsage } from "./api.js";
4
+ export { RateLimitError, getTavilyUsage } from "./api.js";
5
5
  export type { TavilyUsageData } from "./api.js";
6
6
  export { UsageCache } from "./status.js";
7
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/usage/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1C,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/usage/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC1D,YAAY,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
@@ -1,6 +1,6 @@
1
1
  /**
2
2
  * Tavily Usage Cache
3
3
  */
4
- export { getTavilyUsage } from "./api.js";
4
+ export { RateLimitError, getTavilyUsage } from "./api.js";
5
5
  export { UsageCache } from "./status.js";
6
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/usage/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1C,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/usage/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAE1D,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC"}
@@ -13,6 +13,7 @@ export declare class UsageCache {
13
13
  private readonly apiKey;
14
14
  private lastUsage;
15
15
  private lastFetchTime;
16
+ private backoffUntil;
16
17
  private static readonly FETCH_COOLDOWN_MS;
17
18
  constructor(apiKey: string);
18
19
  /** Build and set footer status string from usage data */
@@ -1 +1 @@
1
- {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/usage/status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,OAAO,EAAkB,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhE,8EAA8E;AAC9E,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;AAExE,+DAA+D;AAC/D,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAW;gBAExC,MAAM,EAAE,MAAM;IAI1B,yDAAyD;IACzD,OAAO,CAAC,kBAAkB;IAS1B,yDAAyD;IACnD,YAAY,CAChB,GAAG,EAAE,gBAAgB,EACrB,UAAU,GAAE,YAA6B,GACxC,OAAO,CAAC,IAAI,CAAC;IAyBhB,uCAAuC;IACvC,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI;CAGnC"}
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../src/usage/status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAEtE,OAAO,EAAkC,KAAK,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhF,8EAA8E;AAC9E,MAAM,MAAM,YAAY,GAAG,CAAC,MAAM,EAAE,MAAM,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC;AAExE,+DAA+D;AAC/D,qBAAa,UAAU;IACrB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,SAAS,CAAgC;IACjD,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,YAAY,CAAK;IACzB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,CAAW;gBAExC,MAAM,EAAE,MAAM;IAI1B,yDAAyD;IACzD,OAAO,CAAC,kBAAkB;IAS1B,yDAAyD;IACnD,YAAY,CAChB,GAAG,EAAE,gBAAgB,EACrB,UAAU,GAAE,YAA6B,GACxC,OAAO,CAAC,IAAI,CAAC;IAyChB,uCAAuC;IACvC,KAAK,CAAC,GAAG,EAAE,gBAAgB,GAAG,IAAI;CAGnC"}
@@ -5,12 +5,13 @@
5
5
  * with caching to avoid excessive API calls.
6
6
  */
7
7
  import { Temporal } from "temporal-polyfill";
8
- import { getTavilyUsage } from "./api.js";
8
+ import { RateLimitError, getTavilyUsage } from "./api.js";
9
9
  /** Cache for Tavily usage data to avoid excessive API calls */
10
10
  export class UsageCache {
11
11
  apiKey;
12
12
  lastUsage = null;
13
13
  lastFetchTime = 0;
14
+ backoffUntil = 0;
14
15
  static FETCH_COOLDOWN_MS = 120_000;
15
16
  constructor(apiKey) {
16
17
  this.apiKey = apiKey;
@@ -24,23 +25,39 @@ export class UsageCache {
24
25
  }
25
26
  /** Update footer status with Tavily usage information */
26
27
  async updateStatus(ctx, fetchUsage = getTavilyUsage) {
27
- try {
28
- const now = Temporal.Now.instant().epochMilliseconds;
29
- // Use cached data if still fresh
30
- if (this.lastUsage &&
31
- this.lastFetchTime &&
32
- now - this.lastFetchTime < UsageCache.FETCH_COOLDOWN_MS) {
28
+ const now = Temporal.Now.instant().epochMilliseconds;
29
+ // Respect rate-limit backoff — use cached data or skip silently
30
+ if (now < this.backoffUntil) {
31
+ if (this.lastUsage) {
33
32
  this.setStatusFromUsage(ctx, this.lastUsage);
34
- return;
35
33
  }
34
+ return;
35
+ }
36
+ // Use cached data if still fresh
37
+ if (this.lastUsage &&
38
+ this.lastFetchTime &&
39
+ now - this.lastFetchTime < UsageCache.FETCH_COOLDOWN_MS) {
40
+ this.setStatusFromUsage(ctx, this.lastUsage);
41
+ return;
42
+ }
43
+ try {
36
44
  const usage = await fetchUsage(this.apiKey);
37
45
  this.lastUsage = usage;
38
46
  this.lastFetchTime = now;
39
47
  this.setStatusFromUsage(ctx, usage);
40
48
  }
41
49
  catch (error) {
42
- console.error(`Error updating Tavily usage: ${String(error)}`);
43
- this.clear(ctx);
50
+ if (error instanceof RateLimitError) {
51
+ this.backoffUntil = now + error.retryAfterMs;
52
+ // Keep last known status instead of clearing
53
+ if (this.lastUsage) {
54
+ this.setStatusFromUsage(ctx, this.lastUsage);
55
+ }
56
+ }
57
+ else {
58
+ console.error(`Error updating Tavily usage: ${String(error)}`);
59
+ this.clear(ctx);
60
+ }
44
61
  }
45
62
  }
46
63
  /** Clear Tavily usage footer status */
@@ -1 +1 @@
1
- {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/usage/status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAwB,MAAM,UAAU,CAAC;AAKhE,+DAA+D;AAC/D,MAAM,OAAO,UAAU;IACJ,MAAM,CAAS;IACxB,SAAS,GAA2B,IAAI,CAAC;IACzC,aAAa,GAAG,CAAC,CAAC;IAClB,MAAM,CAAU,iBAAiB,GAAG,OAAO,CAAC;IAEpD,YAAY,MAAc;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,yDAAyD;IACjD,kBAAkB,CAAC,GAAqB,EAAE,SAA0B;QAC1E,MAAM,KAAK,GAAG,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC;QAC3B,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;QAErE,IAAI,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,iBAAiB,GAAG,CAAC,CAAC;QAExF,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,yDAAyD;IACzD,KAAK,CAAC,YAAY,CAChB,GAAqB,EACrB,aAA2B,cAAc;QAEzC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,iBAAiB,CAAC;YAErD,iCAAiC;YACjC,IACE,IAAI,CAAC,SAAS;gBACd,IAAI,CAAC,aAAa;gBAClB,GAAG,GAAG,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC,iBAAiB,EACvD,CAAC;gBACD,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC7C,OAAO;YACT,CAAC;YAED,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC5C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,aAAa,GAAG,GAAG,CAAC;YAEzB,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,gCAAgC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YAC/D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,KAAK,CAAC,GAAqB;QACzB,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IAC9C,CAAC"}
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/usage/status.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,QAAQ,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,cAAc,EAAE,cAAc,EAAwB,MAAM,UAAU,CAAC;AAKhF,+DAA+D;AAC/D,MAAM,OAAO,UAAU;IACJ,MAAM,CAAS;IACxB,SAAS,GAA2B,IAAI,CAAC;IACzC,aAAa,GAAG,CAAC,CAAC;IAClB,YAAY,GAAG,CAAC,CAAC;IACjB,MAAM,CAAU,iBAAiB,GAAG,OAAO,CAAC;IAEpD,YAAY,MAAc;QACxB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,yDAAyD;IACjD,kBAAkB,CAAC,GAAqB,EAAE,SAA0B;QAC1E,MAAM,KAAK,GAAG,GAAG,CAAC,EAAE,CAAC,KAAK,CAAC;QAC3B,MAAM,iBAAiB,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,GAAG,EAAE,CAAC,GAAG,EAAE,CAAC;QAErE,IAAI,MAAM,GAAG,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,iBAAiB,GAAG,CAAC,CAAC;QAExF,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;IAC3C,CAAC;IAED,yDAAyD;IACzD,KAAK,CAAC,YAAY,CAChB,GAAqB,EACrB,aAA2B,cAAc;QAEzC,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,OAAO,EAAE,CAAC,iBAAiB,CAAC;QAErD,gEAAgE;QAChE,IAAI,GAAG,GAAG,IAAI,CAAC,YAAY,EAAE,CAAC;YAC5B,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gBACnB,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC/C,CAAC;YACD,OAAO;QACT,CAAC;QAED,iCAAiC;QACjC,IACE,IAAI,CAAC,SAAS;YACd,IAAI,CAAC,aAAa;YAClB,GAAG,GAAG,IAAI,CAAC,aAAa,GAAG,UAAU,CAAC,iBAAiB,EACvD,CAAC;YACD,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;YAC7C,OAAO;QACT,CAAC;QAED,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,MAAM,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;YAC5C,IAAI,CAAC,SAAS,GAAG,KAAK,CAAC;YACvB,IAAI,CAAC,aAAa,GAAG,GAAG,CAAC;YAEzB,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACtC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IAAI,KAAK,YAAY,cAAc,EAAE,CAAC;gBACpC,IAAI,CAAC,YAAY,GAAG,GAAG,GAAG,KAAK,CAAC,YAAY,CAAC;gBAC7C,6CAA6C;gBAC7C,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;oBACnB,IAAI,CAAC,kBAAkB,CAAC,GAAG,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;gBAC/C,CAAC;YACH,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,KAAK,CAAC,gCAAgC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;gBAC/D,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YAClB,CAAC;QACH,CAAC;IACH,CAAC;IAED,uCAAuC;IACvC,KAAK,CAAC,GAAqB;QACzB,GAAG,CAAC,EAAE,CAAC,SAAS,CAAC,cAAc,EAAE,SAAS,CAAC,CAAC;IAC9C,CAAC"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@alexanderfortin/pi-tavily-tools",
3
3
  "author": "Alexander Fortin",
4
- "version": "0.5.5",
4
+ "version": "0.5.6",
5
5
  "description": "Pi coding agent extension for web search and content extraction using Tavily",
6
6
  "keywords": [
7
7
  "pi-package",