@tensorcost/sdk 0.5.0 → 1.0.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.
Files changed (100) hide show
  1. package/CHANGELOG.md +117 -0
  2. package/README.md +63 -95
  3. package/dist/adapters/crewai.d.ts +4 -0
  4. package/dist/adapters/crewai.d.ts.map +1 -0
  5. package/dist/adapters/crewai.js +6 -0
  6. package/dist/adapters/crewai.js.map +1 -0
  7. package/dist/adapters/langchain.d.ts +4 -0
  8. package/dist/adapters/langchain.d.ts.map +1 -0
  9. package/dist/adapters/langchain.js +6 -0
  10. package/dist/adapters/langchain.js.map +1 -0
  11. package/dist/adapters/llamaindex.d.ts +4 -0
  12. package/dist/adapters/llamaindex.d.ts.map +1 -0
  13. package/dist/adapters/llamaindex.js +6 -0
  14. package/dist/adapters/llamaindex.js.map +1 -0
  15. package/dist/adapters/vercel-ai.d.ts +4 -0
  16. package/dist/adapters/vercel-ai.d.ts.map +1 -0
  17. package/dist/adapters/vercel-ai.js +6 -0
  18. package/dist/adapters/vercel-ai.js.map +1 -0
  19. package/dist/admit-client.d.ts +39 -0
  20. package/dist/admit-client.d.ts.map +1 -0
  21. package/dist/admit-client.js +93 -0
  22. package/dist/admit-client.js.map +1 -0
  23. package/dist/applied.d.ts +6 -1
  24. package/dist/applied.d.ts.map +1 -1
  25. package/dist/applied.js +13 -1
  26. package/dist/applied.js.map +1 -1
  27. package/dist/circuit-observations.d.ts +12 -0
  28. package/dist/circuit-observations.d.ts.map +1 -0
  29. package/dist/circuit-observations.js +37 -0
  30. package/dist/circuit-observations.js.map +1 -0
  31. package/dist/circuit.d.ts +4 -1
  32. package/dist/circuit.d.ts.map +1 -1
  33. package/dist/circuit.js +13 -7
  34. package/dist/circuit.js.map +1 -1
  35. package/dist/config.d.ts +2 -3
  36. package/dist/config.d.ts.map +1 -1
  37. package/dist/config.js +74 -6
  38. package/dist/config.js.map +1 -1
  39. package/dist/decision.d.ts +11 -0
  40. package/dist/decision.d.ts.map +1 -0
  41. package/dist/decision.js +40 -0
  42. package/dist/decision.js.map +1 -0
  43. package/dist/errors.d.ts +40 -0
  44. package/dist/errors.d.ts.map +1 -1
  45. package/dist/errors.js +46 -0
  46. package/dist/errors.js.map +1 -1
  47. package/dist/index.d.ts +8 -3
  48. package/dist/index.d.ts.map +1 -1
  49. package/dist/index.js +7 -2
  50. package/dist/index.js.map +1 -1
  51. package/dist/layer.d.ts +27 -0
  52. package/dist/layer.d.ts.map +1 -0
  53. package/dist/layer.js +77 -0
  54. package/dist/layer.js.map +1 -0
  55. package/dist/providers/anthropic.d.ts +11 -1
  56. package/dist/providers/anthropic.d.ts.map +1 -1
  57. package/dist/providers/anthropic.js +196 -18
  58. package/dist/providers/anthropic.js.map +1 -1
  59. package/dist/providers/bedrock.d.ts +1 -1
  60. package/dist/providers/bedrock.d.ts.map +1 -1
  61. package/dist/providers/bedrock.js +21 -3
  62. package/dist/providers/bedrock.js.map +1 -1
  63. package/dist/providers/detect.d.ts.map +1 -1
  64. package/dist/providers/detect.js +17 -2
  65. package/dist/providers/detect.js.map +1 -1
  66. package/dist/providers/index.d.ts +1 -0
  67. package/dist/providers/index.d.ts.map +1 -1
  68. package/dist/providers/index.js +1 -0
  69. package/dist/providers/index.js.map +1 -1
  70. package/dist/providers/openai.d.ts +11 -1
  71. package/dist/providers/openai.d.ts.map +1 -1
  72. package/dist/providers/openai.js +255 -20
  73. package/dist/providers/openai.js.map +1 -1
  74. package/dist/providers/vertex.d.ts +14 -0
  75. package/dist/providers/vertex.d.ts.map +1 -0
  76. package/dist/providers/vertex.js +174 -0
  77. package/dist/providers/vertex.js.map +1 -0
  78. package/dist/proxy-client.d.ts +37 -1
  79. package/dist/proxy-client.d.ts.map +1 -1
  80. package/dist/proxy-client.js +124 -4
  81. package/dist/proxy-client.js.map +1 -1
  82. package/dist/sdk-layer.d.ts +26 -0
  83. package/dist/sdk-layer.d.ts.map +1 -0
  84. package/dist/sdk-layer.js +73 -0
  85. package/dist/sdk-layer.js.map +1 -0
  86. package/dist/transport.d.ts +6 -1
  87. package/dist/transport.d.ts.map +1 -1
  88. package/dist/transport.js +14 -3
  89. package/dist/transport.js.map +1 -1
  90. package/dist/types.d.ts +178 -17
  91. package/dist/types.d.ts.map +1 -1
  92. package/dist/version.d.ts +9 -0
  93. package/dist/version.d.ts.map +1 -0
  94. package/dist/version.js +10 -0
  95. package/dist/version.js.map +1 -0
  96. package/dist/wrap.d.ts +13 -14
  97. package/dist/wrap.d.ts.map +1 -1
  98. package/dist/wrap.js +66 -59
  99. package/dist/wrap.js.map +1 -1
  100. package/package.json +7 -2
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Fetches the console-published control layer with a 30s cache.
3
+ * Decays to govern when the endpoint is unreachable for SDK_LAYER_DECAY_MS.
4
+ */
5
+ import { intersectGrants, isControlLayer, minLayer, SDK_LAYER_CACHE_TTL_MS, SDK_LAYER_DECAY_MS, SDK_LAYER_PATH, } from "./layer.js";
6
+ import { SDK_VERSION, sdkCapabilityHeader } from "./version.js";
7
+ export class SdkLayerClient {
8
+ constructor(opts) {
9
+ this.cache = null;
10
+ /** 0 until the first successful fetch — cold start must not skip decay-to-govern. */
11
+ this.lastSuccessAt = 0;
12
+ this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
13
+ this.getToken = opts.getToken;
14
+ this.fetchImpl = opts.fetchImpl ?? globalThis.fetch.bind(globalThis);
15
+ }
16
+ /** effective = min(codeMaxLayer, published). */
17
+ async effectiveLayer(codeMaxLayer) {
18
+ const snap = await this.fetchPublishedSnapshot(codeMaxLayer);
19
+ return minLayer(codeMaxLayer, snap.layer);
20
+ }
21
+ /** intersect(codeMaxGrants, console.data_grants). Absent codeMax = all console grants. */
22
+ async effectiveGrants(codeMaxGrants, codeMaxLayer = "observe") {
23
+ const snap = await this.fetchPublishedSnapshot(codeMaxLayer);
24
+ return intersectGrants(codeMaxGrants, snap.dataGrants);
25
+ }
26
+ async fetchPublishedSnapshot(codeMaxLayer) {
27
+ const now = Date.now();
28
+ if (this.cache && now - this.cache.fetchedAt < SDK_LAYER_CACHE_TTL_MS) {
29
+ return {
30
+ layer: this.cache.layer,
31
+ dataGrants: this.cache.dataGrants,
32
+ };
33
+ }
34
+ try {
35
+ const token = await this.getToken();
36
+ const url = `${this.baseUrl}${SDK_LAYER_PATH}`;
37
+ const resp = await this.fetchImpl(url, {
38
+ method: "GET",
39
+ headers: {
40
+ Authorization: `Bearer ${token}`,
41
+ "x-tc-sdk-version": SDK_VERSION,
42
+ "x-tc-sdk-capabilities": sdkCapabilityHeader(),
43
+ },
44
+ });
45
+ if (!resp.ok) {
46
+ throw new Error(`sdk-layer GET failed status=${resp.status}`);
47
+ }
48
+ const body = (await resp.json());
49
+ const layerRaw = body.published_layer ?? body.layer ?? "observe";
50
+ let layer = isControlLayer(layerRaw) ? layerRaw : "observe";
51
+ if (body.routing_paused) {
52
+ layer = minLayer(layer, "govern");
53
+ }
54
+ const dataGrants = (body.data_grants ?? []).filter((g) => g === "telemetry" ||
55
+ g === "retain_completions" ||
56
+ g === "retain_prompts" ||
57
+ g === "retain_tools");
58
+ this.cache = { layer, dataGrants, fetchedAt: now };
59
+ this.lastSuccessAt = now;
60
+ return { layer, dataGrants };
61
+ }
62
+ catch {
63
+ if (now - this.lastSuccessAt >= SDK_LAYER_DECAY_MS) {
64
+ return { layer: "govern", dataGrants: [] };
65
+ }
66
+ return {
67
+ layer: this.cache?.layer ?? codeMaxLayer,
68
+ dataGrants: this.cache?.dataGrants ?? [],
69
+ };
70
+ }
71
+ }
72
+ }
73
+ //# sourceMappingURL=sdk-layer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdk-layer.js","sourceRoot":"","sources":["../src/sdk-layer.ts"],"names":[],"mappings":"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"}
@@ -23,6 +23,8 @@ import type { Observation } from "./types.js";
23
23
  export interface TransportOptions {
24
24
  baseUrl: string;
25
25
  apiKey: string;
26
+ /** Required for token exchange against current inference-proxy DTO. */
27
+ tenantId?: string | null;
26
28
  timeoutMs?: number;
27
29
  failOpen?: boolean;
28
30
  /** Optional fetch override for testing. Defaults to global fetch. */
@@ -31,6 +33,7 @@ export interface TransportOptions {
31
33
  export declare class ObservationTransport {
32
34
  private readonly baseUrl;
33
35
  private readonly apiKey;
36
+ private readonly tenantId;
34
37
  private readonly timeoutMs;
35
38
  private readonly failOpen;
36
39
  private readonly fetchImpl;
@@ -46,7 +49,9 @@ export declare class ObservationTransport {
46
49
  */
47
50
  post(observation: Observation): void;
48
51
  private deliver;
49
- private getToken;
52
+ /** Exchange or return cached JWT for proxy/admit/sdk-layer calls. */
53
+ getToken(): Promise<string>;
54
+ private fetchToken;
50
55
  private exchangeToken;
51
56
  }
52
57
  export declare const __test__: {
@@ -1 +1 @@
1
- {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAQ9C,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAOD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IAEzC,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,UAAU,CAA2B;IAC7C,wEAAwE;IACxE,OAAO,CAAC,aAAa,CAAgC;gBAEzC,IAAI,EAAE,gBAAgB;IAQlC;;;;OAIG;IACH,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;YAqBtB,OAAO;YAqCP,QAAQ;YAiBR,aAAa;CAuC5B;AAED,eAAO,MAAM,QAAQ;;;CAGpB,CAAC"}
1
+ {"version":3,"file":"transport.d.ts","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAO9C,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,uEAAuE;IACvE,QAAQ,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qEAAqE;IACrE,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;CAC1B;AAOD,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAgB;IACzC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAU;IACnC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;IAEzC,OAAO,CAAC,OAAO,CAAK;IACpB,OAAO,CAAC,UAAU,CAA2B;IAC7C,wEAAwE;IACxE,OAAO,CAAC,aAAa,CAAgC;gBAEzC,IAAI,EAAE,gBAAgB;IASlC;;;;OAIG;IACH,IAAI,CAAC,WAAW,EAAE,WAAW,GAAG,IAAI;YAqBtB,OAAO;IAqCrB,qEAAqE;IAC/D,QAAQ,IAAI,OAAO,CAAC,MAAM,CAAC;YAInB,UAAU;YAiBV,aAAa;CA+C5B;AAED,eAAO,MAAM,QAAQ;;;CAGpB,CAAC"}
package/dist/transport.js CHANGED
@@ -19,7 +19,7 @@
19
19
  * (the default) and surfaced via console.warn. The customer's call
20
20
  * site never sees an exception.
21
21
  */
22
- const SDK_VERSION = "tensorcost-node/0.3.0";
22
+ import { SDK_VERSION } from "./version.js";
23
23
  const TOKEN_REFRESH_LEEWAY_MS = 60_000;
24
24
  const DEFAULT_TOKEN_LIFETIME_MS = 15 * 60_000;
25
25
  const MAX_QUEUE_DEPTH = 1024;
@@ -32,6 +32,7 @@ export class ObservationTransport {
32
32
  this.tokenInflight = null;
33
33
  this.baseUrl = opts.baseUrl.replace(/\/+$/, "");
34
34
  this.apiKey = opts.apiKey;
35
+ this.tenantId = opts.tenantId ?? null;
35
36
  this.timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
36
37
  this.failOpen = opts.failOpen ?? true;
37
38
  this.fetchImpl = opts.fetchImpl ?? globalThis.fetch.bind(globalThis);
@@ -61,7 +62,7 @@ export class ObservationTransport {
61
62
  }
62
63
  async deliver(observation) {
63
64
  try {
64
- const token = await this.getToken();
65
+ const token = await this.fetchToken();
65
66
  const url = `${this.baseUrl}/api/inference-proxy/observation`;
66
67
  const controller = new AbortController();
67
68
  const timer = setTimeout(() => controller.abort(), this.timeoutMs);
@@ -93,7 +94,11 @@ export class ObservationTransport {
93
94
  console.warn(`tensorcost: observation delivery failed: ${err.message}`);
94
95
  }
95
96
  }
97
+ /** Exchange or return cached JWT for proxy/admit/sdk-layer calls. */
96
98
  async getToken() {
99
+ return this.fetchToken();
100
+ }
101
+ async fetchToken() {
97
102
  const now = Date.now();
98
103
  if (this.tokenCache &&
99
104
  now < this.tokenCache.expiresAt - TOKEN_REFRESH_LEEWAY_MS) {
@@ -108,6 +113,9 @@ export class ObservationTransport {
108
113
  return this.tokenInflight;
109
114
  }
110
115
  async exchangeToken() {
116
+ if (!this.tenantId) {
117
+ throw new Error("tensorcost: tenant_id required for token exchange (pass tenantId to wrap() or set TENSORCOST_TENANT_ID)");
118
+ }
111
119
  const url = `${this.baseUrl}/api/inference-proxy/sdk-token/exchange`;
112
120
  const controller = new AbortController();
113
121
  const timer = setTimeout(() => controller.abort(), this.timeoutMs);
@@ -118,7 +126,10 @@ export class ObservationTransport {
118
126
  "Content-Type": "application/json",
119
127
  "User-Agent": SDK_VERSION,
120
128
  },
121
- body: JSON.stringify({ api_key: this.apiKey }),
129
+ body: JSON.stringify({
130
+ tenant_id: this.tenantId,
131
+ sdk_long_lived_token: this.apiKey,
132
+ }),
122
133
  signal: controller.signal,
123
134
  });
124
135
  if (!resp.ok) {
@@ -1 +1 @@
1
- {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transport.js","sourceRoot":"","sources":["../src/transport.ts"],"names":[],"mappings":"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"}
package/dist/types.d.ts CHANGED
@@ -7,9 +7,12 @@
7
7
  */
8
8
  import type { LifecycleEventCallback } from "./telemetry.js";
9
9
  import type { RetryConfig } from "./retry.js";
10
- export type Provider = "openai" | "anthropic" | "bedrock";
11
- export type Operation = "chat.completions" | "completions" | "messages" | "bedrock.invoke_model" | "bedrock.converse" | "bedrock.invoke_model_stream" | "bedrock.converse_stream";
10
+ import type { ControlLayer, DataGrant } from "./layer.js";
11
+ export type { ControlLayer, DataGrant } from "./layer.js";
12
+ export type Provider = "openai" | "anthropic" | "bedrock" | "vertex";
13
+ export type Operation = "chat.completions" | "completions" | "messages" | "bedrock.invoke_model" | "bedrock.converse" | "bedrock.invoke_model_stream" | "bedrock.converse_stream" | "vertex.generate_content" | "vertex.generate_content_stream";
12
14
  export type ObservationStatus = "success" | "error";
15
+ export type ObservationModality = "text" | "image" | "audio" | "video" | "mixed";
13
16
  /**
14
17
  * Wire shape posted to `POST /api/proxy/observation`. Mirrors the
15
18
  * Python SDK's `Observation` model byte-for-byte so the two SDKs
@@ -20,6 +23,8 @@ export interface Observation {
20
23
  provider: Provider;
21
24
  model: string;
22
25
  operation: Operation;
26
+ /** Defaults to "text" when omitted on the wire. */
27
+ modality?: ObservationModality;
23
28
  request_at: string;
24
29
  response_at: string;
25
30
  input_tokens: number | null;
@@ -47,6 +52,65 @@ export interface Observation {
47
52
  * did not set `environment`.
48
53
  */
49
54
  connection_id?: string;
55
+ /**
56
+ * SDK metadata bag. Merged from wrap-time defaults and per-call
57
+ * withMeta() overrides. The backend stores this verbatim in
58
+ * trace_span.metadata; two well-known keys are indexed for
59
+ * group-by queries:
60
+ * - deployment — git SHA, CI run id, or any operator marker
61
+ * - prompt_template_id — per-call-site template name/version
62
+ */
63
+ metadata?: Record<string, unknown>;
64
+ /**
65
+ * Per-agent-run cost attribution — agent identity. Optional. Stamped
66
+ * onto the observation envelope when the SDK was constructed with
67
+ * `wrap(client, { agentId: '...' })`, or overridden per-call via
68
+ * `.withMeta({ agentId: '...' })`. Forwarded verbatim by
69
+ * inference-proxy-service's ObservationService onto the Kafka/event-bus
70
+ * envelope; ai-service writes it straight into
71
+ * `ai.ai_spend_events.agent_id` (migration 011 — the column has existed
72
+ * since April 2026 as `agent_id text -- populated by tag propagation
73
+ * (post-MVP)`; this is that propagation).
74
+ *
75
+ * A stable identifier for the *kind* of agent making calls (e.g.
76
+ * "code-review-agent", "support-triage-bot") — set once per wrapped
77
+ * client is the common case, hence the wrap-time default.
78
+ *
79
+ * Unlike `environment` / `connection_id`, this is NOT stored in the
80
+ * `metadata` JSONB bag — it is a dedicated indexed column
81
+ * (`spend_events_tenant_agent_time` partial index), so it is threaded
82
+ * through as its own top-level envelope field the same way
83
+ * `environment` / `connection_id` are.
84
+ */
85
+ agent_id?: string;
86
+ /**
87
+ * Per-agent-run cost attribution — run identity. Optional. Same
88
+ * plumbing as `agent_id` (see above), landing in
89
+ * `ai.ai_spend_events.workflow_id`.
90
+ *
91
+ * A unique identifier for ONE execution of an agent (e.g. a session id,
92
+ * a job id) — this almost always varies call-to-call within a single
93
+ * wrapped client's lifetime, so the primary way to set it is per-call
94
+ * via `.withMeta({ workflowId: '...' })` rather than at `wrap()` time.
95
+ * A wrap-time default is still supported for the case where one
96
+ * process = one run (e.g. a short-lived batch job).
97
+ *
98
+ * "Cost of one agent run" is defined as
99
+ * `SUM(total_cost_cents) WHERE tenant_id = ? AND workflow_id = ? AND
100
+ * superseded_at IS NULL` — see ai-service's `agent-runs` module.
101
+ */
102
+ workflow_id?: string;
103
+ /**
104
+ * A-04 chargeback — end-customer cohort. Optional. Stamped on every
105
+ * observation when configured via `wrap({ customer })` or per-call
106
+ * `.withMeta({ customer })`. Lands in `ai.ai_spend_events.customer`.
107
+ */
108
+ customer?: string;
109
+ /**
110
+ * A-04 chargeback — product feature. Same plumbing as `customer`,
111
+ * landing in `ai.ai_spend_events.feature`.
112
+ */
113
+ feature?: string;
50
114
  }
51
115
  export interface WrapOptions {
52
116
  /** Long-lived TensorCost API key. Falls back to `TENSORCOST_API_KEY`. */
@@ -91,19 +155,26 @@ export interface WrapOptions {
91
155
  */
92
156
  failOpen?: boolean;
93
157
  /**
94
- * Layer 2 applied mode. When true, the SDK routes every inference
95
- * request through the TensorCost inference-proxy rather than sending
96
- * it directly to the upstream AI provider. The proxy decides
97
- * per-request whether to actually re-route or pass through unchanged.
158
+ * Control-layer ceiling for this wrapped client. A layer is a ceiling,
159
+ * not a setting — effective layer is min(code.maxLayer, console published).
98
160
  *
99
- * Defaults to false. Observe-only telemetry continues to fire
100
- * regardless of this setting.
161
+ * off — no SDK wiring; client returned unchanged
162
+ * observe — telemetry only (default when maxLayer unset)
163
+ * govern — metadata-only admit before direct provider call
164
+ * steer — proxy in path; proxy may steer without full route
165
+ * route — full applied-mode routing through inference-proxy
101
166
  *
102
- * Requires `proxyUrl` (or `TENSORCOST_PROXY_URL` env var) to be set;
103
- * throws `TensorCostConfigError` at `wrap()` time if neither is present.
104
- *
105
- * Not yet supported for AWS Bedrock clients — `wrap()` will throw
106
- * immediately if you enable applied mode with a Bedrock client.
167
+ * Requires `proxyUrl` when maxLayer is steer or route.
168
+ */
169
+ maxLayer?: ControlLayer;
170
+ /**
171
+ * Code-side data-grant ceiling. Effective grants =
172
+ * intersect(maxGrants, console.data_grants). Omit to allow all console grants.
173
+ */
174
+ maxGrants?: readonly DataGrant[];
175
+ /**
176
+ * @deprecated Use `maxLayer: 'route'` instead. When true and maxLayer is
177
+ * unset, resolves to route and emits a console warning.
107
178
  */
108
179
  appliedMode?: boolean;
109
180
  /**
@@ -167,6 +238,78 @@ export interface WrapOptions {
167
238
  * you are using the SDK in a context where the client's key is unavailable.
168
239
  */
169
240
  providerApiKey?: string;
241
+ /**
242
+ * Deployment identifier stamped on every observation from this wrapped
243
+ * client. Typically a git SHA, CI run id, or a human-readable release
244
+ * label like `"2026-05-28-hotfix"`.
245
+ *
246
+ * Stored as `metadata.deployment` in the trace_span row. The dashboard's
247
+ * "Group by deployment" view buckets spans by this value so Priya can
248
+ * answer "did my latest deploy change cost?".
249
+ *
250
+ * Falls back to `TENSORCOST_DEPLOYMENT` env var. Leave unset if you don't
251
+ * use deployment-level cost attribution.
252
+ */
253
+ deployment?: string;
254
+ /**
255
+ * Default prompt-template identifier for every call made through this
256
+ * client. Stored as `metadata.prompt_template_id` on each observation.
257
+ *
258
+ * Per-call overrides are available via `.withMeta({ promptTemplateId })`.
259
+ * The per-call value wins over this wrap-time default.
260
+ *
261
+ * Falls back to `TENSORCOST_PROMPT_TEMPLATE_ID` env var.
262
+ */
263
+ promptTemplateId?: string;
264
+ /**
265
+ * Stable identifier for the kind of agent making calls through this
266
+ * client (e.g. "code-review-agent"). Stamped on every observation as
267
+ * the top-level `agent_id` field — NOT the metadata bag — and lands in
268
+ * `ai.ai_spend_events.agent_id`.
269
+ *
270
+ * Per-call overrides are available via `.withMeta({ agentId })` on the
271
+ * OpenAI and Anthropic wrappers. Bedrock has no per-call hook (Smithy
272
+ * middleware is registered once at wrap() time), so for Bedrock this
273
+ * wrap-time value is the only way to set `agent_id`.
274
+ *
275
+ * Falls back to `TENSORCOST_AGENT_ID` env var.
276
+ */
277
+ agentId?: string;
278
+ /**
279
+ * Identifier for ONE execution of an agent (a run/session id). Stamped
280
+ * on every observation as the top-level `workflow_id` field and lands
281
+ * in `ai.ai_spend_events.workflow_id`.
282
+ *
283
+ * Because a run id almost always changes between calls, the primary
284
+ * way to set this is per-call via `.withMeta({ workflowId })`. This
285
+ * wrap-time default exists for the one-process-per-run case (batch
286
+ * jobs, Bedrock clients with no per-call hook).
287
+ *
288
+ * Falls back to `TENSORCOST_WORKFLOW_ID` env var.
289
+ */
290
+ workflowId?: string;
291
+ /**
292
+ * Routing-policy application scope. Sent as `x-tc-application` on proxy
293
+ * requests. Falls back to `TC_APPLICATION` / `TENSORCOST_APPLICATION`.
294
+ */
295
+ application?: string;
296
+ /**
297
+ * Routing-policy tags. Sent as comma-separated `x-tc-tags` on proxy
298
+ * requests. Falls back to `TC_TAGS` / `TENSORCOST_TAGS` (comma-separated).
299
+ */
300
+ tags?: string | string[];
301
+ /**
302
+ * A-04 chargeback — end-customer cohort (max 128 chars). Sent on
303
+ * observations and as `x-tc-customer` in applied mode.
304
+ * Falls back to `TENSORCOST_CUSTOMER`.
305
+ */
306
+ customer?: string;
307
+ /**
308
+ * A-04 chargeback — product feature (max 128 chars). Sent on
309
+ * observations and as `x-tc-feature` in applied mode.
310
+ * Falls back to `TENSORCOST_FEATURE`.
311
+ */
312
+ feature?: string;
170
313
  }
171
314
  export interface ResolvedConfig {
172
315
  apiKey: string;
@@ -186,12 +329,12 @@ export interface ResolvedConfig {
186
329
  */
187
330
  connectionId: string | null;
188
331
  failOpen: boolean;
189
- /** Resolved applied-mode flag. */
332
+ /** Resolved control-layer ceiling. */
333
+ maxLayer: ControlLayer;
334
+ /** @deprecated Derived: maxLayer is steer or route. */
190
335
  appliedMode: boolean;
191
336
  /**
192
- * Resolved proxy base URL. Non-null only when `appliedMode=true`.
193
- * Guaranteed by config resolution — `wrap()` throws before returning
194
- * a config with `appliedMode=true` and `proxyUrl=null`.
337
+ * Resolved proxy base URL. Required when maxLayer is steer or route.
195
338
  */
196
339
  proxyUrl: string | null;
197
340
  retry: RetryConfig;
@@ -200,5 +343,23 @@ export interface ResolvedConfig {
200
343
  onLifecycleEvent: LifecycleEventCallback | undefined;
201
344
  failOpenEnabled: boolean;
202
345
  providerApiKey: string | null;
346
+ /** Resolved deployment tag. `null` when not configured. */
347
+ deployment: string | null;
348
+ /** Resolved default prompt-template id. `null` when not configured. */
349
+ promptTemplateId: string | null;
350
+ /** Resolved wrap-time agent id default. `null` when not configured. */
351
+ agentId: string | null;
352
+ /** Resolved wrap-time workflow (run) id default. `null` when not configured. */
353
+ workflowId: string | null;
354
+ /** Resolved application scope for routing policies. `null` when unset. */
355
+ application: string | null;
356
+ /** Resolved routing tags (normalized list). Empty when unset. */
357
+ tags: string[];
358
+ /** A-04 — resolved customer cohort. `null` when unset. */
359
+ customer: string | null;
360
+ /** A-04 — resolved product feature. `null` when unset. */
361
+ feature: string | null;
362
+ /** Resolved code-side data grant ceiling. Empty = no ceiling. */
363
+ maxGrants: DataGrant[];
203
364
  }
204
365
  //# sourceMappingURL=types.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Central SDK identity — wire headers and observation sdk_version.
3
+ */
4
+ export declare const SDK_VERSION = "tensorcost-node/1.0.0";
5
+ /** Advertise only capabilities this build implements. */
6
+ export declare const SDK_CAPABILITIES: readonly ["streaming", "refusal-v1"];
7
+ export type SdkCapability = (typeof SDK_CAPABILITIES)[number];
8
+ export declare function sdkCapabilityHeader(): string;
9
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,eAAO,MAAM,WAAW,0BAA0B,CAAC;AAEnD,yDAAyD;AACzD,eAAO,MAAM,gBAAgB,sCAAuC,CAAC;AACrE,MAAM,MAAM,aAAa,GAAG,CAAC,OAAO,gBAAgB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE9D,wBAAgB,mBAAmB,IAAI,MAAM,CAE5C"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Central SDK identity — wire headers and observation sdk_version.
3
+ */
4
+ export const SDK_VERSION = "tensorcost-node/1.0.0";
5
+ /** Advertise only capabilities this build implements. */
6
+ export const SDK_CAPABILITIES = ["streaming", "refusal-v1"];
7
+ export function sdkCapabilityHeader() {
8
+ return SDK_CAPABILITIES.join(",");
9
+ }
10
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../src/version.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,uBAAuB,CAAC;AAEnD,yDAAyD;AACzD,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAAC,WAAW,EAAE,YAAY,CAAU,CAAC;AAGrE,MAAM,UAAU,mBAAmB;IACjC,OAAO,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACpC,CAAC"}
package/dist/wrap.d.ts CHANGED
@@ -5,21 +5,20 @@
5
5
  * ergonomics non-negotiable: customer changes one line, no other code
6
6
  * paths shift.
7
7
  *
8
- * Applied mode (Layer 2): when `options.appliedMode=true`, the client's
9
- * baseURL is permanently redirected to the TensorCost inference-proxy and
10
- * two custom headers (`x-tc-provider-url`, `x-tc-provider-auth`) are
11
- * injected into `client.defaultHeaders`. The proxy handles per-request
12
- * routing decisions. Observe-only telemetry still fires post-call.
13
- *
14
- * Hardening (v0.4.0): applied-mode requests now go through the proxy-client
15
- * module which adds retries, timeouts, typed errors, telemetry hooks, and
16
- * the fail-open circuit breaker.
17
- *
18
- * Bedrock (v0.4.0): observe-only. Applied mode is not supported for Bedrock —
19
- * wrap(bedrockClient, { appliedMode: true }) throws TensorCostConfigError.
20
- * The Smithy middleware registered on client.middlewareStack intercepts
21
- * every client.send() call transparently.
8
+ * Control layers:
9
+ * off — client returned unchanged (no transport, no hooks)
10
+ * observe — telemetry only
11
+ * govern — admit (metadata) then direct provider call
12
+ * steer/route — proxy in request path (OpenAI / Anthropic only)
22
13
  */
14
+ import { TensorCostConfigError } from "./config.js";
15
+ import { layerRank } from "./layer.js";
23
16
  import type { WrapOptions } from "./types.js";
17
+ declare function steerRouteUnsupportedError(provider: string, maxLayer: string): TensorCostConfigError;
24
18
  export declare function wrap<T>(client: T, options?: WrapOptions): T;
19
+ export declare const __test__: {
20
+ layerRank: typeof layerRank;
21
+ steerRouteUnsupportedError: typeof steerRouteUnsupportedError;
22
+ };
23
+ export {};
25
24
  //# sourceMappingURL=wrap.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../src/wrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAWH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,GAAE,WAAgB,GAAG,CAAC,CAqF/D"}
1
+ {"version":3,"file":"wrap.d.ts","sourceRoot":"","sources":["../src/wrap.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAGH,OAAO,EAAE,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAUpD,OAAO,EAAE,SAAS,EAAiB,MAAM,YAAY,CAAC;AAEtD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAE9C,iBAAS,0BAA0B,CACjC,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,GACf,qBAAqB,CAOvB;AAED,wBAAgB,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,OAAO,GAAE,WAAgB,GAAG,CAAC,CA4H/D;AAED,eAAO,MAAM,QAAQ;;;CAA4C,CAAC"}