@tensorcost/sdk 0.3.0 → 0.3.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/CHANGELOG.md +74 -0
- package/README.md +89 -1
- package/dist/circuit.d.ts +56 -0
- package/dist/circuit.d.ts.map +1 -0
- package/dist/circuit.js +93 -0
- package/dist/circuit.js.map +1 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +17 -0
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +67 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +84 -0
- package/dist/errors.js.map +1 -0
- package/dist/index.d.ts +4 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/providers/anthropic.d.ts +17 -1
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +179 -20
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/openai.d.ts +19 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +217 -20
- package/dist/providers/openai.js.map +1 -1
- package/dist/proxy-client.d.ts +64 -0
- package/dist/proxy-client.d.ts.map +1 -0
- package/dist/proxy-client.js +259 -0
- package/dist/proxy-client.js.map +1 -0
- package/dist/retry.d.ts +50 -0
- package/dist/retry.d.ts.map +1 -0
- package/dist/retry.js +80 -0
- package/dist/retry.js.map +1 -0
- package/dist/telemetry.d.ts +70 -0
- package/dist/telemetry.d.ts.map +1 -0
- package/dist/telemetry.js +41 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/types.d.ts +61 -0
- package/dist/types.d.ts.map +1 -1
- package/dist/wrap.d.ts +4 -0
- package/dist/wrap.d.ts.map +1 -1
- package/dist/wrap.js +26 -2
- package/dist/wrap.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,79 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.4.0 — 2026-05-13
|
|
4
|
+
|
|
5
|
+
Applied-mode hardening. Five new subsystems sit between `wrap()` and the
|
|
6
|
+
proxy POST; all are opt-in with safe defaults and zero impact on the
|
|
7
|
+
observe-only path.
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
**Typed error hierarchy** — every failure from the proxy path is a subclass of
|
|
12
|
+
`TensorCostError`. Customer code can `instanceof`-branch without importing raw
|
|
13
|
+
HTTP exception types.
|
|
14
|
+
|
|
15
|
+
- `TensorCostError` (base)
|
|
16
|
+
- `TensorCostNetworkError` — could not reach the proxy at all
|
|
17
|
+
- `TensorCostTimeoutError` — wall-clock or idle timeout fired; carries `timeoutKind: "total" | "idle"`
|
|
18
|
+
- `TensorCostProxyError` — proxy returned 5xx
|
|
19
|
+
- `TensorCostQuotaError` — proxy returned 429; carries `retryAfterMs`
|
|
20
|
+
- `TensorCostProviderError` — proxy forwarded a 4xx from the upstream AI provider
|
|
21
|
+
|
|
22
|
+
All carry `status`, `requestId`, `attempt`, and `rootCause` (avoiding the clash
|
|
23
|
+
with ES2022 `Error.cause`).
|
|
24
|
+
|
|
25
|
+
**Retries with jittered exponential backoff** — configurable via `RetryConfig`:
|
|
26
|
+
|
|
27
|
+
```ts
|
|
28
|
+
const client = wrap(new OpenAI(...), {
|
|
29
|
+
retry: { maxAttempts: 5, baseDelayMs: 500, maxDelayMs: 30_000 },
|
|
30
|
+
});
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
Retry rules: 5xx + network errors + 429 always retry; 4xx (except 429) never
|
|
34
|
+
retry; 429 with a `Retry-After` header uses that value, capped at `maxDelayMs`.
|
|
35
|
+
|
|
36
|
+
**Request timeouts** — non-streaming proxy calls have a 60-second default total
|
|
37
|
+
timeout, controllable via `timeoutMs`. Surfaces as `TensorCostTimeoutError`.
|
|
38
|
+
|
|
39
|
+
```ts
|
|
40
|
+
const client = wrap(new OpenAI(...), { timeoutMs: 30_000 });
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
**Lifecycle telemetry hooks** — optional `onLifecycleEvent` callback fires on
|
|
44
|
+
each stage. Events contain only request metadata — never prompt content or
|
|
45
|
+
credentials:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
const client = wrap(new OpenAI(...), {
|
|
49
|
+
onLifecycleEvent(event) {
|
|
50
|
+
console.log(event.kind, event.model, event.attemptNumber);
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Five event kinds: `before_request`, `after_response`, `on_retry`, `on_error`,
|
|
56
|
+
`on_fallback`. Errors in the callback are swallowed.
|
|
57
|
+
|
|
58
|
+
**Fail-open circuit breaker** — after 3 consecutive proxy 5xx responses the
|
|
59
|
+
circuit opens and all requests route directly to the provider. Closes again
|
|
60
|
+
after 5 consecutive probe successes. Controlled by `failOpenEnabled` (default
|
|
61
|
+
`true`):
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
// In-VPC: no direct provider access — raise on proxy failure instead of
|
|
65
|
+
// falling back.
|
|
66
|
+
const client = wrap(new OpenAI(...), { failOpenEnabled: false });
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
When `failOpenEnabled: true` (default) and the circuit is open, an
|
|
70
|
+
`on_fallback` lifecycle event fires before the direct-provider call.
|
|
71
|
+
|
|
72
|
+
### No breaking changes
|
|
73
|
+
|
|
74
|
+
All new options default to values that preserve 0.3.x behaviour.
|
|
75
|
+
`appliedMode` still defaults to `false`; the observe-only path is unchanged.
|
|
76
|
+
|
|
3
77
|
## 0.3.0 — 2026-05-12
|
|
4
78
|
|
|
5
79
|
- Added: `appliedMode` config flag. When true and `proxyUrl` (or `TENSORCOST_PROXY_URL`) is set, requests route through the TensorCost inference-proxy. See `docs/features/inference-proxy-applied-mode.md`.
|
package/README.md
CHANGED
|
@@ -88,6 +88,94 @@ const resp = await client.chat.completions.create({
|
|
|
88
88
|
|
|
89
89
|
See [`docs/features/inference-proxy-applied-mode.md`](../../docs/features/inference-proxy-applied-mode.md) for the proxy-side design.
|
|
90
90
|
|
|
91
|
+
## Applied-mode hardening (v0.4.0)
|
|
92
|
+
|
|
93
|
+
When `appliedMode: true`, you can configure retry policy, timeouts, lifecycle hooks, and the fail-open circuit breaker.
|
|
94
|
+
|
|
95
|
+
### Retries
|
|
96
|
+
|
|
97
|
+
```ts
|
|
98
|
+
import { wrap, RetryConfig } from "@tensorcost/sdk";
|
|
99
|
+
|
|
100
|
+
const client = wrap(new OpenAI(...), {
|
|
101
|
+
appliedMode: true,
|
|
102
|
+
proxyUrl: "...",
|
|
103
|
+
retry: { maxAttempts: 5, baseDelayMs: 500, maxDelayMs: 30_000 },
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
5xx responses, network errors, and 429 are retried with jittered exponential backoff. A `Retry-After` header on 429 is honoured. 4xx errors (except 429) are never retried.
|
|
108
|
+
|
|
109
|
+
### Timeouts
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
const client = wrap(new OpenAI(...), {
|
|
113
|
+
appliedMode: true,
|
|
114
|
+
proxyUrl: "...",
|
|
115
|
+
timeoutMs: 30_000, // 30 seconds; default 60_000
|
|
116
|
+
});
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
Surfaces as `TensorCostTimeoutError` (with `timeoutKind: "total"`) when exceeded.
|
|
120
|
+
|
|
121
|
+
### Lifecycle telemetry hooks
|
|
122
|
+
|
|
123
|
+
```ts
|
|
124
|
+
import { wrap, LifecycleEvent } from "@tensorcost/sdk";
|
|
125
|
+
|
|
126
|
+
const client = wrap(new OpenAI(...), {
|
|
127
|
+
appliedMode: true,
|
|
128
|
+
proxyUrl: "...",
|
|
129
|
+
onLifecycleEvent(event: LifecycleEvent) {
|
|
130
|
+
// event.kind is one of:
|
|
131
|
+
// "before_request" | "after_response" | "on_retry"
|
|
132
|
+
// | "on_error" | "on_fallback"
|
|
133
|
+
console.log(event.kind, event.model, event.attemptNumber);
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Events contain only request metadata — never prompt content, response bodies, or credentials. Errors thrown by the callback are swallowed.
|
|
139
|
+
|
|
140
|
+
### Typed errors
|
|
141
|
+
|
|
142
|
+
Every failure from the proxy path is a subclass of `TensorCostError`. Import the classes from `@tensorcost/sdk`:
|
|
143
|
+
|
|
144
|
+
```ts
|
|
145
|
+
import {
|
|
146
|
+
TensorCostError,
|
|
147
|
+
TensorCostNetworkError,
|
|
148
|
+
TensorCostTimeoutError,
|
|
149
|
+
TensorCostProxyError,
|
|
150
|
+
TensorCostQuotaError,
|
|
151
|
+
TensorCostProviderError,
|
|
152
|
+
} from "@tensorcost/sdk";
|
|
153
|
+
|
|
154
|
+
try {
|
|
155
|
+
await client.chat.completions.create({ model: "gpt-4o-mini", messages: [] });
|
|
156
|
+
} catch (err) {
|
|
157
|
+
if (err instanceof TensorCostQuotaError) {
|
|
158
|
+
console.log("rate limited; retry after", err.retryAfterMs, "ms");
|
|
159
|
+
} else if (err instanceof TensorCostError) {
|
|
160
|
+
console.log("tensorcost error", err.status, err.attempt);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
### Circuit breaker
|
|
166
|
+
|
|
167
|
+
After 3 consecutive proxy 5xx responses the circuit opens and requests route directly to the provider (fail-open). The circuit closes after 5 consecutive probe successes.
|
|
168
|
+
|
|
169
|
+
Set `failOpenEnabled: false` if direct provider access is unavailable (e.g. in-VPC deployments) — proxy failures then surface as `TensorCostProxyError` instead of falling back.
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
const client = wrap(new OpenAI(...), {
|
|
173
|
+
appliedMode: true,
|
|
174
|
+
proxyUrl: "...",
|
|
175
|
+
failOpenEnabled: false, // raise on proxy error instead of falling through
|
|
176
|
+
});
|
|
177
|
+
```
|
|
178
|
+
|
|
91
179
|
## Fail-open guarantee
|
|
92
180
|
|
|
93
181
|
If TensorCost is slow, down, or misconfigured, your customer call STILL succeeds. The SDK swallows internal errors and surfaces them via `console.warn`. The one exception: a missing API key throws `MissingConfigError` at `wrap()` time — silently dropping every observation would be worse than a loud import-time failure.
|
|
@@ -116,4 +204,4 @@ Only metadata — never prompt or completion content:
|
|
|
116
204
|
|
|
117
205
|
## License
|
|
118
206
|
|
|
119
|
-
Proprietary —
|
|
207
|
+
Proprietary — TensorCost.
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Circuit breaker for the fail-open fallback (Feature E).
|
|
3
|
+
*
|
|
4
|
+
* Tracks consecutive proxy failures. When the failure count hits
|
|
5
|
+
* `openThreshold`, the circuit opens and all subsequent requests route
|
|
6
|
+
* directly to the provider instead of through the proxy. The circuit
|
|
7
|
+
* moves back to closed once `closeThreshold` consecutive probe calls
|
|
8
|
+
* (which go through the proxy) succeed.
|
|
9
|
+
*
|
|
10
|
+
* State machine:
|
|
11
|
+
*
|
|
12
|
+
* CLOSED ──(failures >= openThreshold)──> OPEN
|
|
13
|
+
* OPEN ──(next call, always probes)───> HALF_OPEN
|
|
14
|
+
* HALF_OPEN ──(proxy 2xx)──────────────> probeSuccesses++
|
|
15
|
+
* ──(proxy 5xx/err)──────────> back to OPEN (resets probes)
|
|
16
|
+
* HALF_OPEN ──(probeSuccesses >= closeThreshold)──> CLOSED
|
|
17
|
+
*
|
|
18
|
+
* This is intentionally simple and synchronous — the circuit lives on the
|
|
19
|
+
* SDK client instance and is not shared across network calls.
|
|
20
|
+
*/
|
|
21
|
+
export type CircuitState = "CLOSED" | "OPEN" | "HALF_OPEN";
|
|
22
|
+
export interface CircuitBreakerConfig {
|
|
23
|
+
/** Number of consecutive proxy failures before the circuit opens. Default: 3. */
|
|
24
|
+
openThreshold: number;
|
|
25
|
+
/** Number of consecutive successful probes before the circuit closes. Default: 5. */
|
|
26
|
+
closeThreshold: number;
|
|
27
|
+
}
|
|
28
|
+
export declare const DEFAULT_CIRCUIT_CONFIG: CircuitBreakerConfig;
|
|
29
|
+
export declare class CircuitBreaker {
|
|
30
|
+
private state;
|
|
31
|
+
private consecutiveFailures;
|
|
32
|
+
private probeSuccesses;
|
|
33
|
+
readonly config: CircuitBreakerConfig;
|
|
34
|
+
constructor(config?: CircuitBreakerConfig);
|
|
35
|
+
/** Current circuit state. */
|
|
36
|
+
get currentState(): CircuitState;
|
|
37
|
+
/** How many consecutive failures have been recorded. */
|
|
38
|
+
get failures(): number;
|
|
39
|
+
/**
|
|
40
|
+
* Returns true when calls should bypass the proxy and go directly to the
|
|
41
|
+
* provider. The caller must always call `recordSuccess` or `recordFailure`
|
|
42
|
+
* afterwards to keep the state machine moving.
|
|
43
|
+
*/
|
|
44
|
+
shouldBypass(): boolean;
|
|
45
|
+
/**
|
|
46
|
+
* Returns true when the next call should be a probe (the circuit is
|
|
47
|
+
* OPEN and we are transitioning to HALF_OPEN to test the proxy).
|
|
48
|
+
*/
|
|
49
|
+
shouldProbe(): boolean;
|
|
50
|
+
/** Call after a proxy request succeeds. */
|
|
51
|
+
recordSuccess(): void;
|
|
52
|
+
/** Call after a proxy request fails (5xx or network error). */
|
|
53
|
+
recordFailure(): void;
|
|
54
|
+
private reset;
|
|
55
|
+
}
|
|
56
|
+
//# sourceMappingURL=circuit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit.d.ts","sourceRoot":"","sources":["../src/circuit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,MAAM,GAAG,WAAW,CAAC;AAE3D,MAAM,WAAW,oBAAoB;IACnC,iFAAiF;IACjF,aAAa,EAAE,MAAM,CAAC;IACtB,qFAAqF;IACrF,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,eAAO,MAAM,sBAAsB,EAAE,oBAGpC,CAAC;AAEF,qBAAa,cAAc;IACzB,OAAO,CAAC,KAAK,CAA0B;IACvC,OAAO,CAAC,mBAAmB,CAAK;IAChC,OAAO,CAAC,cAAc,CAAK;IAC3B,QAAQ,CAAC,MAAM,EAAE,oBAAoB,CAAC;gBAE1B,MAAM,GAAE,oBAA6C;IAIjE,6BAA6B;IAC7B,IAAI,YAAY,IAAI,YAAY,CAE/B;IAED,wDAAwD;IACxD,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED;;;;OAIG;IACH,YAAY,IAAI,OAAO;IAIvB;;;OAGG;IACH,WAAW,IAAI,OAAO;IAStB,2CAA2C;IAC3C,aAAa,IAAI,IAAI;IAWrB,+DAA+D;IAC/D,aAAa,IAAI,IAAI;IAcrB,OAAO,CAAC,KAAK;CAKd"}
|
package/dist/circuit.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Circuit breaker for the fail-open fallback (Feature E).
|
|
3
|
+
*
|
|
4
|
+
* Tracks consecutive proxy failures. When the failure count hits
|
|
5
|
+
* `openThreshold`, the circuit opens and all subsequent requests route
|
|
6
|
+
* directly to the provider instead of through the proxy. The circuit
|
|
7
|
+
* moves back to closed once `closeThreshold` consecutive probe calls
|
|
8
|
+
* (which go through the proxy) succeed.
|
|
9
|
+
*
|
|
10
|
+
* State machine:
|
|
11
|
+
*
|
|
12
|
+
* CLOSED ──(failures >= openThreshold)──> OPEN
|
|
13
|
+
* OPEN ──(next call, always probes)───> HALF_OPEN
|
|
14
|
+
* HALF_OPEN ──(proxy 2xx)──────────────> probeSuccesses++
|
|
15
|
+
* ──(proxy 5xx/err)──────────> back to OPEN (resets probes)
|
|
16
|
+
* HALF_OPEN ──(probeSuccesses >= closeThreshold)──> CLOSED
|
|
17
|
+
*
|
|
18
|
+
* This is intentionally simple and synchronous — the circuit lives on the
|
|
19
|
+
* SDK client instance and is not shared across network calls.
|
|
20
|
+
*/
|
|
21
|
+
export const DEFAULT_CIRCUIT_CONFIG = {
|
|
22
|
+
openThreshold: 3,
|
|
23
|
+
closeThreshold: 5,
|
|
24
|
+
};
|
|
25
|
+
export class CircuitBreaker {
|
|
26
|
+
constructor(config = DEFAULT_CIRCUIT_CONFIG) {
|
|
27
|
+
this.state = "CLOSED";
|
|
28
|
+
this.consecutiveFailures = 0;
|
|
29
|
+
this.probeSuccesses = 0;
|
|
30
|
+
this.config = config;
|
|
31
|
+
}
|
|
32
|
+
/** Current circuit state. */
|
|
33
|
+
get currentState() {
|
|
34
|
+
return this.state;
|
|
35
|
+
}
|
|
36
|
+
/** How many consecutive failures have been recorded. */
|
|
37
|
+
get failures() {
|
|
38
|
+
return this.consecutiveFailures;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Returns true when calls should bypass the proxy and go directly to the
|
|
42
|
+
* provider. The caller must always call `recordSuccess` or `recordFailure`
|
|
43
|
+
* afterwards to keep the state machine moving.
|
|
44
|
+
*/
|
|
45
|
+
shouldBypass() {
|
|
46
|
+
return this.state === "OPEN";
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Returns true when the next call should be a probe (the circuit is
|
|
50
|
+
* OPEN and we are transitioning to HALF_OPEN to test the proxy).
|
|
51
|
+
*/
|
|
52
|
+
shouldProbe() {
|
|
53
|
+
if (this.state === "OPEN") {
|
|
54
|
+
// Transition to HALF_OPEN for the probe attempt.
|
|
55
|
+
this.state = "HALF_OPEN";
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
return false;
|
|
59
|
+
}
|
|
60
|
+
/** Call after a proxy request succeeds. */
|
|
61
|
+
recordSuccess() {
|
|
62
|
+
if (this.state === "HALF_OPEN") {
|
|
63
|
+
this.probeSuccesses += 1;
|
|
64
|
+
if (this.probeSuccesses >= this.config.closeThreshold) {
|
|
65
|
+
this.reset();
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
else if (this.state === "CLOSED") {
|
|
69
|
+
this.consecutiveFailures = 0;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
/** Call after a proxy request fails (5xx or network error). */
|
|
73
|
+
recordFailure() {
|
|
74
|
+
if (this.state === "HALF_OPEN") {
|
|
75
|
+
// Probe failed — go back to fully open.
|
|
76
|
+
this.state = "OPEN";
|
|
77
|
+
this.probeSuccesses = 0;
|
|
78
|
+
}
|
|
79
|
+
else if (this.state === "CLOSED") {
|
|
80
|
+
this.consecutiveFailures += 1;
|
|
81
|
+
if (this.consecutiveFailures >= this.config.openThreshold) {
|
|
82
|
+
this.state = "OPEN";
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// OPEN + another failure: stay open, no state change needed.
|
|
86
|
+
}
|
|
87
|
+
reset() {
|
|
88
|
+
this.state = "CLOSED";
|
|
89
|
+
this.consecutiveFailures = 0;
|
|
90
|
+
this.probeSuccesses = 0;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=circuit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"circuit.js","sourceRoot":"","sources":["../src/circuit.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAWH,MAAM,CAAC,MAAM,sBAAsB,GAAyB;IAC1D,aAAa,EAAE,CAAC;IAChB,cAAc,EAAE,CAAC;CAClB,CAAC;AAEF,MAAM,OAAO,cAAc;IAMzB,YAAY,SAA+B,sBAAsB;QALzD,UAAK,GAAiB,QAAQ,CAAC;QAC/B,wBAAmB,GAAG,CAAC,CAAC;QACxB,mBAAc,GAAG,CAAC,CAAC;QAIzB,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC;IACvB,CAAC;IAED,6BAA6B;IAC7B,IAAI,YAAY;QACd,OAAO,IAAI,CAAC,KAAK,CAAC;IACpB,CAAC;IAED,wDAAwD;IACxD,IAAI,QAAQ;QACV,OAAO,IAAI,CAAC,mBAAmB,CAAC;IAClC,CAAC;IAED;;;;OAIG;IACH,YAAY;QACV,OAAO,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC;IAC/B,CAAC;IAED;;;OAGG;IACH,WAAW;QACT,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,EAAE,CAAC;YAC1B,iDAAiD;YACjD,IAAI,CAAC,KAAK,GAAG,WAAW,CAAC;YACzB,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,KAAK,CAAC;IACf,CAAC;IAED,2CAA2C;IAC3C,aAAa;QACX,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAC/B,IAAI,CAAC,cAAc,IAAI,CAAC,CAAC;YACzB,IAAI,IAAI,CAAC,cAAc,IAAI,IAAI,CAAC,MAAM,CAAC,cAAc,EAAE,CAAC;gBACtD,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,CAAC;QACH,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACnC,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAC/B,CAAC;IACH,CAAC;IAED,+DAA+D;IAC/D,aAAa;QACX,IAAI,IAAI,CAAC,KAAK,KAAK,WAAW,EAAE,CAAC;YAC/B,wCAAwC;YACxC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC;YACpB,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;QAC1B,CAAC;aAAM,IAAI,IAAI,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;YACnC,IAAI,CAAC,mBAAmB,IAAI,CAAC,CAAC;YAC9B,IAAI,IAAI,CAAC,mBAAmB,IAAI,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,CAAC;gBAC1D,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC;YACtB,CAAC;QACH,CAAC;QACD,6DAA6D;IAC/D,CAAC;IAEO,KAAK;QACX,IAAI,CAAC,KAAK,GAAG,QAAQ,CAAC;QACtB,IAAI,CAAC,mBAAmB,GAAG,CAAC,CAAC;QAC7B,IAAI,CAAC,cAAc,GAAG,CAAC,CAAC;IAC1B,CAAC;CACF"}
|
package/dist/config.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAG9D,eAAO,MAAM,gBAAgB,+BAA+B,CAAC;AAE7D,qBAAa,kBAAmB,SAAQ,KAAK;gBAC/B,OAAO,EAAE,MAAM;CAI5B;AAED,yEAAyE;AACzE,qBAAa,qBAAsB,SAAQ,KAAK;gBAClC,OAAO,EAAE,MAAM;CAI5B;AAED,wBAAgB,aAAa,CAAC,OAAO,GAAE,WAAgB,GAAG,cAAc,CAuFvE"}
|
package/dist/config.js
CHANGED
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
* TensorCostConfigError is thrown. Applied mode needs an explicit proxy
|
|
17
17
|
* URL; there is no safe default.
|
|
18
18
|
*/
|
|
19
|
+
import { DEFAULT_RETRY_CONFIG } from "./retry.js";
|
|
19
20
|
export const DEFAULT_BASE_URL = "https://api.tensorcost.com";
|
|
20
21
|
export class MissingConfigError extends Error {
|
|
21
22
|
constructor(message) {
|
|
@@ -72,6 +73,16 @@ export function resolveConfig(options = {}) {
|
|
|
72
73
|
"Pass { proxyUrl } to wrap() or set the TENSORCOST_PROXY_URL " +
|
|
73
74
|
"environment variable.");
|
|
74
75
|
}
|
|
76
|
+
// Hardening defaults.
|
|
77
|
+
const retry = {
|
|
78
|
+
...DEFAULT_RETRY_CONFIG,
|
|
79
|
+
...options.retry,
|
|
80
|
+
};
|
|
81
|
+
const timeoutMs = options.timeoutMs ?? 60_000;
|
|
82
|
+
const idleTimeoutMs = options.idleTimeoutMs ?? 30_000;
|
|
83
|
+
const onLifecycleEvent = options.onLifecycleEvent;
|
|
84
|
+
const failOpenEnabled = options.failOpenEnabled ?? true;
|
|
85
|
+
const providerApiKey = options.providerApiKey ?? null;
|
|
75
86
|
return {
|
|
76
87
|
apiKey,
|
|
77
88
|
baseUrl: baseUrlRaw.replace(/\/+$/, ""),
|
|
@@ -81,6 +92,12 @@ export function resolveConfig(options = {}) {
|
|
|
81
92
|
failOpen,
|
|
82
93
|
appliedMode,
|
|
83
94
|
proxyUrl,
|
|
95
|
+
retry,
|
|
96
|
+
timeoutMs,
|
|
97
|
+
idleTimeoutMs,
|
|
98
|
+
onLifecycleEvent,
|
|
99
|
+
failOpenEnabled,
|
|
100
|
+
providerApiKey,
|
|
84
101
|
};
|
|
85
102
|
}
|
|
86
103
|
//# sourceMappingURL=config.js.map
|
package/dist/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"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"}
|
package/dist/errors.d.ts
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed error hierarchy for the TensorCost Node SDK.
|
|
3
|
+
*
|
|
4
|
+
* Every error thrown by the SDK's applied-mode request path is one of
|
|
5
|
+
* these classes. Customer code can `instanceof`-branch on any of them
|
|
6
|
+
* without importing raw Error types from the underlying http layer.
|
|
7
|
+
*
|
|
8
|
+
* Hierarchy:
|
|
9
|
+
*
|
|
10
|
+
* TensorCostError (base)
|
|
11
|
+
* ├── TensorCostNetworkError couldn't reach the proxy at all
|
|
12
|
+
* ├── TensorCostTimeoutError request or idle window exceeded limit
|
|
13
|
+
* ├── TensorCostProxyError proxy responded with 5xx
|
|
14
|
+
* ├── TensorCostQuotaError proxy responded with 429
|
|
15
|
+
* └── TensorCostProviderError proxy forwarded an upstream provider error
|
|
16
|
+
*
|
|
17
|
+
* All subclasses carry:
|
|
18
|
+
* - `rootCause` the underlying Error, if any (avoids clash with ES2022 Error.cause)
|
|
19
|
+
* - `status` HTTP status code (null when the request never completed)
|
|
20
|
+
* - `requestId` value of the X-TC-Request-ID header the proxy stamps
|
|
21
|
+
* - `attempt` 1-based attempt number at the time the error occurred
|
|
22
|
+
*/
|
|
23
|
+
export interface TensorCostErrorOptions {
|
|
24
|
+
cause?: Error;
|
|
25
|
+
status?: number | null;
|
|
26
|
+
requestId?: string | null;
|
|
27
|
+
attempt?: number;
|
|
28
|
+
}
|
|
29
|
+
export declare abstract class TensorCostError extends Error {
|
|
30
|
+
/** The underlying Error that triggered this one, if any. */
|
|
31
|
+
readonly rootCause: Error | undefined;
|
|
32
|
+
readonly status: number | null;
|
|
33
|
+
readonly requestId: string | null;
|
|
34
|
+
readonly attempt: number;
|
|
35
|
+
constructor(message: string, opts?: TensorCostErrorOptions);
|
|
36
|
+
}
|
|
37
|
+
/** The SDK could not establish a connection to the proxy at all. */
|
|
38
|
+
export declare class TensorCostNetworkError extends TensorCostError {
|
|
39
|
+
constructor(message: string, opts?: TensorCostErrorOptions);
|
|
40
|
+
}
|
|
41
|
+
/** A request or idle-window timeout fired before the operation completed. */
|
|
42
|
+
export declare class TensorCostTimeoutError extends TensorCostError {
|
|
43
|
+
/** "total" — wall-clock limit exceeded; "idle" — no bytes for N seconds. */
|
|
44
|
+
readonly timeoutKind: "total" | "idle";
|
|
45
|
+
constructor(message: string, timeoutKind: "total" | "idle", opts?: TensorCostErrorOptions);
|
|
46
|
+
}
|
|
47
|
+
/** The proxy returned a 5xx response (TensorCost's own infrastructure error). */
|
|
48
|
+
export declare class TensorCostProxyError extends TensorCostError {
|
|
49
|
+
constructor(message: string, opts?: TensorCostErrorOptions);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* The proxy returned 429 Too Many Requests.
|
|
53
|
+
* `retryAfterMs` is set when the response included a `Retry-After` header.
|
|
54
|
+
*/
|
|
55
|
+
export declare class TensorCostQuotaError extends TensorCostError {
|
|
56
|
+
readonly retryAfterMs: number | null;
|
|
57
|
+
constructor(message: string, retryAfterMs: number | null, opts?: TensorCostErrorOptions);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* The proxy successfully reached the upstream provider, but the provider
|
|
61
|
+
* itself returned an error (4xx/5xx from OpenAI, Anthropic, etc.). The
|
|
62
|
+
* proxy's response still carries the provider's status in `status`.
|
|
63
|
+
*/
|
|
64
|
+
export declare class TensorCostProviderError extends TensorCostError {
|
|
65
|
+
constructor(message: string, opts?: TensorCostErrorOptions);
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,MAAM,WAAW,sBAAsB;IACrC,KAAK,CAAC,EAAE,KAAK,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,8BAAsB,eAAgB,SAAQ,KAAK;IACjD,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,EAAE,KAAK,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IAC/B,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IAClC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEb,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,sBAA2B;CAqB/D;AAED,oEAAoE;AACpE,qBAAa,sBAAuB,SAAQ,eAAe;gBAC7C,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,sBAA2B;CAG/D;AAED,6EAA6E;AAC7E,qBAAa,sBAAuB,SAAQ,eAAe;IACzD,4EAA4E;IAC5E,QAAQ,CAAC,WAAW,EAAE,OAAO,GAAG,MAAM,CAAC;gBAGrC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,OAAO,GAAG,MAAM,EAC7B,IAAI,GAAE,sBAA2B;CAKpC;AAED,iFAAiF;AACjF,qBAAa,oBAAqB,SAAQ,eAAe;gBAC3C,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,sBAA2B;CAG/D;AAED;;;GAGG;AACH,qBAAa,oBAAqB,SAAQ,eAAe;IACvD,QAAQ,CAAC,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;gBAGnC,OAAO,EAAE,MAAM,EACf,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,IAAI,GAAE,sBAA2B;CAKpC;AAED;;;;GAIG;AACH,qBAAa,uBAAwB,SAAQ,eAAe;gBAC9C,OAAO,EAAE,MAAM,EAAE,IAAI,GAAE,sBAA2B;CAG/D"}
|
package/dist/errors.js
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed error hierarchy for the TensorCost Node SDK.
|
|
3
|
+
*
|
|
4
|
+
* Every error thrown by the SDK's applied-mode request path is one of
|
|
5
|
+
* these classes. Customer code can `instanceof`-branch on any of them
|
|
6
|
+
* without importing raw Error types from the underlying http layer.
|
|
7
|
+
*
|
|
8
|
+
* Hierarchy:
|
|
9
|
+
*
|
|
10
|
+
* TensorCostError (base)
|
|
11
|
+
* ├── TensorCostNetworkError couldn't reach the proxy at all
|
|
12
|
+
* ├── TensorCostTimeoutError request or idle window exceeded limit
|
|
13
|
+
* ├── TensorCostProxyError proxy responded with 5xx
|
|
14
|
+
* ├── TensorCostQuotaError proxy responded with 429
|
|
15
|
+
* └── TensorCostProviderError proxy forwarded an upstream provider error
|
|
16
|
+
*
|
|
17
|
+
* All subclasses carry:
|
|
18
|
+
* - `rootCause` the underlying Error, if any (avoids clash with ES2022 Error.cause)
|
|
19
|
+
* - `status` HTTP status code (null when the request never completed)
|
|
20
|
+
* - `requestId` value of the X-TC-Request-ID header the proxy stamps
|
|
21
|
+
* - `attempt` 1-based attempt number at the time the error occurred
|
|
22
|
+
*/
|
|
23
|
+
export class TensorCostError extends Error {
|
|
24
|
+
constructor(message, opts = {}) {
|
|
25
|
+
super(message);
|
|
26
|
+
// noImplicitOverride requires `override` for inherited props.
|
|
27
|
+
// We set name on the *instance* without re-declaring the property type,
|
|
28
|
+
// which is the correct approach for custom Error subclasses in strict TS.
|
|
29
|
+
Object.defineProperty(this, "name", {
|
|
30
|
+
value: this.constructor.name,
|
|
31
|
+
writable: true,
|
|
32
|
+
enumerable: false,
|
|
33
|
+
configurable: true,
|
|
34
|
+
});
|
|
35
|
+
this.rootCause = opts.cause;
|
|
36
|
+
this.status = opts.status ?? null;
|
|
37
|
+
this.requestId = opts.requestId ?? null;
|
|
38
|
+
this.attempt = opts.attempt ?? 1;
|
|
39
|
+
// Keep stack traces clean in V8 environments.
|
|
40
|
+
if (Error.captureStackTrace) {
|
|
41
|
+
Error.captureStackTrace(this, this.constructor);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/** The SDK could not establish a connection to the proxy at all. */
|
|
46
|
+
export class TensorCostNetworkError extends TensorCostError {
|
|
47
|
+
constructor(message, opts = {}) {
|
|
48
|
+
super(message, opts);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
/** A request or idle-window timeout fired before the operation completed. */
|
|
52
|
+
export class TensorCostTimeoutError extends TensorCostError {
|
|
53
|
+
constructor(message, timeoutKind, opts = {}) {
|
|
54
|
+
super(message, opts);
|
|
55
|
+
this.timeoutKind = timeoutKind;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
/** The proxy returned a 5xx response (TensorCost's own infrastructure error). */
|
|
59
|
+
export class TensorCostProxyError extends TensorCostError {
|
|
60
|
+
constructor(message, opts = {}) {
|
|
61
|
+
super(message, opts);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The proxy returned 429 Too Many Requests.
|
|
66
|
+
* `retryAfterMs` is set when the response included a `Retry-After` header.
|
|
67
|
+
*/
|
|
68
|
+
export class TensorCostQuotaError extends TensorCostError {
|
|
69
|
+
constructor(message, retryAfterMs, opts = {}) {
|
|
70
|
+
super(message, { ...opts, status: opts.status ?? 429 });
|
|
71
|
+
this.retryAfterMs = retryAfterMs;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* The proxy successfully reached the upstream provider, but the provider
|
|
76
|
+
* itself returned an error (4xx/5xx from OpenAI, Anthropic, etc.). The
|
|
77
|
+
* proxy's response still carries the provider's status in `status`.
|
|
78
|
+
*/
|
|
79
|
+
export class TensorCostProviderError extends TensorCostError {
|
|
80
|
+
constructor(message, opts = {}) {
|
|
81
|
+
super(message, opts);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AASH,MAAM,OAAgB,eAAgB,SAAQ,KAAK;IAOjD,YAAY,OAAe,EAAE,OAA+B,EAAE;QAC5D,KAAK,CAAC,OAAO,CAAC,CAAC;QACf,8DAA8D;QAC9D,wEAAwE;QACxE,0EAA0E;QAC1E,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE;YAClC,KAAK,EAAE,IAAI,CAAC,WAAW,CAAC,IAAI;YAC5B,QAAQ,EAAE,IAAI;YACd,UAAU,EAAE,KAAK;YACjB,YAAY,EAAE,IAAI;SACnB,CAAC,CAAC;QACH,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC;QAC5B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,IAAI,CAAC;QAClC,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC;QACxC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,CAAC;QAEjC,8CAA8C;QAC9C,IAAI,KAAK,CAAC,iBAAiB,EAAE,CAAC;YAC5B,KAAK,CAAC,iBAAiB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;CACF;AAED,oEAAoE;AACpE,MAAM,OAAO,sBAAuB,SAAQ,eAAe;IACzD,YAAY,OAAe,EAAE,OAA+B,EAAE;QAC5D,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACvB,CAAC;CACF;AAED,6EAA6E;AAC7E,MAAM,OAAO,sBAAuB,SAAQ,eAAe;IAIzD,YACE,OAAe,EACf,WAA6B,EAC7B,OAA+B,EAAE;QAEjC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;QACrB,IAAI,CAAC,WAAW,GAAG,WAAW,CAAC;IACjC,CAAC;CACF;AAED,iFAAiF;AACjF,MAAM,OAAO,oBAAqB,SAAQ,eAAe;IACvD,YAAY,OAAe,EAAE,OAA+B,EAAE;QAC5D,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACvB,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,OAAO,oBAAqB,SAAQ,eAAe;IAGvD,YACE,OAAe,EACf,YAA2B,EAC3B,OAA+B,EAAE;QAEjC,KAAK,CAAC,OAAO,EAAE,EAAE,GAAG,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,GAAG,EAAE,CAAC,CAAC;QACxD,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,OAAO,uBAAwB,SAAQ,eAAe;IAC1D,YAAY,OAAe,EAAE,OAA+B,EAAE;QAC5D,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;IACvB,CAAC;CACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
export { wrap } from "./wrap.js";
|
|
2
2
|
export { MissingConfigError, TensorCostConfigError } from "./config.js";
|
|
3
3
|
export { UnsupportedClientError } from "./providers/detect.js";
|
|
4
|
+
export { TensorCostError, TensorCostNetworkError, TensorCostTimeoutError, TensorCostProxyError, TensorCostQuotaError, TensorCostProviderError, } from "./errors.js";
|
|
5
|
+
export type { LifecycleEvent, BeforeRequestEvent, AfterResponseEvent, OnRetryEvent, OnErrorEvent, OnFallbackEvent, LifecycleEventCallback, } from "./telemetry.js";
|
|
6
|
+
export type { RetryConfig } from "./retry.js";
|
|
4
7
|
export type { WrapOptions, Observation, Provider } from "./types.js";
|
|
5
|
-
export declare const version = "0.
|
|
8
|
+
export declare const version = "0.4.0";
|
|
6
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAErE,eAAO,MAAM,OAAO,UAAU,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AACrB,YAAY,EACV,cAAc,EACd,kBAAkB,EAClB,kBAAkB,EAClB,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,sBAAsB,GACvB,MAAM,gBAAgB,CAAC;AACxB,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAErE,eAAO,MAAM,OAAO,UAAU,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export { wrap } from "./wrap.js";
|
|
2
2
|
export { MissingConfigError, TensorCostConfigError } from "./config.js";
|
|
3
3
|
export { UnsupportedClientError } from "./providers/detect.js";
|
|
4
|
-
export
|
|
4
|
+
export { TensorCostError, TensorCostNetworkError, TensorCostTimeoutError, TensorCostProxyError, TensorCostQuotaError, TensorCostProviderError, } from "./errors.js";
|
|
5
|
+
export const version = "0.4.0";
|
|
5
6
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AACxE,OAAO,EAAE,sBAAsB,EAAE,MAAM,uBAAuB,CAAC;AAC/D,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,sBAAsB,EACtB,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,GACxB,MAAM,aAAa,CAAC;AAarB,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
|
|
@@ -4,9 +4,25 @@
|
|
|
4
4
|
* Intercepts `client.messages.create`. Same observation contract as the
|
|
5
5
|
* OpenAI wrapper — only metadata is captured (model, input/output tokens),
|
|
6
6
|
* never the message content itself.
|
|
7
|
+
*
|
|
8
|
+
* Applied-mode hardening (v0.4.0): messages.create routes through the
|
|
9
|
+
* proxy-client module, which handles retries, timeouts, typed errors,
|
|
10
|
+
* telemetry hooks, and the fail-open circuit breaker.
|
|
7
11
|
*/
|
|
8
12
|
import type { ObservationTransport } from "../transport.js";
|
|
9
|
-
|
|
13
|
+
import type { CircuitBreaker } from "../circuit.js";
|
|
14
|
+
import type { LifecycleEventCallback } from "../telemetry.js";
|
|
15
|
+
import type { RetryConfig } from "../retry.js";
|
|
16
|
+
export interface AppliedModeHardeningOpts {
|
|
17
|
+
appliedMode: boolean;
|
|
18
|
+
proxyUrl: string | null;
|
|
19
|
+
retry: RetryConfig;
|
|
20
|
+
timeoutMs: number;
|
|
21
|
+
onLifecycleEvent: LifecycleEventCallback | undefined;
|
|
22
|
+
failOpenEnabled: boolean;
|
|
23
|
+
circuit: CircuitBreaker;
|
|
24
|
+
}
|
|
25
|
+
export declare function install(client: unknown, transport: ObservationTransport, tenantId: string | null, environment: string | null, connectionId: string | null, hardening: AppliedModeHardeningOpts): void;
|
|
10
26
|
export declare const __test__: {
|
|
11
27
|
MARKER: string;
|
|
12
28
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAIH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAG5D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAEpD,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK/C,MAAM,WAAW,wBAAwB;IACvC,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,sBAAsB,GAAG,SAAS,CAAC;IACrD,eAAe,EAAE,OAAO,CAAC;IACzB,OAAO,EAAE,cAAc,CAAC;CACzB;AA6PD,wBAAgB,OAAO,CACrB,MAAM,EAAE,OAAO,EACf,SAAS,EAAE,oBAAoB,EAC/B,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,WAAW,EAAE,MAAM,GAAG,IAAI,EAC1B,YAAY,EAAE,MAAM,GAAG,IAAI,EAC3B,SAAS,EAAE,wBAAwB,GAClC,IAAI,CAoBN;AAED,eAAO,MAAM,QAAQ;;CAAa,CAAC"}
|