@tensorcost/sdk 1.2.0 → 1.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.
Files changed (66) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/README.md +33 -1
  3. package/dist/errors.d.ts +12 -0
  4. package/dist/errors.d.ts.map +1 -1
  5. package/dist/errors.js +14 -0
  6. package/dist/errors.js.map +1 -1
  7. package/dist/index.d.ts +2 -2
  8. package/dist/index.d.ts.map +1 -1
  9. package/dist/index.js +2 -2
  10. package/dist/index.js.map +1 -1
  11. package/dist/providers/anthropic.d.ts.map +1 -1
  12. package/dist/providers/anthropic.js +78 -34
  13. package/dist/providers/anthropic.js.map +1 -1
  14. package/dist/providers/bedrock.d.ts +7 -6
  15. package/dist/providers/bedrock.d.ts.map +1 -1
  16. package/dist/providers/bedrock.js +42 -10
  17. package/dist/providers/bedrock.js.map +1 -1
  18. package/dist/providers/openai.d.ts.map +1 -1
  19. package/dist/providers/openai.js +87 -14
  20. package/dist/providers/openai.js.map +1 -1
  21. package/dist/providers/vertex.d.ts.map +1 -1
  22. package/dist/providers/vertex.js +5 -2
  23. package/dist/providers/vertex.js.map +1 -1
  24. package/dist/proxy-client.d.ts.map +1 -1
  25. package/dist/proxy-client.js +265 -5
  26. package/dist/proxy-client.js.map +1 -1
  27. package/dist/trace-link.d.ts +24 -0
  28. package/dist/trace-link.d.ts.map +1 -0
  29. package/dist/trace-link.js +61 -0
  30. package/dist/trace-link.js.map +1 -0
  31. package/dist/types.d.ts +7 -0
  32. package/dist/types.d.ts.map +1 -1
  33. package/dist/version.d.ts +1 -1
  34. package/dist/version.js +1 -1
  35. package/dist/wrap.d.ts.map +1 -1
  36. package/dist/wrap.js +1 -0
  37. package/dist/wrap.js.map +1 -1
  38. package/package.json +6 -1
  39. package/dist/adapters/crewai.d.ts +0 -4
  40. package/dist/adapters/langchain.d.ts +0 -4
  41. package/dist/adapters/llamaindex.d.ts +0 -4
  42. package/dist/adapters/vercel-ai.d.ts +0 -4
  43. package/dist/admit-client.d.ts +0 -40
  44. package/dist/applied.d.ts +0 -104
  45. package/dist/circuit-observations.d.ts +0 -12
  46. package/dist/circuit.d.ts +0 -67
  47. package/dist/compliance-guard.d.ts +0 -16
  48. package/dist/compliance-team.d.ts +0 -11
  49. package/dist/config.d.ts +0 -28
  50. package/dist/decision.d.ts +0 -11
  51. package/dist/dlp.d.ts +0 -16
  52. package/dist/layer.d.ts +0 -54
  53. package/dist/prewarm.d.ts +0 -14
  54. package/dist/providers/anthropic.d.ts +0 -41
  55. package/dist/providers/detect.d.ts +0 -19
  56. package/dist/providers/index.d.ts +0 -6
  57. package/dist/providers/openai.d.ts +0 -46
  58. package/dist/providers/vertex.d.ts +0 -14
  59. package/dist/proxy-client.d.ts +0 -114
  60. package/dist/retry.d.ts +0 -50
  61. package/dist/runtime.d.ts +0 -24
  62. package/dist/sdk-layer.d.ts +0 -38
  63. package/dist/telemetry.d.ts +0 -70
  64. package/dist/transport.d.ts +0 -68
  65. package/dist/wrap-overhead.d.ts +0 -32
  66. package/dist/wrap.d.ts +0 -24
