@tensorcost/sdk 1.4.0 → 1.5.0
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 +210 -0
- package/README.md +34 -16
- package/dist/admit-client.d.ts +17 -9
- package/dist/admit-client.d.ts.map +1 -1
- package/dist/admit-client.js +85 -30
- package/dist/admit-client.js.map +1 -1
- package/dist/applied.d.ts +114 -0
- package/dist/applied.d.ts.map +1 -1
- package/dist/applied.js +40 -50
- package/dist/applied.js.map +1 -1
- package/dist/errors.d.ts +155 -27
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +137 -27
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/provider-errors.d.ts +15 -0
- package/dist/provider-errors.d.ts.map +1 -0
- package/dist/provider-errors.js +69 -0
- package/dist/provider-errors.js.map +1 -0
- package/dist/providers/anthropic.d.ts +54 -0
- package/dist/providers/anthropic.d.ts.map +1 -1
- package/dist/providers/anthropic.js +57 -18
- package/dist/providers/anthropic.js.map +1 -1
- package/dist/providers/bedrock.d.ts +4 -1
- package/dist/providers/bedrock.d.ts.map +1 -1
- package/dist/providers/bedrock.js +3 -2
- package/dist/providers/bedrock.js.map +1 -1
- package/dist/providers/detect.d.ts.map +1 -1
- package/dist/providers/detect.js +9 -6
- package/dist/providers/detect.js.map +1 -1
- package/dist/providers/openai.d.ts.map +1 -1
- package/dist/providers/openai.js +21 -47
- package/dist/providers/openai.js.map +1 -1
- package/dist/providers/vertex.d.ts +17 -0
- package/dist/providers/vertex.d.ts.map +1 -1
- package/dist/providers/vertex.js +5 -2
- package/dist/providers/vertex.js.map +1 -1
- package/dist/proxy-client.d.ts +157 -0
- package/dist/proxy-client.d.ts.map +1 -1
- package/dist/proxy-client.js +188 -201
- package/dist/proxy-client.js.map +1 -1
- package/dist/refusal.d.ts +43 -0
- package/dist/refusal.d.ts.map +1 -0
- package/dist/refusal.js +154 -0
- package/dist/refusal.js.map +1 -0
- package/dist/transport.d.ts.map +1 -1
- package/dist/transport.js +45 -13
- package/dist/transport.js.map +1 -1
- package/dist/types.d.ts +15 -1
- package/dist/types.d.ts.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/wrap-overhead.d.ts +43 -0
- package/dist/wrap-overhead.d.ts.map +1 -1
- package/dist/wrap-overhead.js +28 -1
- package/dist/wrap-overhead.js.map +1 -1
- package/dist/wrap.d.ts +25 -0
- package/dist/wrap.d.ts.map +1 -1
- package/dist/wrap.js +51 -8
- package/dist/wrap.js.map +1 -1
- package/package.json +1 -1
package/dist/errors.js
CHANGED
|
@@ -8,11 +8,27 @@
|
|
|
8
8
|
* Hierarchy:
|
|
9
9
|
*
|
|
10
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
|
|
15
|
-
*
|
|
11
|
+
* ├── TensorCostNetworkError couldn't reach the proxy at all ┐
|
|
12
|
+
* ├── TensorCostTimeoutError request or idle window exceeded limit │ outages: the only
|
|
13
|
+
* ├── TensorCostProxyError proxy responded with 5xx │ errors that may fall
|
|
14
|
+
* ├── TensorCostQuotaError proxy 429, or 402 plan ceiling ┘ back to the provider
|
|
15
|
+
* ├── TensorCostProviderError proxy relayed an upstream provider 4xx
|
|
16
|
+
* │ (rethrown as the provider SDK's own error
|
|
17
|
+
* │ type when the client can build one)
|
|
18
|
+
* ├── TensorCostGatewayRejectedError non-JSON 4xx from in front of TensorCost
|
|
19
|
+
* ├── TensorCostKeyRejectedError token exchange rejected the API key
|
|
20
|
+
* └── TensorCostRefusedError TensorCost refused the call (terminal)
|
|
21
|
+
* ├── TensorCostRunBudgetExceededError
|
|
22
|
+
* ├── TensorCostRunStoppedError
|
|
23
|
+
* ├── TensorCostPeriodBudgetExceededError
|
|
24
|
+
* │ └── TensorCostBudgetHardCapError
|
|
25
|
+
* ├── TensorCostModelGovernanceDeniedError
|
|
26
|
+
* ├── TensorCostGuardrailHardStopError
|
|
27
|
+
* ├── TensorCostComplianceDeniedError
|
|
28
|
+
* └── TensorCostComplianceTeamMismatchError
|
|
29
|
+
*
|
|
30
|
+
* A refusal code this SDK version doesn't model still arrives as a plain
|
|
31
|
+
* TensorCostRefusedError with its `code`, `reason` and message intact.
|
|
16
32
|
*
|
|
17
33
|
* All subclasses carry:
|
|
18
34
|
* - `rootCause` the underlying Error, if any (avoids clash with ES2022 Error.cause)
|
|
@@ -62,7 +78,9 @@ export class TensorCostProxyError extends TensorCostError {
|
|
|
62
78
|
}
|
|
63
79
|
}
|
|
64
80
|
/**
|
|
65
|
-
* The proxy returned 429 Too Many Requests
|
|
81
|
+
* The proxy returned 429 Too Many Requests (TensorCost's own rate limit),
|
|
82
|
+
* or 402 with no refusal body (the plan's monthly proxy-request ceiling;
|
|
83
|
+
* `status` says which). Neither carries a refusal, so both may fall back.
|
|
66
84
|
* `retryAfterMs` is set when the response included a `Retry-After` header.
|
|
67
85
|
*/
|
|
68
86
|
export class TensorCostQuotaError extends TensorCostError {
|
|
@@ -72,13 +90,64 @@ export class TensorCostQuotaError extends TensorCostError {
|
|
|
72
90
|
}
|
|
73
91
|
}
|
|
74
92
|
/**
|
|
75
|
-
* The proxy
|
|
76
|
-
*
|
|
77
|
-
*
|
|
93
|
+
* The proxy reached the upstream provider and relayed the provider's own
|
|
94
|
+
* 4xx (OpenAI 400 invalid request, Anthropic 401, and so on). `status` is
|
|
95
|
+
* the provider's status and `body` is what the provider sent, parsed as
|
|
96
|
+
* JSON when it was JSON. Never falls back: the provider would only answer
|
|
97
|
+
* the same way again.
|
|
78
98
|
*/
|
|
79
99
|
export class TensorCostProviderError extends TensorCostError {
|
|
80
100
|
constructor(message, opts = {}) {
|
|
81
101
|
super(message, opts);
|
|
102
|
+
this.body = opts.body ?? null;
|
|
103
|
+
this.headers = opts.headers ?? {};
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/**
|
|
107
|
+
* Something in front of TensorCost turned the request away: a 4xx whose
|
|
108
|
+
* body isn't JSON (an HTML page from a firewall or load balancer, or
|
|
109
|
+
* nothing at all). Neither TensorCost nor the provider saw the call.
|
|
110
|
+
* Terminal: going around it would mean going around whatever put the
|
|
111
|
+
* firewall there, and the next call would most likely meet it too.
|
|
112
|
+
*/
|
|
113
|
+
export class TensorCostGatewayRejectedError extends TensorCostError {
|
|
114
|
+
constructor(status, bodyText, opts = {}) {
|
|
115
|
+
super(`tensorcost: the request was rejected with ${status} before it reached TensorCost ` +
|
|
116
|
+
"or the provider (for example by a firewall or load balancer in front of the " +
|
|
117
|
+
"TensorCost proxy). Check the proxy URL and anything in front of it.", { ...opts, status });
|
|
118
|
+
this.bodyText = bodyText;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
122
|
+
* The token exchange rejected the TensorCost API key (401 or 403): revoked,
|
|
123
|
+
* mistyped, or issued for a different tenant than the one configured. Not
|
|
124
|
+
* an outage, so it never fails open.
|
|
125
|
+
*/
|
|
126
|
+
export class TensorCostKeyRejectedError extends TensorCostError {
|
|
127
|
+
constructor(status, opts = {}) {
|
|
128
|
+
super(`tensorcost: the TensorCost key was rejected (${status}); check it's current and ` +
|
|
129
|
+
"that it belongs to the configured tenant id", { ...opts, status });
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* TensorCost answered and the answer is no: a budget, a stop, a policy.
|
|
134
|
+
*
|
|
135
|
+
* Every refusal is terminal. It never retries and never falls back to the
|
|
136
|
+
* provider, because the proxy that sent it is healthy and the refusal is
|
|
137
|
+
* the product. `code` is the server's refusal code (null when the server
|
|
138
|
+
* refused without naming one), `reason` its optional sub-reason, and
|
|
139
|
+
* `detail` the refusal object as the server sent it.
|
|
140
|
+
*
|
|
141
|
+
* Subclasses cover the codes this SDK version models. Anything else, a
|
|
142
|
+
* code added on the server after this release included, is thrown as this
|
|
143
|
+
* class directly so it is still terminal.
|
|
144
|
+
*/
|
|
145
|
+
export class TensorCostRefusedError extends TensorCostError {
|
|
146
|
+
constructor(message, refusal = {}, opts = {}) {
|
|
147
|
+
super(message, opts);
|
|
148
|
+
this.code = refusal.code ?? null;
|
|
149
|
+
this.reason = refusal.reason ?? null;
|
|
150
|
+
this.detail = refusal.detail ?? null;
|
|
82
151
|
}
|
|
83
152
|
}
|
|
84
153
|
/**
|
|
@@ -93,11 +162,12 @@ export class TensorCostProviderError extends TensorCostError {
|
|
|
93
162
|
* anyway, bill the customer, and reduce the cap to a suggestion.
|
|
94
163
|
*
|
|
95
164
|
* See `shouldFallBackToProvider()` in proxy-client.ts, which is the single
|
|
96
|
-
* predicate every provider wrapper consults before falling back.
|
|
165
|
+
* predicate every provider wrapper consults before falling back. Since
|
|
166
|
+
* 1.5.0 it is an allow-list of outages, so a refusal can't slip past it.
|
|
97
167
|
*/
|
|
98
|
-
export class TensorCostRunBudgetExceededError extends
|
|
168
|
+
export class TensorCostRunBudgetExceededError extends TensorCostRefusedError {
|
|
99
169
|
constructor(message, workflowId, capCents, spentCents, opts = {}) {
|
|
100
|
-
super(message, opts);
|
|
170
|
+
super(message, { code: "RUN_BUDGET_EXCEEDED", detail: opts.detail ?? null }, opts);
|
|
101
171
|
this.workflowId = workflowId;
|
|
102
172
|
this.capCents = capCents;
|
|
103
173
|
this.spentCents = spentCents;
|
|
@@ -111,7 +181,7 @@ export class TensorCostRunBudgetExceededError extends TensorCostError {
|
|
|
111
181
|
* from a healthy proxy, so falling back to the provider would simply undo
|
|
112
182
|
* it. Carries the who / when / why the proxy recorded.
|
|
113
183
|
*/
|
|
114
|
-
export class TensorCostRunStoppedError extends
|
|
184
|
+
export class TensorCostRunStoppedError extends TensorCostRefusedError {
|
|
115
185
|
/**
|
|
116
186
|
* Build the error from the proxy's 403 `error` object. Shared by the
|
|
117
187
|
* chat-completions client and the govern-layer admit client, which both
|
|
@@ -124,15 +194,14 @@ export class TensorCostRunStoppedError extends TensorCostError {
|
|
|
124
194
|
stoppedBy: str(detail?.["stopped_by"]),
|
|
125
195
|
stoppedAt: str(detail?.["stopped_at"]),
|
|
126
196
|
reason: str(detail?.["reason"]),
|
|
127
|
-
}, opts);
|
|
197
|
+
}, { ...opts, detail: detail ?? null });
|
|
128
198
|
}
|
|
129
199
|
constructor(message, detail = {}, opts = {}) {
|
|
130
|
-
super(message, { ...opts, status: opts.status ?? 403 });
|
|
200
|
+
super(message, { code: "RUN_STOPPED", reason: detail.reason ?? null, detail: opts.detail ?? null }, { ...opts, status: opts.status ?? 403 });
|
|
131
201
|
this.code = "RUN_STOPPED";
|
|
132
202
|
this.workflowId = detail.workflowId ?? null;
|
|
133
203
|
this.stoppedBy = detail.stoppedBy ?? null;
|
|
134
204
|
this.stoppedAt = detail.stoppedAt ?? null;
|
|
135
|
-
this.reason = detail.reason ?? null;
|
|
136
205
|
}
|
|
137
206
|
}
|
|
138
207
|
/**
|
|
@@ -140,23 +209,65 @@ export class TensorCostRunStoppedError extends TensorCostError {
|
|
|
140
209
|
* `code: "PERIOD_BUDGET_EXCEEDED"`). Terminal — must not fall back to the
|
|
141
210
|
* provider or the cap becomes a suggestion.
|
|
142
211
|
*/
|
|
143
|
-
export class TensorCostPeriodBudgetExceededError extends
|
|
212
|
+
export class TensorCostPeriodBudgetExceededError extends TensorCostRefusedError {
|
|
144
213
|
constructor(message, scope, period, capCents, spentCents, opts = {}) {
|
|
145
|
-
super(message,
|
|
214
|
+
super(message, {
|
|
215
|
+
code: opts.code ?? "PERIOD_BUDGET_EXCEEDED",
|
|
216
|
+
reason: opts.reason ?? null,
|
|
217
|
+
detail: opts.detail ?? null,
|
|
218
|
+
}, opts);
|
|
146
219
|
this.scope = scope;
|
|
147
220
|
this.period = period;
|
|
148
221
|
this.capCents = capCents;
|
|
149
222
|
this.spentCents = spentCents;
|
|
150
223
|
}
|
|
151
224
|
}
|
|
225
|
+
/**
|
|
226
|
+
* A money budget's hard cap refused the call (HTTP 403).
|
|
227
|
+
*
|
|
228
|
+
* The server sends `error.code: "PERIOD_BUDGET_EXCEEDED"` with
|
|
229
|
+
* `error.budget_code: "BUDGET_HARD_CAP"` (that code is what made 1.4.0
|
|
230
|
+
* treat it as terminal), and older servers sent `error.code:
|
|
231
|
+
* "BUDGET_HARD_CAP"`. Both map here. `code` keeps whichever the server
|
|
232
|
+
* sent; `budgetCode` is always "BUDGET_HARD_CAP".
|
|
233
|
+
*
|
|
234
|
+
* It extends TensorCostPeriodBudgetExceededError because 1.4.0 already
|
|
235
|
+
* raised that class for the current wire shape, so an existing `catch` for
|
|
236
|
+
* it keeps working, and scope / period / capCents / spentCents are filled
|
|
237
|
+
* the same way.
|
|
238
|
+
*
|
|
239
|
+
* `reason: "spend_not_known_yet"` (with `retryable: true` on the wire)
|
|
240
|
+
* means the budget hasn't been counted yet, usually for a few seconds after
|
|
241
|
+
* it is created or its scope changes, so the cap holds calls until the
|
|
242
|
+
* first count lands. That case is `retryable`, and `retryAfterSeconds`
|
|
243
|
+
* comes from the Retry-After header or the body's `retry_after_seconds`.
|
|
244
|
+
* The SDK does not retry on its own.
|
|
245
|
+
*/
|
|
246
|
+
export class TensorCostBudgetHardCapError extends TensorCostPeriodBudgetExceededError {
|
|
247
|
+
constructor(message, fields = {}, opts = {}) {
|
|
248
|
+
super(message, fields.scope ?? null, fields.period ?? null, fields.capCents ?? null, fields.spentCents ?? null, {
|
|
249
|
+
...opts,
|
|
250
|
+
status: opts.status ?? 403,
|
|
251
|
+
code: fields.code ?? "BUDGET_HARD_CAP",
|
|
252
|
+
reason: fields.reason ?? null,
|
|
253
|
+
detail: fields.detail ?? null,
|
|
254
|
+
});
|
|
255
|
+
this.budgetCode = "BUDGET_HARD_CAP";
|
|
256
|
+
this.budgetId = fields.budgetId ?? null;
|
|
257
|
+
this.budgetName = fields.budgetName ?? null;
|
|
258
|
+
this.burnPct = fields.burnPct ?? null;
|
|
259
|
+
this.retryable = fields.retryable === true || this.reason === "spend_not_known_yet";
|
|
260
|
+
this.retryAfterSeconds = fields.retryAfterSeconds ?? null;
|
|
261
|
+
}
|
|
262
|
+
}
|
|
152
263
|
/**
|
|
153
264
|
* Tenant model governance refused this model (HTTP 403,
|
|
154
265
|
* `code: "MODEL_GOVERNANCE_DENIED"`). Terminal — must not fall back to the
|
|
155
266
|
* provider, or Enforce would become a suggestion.
|
|
156
267
|
*/
|
|
157
|
-
export class TensorCostModelGovernanceDeniedError extends
|
|
268
|
+
export class TensorCostModelGovernanceDeniedError extends TensorCostRefusedError {
|
|
158
269
|
constructor(message, provider, model, governanceStatus, opts = {}) {
|
|
159
|
-
super(message, opts);
|
|
270
|
+
super(message, { code: "MODEL_GOVERNANCE_DENIED", detail: opts.detail ?? null }, opts);
|
|
160
271
|
this.provider = provider;
|
|
161
272
|
this.model = model;
|
|
162
273
|
this.governanceStatus = governanceStatus;
|
|
@@ -167,23 +278,22 @@ export class TensorCostModelGovernanceDeniedError extends TensorCostError {
|
|
|
167
278
|
* `code: "GUARDRAIL_HARD_STOP"`). Terminal — same fail-closed contract as
|
|
168
279
|
* run-budget and model governance denials.
|
|
169
280
|
*/
|
|
170
|
-
export class TensorCostGuardrailHardStopError extends
|
|
281
|
+
export class TensorCostGuardrailHardStopError extends TensorCostRefusedError {
|
|
171
282
|
constructor(message, policyId, opts = {}) {
|
|
172
|
-
super(message, opts);
|
|
283
|
+
super(message, { code: "GUARDRAIL_HARD_STOP", reason: opts.reason ?? null, detail: opts.detail ?? null }, opts);
|
|
173
284
|
this.policyId = policyId;
|
|
174
285
|
}
|
|
175
286
|
}
|
|
176
287
|
/** Compliance policy refused this call (metadata or in-process DLP). */
|
|
177
|
-
export class TensorCostComplianceDeniedError extends
|
|
288
|
+
export class TensorCostComplianceDeniedError extends TensorCostRefusedError {
|
|
178
289
|
constructor(message, reason, opts = {}) {
|
|
179
|
-
super(message, { ...opts, status: opts.status ?? 403 });
|
|
180
|
-
this.reason = reason;
|
|
290
|
+
super(message, { code: "COMPLIANCE_DENIED", reason, detail: opts.detail ?? null }, { ...opts, status: opts.status ?? 403 });
|
|
181
291
|
}
|
|
182
292
|
}
|
|
183
293
|
/** Client team_id does not match token-bound team scope. */
|
|
184
|
-
export class TensorCostComplianceTeamMismatchError extends
|
|
294
|
+
export class TensorCostComplianceTeamMismatchError extends TensorCostRefusedError {
|
|
185
295
|
constructor(message, opts = {}) {
|
|
186
|
-
super(message, { ...opts, status: opts.status ?? 403 });
|
|
296
|
+
super(message, { code: "COMPLIANCE_TEAM_MISMATCH", detail: opts.detail ?? null }, { ...opts, status: opts.status ?? 403 });
|
|
187
297
|
}
|
|
188
298
|
}
|
|
189
299
|
//# sourceMappingURL=errors.js.map
|
package/dist/errors.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../src/errors.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
CHANGED
|
@@ -2,7 +2,7 @@ export { wrap } from "./wrap.js";
|
|
|
2
2
|
export { prewarm, flushObservations } from "./prewarm.js";
|
|
3
3
|
export { MissingConfigError, TensorCostConfigError } from "./config.js";
|
|
4
4
|
export { UnsupportedClientError } from "./providers/detect.js";
|
|
5
|
-
export { TensorCostError, TensorCostNetworkError, TensorCostTimeoutError, TensorCostProxyError, TensorCostQuotaError, TensorCostProviderError, TensorCostRunBudgetExceededError, TensorCostRunStoppedError, TensorCostPeriodBudgetExceededError, TensorCostModelGovernanceDeniedError, TensorCostGuardrailHardStopError, TensorCostComplianceDeniedError, TensorCostComplianceTeamMismatchError, } from "./errors.js";
|
|
5
|
+
export { TensorCostError, TensorCostNetworkError, TensorCostTimeoutError, TensorCostProxyError, TensorCostQuotaError, TensorCostProviderError, TensorCostGatewayRejectedError, TensorCostKeyRejectedError, TensorCostRefusedError, TensorCostBudgetHardCapError, TensorCostRunBudgetExceededError, TensorCostRunStoppedError, TensorCostPeriodBudgetExceededError, TensorCostModelGovernanceDeniedError, TensorCostGuardrailHardStopError, TensorCostComplianceDeniedError, TensorCostComplianceTeamMismatchError, } from "./errors.js";
|
|
6
6
|
export type { LifecycleEvent, BeforeRequestEvent, AfterResponseEvent, OnRetryEvent, OnErrorEvent, OnFallbackEvent, LifecycleEventCallback, } from "./telemetry.js";
|
|
7
7
|
export type { RetryConfig } from "./retry.js";
|
|
8
8
|
export type { WrapOptions, Observation, Provider, ObservationModality, ControlLayer, DataGrant, } from "./types.js";
|
|
@@ -11,5 +11,5 @@ export { wrapLlamaIndex } from "./adapters/llamaindex.js";
|
|
|
11
11
|
export { wrapCrewAI } from "./adapters/crewai.js";
|
|
12
12
|
export { wrapVercelAi } from "./adapters/vercel-ai.js";
|
|
13
13
|
export { intersectGrants } from "./layer.js";
|
|
14
|
-
export declare const version = "1.
|
|
14
|
+
export declare const version = "1.5.0";
|
|
15
15
|
//# 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,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC1D,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,EACvB,gCAAgC,EAChC,yBAAyB,EACzB,mCAAmC,EACnC,oCAAoC,EACpC,gCAAgC,EAChC,+BAA+B,EAC/B,qCAAqC,GACtC,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,EACV,WAAW,EACX,WAAW,EACX,QAAQ,EACR,mBAAmB,EACnB,YAAY,EACZ,SAAS,GACV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,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,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC1D,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,EACvB,8BAA8B,EAC9B,0BAA0B,EAC1B,sBAAsB,EACtB,4BAA4B,EAC5B,gCAAgC,EAChC,yBAAyB,EACzB,mCAAmC,EACnC,oCAAoC,EACpC,gCAAgC,EAChC,+BAA+B,EAC/B,qCAAqC,GACtC,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,EACV,WAAW,EACX,WAAW,EACX,QAAQ,EACR,mBAAmB,EACnB,YAAY,EACZ,SAAS,GACV,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,eAAO,MAAM,OAAO,UAAU,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -2,11 +2,11 @@ export { wrap } from "./wrap.js";
|
|
|
2
2
|
export { prewarm, flushObservations } from "./prewarm.js";
|
|
3
3
|
export { MissingConfigError, TensorCostConfigError } from "./config.js";
|
|
4
4
|
export { UnsupportedClientError } from "./providers/detect.js";
|
|
5
|
-
export { TensorCostError, TensorCostNetworkError, TensorCostTimeoutError, TensorCostProxyError, TensorCostQuotaError, TensorCostProviderError, TensorCostRunBudgetExceededError, TensorCostRunStoppedError, TensorCostPeriodBudgetExceededError, TensorCostModelGovernanceDeniedError, TensorCostGuardrailHardStopError, TensorCostComplianceDeniedError, TensorCostComplianceTeamMismatchError, } from "./errors.js";
|
|
5
|
+
export { TensorCostError, TensorCostNetworkError, TensorCostTimeoutError, TensorCostProxyError, TensorCostQuotaError, TensorCostProviderError, TensorCostGatewayRejectedError, TensorCostKeyRejectedError, TensorCostRefusedError, TensorCostBudgetHardCapError, TensorCostRunBudgetExceededError, TensorCostRunStoppedError, TensorCostPeriodBudgetExceededError, TensorCostModelGovernanceDeniedError, TensorCostGuardrailHardStopError, TensorCostComplianceDeniedError, TensorCostComplianceTeamMismatchError, } from "./errors.js";
|
|
6
6
|
export { wrapLangChain } from "./adapters/langchain.js";
|
|
7
7
|
export { wrapLlamaIndex } from "./adapters/llamaindex.js";
|
|
8
8
|
export { wrapCrewAI } from "./adapters/crewai.js";
|
|
9
9
|
export { wrapVercelAi } from "./adapters/vercel-ai.js";
|
|
10
10
|
export { intersectGrants } from "./layer.js";
|
|
11
|
-
export const version = "1.
|
|
11
|
+
export const version = "1.5.0";
|
|
12
12
|
//# 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,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC1D,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,EACvB,gCAAgC,EAChC,yBAAyB,EACzB,mCAAmC,EACnC,oCAAoC,EACpC,gCAAgC,EAChC,+BAA+B,EAC/B,qCAAqC,GACtC,MAAM,aAAa,CAAC;AAmBrB,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,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,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AAC1D,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,EACvB,8BAA8B,EAC9B,0BAA0B,EAC1B,sBAAsB,EACtB,4BAA4B,EAC5B,gCAAgC,EAChC,yBAAyB,EACzB,mCAAmC,EACnC,oCAAoC,EACpC,gCAAgC,EAChC,+BAA+B,EAC/B,qCAAqC,GACtC,MAAM,aAAa,CAAC;AAmBrB,OAAO,EAAE,aAAa,EAAE,MAAM,yBAAyB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,yBAAyB,CAAC;AACvD,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAE7C,MAAM,CAAC,MAAM,OAAO,GAAG,OAAO,CAAC"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rethrowing a relayed provider error as the provider SDK's own type.
|
|
3
|
+
*
|
|
4
|
+
* When the proxy relays an OpenAI 400, a caller written against the openai
|
|
5
|
+
* package expects `openai.BadRequestError`, not a TensorCost class. Both
|
|
6
|
+
* openai@4 and @anthropic-ai/sdk build their status errors through the
|
|
7
|
+
* client's `makeStatusError(status, body, message, headers)` (which calls
|
|
8
|
+
* `APIError.generate`), so the SDK asks the client to build it, exactly as
|
|
9
|
+
* the client would have for a direct call. Clients without that method, or
|
|
10
|
+
* whose factory rejects both header shapes below, get the
|
|
11
|
+
* TensorCostProviderError as is.
|
|
12
|
+
*/
|
|
13
|
+
/** The provider SDK's error for `err`, or `err` itself when one can't be built. */
|
|
14
|
+
export declare function providerNativeError(client: unknown, err: unknown): unknown;
|
|
15
|
+
//# sourceMappingURL=provider-errors.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-errors.d.ts","sourceRoot":"","sources":["../src/provider-errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAuCH,mFAAmF;AACnF,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,OAAO,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAsB1E"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Rethrowing a relayed provider error as the provider SDK's own type.
|
|
3
|
+
*
|
|
4
|
+
* When the proxy relays an OpenAI 400, a caller written against the openai
|
|
5
|
+
* package expects `openai.BadRequestError`, not a TensorCost class. Both
|
|
6
|
+
* openai@4 and @anthropic-ai/sdk build their status errors through the
|
|
7
|
+
* client's `makeStatusError(status, body, message, headers)` (which calls
|
|
8
|
+
* `APIError.generate`), so the SDK asks the client to build it, exactly as
|
|
9
|
+
* the client would have for a direct call. Clients without that method, or
|
|
10
|
+
* whose factory rejects both header shapes below, get the
|
|
11
|
+
* TensorCostProviderError as is.
|
|
12
|
+
*/
|
|
13
|
+
import { TensorCostProviderError } from "./errors.js";
|
|
14
|
+
function statusErrorFactory(client) {
|
|
15
|
+
if (!client || typeof client !== "object")
|
|
16
|
+
return null;
|
|
17
|
+
const c = client;
|
|
18
|
+
if (typeof c["makeStatusError"] === "function") {
|
|
19
|
+
return c["makeStatusError"].bind(client);
|
|
20
|
+
}
|
|
21
|
+
// Older shapes expose the error class on the constructor instead.
|
|
22
|
+
const ctor = client.constructor;
|
|
23
|
+
const apiError = ctor?.["APIError"];
|
|
24
|
+
if (apiError && typeof apiError.generate === "function") {
|
|
25
|
+
return apiError.generate.bind(apiError);
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* The two header shapes the factories expect. openai@4 reads
|
|
31
|
+
* `headers["x-request-id"]` off a plain object; openai v5/v6 and current
|
|
32
|
+
* @anthropic-ai/sdk call `headers.get(...)` on a `Headers` instance and throw
|
|
33
|
+
* on a plain object. The plain object goes first (openai@4 would take a
|
|
34
|
+
* `Headers` too but lose the request id), then a `Headers` instance.
|
|
35
|
+
*/
|
|
36
|
+
function headerShapes(headers) {
|
|
37
|
+
const shapes = [headers];
|
|
38
|
+
if (typeof Headers === "function")
|
|
39
|
+
shapes.push(new Headers(headers));
|
|
40
|
+
return shapes;
|
|
41
|
+
}
|
|
42
|
+
/** The provider SDK's error for `err`, or `err` itself when one can't be built. */
|
|
43
|
+
export function providerNativeError(client, err) {
|
|
44
|
+
if (!(err instanceof TensorCostProviderError) || err.status === null)
|
|
45
|
+
return err;
|
|
46
|
+
const make = statusErrorFactory(client);
|
|
47
|
+
if (!make)
|
|
48
|
+
return err;
|
|
49
|
+
const body = err.body !== null && typeof err.body === "object" ? err.body : undefined;
|
|
50
|
+
for (const headers of headerShapes(err.headers)) {
|
|
51
|
+
let native;
|
|
52
|
+
try {
|
|
53
|
+
native = make(err.status, body, undefined, headers);
|
|
54
|
+
}
|
|
55
|
+
catch {
|
|
56
|
+
continue;
|
|
57
|
+
}
|
|
58
|
+
if (native instanceof Error) {
|
|
59
|
+
Object.defineProperty(native, "tensorcost", {
|
|
60
|
+
value: err,
|
|
61
|
+
enumerable: false,
|
|
62
|
+
configurable: true,
|
|
63
|
+
});
|
|
64
|
+
return native;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return err;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=provider-errors.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"provider-errors.js","sourceRoot":"","sources":["../src/provider-errors.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,uBAAuB,EAAE,MAAM,aAAa,CAAC;AAStD,SAAS,kBAAkB,CAAC,MAAe;IACzC,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;QAAE,OAAO,IAAI,CAAC;IACvD,MAAM,CAAC,GAAG,MAAiC,CAAC;IAC5C,IAAI,OAAO,CAAC,CAAC,iBAAiB,CAAC,KAAK,UAAU,EAAE,CAAC;QAC/C,OAAQ,CAAC,CAAC,iBAAiB,CAAqB,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAChE,CAAC;IACD,kEAAkE;IAClE,MAAM,IAAI,GAAI,MAAoD,CAAC,WAAW,CAAC;IAC/E,MAAM,QAAQ,GAAG,IAAI,EAAE,CAAC,UAAU,CAA+C,CAAC;IAClF,IAAI,QAAQ,IAAI,OAAO,QAAQ,CAAC,QAAQ,KAAK,UAAU,EAAE,CAAC;QACxD,OAAO,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;GAMG;AACH,SAAS,YAAY,CAAC,OAA+B;IACnD,MAAM,MAAM,GAAc,CAAC,OAAO,CAAC,CAAC;IACpC,IAAI,OAAO,OAAO,KAAK,UAAU;QAAE,MAAM,CAAC,IAAI,CAAC,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IACrE,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,mBAAmB,CAAC,MAAe,EAAE,GAAY;IAC/D,IAAI,CAAC,CAAC,GAAG,YAAY,uBAAuB,CAAC,IAAI,GAAG,CAAC,MAAM,KAAK,IAAI;QAAE,OAAO,GAAG,CAAC;IACjF,MAAM,IAAI,GAAG,kBAAkB,CAAC,MAAM,CAAC,CAAC;IACxC,IAAI,CAAC,IAAI;QAAE,OAAO,GAAG,CAAC;IACtB,MAAM,IAAI,GAAG,GAAG,CAAC,IAAI,KAAK,IAAI,IAAI,OAAO,GAAG,CAAC,IAAI,KAAK,QAAQ,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC;IACtF,KAAK,MAAM,OAAO,IAAI,YAAY,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;QAChD,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QACtD,CAAC;QAAC,MAAM,CAAC;YACP,SAAS;QACX,CAAC;QACD,IAAI,MAAM,YAAY,KAAK,EAAE,CAAC;YAC5B,MAAM,CAAC,cAAc,CAAC,MAAM,EAAE,YAAY,EAAE;gBAC1C,KAAK,EAAE,GAAG;gBACV,UAAU,EAAE,KAAK;gBACjB,YAAY,EAAE,IAAI;aACnB,CAAC,CAAC;YACH,OAAO,MAAM,CAAC;QAChB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Anthropic client wrapping.
|
|
3
|
+
*
|
|
4
|
+
* Intercepts `client.messages.create`. Same observation contract as the
|
|
5
|
+
* OpenAI wrapper — only metadata is captured (model, input/output tokens),
|
|
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.
|
|
11
|
+
*/
|
|
12
|
+
import type { ObservationTransport } from "../transport.js";
|
|
13
|
+
import type { CircuitBreaker } from "../circuit.js";
|
|
14
|
+
import type { LifecycleEventCallback } from "../telemetry.js";
|
|
15
|
+
import type { RetryConfig } from "../retry.js";
|
|
16
|
+
import type { ControlLayer } from "../layer.js";
|
|
17
|
+
import type { SdkLayerClient } from "../sdk-layer.js";
|
|
18
|
+
export interface AppliedModeHardeningOpts {
|
|
19
|
+
maxLayer: ControlLayer;
|
|
20
|
+
appliedMode: boolean;
|
|
21
|
+
proxyUrl: string | null;
|
|
22
|
+
baseUrl: string;
|
|
23
|
+
sdkLayer: SdkLayerClient;
|
|
24
|
+
retry: RetryConfig;
|
|
25
|
+
timeoutMs: number;
|
|
26
|
+
headersTimeoutMs: number;
|
|
27
|
+
idleTimeoutMs: number;
|
|
28
|
+
onLifecycleEvent: LifecycleEventCallback | undefined;
|
|
29
|
+
failOpenEnabled: boolean;
|
|
30
|
+
circuit: CircuitBreaker;
|
|
31
|
+
application?: string | null;
|
|
32
|
+
tags?: string[];
|
|
33
|
+
customer?: string | null;
|
|
34
|
+
feature?: string | null;
|
|
35
|
+
teamId?: string | null;
|
|
36
|
+
}
|
|
37
|
+
/**
|
|
38
|
+
* The layer an Anthropic client actually runs at.
|
|
39
|
+
*
|
|
40
|
+
* The proxy has no Anthropic Messages route yet, so steer/route can't put
|
|
41
|
+
* the proxy in the request path for Claude. Before 1.5.0 that proxy call
|
|
42
|
+
* failed and fail-open sent the call straight to Anthropic, which meant
|
|
43
|
+
* nothing could stop a Claude run. Govern runs the pre-call /admit check
|
|
44
|
+
* instead, so stops, caps and budgets still apply. One warning per
|
|
45
|
+
* process says so.
|
|
46
|
+
*/
|
|
47
|
+
export declare function anthropicLayer(requested: ControlLayer): ControlLayer;
|
|
48
|
+
export declare function install(client: unknown, transport: ObservationTransport, tenantId: string | null, environment: string | null, connectionId: string | null, hardeningIn: AppliedModeHardeningOpts, deployment?: string | null, promptTemplateId?: string | null, agentId?: string | null, workflowId?: string | null): void;
|
|
49
|
+
export declare const __test__: {
|
|
50
|
+
MARKER: string;
|
|
51
|
+
WITH_META_MARKER: string;
|
|
52
|
+
resetPinWarning(): void;
|
|
53
|
+
};
|
|
54
|
+
//# sourceMappingURL=anthropic.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"anthropic.d.ts","sourceRoot":"","sources":["../../src/providers/anthropic.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAGH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AAuB5D,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;AAC/C,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAatD,MAAM,WAAW,wBAAwB;IACvC,QAAQ,EAAE,YAAY,CAAC;IACvB,WAAW,EAAE,OAAO,CAAC;IACrB,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,cAAc,CAAC;IACzB,KAAK,EAAE,WAAW,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;IACzB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,sBAAsB,GAAG,SAAS,CAAC;IACrD,eAAe,EAAE,OAAO,CAAC;IACzB,OAAO,EAAE,cAAc,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAyfD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,YAAY,GAAG,YAAY,CAcpE;AAED,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,WAAW,EAAE,wBAAwB,EACrC,UAAU,GAAE,MAAM,GAAG,IAAW,EAChC,gBAAgB,GAAE,MAAM,GAAG,IAAW,EACtC,OAAO,GAAE,MAAM,GAAG,IAAW,EAC7B,UAAU,GAAE,MAAM,GAAG,IAAW,GAC/B,IAAI,CA8GN;AAED,eAAO,MAAM,QAAQ;;;uBAGA,IAAI;CAGxB,CAAC"}
|
|
@@ -13,13 +13,15 @@ import { proxyRequest, proxyRequestStream, sseChunksFromStream, shouldFallBackTo
|
|
|
13
13
|
import { admitRequest } from "../admit-client.js";
|
|
14
14
|
import { assertTeamScope, complianceStampFrom, enforceInProcessDlp, } from "../compliance-guard.js";
|
|
15
15
|
import { extractAnthropicMessagesText } from "../dlp.js";
|
|
16
|
-
import { TensorCostProxyError,
|
|
16
|
+
import { TensorCostProxyError, TensorCostComplianceDeniedError, TensorCostComplianceTeamMismatchError, TensorCostRefusedError, } from "../errors.js";
|
|
17
|
+
import { providerTarget } from "../applied.js";
|
|
18
|
+
import { providerNativeError } from "../provider-errors.js";
|
|
17
19
|
import { emitEvent } from "../telemetry.js";
|
|
18
20
|
import { needsProxyUrl } from "../layer.js";
|
|
19
21
|
import { decisionMetadata } from "../decision.js";
|
|
20
22
|
import { SDK_VERSION } from "../version.js";
|
|
21
23
|
import { resolveModelCallLink } from "../trace-link.js";
|
|
22
|
-
import { WrapOverhead, postObservation, withAwaitExcluded } from "../wrap-overhead.js";
|
|
24
|
+
import { WrapOverhead, observationScope, postObservation, withAwaitExcluded, } from "../wrap-overhead.js";
|
|
23
25
|
const MARKER = "__tensorcost_wrapped__";
|
|
24
26
|
const WITH_META_MARKER = "__tensorcost_with_meta__";
|
|
25
27
|
function nowIso() {
|
|
@@ -113,21 +115,27 @@ function wrapMethod(bound, opts) {
|
|
|
113
115
|
team_id: opts.hardening.teamId ?? null,
|
|
114
116
|
},
|
|
115
117
|
transport: opts.transport,
|
|
116
|
-
failOpen:
|
|
118
|
+
failOpen: opts.hardening.failOpenEnabled,
|
|
117
119
|
});
|
|
118
120
|
});
|
|
119
121
|
if (!admit.allowed) {
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
122
|
+
// The admit client types every refusal by its code. The generic
|
|
123
|
+
// error is only a guard; it used to say "model governance" for
|
|
124
|
+
// every refusal, budget caps included.
|
|
125
|
+
throw (admit.refusal ??
|
|
126
|
+
new TensorCostRefusedError("tensorcost: request refused at govern layer", {}, {
|
|
127
|
+
status: 403,
|
|
128
|
+
attempt: 1,
|
|
129
|
+
}));
|
|
123
130
|
}
|
|
124
131
|
decisionMeta = decisionMetadata(admit.decisionHeader);
|
|
125
132
|
}
|
|
126
133
|
catch (err) {
|
|
127
|
-
|
|
128
|
-
|
|
134
|
+
// Same rule as the proxy path: go around TensorCost only when it
|
|
135
|
+
// is unavailable (token exchange or admit unreachable), and only
|
|
136
|
+
// with failOpenEnabled. A refusal, known code or not, stops the call.
|
|
137
|
+
if (!shouldFallBackToProvider(err) || !opts.hardening.failOpenEnabled)
|
|
129
138
|
throw err;
|
|
130
|
-
}
|
|
131
139
|
}
|
|
132
140
|
}
|
|
133
141
|
const decisionSpread = decisionMeta !== undefined
|
|
@@ -144,15 +152,11 @@ function wrapMethod(bound, opts) {
|
|
|
144
152
|
? { compliance_frameworks: complianceStamp.compliance_frameworks }
|
|
145
153
|
: {}),
|
|
146
154
|
...(complianceStamp.dlp_action ? { dlp_action: complianceStamp.dlp_action } : {}),
|
|
155
|
+
...observationScope(opts.hardening.application, opts.hardening.tags),
|
|
147
156
|
});
|
|
148
157
|
const proxyUrl = opts.hardening.proxyUrl;
|
|
149
158
|
if (needsProxyUrl(effectiveLayer) && proxyUrl) {
|
|
150
|
-
|
|
151
|
-
const dh = opts.clientRef && typeof opts.clientRef === "object"
|
|
152
|
-
? opts.clientRef["defaultHeaders"]
|
|
153
|
-
: undefined;
|
|
154
|
-
const providerUrl = dh?.["x-tc-provider-url"] ?? "https://api.anthropic.com";
|
|
155
|
-
const providerAuth = dh?.["x-tc-provider-auth"] ?? "";
|
|
159
|
+
const { providerUrl, providerAuth } = providerTarget(opts.clientRef, "anthropic", "https://api.anthropic.com");
|
|
156
160
|
const body = {
|
|
157
161
|
...(firstArg && typeof firstArg === "object" ? firstArg : {}),
|
|
158
162
|
model: String(model),
|
|
@@ -238,7 +242,7 @@ function wrapMethod(bound, opts) {
|
|
|
238
242
|
}
|
|
239
243
|
catch (proxyErr) {
|
|
240
244
|
if (!shouldFallBackToProvider(proxyErr))
|
|
241
|
-
throw proxyErr;
|
|
245
|
+
throw providerNativeError(opts.clientRef, proxyErr);
|
|
242
246
|
proxyFailed = true;
|
|
243
247
|
proxyFailureError = proxyErr;
|
|
244
248
|
}
|
|
@@ -440,9 +444,38 @@ function wrapMethod(bound, opts) {
|
|
|
440
444
|
Object.defineProperty(wrapped, MARKER, { value: true, enumerable: false });
|
|
441
445
|
return wrapped;
|
|
442
446
|
}
|
|
443
|
-
|
|
447
|
+
let pinWarned = false;
|
|
448
|
+
/**
|
|
449
|
+
* The layer an Anthropic client actually runs at.
|
|
450
|
+
*
|
|
451
|
+
* The proxy has no Anthropic Messages route yet, so steer/route can't put
|
|
452
|
+
* the proxy in the request path for Claude. Before 1.5.0 that proxy call
|
|
453
|
+
* failed and fail-open sent the call straight to Anthropic, which meant
|
|
454
|
+
* nothing could stop a Claude run. Govern runs the pre-call /admit check
|
|
455
|
+
* instead, so stops, caps and budgets still apply. One warning per
|
|
456
|
+
* process says so.
|
|
457
|
+
*/
|
|
458
|
+
export function anthropicLayer(requested) {
|
|
459
|
+
if (!needsProxyUrl(requested))
|
|
460
|
+
return requested;
|
|
461
|
+
if (!pinWarned) {
|
|
462
|
+
pinWarned = true;
|
|
463
|
+
// eslint-disable-next-line no-console
|
|
464
|
+
console.warn(`tensorcost: maxLayer '${requested}' isn't available for Anthropic clients yet ` +
|
|
465
|
+
"(the TensorCost proxy has no Anthropic Messages route), so this client runs " +
|
|
466
|
+
"in 'govern': every call is checked with /admit before it goes to Anthropic, " +
|
|
467
|
+
"which is what lets a run be stopped or capped. Set maxLayer: 'govern' to " +
|
|
468
|
+
"silence this warning.");
|
|
469
|
+
}
|
|
470
|
+
return "govern";
|
|
471
|
+
}
|
|
472
|
+
export function install(client, transport, tenantId, environment, connectionId, hardeningIn, deployment = null, promptTemplateId = null, agentId = null, workflowId = null) {
|
|
444
473
|
if (!client || typeof client !== "object")
|
|
445
474
|
return;
|
|
475
|
+
const pinned = anthropicLayer(hardeningIn.maxLayer);
|
|
476
|
+
const hardening = pinned === hardeningIn.maxLayer
|
|
477
|
+
? hardeningIn
|
|
478
|
+
: { ...hardeningIn, maxLayer: pinned, appliedMode: false };
|
|
446
479
|
const c = client;
|
|
447
480
|
const messages = c.messages;
|
|
448
481
|
let originalMessagesBound;
|
|
@@ -525,5 +558,11 @@ export function install(client, transport, tenantId, environment, connectionId,
|
|
|
525
558
|
};
|
|
526
559
|
}
|
|
527
560
|
}
|
|
528
|
-
export const __test__ = {
|
|
561
|
+
export const __test__ = {
|
|
562
|
+
MARKER,
|
|
563
|
+
WITH_META_MARKER,
|
|
564
|
+
resetPinWarning() {
|
|
565
|
+
pinWarned = false;
|
|
566
|
+
},
|
|
567
|
+
};
|
|
529
568
|
//# sourceMappingURL=anthropic.js.map
|