@coval/sdk 0.4.0 → 0.4.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/README.md CHANGED
@@ -108,6 +108,48 @@ const all = await collectAll({
108
108
  });
109
109
  ```
110
110
 
111
+ ### Diagnosing intermittent failures
112
+
113
+ A request that dies in transit never reaches the API, so there is no
114
+ server-side trace of it. The client keeps live counters:
115
+
116
+ ```ts
117
+ coval.stats;
118
+ // { calls: 12, requests: 14, retries: 2, networkErrors: 1 }
119
+ ```
120
+
121
+ `calls` is logical API calls, `requests` counts every `fetch` including
122
+ retries, and `networkErrors` counts failures where no response came back at
123
+ all. Include these when reporting sporadic timeouts. For a line per retry and
124
+ per in-transit failure:
125
+
126
+ ```ts
127
+ const coval = new CovalClient({ apiKey, onDebug: console.debug });
128
+ ```
129
+
130
+ ### Connection reuse
131
+
132
+ On Node the client uses the global `fetch` (undici), which expires idle
133
+ keep-alive connections after roughly 4 seconds. That bound matters: some
134
+ network paths silently drop an idle connection without closing it, and reusing
135
+ one stalls the request until your timeout, because it never reaches the server.
136
+
137
+ Requests made within that window can still reuse a pooled connection. If you
138
+ submit infrequently, or you have seen unexplained timeouts, pass an explicit
139
+ dispatcher:
140
+
141
+ ```ts
142
+ import { Agent, fetch as undiciFetch } from 'undici';
143
+
144
+ const coval = new CovalClient({
145
+ apiKey,
146
+ fetch: ((input, init) =>
147
+ undiciFetch(input as never, { ...init, dispatcher: new Agent({ keepAliveTimeout: 1_000 }) })) as typeof fetch,
148
+ });
149
+ ```
150
+
151
+ The Python SDK exposes the same bound directly as `max_idle_seconds`.
152
+
111
153
  ## Customization
112
154
 
113
155
  ### Override base URL (staging, self-host)
@@ -1,4 +1,5 @@
1
1
  import { type RetryOptions } from './retry.js';
2
+ import { type CovalTransportStats } from './stats.js';
2
3
  import { AgentsApi, APIKeysApi, AudioApi, Configuration, ConversationsApi, DashboardsApi, type FetchAPI, IntegrationsApi, type Middleware, MetricOutputsApi, MetricsApi, MonitorEventsApi, MonitorsApi, MutationsApi, OrganizationConversationsConfigApi, PersonasApi, ReportsApi, ReviewAnnotationsApi, ReviewProjectsApi, RunsApi, RunTemplatesApi, ScheduledRunsApi, SimulationsApi, TagsApi, TestCasesApi, TestSetsApi, TracesApi, WebhooksApi, WidgetsApi } from './generated/index.js';
3
4
  export interface CovalClientOptions {
4
5
  /** Coval API key. Required. Sent as `x-api-key` (lowercase). */
@@ -11,6 +12,11 @@ export interface CovalClientOptions {
11
12
  middleware?: Middleware[];
12
13
  /** Override the global fetch (e.g., for tests, undici-with-keepalive, etc). */
13
14
  fetch?: FetchAPI;
15
+ /**
16
+ * Called with a diagnostic line on each retry and each in-transit failure.
17
+ * Pass `console.debug` when investigating intermittent timeouts.
18
+ */
19
+ onDebug?: (message: string) => void;
14
20
  }
15
21
  export declare class CovalClient {
16
22
  readonly agents: AgentsApi;
@@ -40,6 +46,12 @@ export declare class CovalClient {
40
46
  readonly webhooks: WebhooksApi;
41
47
  readonly widgets: WidgetsApi;
42
48
  readonly configuration: Configuration;
49
+ /**
50
+ * Live transport counters. A request that dies in transit leaves no
51
+ * server-side trace, so these are often the only evidence when diagnosing
52
+ * intermittent failures. Include them when reporting one.
53
+ */
54
+ readonly stats: CovalTransportStats;
43
55
  constructor(options: CovalClientOptions);
44
56
  }
45
57
  //# sourceMappingURL=CovalClient.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"CovalClient.d.ts","sourceRoot":"","sources":["../src/CovalClient.ts"],"names":[],"mappings":"AAcA,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EACL,SAAS,EACT,UAAU,EACV,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,KAAK,QAAQ,EACb,eAAe,EACf,KAAK,UAAU,EACf,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,kCAAkC,EAClC,WAAW,EACX,UAAU,EACV,oBAAoB,EACpB,iBAAiB,EACjB,OAAO,EACP,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,OAAO,EACP,YAAY,EACZ,WAAW,EACX,SAAS,EACT,WAAW,EACX,UAAU,EACX,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,kBAAkB;IACjC,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,KAAK,CAAC,EAAE,YAAY,GAAG,KAAK,CAAC;IAC7B,yDAAyD;IACzD,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;IAC1B,+EAA+E;IAC/E,KAAK,CAAC,EAAE,QAAQ,CAAC;CAClB;AAID,qBAAa,WAAW;IACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,gBAAgB,CAAC;IACzC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC;IACnC,QAAQ,CAAC,YAAY,EAAE,eAAe,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,gBAAgB,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,gBAAgB,CAAC;IACzC,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,+BAA+B,EAAE,kCAAkC,CAAC;IAC7E,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,oBAAoB,CAAC;IACjD,QAAQ,CAAC,cAAc,EAAE,iBAAiB,CAAC;IAC3C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,eAAe,CAAC;IACvC,QAAQ,CAAC,aAAa,EAAE,gBAAgB,CAAC;IACzC,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAE7B,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;gBAE1B,OAAO,EAAE,kBAAkB;CAkDxC"}
1
+ {"version":3,"file":"CovalClient.d.ts","sourceRoot":"","sources":["../src/CovalClient.ts"],"names":[],"mappings":"AAcA,OAAO,EAAuB,KAAK,YAAY,EAAE,MAAM,YAAY,CAAC;AACpE,OAAO,EAAwB,KAAK,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,EACL,SAAS,EACT,UAAU,EACV,QAAQ,EACR,aAAa,EACb,gBAAgB,EAChB,aAAa,EACb,KAAK,QAAQ,EACb,eAAe,EACf,KAAK,UAAU,EACf,gBAAgB,EAChB,UAAU,EACV,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,kCAAkC,EAClC,WAAW,EACX,UAAU,EACV,oBAAoB,EACpB,iBAAiB,EACjB,OAAO,EACP,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,OAAO,EACP,YAAY,EACZ,WAAW,EACX,SAAS,EACT,WAAW,EACX,UAAU,EACX,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,kBAAkB;IACjC,gEAAgE;IAChE,MAAM,EAAE,MAAM,CAAC;IACf,sDAAsD;IACtD,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,uEAAuE;IACvE,KAAK,CAAC,EAAE,YAAY,GAAG,KAAK,CAAC;IAC7B,yDAAyD;IACzD,UAAU,CAAC,EAAE,UAAU,EAAE,CAAC;IAC1B,+EAA+E;IAC/E,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB;;;OAGG;IACH,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAID,qBAAa,WAAW;IACtB,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,KAAK,EAAE,QAAQ,CAAC;IACzB,QAAQ,CAAC,aAAa,EAAE,gBAAgB,CAAC;IACzC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC;IACnC,QAAQ,CAAC,YAAY,EAAE,eAAe,CAAC;IACvC,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,aAAa,EAAE,gBAAgB,CAAC;IACzC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,aAAa,EAAE,gBAAgB,CAAC;IACzC,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,+BAA+B,EAAE,kCAAkC,CAAC;IAC7E,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAC7B,QAAQ,CAAC,iBAAiB,EAAE,oBAAoB,CAAC;IACjD,QAAQ,CAAC,cAAc,EAAE,iBAAiB,CAAC;IAC3C,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,YAAY,EAAE,eAAe,CAAC;IACvC,QAAQ,CAAC,aAAa,EAAE,gBAAgB,CAAC;IACzC,QAAQ,CAAC,WAAW,EAAE,cAAc,CAAC;IACrC,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;IACvB,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAC;IACjC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,UAAU,CAAC;IAE7B,QAAQ,CAAC,aAAa,EAAE,aAAa,CAAC;IAEtC;;;;OAIG;IACH,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAC;gBAExB,OAAO,EAAE,kBAAkB;CAwDxC"}
@@ -12,6 +12,7 @@
12
12
  import { apiKeyAuthMiddleware } from './auth.js';
13
13
  import { CovalApiError, parseErrorResponse } from './errors.js';
14
14
  import { createRetryingFetch } from './retry.js';
15
+ import { createTransportStats } from './stats.js';
15
16
  import { AgentsApi, APIKeysApi, AudioApi, Configuration, ConversationsApi, DashboardsApi, IntegrationsApi, MetricOutputsApi, MetricsApi, MonitorEventsApi, MonitorsApi, MutationsApi, OrganizationConversationsConfigApi, PersonasApi, ReportsApi, ReviewAnnotationsApi, ReviewProjectsApi, RunsApi, RunTemplatesApi, ScheduledRunsApi, SimulationsApi, TagsApi, TestCasesApi, TestSetsApi, TracesApi, WebhooksApi, WidgetsApi, } from './generated/index.js';
16
17
  const DEFAULT_BASE_URL = 'https://api.coval.dev/v1';
17
18
  export class CovalClient {
@@ -42,14 +43,25 @@ export class CovalClient {
42
43
  webhooks;
43
44
  widgets;
44
45
  configuration;
46
+ /**
47
+ * Live transport counters. A request that dies in transit leaves no
48
+ * server-side trace, so these are often the only evidence when diagnosing
49
+ * intermittent failures. Include them when reporting one.
50
+ */
51
+ stats;
45
52
  constructor(options) {
46
53
  if (!options.apiKey) {
47
54
  throw new Error('CovalClient: apiKey is required');
48
55
  }
56
+ this.stats = createTransportStats();
49
57
  const innerFetch = options.fetch ?? globalThis.fetch;
50
58
  const fetchApi = options.retry === false
51
59
  ? innerFetch
52
- : createRetryingFetch(options.retry ?? {}, { fetch: innerFetch });
60
+ : createRetryingFetch(options.retry ?? {}, {
61
+ fetch: innerFetch,
62
+ stats: this.stats,
63
+ onDebug: options.onDebug,
64
+ });
53
65
  const middleware = [
54
66
  apiKeyAuthMiddleware({ apiKey: options.apiKey }),
55
67
  errorMiddleware(),
@@ -1 +1 @@
1
- {"version":3,"file":"CovalClient.js","sourceRoot":"","sources":["../src/CovalClient.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"CovalClient.js","sourceRoot":"","sources":["../src/CovalClient.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -7,5 +7,7 @@ export type { PaginateOptions } from './pagination.js';
7
7
  export { apiKeyAuthMiddleware } from './auth.js';
8
8
  export { createRetryingFetch } from './retry.js';
9
9
  export type { RetryOptions } from './retry.js';
10
+ export { createTransportStats, formatTransportStats } from './stats.js';
11
+ export type { CovalTransportStats } from './stats.js';
10
12
  export * from './generated/index.js';
11
13
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC/D,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACvD,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAK/C,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,YAAY,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC/D,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AACvD,YAAY,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AACjD,YAAY,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAC/C,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACxE,YAAY,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAKtD,cAAc,sBAAsB,CAAC"}
package/dist/index.js CHANGED
@@ -4,6 +4,7 @@ export { CovalApiError, CovalNetworkError } from './errors.js';
4
4
  export { paginate, collectAll } from './pagination.js';
5
5
  export { apiKeyAuthMiddleware } from './auth.js';
6
6
  export { createRetryingFetch } from './retry.js';
7
+ export { createTransportStats, formatTransportStats } from './stats.js';
7
8
  // Re-export the entire generated surface so callers can reach for request
8
9
  // types, model types, and individual API classes if they want to bypass the
9
10
  // CovalClient wrapper.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qCAAqC;AAErC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAGjD,0EAA0E;AAC1E,4EAA4E;AAC5E,uBAAuB;AACvB,cAAc,sBAAsB,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,qCAAqC;AAErC,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAEvD,OAAO,EAAE,oBAAoB,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAEjD,OAAO,EAAE,oBAAoB,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAGxE,0EAA0E;AAC1E,4EAA4E;AAC5E,uBAAuB;AACvB,cAAc,sBAAsB,CAAC"}
package/dist/retry.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type { FetchAPI } from './generated/runtime.js';
2
+ import type { CovalTransportStats } from './stats.js';
2
3
  export interface RetryOptions {
3
4
  /** Max total attempts including the first. Default 3. */
4
5
  maxAttempts?: number;
@@ -16,6 +17,10 @@ export interface RetryOptions {
16
17
  export interface RetryDeps {
17
18
  fetch?: FetchAPI;
18
19
  sleep?: (ms: number) => Promise<void>;
20
+ /** Counters mutated in place so the client can expose a live view. */
21
+ stats?: CovalTransportStats;
22
+ /** Called with a human-readable line on each retry or network error. */
23
+ onDebug?: (message: string) => void;
19
24
  }
20
25
  export declare function createRetryingFetch(options?: RetryOptions, deps?: RetryDeps): FetchAPI;
21
26
  //# sourceMappingURL=retry.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AAKvD,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wFAAwF;IACxF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACvC;AAED,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,YAAiB,EAAE,IAAI,GAAE,SAAc,GAAG,QAAQ,CA6D9F"}
1
+ {"version":3,"file":"retry.d.ts","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAC;AACvD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAKtD,MAAM,WAAW,YAAY;IAC3B,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wFAAwF;IACxF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gDAAgD;IAChD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4DAA4D;IAC5D,MAAM,CAAC,EAAE,MAAM,MAAM,CAAC;IACtB,4EAA4E;IAC5E,iBAAiB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAChC,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAChC;AAED,MAAM,WAAW,SAAS;IACxB,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,KAAK,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACtC,sEAAsE;IACtE,KAAK,CAAC,EAAE,mBAAmB,CAAC;IAC5B,wEAAwE;IACxE,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CACrC;AAED,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,YAAiB,EAAE,IAAI,GAAE,SAAc,GAAG,QAAQ,CAgF9F"}
package/dist/retry.js CHANGED
@@ -17,15 +17,24 @@ export function createRetryingFetch(options = {}, deps = {}) {
17
17
  const retryableMethods = options.retryableMethods ?? RETRYABLE_METHODS;
18
18
  const innerFetch = deps.fetch ?? globalThis.fetch;
19
19
  const sleep = deps.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
20
+ const stats = deps.stats;
21
+ const debug = deps.onDebug;
20
22
  return async function retryingFetch(input, init) {
21
23
  let lastError;
22
24
  const method = (init?.method ?? 'GET').toUpperCase();
23
25
  const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;
26
+ if (stats)
27
+ stats.calls += 1;
24
28
  if (!retryableMethods.has(method)) {
25
29
  try {
30
+ if (stats)
31
+ stats.requests += 1;
26
32
  return await innerFetch(input, init);
27
33
  }
28
34
  catch (err) {
35
+ if (stats)
36
+ stats.networkErrors += 1;
37
+ debug?.(`coval-sdk: ${method} ${url} failed in transit (not retried): ${stringifyError(err)}`);
29
38
  throw new CovalNetworkError({
30
39
  message: `Coval API request failed: ${stringifyError(err)}`,
31
40
  url,
@@ -37,16 +46,24 @@ export function createRetryingFetch(options = {}, deps = {}) {
37
46
  }
38
47
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
39
48
  try {
49
+ if (stats)
50
+ stats.requests += 1;
40
51
  const response = await innerFetch(input, init);
41
52
  if (!retryable.has(response.status) || attempt === maxAttempts) {
42
53
  return response;
43
54
  }
44
55
  const wait = computeDelay({ attempt, baseDelay, maxDelay, jitter, response });
56
+ if (stats)
57
+ stats.retries += 1;
58
+ debug?.(`coval-sdk: ${method} ${url} returned ${response.status}, retrying in ${wait}ms (attempt ${attempt}/${maxAttempts})`);
45
59
  await sleep(wait);
46
60
  }
47
61
  catch (err) {
48
62
  lastError = err;
63
+ if (stats)
64
+ stats.networkErrors += 1;
49
65
  if (attempt === maxAttempts) {
66
+ debug?.(`coval-sdk: ${method} ${url} failed in transit after ${attempt} attempts: ${stringifyError(err)}`);
50
67
  throw new CovalNetworkError({
51
68
  message: `Coval API request failed after ${attempt} attempt${attempt > 1 ? 's' : ''}: ${stringifyError(err)}`,
52
69
  url,
@@ -56,6 +73,9 @@ export function createRetryingFetch(options = {}, deps = {}) {
56
73
  });
57
74
  }
58
75
  const wait = computeDelay({ attempt, baseDelay, maxDelay, jitter });
76
+ if (stats)
77
+ stats.retries += 1;
78
+ debug?.(`coval-sdk: ${method} ${url} failed in transit (${stringifyError(err)}), retrying in ${wait}ms (attempt ${attempt}/${maxAttempts})`);
59
79
  await sleep(wait);
60
80
  }
61
81
  }
package/dist/retry.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"retry.js","sourceRoot":"","sources":["../src/retry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ export interface CovalTransportStats {
2
+ /** Logical API calls started. */
3
+ calls: number;
4
+ /** fetch invocations, including retries — exceeds `calls` when retries fire. */
5
+ requests: number;
6
+ /** Retry attempts beyond the initial request. */
7
+ retries: number;
8
+ /** fetch rejections: DNS failure, reset, abort, or a stranded pooled socket. */
9
+ networkErrors: number;
10
+ }
11
+ export declare function createTransportStats(): CovalTransportStats;
12
+ export declare function formatTransportStats(stats: CovalTransportStats): string;
13
+ //# sourceMappingURL=stats.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.d.ts","sourceRoot":"","sources":["../src/stats.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,mBAAmB;IAClC,iCAAiC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,gFAAgF;IAChF,QAAQ,EAAE,MAAM,CAAC;IACjB,iDAAiD;IACjD,OAAO,EAAE,MAAM,CAAC;IAChB,gFAAgF;IAChF,aAAa,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,oBAAoB,IAAI,mBAAmB,CAE1D;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CAEvE"}
package/dist/stats.js ADDED
@@ -0,0 +1,13 @@
1
+ // Transport counters for diagnosing intermittent failures.
2
+ //
3
+ // A request that dies in transit never reaches the API, so there is no
4
+ // server-side trace of it. These counters are often the only evidence available
5
+ // when a caller reports sporadic timeouts. Mirrors `connection_stats` in the
6
+ // Python SDK.
7
+ export function createTransportStats() {
8
+ return { calls: 0, requests: 0, retries: 0, networkErrors: 0 };
9
+ }
10
+ export function formatTransportStats(stats) {
11
+ return `CovalTransportStats(calls=${stats.calls}, requests=${stats.requests}, retries=${stats.retries}, networkErrors=${stats.networkErrors})`;
12
+ }
13
+ //# sourceMappingURL=stats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stats.js","sourceRoot":"","sources":["../src/stats.ts"],"names":[],"mappings":"AAAA,2DAA2D;AAC3D,EAAE;AACF,uEAAuE;AACvE,gFAAgF;AAChF,6EAA6E;AAC7E,cAAc;AAad,MAAM,UAAU,oBAAoB;IAClC,OAAO,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,CAAC;AACjE,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAA0B;IAC7D,OAAO,6BAA6B,KAAK,CAAC,KAAK,cAAc,KAAK,CAAC,QAAQ,aAAa,KAAK,CAAC,OAAO,mBAAmB,KAAK,CAAC,aAAa,GAAG,CAAC;AACjJ,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@coval/sdk",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "Typed TypeScript client for the Coval evaluation platform API.",
5
5
  "license": "MIT",
6
6
  "author": "Coval <support@coval.dev>",
@@ -13,6 +13,7 @@
13
13
  import { apiKeyAuthMiddleware } from './auth.js';
14
14
  import { CovalApiError, parseErrorResponse } from './errors.js';
15
15
  import { createRetryingFetch, type RetryOptions } from './retry.js';
16
+ import { createTransportStats, type CovalTransportStats } from './stats.js';
16
17
  import {
17
18
  AgentsApi,
18
19
  APIKeysApi,
@@ -56,6 +57,11 @@ export interface CovalClientOptions {
56
57
  middleware?: Middleware[];
57
58
  /** Override the global fetch (e.g., for tests, undici-with-keepalive, etc). */
58
59
  fetch?: FetchAPI;
60
+ /**
61
+ * Called with a diagnostic line on each retry and each in-transit failure.
62
+ * Pass `console.debug` when investigating intermittent timeouts.
63
+ */
64
+ onDebug?: (message: string) => void;
59
65
  }
60
66
 
61
67
  const DEFAULT_BASE_URL = 'https://api.coval.dev/v1';
@@ -90,16 +96,29 @@ export class CovalClient {
90
96
 
91
97
  readonly configuration: Configuration;
92
98
 
99
+ /**
100
+ * Live transport counters. A request that dies in transit leaves no
101
+ * server-side trace, so these are often the only evidence when diagnosing
102
+ * intermittent failures. Include them when reporting one.
103
+ */
104
+ readonly stats: CovalTransportStats;
105
+
93
106
  constructor(options: CovalClientOptions) {
94
107
  if (!options.apiKey) {
95
108
  throw new Error('CovalClient: apiKey is required');
96
109
  }
97
110
 
111
+ this.stats = createTransportStats();
112
+
98
113
  const innerFetch: FetchAPI = options.fetch ?? (globalThis.fetch as FetchAPI);
99
114
  const fetchApi: FetchAPI =
100
115
  options.retry === false
101
116
  ? innerFetch
102
- : createRetryingFetch(options.retry ?? {}, { fetch: innerFetch });
117
+ : createRetryingFetch(options.retry ?? {}, {
118
+ fetch: innerFetch,
119
+ stats: this.stats,
120
+ onDebug: options.onDebug,
121
+ });
103
122
 
104
123
  const middleware: Middleware[] = [
105
124
  apiKeyAuthMiddleware({ apiKey: options.apiKey }),
package/src/index.ts CHANGED
@@ -9,6 +9,8 @@ export type { PaginateOptions } from './pagination.js';
9
9
  export { apiKeyAuthMiddleware } from './auth.js';
10
10
  export { createRetryingFetch } from './retry.js';
11
11
  export type { RetryOptions } from './retry.js';
12
+ export { createTransportStats, formatTransportStats } from './stats.js';
13
+ export type { CovalTransportStats } from './stats.js';
12
14
 
13
15
  // Re-export the entire generated surface so callers can reach for request
14
16
  // types, model types, and individual API classes if they want to bypass the
package/src/retry.ts CHANGED
@@ -8,6 +8,7 @@
8
8
 
9
9
  import { CovalNetworkError } from './errors.js';
10
10
  import type { FetchAPI } from './generated/runtime.js';
11
+ import type { CovalTransportStats } from './stats.js';
11
12
 
12
13
  const RETRYABLE_STATUSES = new Set([408, 429, 500, 502, 503, 504]);
13
14
  const RETRYABLE_METHODS = new Set(['GET', 'HEAD', 'OPTIONS']);
@@ -30,6 +31,10 @@ export interface RetryOptions {
30
31
  export interface RetryDeps {
31
32
  fetch?: FetchAPI;
32
33
  sleep?: (ms: number) => Promise<void>;
34
+ /** Counters mutated in place so the client can expose a live view. */
35
+ stats?: CovalTransportStats;
36
+ /** Called with a human-readable line on each retry or network error. */
37
+ onDebug?: (message: string) => void;
33
38
  }
34
39
 
35
40
  export function createRetryingFetch(options: RetryOptions = {}, deps: RetryDeps = {}): FetchAPI {
@@ -41,16 +46,22 @@ export function createRetryingFetch(options: RetryOptions = {}, deps: RetryDeps
41
46
  const retryableMethods = options.retryableMethods ?? RETRYABLE_METHODS;
42
47
  const innerFetch: FetchAPI = deps.fetch ?? (globalThis.fetch as FetchAPI);
43
48
  const sleep = deps.sleep ?? ((ms: number) => new Promise((resolve) => setTimeout(resolve, ms)));
49
+ const stats = deps.stats;
50
+ const debug = deps.onDebug;
44
51
 
45
52
  return async function retryingFetch(input, init) {
46
53
  let lastError: unknown;
47
54
  const method = (init?.method ?? 'GET').toUpperCase();
48
55
  const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;
56
+ if (stats) stats.calls += 1;
49
57
 
50
58
  if (!retryableMethods.has(method)) {
51
59
  try {
60
+ if (stats) stats.requests += 1;
52
61
  return await innerFetch(input, init);
53
62
  } catch (err) {
63
+ if (stats) stats.networkErrors += 1;
64
+ debug?.(`coval-sdk: ${method} ${url} failed in transit (not retried): ${stringifyError(err)}`);
54
65
  throw new CovalNetworkError({
55
66
  message: `Coval API request failed: ${stringifyError(err)}`,
56
67
  url,
@@ -63,15 +74,24 @@ export function createRetryingFetch(options: RetryOptions = {}, deps: RetryDeps
63
74
 
64
75
  for (let attempt = 1; attempt <= maxAttempts; attempt++) {
65
76
  try {
77
+ if (stats) stats.requests += 1;
66
78
  const response = await innerFetch(input, init);
67
79
  if (!retryable.has(response.status) || attempt === maxAttempts) {
68
80
  return response;
69
81
  }
70
82
  const wait = computeDelay({ attempt, baseDelay, maxDelay, jitter, response });
83
+ if (stats) stats.retries += 1;
84
+ debug?.(
85
+ `coval-sdk: ${method} ${url} returned ${response.status}, retrying in ${wait}ms (attempt ${attempt}/${maxAttempts})`,
86
+ );
71
87
  await sleep(wait);
72
88
  } catch (err) {
73
89
  lastError = err;
90
+ if (stats) stats.networkErrors += 1;
74
91
  if (attempt === maxAttempts) {
92
+ debug?.(
93
+ `coval-sdk: ${method} ${url} failed in transit after ${attempt} attempts: ${stringifyError(err)}`,
94
+ );
75
95
  throw new CovalNetworkError({
76
96
  message: `Coval API request failed after ${attempt} attempt${attempt > 1 ? 's' : ''}: ${stringifyError(err)}`,
77
97
  url,
@@ -81,6 +101,10 @@ export function createRetryingFetch(options: RetryOptions = {}, deps: RetryDeps
81
101
  });
82
102
  }
83
103
  const wait = computeDelay({ attempt, baseDelay, maxDelay, jitter });
104
+ if (stats) stats.retries += 1;
105
+ debug?.(
106
+ `coval-sdk: ${method} ${url} failed in transit (${stringifyError(err)}), retrying in ${wait}ms (attempt ${attempt}/${maxAttempts})`,
107
+ );
84
108
  await sleep(wait);
85
109
  }
86
110
  }
package/src/stats.ts ADDED
@@ -0,0 +1,25 @@
1
+ // Transport counters for diagnosing intermittent failures.
2
+ //
3
+ // A request that dies in transit never reaches the API, so there is no
4
+ // server-side trace of it. These counters are often the only evidence available
5
+ // when a caller reports sporadic timeouts. Mirrors `connection_stats` in the
6
+ // Python SDK.
7
+
8
+ export interface CovalTransportStats {
9
+ /** Logical API calls started. */
10
+ calls: number;
11
+ /** fetch invocations, including retries — exceeds `calls` when retries fire. */
12
+ requests: number;
13
+ /** Retry attempts beyond the initial request. */
14
+ retries: number;
15
+ /** fetch rejections: DNS failure, reset, abort, or a stranded pooled socket. */
16
+ networkErrors: number;
17
+ }
18
+
19
+ export function createTransportStats(): CovalTransportStats {
20
+ return { calls: 0, requests: 0, retries: 0, networkErrors: 0 };
21
+ }
22
+
23
+ export function formatTransportStats(stats: CovalTransportStats): string {
24
+ return `CovalTransportStats(calls=${stats.calls}, requests=${stats.requests}, retries=${stats.retries}, networkErrors=${stats.networkErrors})`;
25
+ }