@@ -1,40 +0,0 @@
1
- /**
2
- * Govern-layer admit — metadata-only POST /api/inference-proxy/v1/admit.
3
- *
4
- * Fail-open on transport failure: the customer's call proceeds to the
5
- * provider and an error observation is emitted when transport is available.
6
- */
7
- import type { ControlLayer } from "./layer.js";
8
- import type { Operation, Provider } from "./types.js";
9
- import type { ObservationTransport } from "./transport.js";
10
- export interface AdmitMetadata {
11
- provider: Provider;
12
- model: string;
13
- operation: Operation;
14
- correlation_id: string;
15
- environment?: string | null;
16
- connection_id?: string | null;
17
- agent_id?: string;
18
- workflow_id?: string;
19
- customer?: string;
20
- feature?: string;
21
- application?: string | null;
22
- tags?: string[];
23
- team_id?: string | null;
24
- }
25
- export interface AdmitRequestOptions {
26
- baseUrl: string;
27
- bearerToken: string;
28
- maxLayer: ControlLayer;
29
- metadata: AdmitMetadata;
30
- transport?: ObservationTransport;
31
- failOpen?: boolean;
32
- timeoutMs?: number;
33
- fetchImpl?: typeof fetch;
34
- }
35
- export interface AdmitResult {
36
- allowed: boolean;
37
- decisionHeader: string | null;
38
- }
39
- export declare function admitRequest(opts: AdmitRequestOptions): Promise<AdmitResult>;
40
- //# sourceMappingURL=admit-client.d.ts.map
package/dist/applied.d.ts DELETED
@@ -1,104 +0,0 @@
1
- /**
2
- * Applied-mode wiring — Layer 2.
3
- *
4
- * When the customer opts into applied mode, the SDK routes every inference
5
- * request through the TensorCost inference-proxy instead of directly to the
6
- * upstream AI provider. The proxy decides per-request whether to re-route
7
- * or pass through unchanged; the SDK doesn't make that call.
8
- *
9
- * The mechanism is straightforward: at `wrap()` time we read the
10
- * provider's original baseURL and auth from the client, permanently
11
- * redirect the client's baseURL to the proxy endpoint, and inject two
12
- * custom headers the proxy expects:
13
- *
14
- * x-tc-provider-url — the original provider base URL
15
- * x-tc-provider-auth — the auth header value to forward upstream
16
- *
17
- * Both the OpenAI SDK and the Anthropic SDK expose `baseURL` and
18
- * `defaultHeaders` as first-class properties, so we can set them
19
- * without monkey-patching the HTTP layer.
20
- *
21
- * Bedrock is not supported in v1. The AWS SDK uses SigV4 signing on
22
- * regional endpoints and doesn't expose baseURL / defaultHeaders in
23
- * the same shape. Passing a Bedrock-shaped client with appliedMode=true
24
- * throws `TensorCostConfigError` at wrap time.
25
- *
26
- * Observe-only telemetry (the 0.2.x substrate) continues to fire
27
- * after every call regardless of this setting.
28
- */
29
- /**
30
- * Client shapes we understand. All detection is duck-typed; no import
31
- * of the actual openai or @anthropic-ai/sdk packages.
32
- */
33
- /** Header value the proxy expects for OpenAI + Azure OpenAI. */
34
- declare function bearerAuth(apiKey: string): string;
35
- /** Header value the proxy expects for Anthropic. */
36
- declare function anthropicAuth(apiKey: string): string;
37
- /**
38
- * Read the original baseURL from a duck-typed client. Both the OpenAI
39
- * and Anthropic SDKs expose a `baseURL` string property on the client
40
- * instance (the actual HTTP origin, e.g. "https://api.openai.com/v1").
41
- * Returns null when the property is absent or not a string.
42
- */
43
- declare function readBaseUrl(client: Record<string, unknown>): string | null;
44
- /**
45
- * Read the API key from the client. OpenAI SDK exposes `client.apiKey`;
46
- * Anthropic SDK exposes `client.apiKey` too. Returns null when absent.
47
- */
48
- declare function readApiKey(client: Record<string, unknown>): string | null;
49
- /**
50
- * Detect whether this client looks like an Azure OpenAI client (the
51
- * openai package's `AzureOpenAI` subclass). Azure uses `api-key` header
52
- * auth and a custom endpoint URL, so the auth value we forward differs
53
- * from vanilla OpenAI.
54
- *
55
- * Detection: Azure clients have an `azure` property set to true, OR
56
- * their baseURL contains `.openai.azure.com`.
57
- */
58
- declare function isAzureOpenAI(client: Record<string, unknown>): boolean;
59
- /**
60
- * Azure OpenAI uses an `api-key` header rather than `Authorization: Bearer`.
61
- * The proxy forwards `x-tc-provider-auth` verbatim as the upstream auth
62
- * header, so we need to format it as the proxy expects: "api-key <value>".
63
- *
64
- * Note: The proxy currently only supports `Authorization` and `api-key`
65
- * style headers. This value is forwarded in the `x-tc-provider-auth`
66
- * header and then sent by the proxy as the upstream Authorization.
67
- */
68
- declare function azureAuth(apiKey: string): string;
69
- /**
70
- * Install applied-mode routing on the client. Called once by `wrap()`.
71
- *
72
- * Mutates `client.baseURL` to point at the proxy endpoint and injects
73
- * `x-tc-provider-url` / `x-tc-provider-auth` into `client.defaultHeaders`.
74
- * These headers survive for the lifetime of the client — every subsequent
75
- * request automatically carries them.
76
- *
77
- * @param client - The customer's AI SDK client (duck-typed).
78
- * @param proxyUrl - The TensorCost proxy base URL (already stripped of trailing slash).
79
- * @param provider - "openai" | "anthropic", as detected by detectProvider().
80
- *
81
- * @throws TensorCostConfigError
82
- * - If the client doesn't expose `baseURL` (can't determine the original
83
- * provider URL to forward in `x-tc-provider-url`).
84
- * - If the client doesn't expose `apiKey` (can't build `x-tc-provider-auth`).
85
- * - If the provider is "bedrock" (not yet supported in v1).
86
- */
87
- export declare function installAppliedMode(client: unknown, proxyUrl: string, provider: "openai" | "anthropic", scope?: {
88
- application?: string | null;
89
- tags?: string[];
90
- customer?: string | null;
91
- feature?: string | null;
92
- teamId?: string | null;
93
- }): void;
94
- export declare const PROXY_PATH_SUFFIX = "/api/inference-proxy/v1/chat/completions";
95
- export declare const __test__: {
96
- readBaseUrl: typeof readBaseUrl;
97
- readApiKey: typeof readApiKey;
98
- isAzureOpenAI: typeof isAzureOpenAI;
99
- bearerAuth: typeof bearerAuth;
100
- anthropicAuth: typeof anthropicAuth;
101
- azureAuth: typeof azureAuth;
102
- };
103
- export {};
104
- //# sourceMappingURL=applied.d.ts.map
@@ -1,12 +0,0 @@
1
- /**
2
- * Emit circuit-breaker state transitions as observations (Phase 4).
3
- */
4
- import type { CircuitState } from "./circuit.js";
5
- import type { ObservationTransport } from "./transport.js";
6
- import type { Provider } from "./types.js";
7
- export declare function bindCircuitObservations(transport: ObservationTransport, ctx: {
8
- provider: Provider;
9
- tenantId: string | null;
10
- environment: string | null;
11
- }): (from: CircuitState, to: CircuitState) => void;
12
- //# sourceMappingURL=circuit-observations.d.ts.map
package/dist/circuit.d.ts DELETED
@@ -1,67 +0,0 @@
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 ──(single-flight probe)───────> 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 type CircuitTransitionListener = (from: CircuitState, to: CircuitState) => void;
30
- export declare class CircuitBreaker {
31
- private state;
32
- private consecutiveFailures;
33
- private probeSuccesses;
34
- /** True while a HALF_OPEN probe is in flight (single-flight). */
35
- private probeInFlight;
36
- readonly config: CircuitBreakerConfig;
37
- private readonly onTransition?;
38
- constructor(config?: CircuitBreakerConfig, onTransition?: CircuitTransitionListener);
39
- private transition;
40
- /** Current circuit state. */
41
- get currentState(): CircuitState;
42
- /** How many consecutive failures have been recorded. */
43
- get failures(): number;
44
- /**
45
- * Returns true when calls should bypass the proxy and go directly to the
46
- * provider. The caller must always call `recordSuccess` or `recordFailure`
47
- * afterwards to keep the state machine moving.
48
- */
49
- shouldBypass(): boolean;
50
- /**
51
- * Returns true when this caller should run the single-flight HALF_OPEN
52
- * probe (OPEN → HALF_OPEN). Concurrent OPEN callers get false and bypass.
53
- */
54
- shouldProbe(): boolean;
55
- /** Call after a proxy request succeeds. */
56
- recordSuccess(): void;
57
- /**
58
- * Clear a HALF_OPEN probe that never reached recordSuccess/recordFailure
59
- * (e.g. token exchange threw before the HTTP call). Idempotent once the
60
- * probe has settled.
61
- */
62
- releaseStuckProbe(): void;
63
- /** Call after a proxy request fails (5xx or network error). */
64
- recordFailure(): void;
65
- private reset;
66
- }
67
- //# sourceMappingURL=circuit.d.ts.map
@@ -1,16 +0,0 @@
1
- /**
2
- * Client-side compliance — team narrow-check + in-process DLP before provider calls.
3
- */
4
- import { type DlpScanResult } from "./dlp.js";
5
- import type { CompiledComplianceSnapshot } from "./layer.js";
6
- export interface ComplianceStamp {
7
- compliance_frameworks?: string[];
8
- dlp_action?: string;
9
- }
10
- export declare function assertTeamScope(args: {
11
- tokenTeamId?: string | null;
12
- clientTeamId?: string | null;
13
- }): void;
14
- export declare function enforceInProcessDlp(text: string, snapshot: CompiledComplianceSnapshot | null | undefined, args?: unknown[]): DlpScanResult;
15
- export declare function complianceStampFrom(snapshot: CompiledComplianceSnapshot | null | undefined, dlp: DlpScanResult): ComplianceStamp;
16
- //# sourceMappingURL=compliance-guard.d.ts.map
@@ -1,11 +0,0 @@
1
- /** Narrow-only team resolution — mirrors @tensorcost/contracts (no runtime dep). */
2
- export type TeamResolutionError = "compliance_team_mismatch";
3
- export interface ResolvedTeamContext {
4
- teamId: string | null;
5
- error?: TeamResolutionError;
6
- }
7
- export declare function resolveEffectiveTeam(args: {
8
- tokenTeamId?: string | null;
9
- clientTeamId?: string | null;
10
- }): ResolvedTeamContext;
11
- //# sourceMappingURL=compliance-team.d.ts.map
package/dist/config.d.ts DELETED
@@ -1,28 +0,0 @@
1
- /**
2
- * Configuration resolution for the SDK.
3
- *
4
- * Resolution order:
5
- * 1. Explicit options to wrap()
6
- * 2. Environment variables (TENSORCOST_API_KEY, TENSORCOST_BASE_URL,
7
- * TENSORCOST_TENANT_ID, TENSORCOST_PROXY_URL)
8
- * 3. Defaults (only for baseUrl)
9
- *
10
- * If apiKey is still missing after resolution, MissingConfigError is
11
- * raised. This is the *one* case the SDK does not fail open — it means
12
- * the SDK was never configured at all, and silently dropping every
13
- * observation would be worse than a loud import-time failure.
14
- *
15
- * If maxLayer is steer or route and proxyUrl is missing from both options
16
- * and env, TensorCostConfigError is thrown.
17
- */
18
- import type { ResolvedConfig, WrapOptions } from "./types.js";
19
- export declare const DEFAULT_BASE_URL = "https://api.tensorcost.com";
20
- export declare class MissingConfigError extends Error {
21
- constructor(message: string);
22
- }
23
- /** Thrown when applied mode is enabled but required config is absent. */
24
- export declare class TensorCostConfigError extends Error {
25
- constructor(message: string);
26
- }
27
- export declare function resolveConfig(options?: WrapOptions): ResolvedConfig;
28
- //# sourceMappingURL=config.d.ts.map
@@ -1,11 +0,0 @@
1
- /**
2
- * Parse x-tc-decision response header for observation metadata.
3
- */
4
- export interface ParsedDecision {
5
- layer: string;
6
- action: string;
7
- reason?: string;
8
- }
9
- export declare function parseDecisionHeader(header: string | null | undefined): ParsedDecision | null;
10
- export declare function decisionMetadata(header: string | null | undefined): Record<string, string> | undefined;
11
- //# sourceMappingURL=decision.d.ts.map
package/dist/dlp.d.ts DELETED
@@ -1,16 +0,0 @@
1
- /**
2
- * In-process DLP — prompt text never leaves the customer process.
3
- */
4
- import type { CompiledComplianceSnapshot } from "./layer.js";
5
- export type { CompiledComplianceSnapshot };
6
- export type DlpOutcome = "none" | "redacted" | "refused";
7
- export interface DlpScanResult {
8
- outcome: DlpOutcome;
9
- matchedDetectors: string[];
10
- }
11
- export declare function extractAnthropicMessagesText(firstArg: unknown): string;
12
- export declare function extractOpenAiMessagesText(args: unknown[]): string;
13
- export declare function redactTextForCompliance(text: string, detectors: readonly string[]): string;
14
- export declare function applyDlpRedactionToOpenAiArgs(args: unknown[], matchedDetectors: readonly string[]): void;
15
- export declare function scanTextForCompliance(text: string, snapshot: CompiledComplianceSnapshot | null | undefined): DlpScanResult;
16
- //# sourceMappingURL=dlp.d.ts.map
package/dist/layer.d.ts DELETED
@@ -1,54 +0,0 @@
1
- /**
2
- * Control-layer ladder — mirrors @tensorcost/contracts/control-layer for
3
- * the published SDK (no contracts runtime dependency).
4
- */
5
- export declare const CONTROL_LAYERS: readonly ["off", "observe", "govern", "steer", "route"];
6
- export type ControlLayer = (typeof CONTROL_LAYERS)[number];
7
- export declare function layerRank(layer: ControlLayer): number;
8
- export declare function minLayer(a: ControlLayer, b: ControlLayer): ControlLayer;
9
- export declare function isControlLayer(value: string): value is ControlLayer;
10
- /** steer and route require a proxy URL. */
11
- export declare function needsProxyUrl(layer: ControlLayer): boolean;
12
- /** govern runs metadata-only admit before the direct provider call. */
13
- export declare function needsAdmit(layer: ControlLayer): boolean;
14
- export declare function resolveMaxLayer(options: {
15
- maxLayer?: ControlLayer;
16
- appliedMode?: boolean;
17
- }): ControlLayer;
18
- export declare const PROXY_OPERATION_PATHS: Record<string, string>;
19
- export declare function proxyPathForOperation(operation: string): string | null;
20
- export declare const ADMIT_PATH = "/api/inference-proxy/v1/admit";
21
- export declare const SDK_LAYER_PATH = "/api/inference-proxy/v1/sdk-layer";
22
- /** Wire shape from GET /v1/sdk-layer — mirrors @tensorcost/contracts (no runtime dep). */
23
- export type ComplianceEnforcementMode = "observe" | "enforce";
24
- export type ComplianceFailMode = "open" | "closed";
25
- export type DlpAction = "redact" | "refuse";
26
- export interface CompiledComplianceSnapshot {
27
- frameworks: string[];
28
- mode: ComplianceEnforcementMode;
29
- fail_mode: ComplianceFailMode;
30
- allowed_providers?: string[];
31
- allowed_models?: string[];
32
- allowed_regions?: string[];
33
- max_grants: DataGrant[];
34
- dlp: {
35
- enabled: boolean;
36
- detectors: string[];
37
- action: DlpAction;
38
- };
39
- audit: {
40
- stamp: boolean;
41
- };
42
- }
43
- export declare const SDK_LAYER_CACHE_TTL_MS = 30000;
44
- export declare const SDK_LAYER_DECAY_MS: number;
45
- /** Cap on the blocking sdk-layer GET so a hung TensorCost cannot stall the agent. */
46
- export declare const SDK_LAYER_FETCH_TIMEOUT_MS = 250;
47
- /** Govern admit must fail-open quickly; agents already wait on the model. */
48
- export declare const ADMIT_TIMEOUT_MS = 500;
49
- /** Steer proxy must send response headers quickly or fail-open to direct. */
50
- export declare const PROXY_HEADERS_TIMEOUT_MS = 2000;
51
- export declare const DATA_GRANTS: readonly ["telemetry", "retain_completions", "retain_prompts", "retain_tools"];
52
- export type DataGrant = (typeof DATA_GRANTS)[number];
53
- export declare function intersectGrants(codeMax: readonly DataGrant[] | null | undefined, consoleGrants: readonly DataGrant[]): DataGrant[];
54
- //# sourceMappingURL=layer.d.ts.map
package/dist/prewarm.d.ts DELETED
@@ -1,14 +0,0 @@
1
- /**
2
- * Prefetch JWT + published control layer so the first model call is not
3
- * blocked on cold `/sdk-token/exchange` or `/sdk-layer`.
4
- *
5
- * Call once at process/Lambda init (module scope), before traffic arrives:
6
- *
7
- * import { prewarm } from "@tensorcost/sdk";
8
- * await prewarm({ apiKey, tenantId, baseUrl });
9
- */
10
- import type { WrapOptions } from "./types.js";
11
- export declare function prewarm(options?: WrapOptions): Promise<void>;
12
- /** Best-effort drain of fire-and-forget observation POSTs before Lambda freeze. */
13
- export declare function flushObservations(options?: WrapOptions, timeoutMs?: number): Promise<void>;
14
- //# sourceMappingURL=prewarm.d.ts.map
@@ -1,41 +0,0 @@
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
- onLifecycleEvent: LifecycleEventCallback | undefined;
28
- failOpenEnabled: boolean;
29
- circuit: CircuitBreaker;
30
- application?: string | null;
31
- tags?: string[];
32
- customer?: string | null;
33
- feature?: string | null;
34
- teamId?: string | null;
35
- }
36
- export declare function install(client: unknown, transport: ObservationTransport, tenantId: string | null, environment: string | null, connectionId: string | null, hardening: AppliedModeHardeningOpts, deployment?: string | null, promptTemplateId?: string | null, agentId?: string | null, workflowId?: string | null): void;
37
- export declare const __test__: {
38
- MARKER: string;
39
- WITH_META_MARKER: string;
40
- };
41
- //# sourceMappingURL=anthropic.d.ts.map
@@ -1,19 +0,0 @@
1
- /**
2
- * Provider detection — duck-typed.
3
- *
4
- * We avoid importing `openai`, `@anthropic-ai/sdk`, or
5
- * `@aws-sdk/client-bedrock-runtime` at runtime so that the SDK has zero
6
- * peer-dep cost when the customer only uses one provider. Detection
7
- * inspects the shape of the client object instead.
8
- *
9
- * Bedrock detection uses the Smithy-generated `config.serviceId` field,
10
- * which is the most precise available discriminator — it's set by the
11
- * AWS SDK generator and does not depend on the constructor name (which
12
- * minifiers can change).
13
- */
14
- import type { Provider } from "../types.js";
15
- export declare class UnsupportedClientError extends Error {
16
- constructor(message: string);
17
- }
18
- export declare function detectProvider(client: unknown): Provider;
19
- //# sourceMappingURL=detect.d.ts.map
@@ -1,6 +0,0 @@
1
- export { detectProvider, UnsupportedClientError } from "./detect.js";
2
- export * as openaiProvider from "./openai.js";
3
- export * as anthropicProvider from "./anthropic.js";
4
- export * as bedrockProvider from "./bedrock.js";
5
- export * as vertexProvider from "./vertex.js";
6
- //# sourceMappingURL=index.d.ts.map
@@ -1,46 +0,0 @@
1
- /**
2
- * OpenAI client wrapping.
3
- *
4
- * Intercepts:
5
- * * `client.chat.completions.create`
6
- * * `client.completions.create` (legacy text completions; v0 still ships)
7
- *
8
- * We capture only metadata (model, token usage) — never prompt content.
9
- * Customer prompts stay on their machine.
10
- *
11
- * Applied-mode hardening (v0.4.0): chat.completions.create routes through
12
- * the proxy-client module, which handles retries, timeouts, typed errors,
13
- * telemetry hooks, and the fail-open circuit breaker. When the circuit is
14
- * open or the proxy errors after retries, and `failOpenEnabled=true`, the
15
- * call falls back to the customer's direct provider path.
16
- */
17
- import type { ObservationTransport } from "../transport.js";
18
- import type { CircuitBreaker } from "../circuit.js";
19
- import type { LifecycleEventCallback } from "../telemetry.js";
20
- import type { RetryConfig } from "../retry.js";
21
- import type { ControlLayer } from "../layer.js";
22
- import type { SdkLayerClient } from "../sdk-layer.js";
23
- export interface AppliedModeHardeningOpts {
24
- maxLayer: ControlLayer;
25
- appliedMode: boolean;
26
- proxyUrl: string | null;
27
- baseUrl: string;
28
- sdkLayer: SdkLayerClient;
29
- retry: RetryConfig;
30
- timeoutMs: number;
31
- headersTimeoutMs: number;
32
- onLifecycleEvent: LifecycleEventCallback | undefined;
33
- failOpenEnabled: boolean;
34
- circuit: CircuitBreaker;
35
- application?: string | null;
36
- tags?: string[];
37
- customer?: string | null;
38
- feature?: string | null;
39
- teamId?: string | null;
40
- }
41
- export declare function install(client: unknown, transport: ObservationTransport, tenantId: string | null, environment: string | null, connectionId: string | null, hardening: AppliedModeHardeningOpts, deployment?: string | null, promptTemplateId?: string | null, agentId?: string | null, workflowId?: string | null): void;
42
- export declare const __test__: {
43
- MARKER: string;
44
- WITH_META_MARKER: string;
45
- };
46
- //# sourceMappingURL=openai.d.ts.map
@@ -1,14 +0,0 @@
1
- /**
2
- * Google Vertex AI (google-genai Client, vertexai=true) — observe-only.
3
- *
4
- * Patches `client.models.generate_content` and `generate_content_stream`
5
- * on the unified `@google/genai` Client when constructed in Vertex mode.
6
- * Mirrors the Python `_vertex.py` provider and the Bedrock observe-only
7
- * contract: no applied mode, fail-open transport, streaming placeholders.
8
- */
9
- import type { ObservationTransport } from "../transport.js";
10
- export declare function install(client: unknown, transport: ObservationTransport, tenantId: string | null, environment: string | null, connectionId: string | null, deployment?: string | null, promptTemplateId?: string | null, agentId?: string | null, workflowId?: string | null, customer?: string | null, feature?: string | null): void;
11
- export declare const __test__: {
12
- MARKER: string;
13
- };
14
- //# sourceMappingURL=vertex.d.ts.map
@@ -1,114 +0,0 @@
1
- /**
2
- * Applied-mode proxy HTTP client.
3
- *
4
- * This is the single place that combines retries, timeouts, typed errors,
5
- * telemetry hooks, and the fail-open circuit breaker. The provider wrappers
6
- * (openai.ts, anthropic.ts) call `proxyRequest()` instead of hitting the
7
- * proxy directly.
8
- *
9
- * The contract:
10
- * - Returns the parsed response body on success.
11
- * - On all non-success outcomes, throws a subclass of TensorCostError.
12
- * - Never swallows errors — the provider wrapper's fail-open logic
13
- * (fall back to direct call on proxy failure) lives in the provider
14
- * wrapper, not here.
15
- *
16
- * Timeout handling:
17
- * - `headersTimeoutMs` (default 2s): abort if the proxy never returns
18
- * response headers (TCP accepted but wedged). Fail-open to direct.
19
- * - `timeoutMs` (default 60s): wall-clock budget for the full response
20
- * body after headers (model time through the proxy).
21
- * - Streaming through steer is refused at the provider wrapper; proxy
22
- * server supports SSE but the SDK client does not consume streams yet.
23
- *
24
- * Retry logic:
25
- * - Retries on 5xx + network errors + 429.
26
- * - Respects Retry-After on 429.
27
- * - Stops at maxAttempts.
28
- * - Does not retry on 4xx (except 429).
29
- *
30
- * Circuit breaker:
31
- * - Maintained on the CircuitBreaker instance passed in.
32
- * - When open, throws TensorCostProxyError immediately with a clear
33
- * message so the provider wrapper can activate the direct-provider
34
- * fallback.
35
- */
36
- import { TensorCostError } from "./errors.js";
37
- import type { RetryConfig } from "./retry.js";
38
- import type { CircuitBreaker } from "./circuit.js";
39
- import type { LifecycleEventCallback } from "./telemetry.js";
40
- import type { Provider } from "./telemetry.js";
41
- import { type ControlLayer } from "./layer.js";
42
- export interface ProxyRequestOptions {
43
- proxyUrl: string;
44
- bearerToken: string;
45
- providerUrl: string;
46
- providerAuth: string;
47
- body: Record<string, unknown>;
48
- model: string;
49
- provider: Provider;
50
- operation: string;
51
- correlationId: string;
52
- environment: string | null;
53
- /**
54
- * Per-agent-run attribution, forwarded as `x-tc-agent-id` /
55
- * `x-tc-workflow-id`. These are what let the proxy scope a spend cap to
56
- * a run; without the workflow id it has no run to cap. Same values the
57
- * observation envelope carries as `agent_id` / `workflow_id`.
58
- */
59
- agentId?: string | undefined;
60
- workflowId?: string | undefined;
61
- /** A-04 chargeback → `x-tc-customer`. */
62
- customer?: string | undefined;
63
- /** A-04 chargeback → `x-tc-feature`. */
64
- feature?: string | undefined;
65
- /** Routing-policy application scope → `x-tc-application`. */
66
- application?: string | null | undefined;
67
- /** Routing-policy tags → comma-separated `x-tc-tags`. */
68
- tags?: string[] | undefined;
69
- /** Compliance team scope → `x-tc-team-id`. */
70
- teamId?: string | undefined;
71
- retry?: RetryConfig;
72
- timeoutMs?: number;
73
- /** Max wait for proxy response headers before fail-open. Default 2s. */
74
- headersTimeoutMs?: number;
75
- onLifecycleEvent?: LifecycleEventCallback;
76
- circuit: CircuitBreaker;
77
- maxLayer?: ControlLayer;
78
- /**
79
- * When true (steer fail-open), do not retry proxy *network* errors —
80
- * fail immediately so the wrapper can go direct. 429/5xx still retry.
81
- * Timeouts still retry: a timeout usually means the upstream model is slow.
82
- */
83
- failOpenFast?: boolean;
84
- /** Injected fetch implementation (for testing). Defaults to globalThis.fetch. */
85
- fetchImpl?: typeof fetch;
86
- }
87
- export interface ProxyRequestResult {
88
- body: unknown;
89
- decisionHeader: string | null;
90
- }
91
- /**
92
- * Execute a single proxied request with retries, timeouts, telemetry,
93
- * and circuit-breaker integration.
94
- *
95
- * Throws a `TensorCostError` subclass on any failure.
96
- * Returns the parsed JSON body on success.
97
- */
98
- export declare function proxyRequest(opts: ProxyRequestOptions): Promise<ProxyRequestResult>;
99
- /**
100
- * Should a failed proxy attempt fall back to calling the provider
101
- * directly?
102
- *
103
- * The applied-mode fail-open contract exists so that TensorCost being
104
- * down never takes the customer's inference down with it. Every transport
105
- * failure — timeout, network error, 5xx, open circuit — is therefore a
106
- * "go around us" signal and returns true.
107
- *
108
- * A policy refusal (run budget, model governance, guardrail hard_stop) is
109
- * when the proxy is healthy and the refusal IS the product. Falling back
110
- * would issue the provider call anyway and turn enforcement into a log line.
111
- */
112
- export declare function shouldFallBackToProvider(err: unknown): boolean;
113
- export { TensorCostError };
114
- //# sourceMappingURL=proxy-client.d.ts.map