@neuraltrust/trustguard-sdk 0.1.0 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,6 +1,9 @@
1
1
  # TrustGuard Node.js SDK
2
2
 
3
- Official Node.js / TypeScript client for the TrustGuard runtime guard API (`POST /v1/guard`). Configure a base URL and an API key, send the payload you want evaluated, and act on the verdict: TrustGuard detects, you enforce.
3
+ [![npm](https://img.shields.io/npm/v/%40neuraltrust%2Ftrustguard-sdk)](https://www.npmjs.com/package/@neuraltrust/trustguard-sdk)
4
+ [Documentation](https://docs.neuraltrust.ai/sdks/trustguard/node) · [Python package](https://pypi.org/project/trustguard-sdk/) · [Go module](https://pkg.go.dev/github.com/NeuralTrust/trustguard-sdk/go) · [GitHub](https://github.com/NeuralTrust/trustguard-sdk)
5
+
6
+ Official Node.js / TypeScript client for the TrustGuard runtime evaluate API (`POST /v1/evaluate`). Configure a base URL and an API key, send the payload you want evaluated, and act on the verdict: TrustGuard detects, you enforce.
4
7
 
5
8
  ## Install
6
9
 
@@ -20,8 +23,8 @@ const client = new TrustGuard({
20
23
  apiKey: process.env.TRUSTGUARD_API_KEY!,
21
24
  });
22
25
 
23
- const response = await client.guard({ input: { prompt: "user text to evaluate" } });
24
- if (response.isFlagged) {
26
+ const response = await client.guard({ payload: { input: "user text to evaluate" } });
27
+ if (response.isBlocked) {
25
28
  // block the request
26
29
  }
27
30
  ```
@@ -30,20 +33,22 @@ if (response.isFlagged) {
30
33
 
31
34
  ```typescript
32
35
  const response = await client.guard({
33
- input: { prompt: "user text" },
36
+ payload: { input: "user text" },
34
37
  direction: "output", // "input" (default) or "output"
38
+ protocol: "llm", // "all" (default), "llm", "mcp", or "a2a"
35
39
  sessionId: "conversation-42", // groups multi-turn traffic
36
40
  consumerId: "user-7", // the end user behind the request
41
+ attributes: { content_type: "text/plain" }, // routing hints
37
42
  });
38
43
  ```
39
44
 
40
45
  ### Attachments
41
46
 
42
- Documents are base64-encoded into `metadata.attachments` for file-aware plugins:
47
+ Documents are base64-encoded into `payload.attachments` for file-aware plugins (or pass a `url` for the server to fetch):
43
48
 
44
49
  ```typescript
45
50
  const response = await client.guard({
46
- input: { prompt: "summarize this file" },
51
+ payload: { input: "summarize this file" },
47
52
  attachments: [{ filename: "doc.pdf", contentType: "application/pdf", data: pdfBytes }],
48
53
  });
49
54
  ```
@@ -52,8 +57,8 @@ const response = await client.guard({
52
57
 
53
58
  | Field | Meaning |
54
59
  |---|---|
55
- | `isFlagged` | The enforcement signal: block when `true` |
56
- | `findings` | What every plugin in the policy chain reported (`detectionType`, `confidence`, `ruleName`, `details`) |
60
+ | `status` | Most restrictive verdict: `allow`, `block`, `transform`, `report`, or `""` when omitted. `isBlocked` is `true` when it is `block` |
61
+ | `findings` | Nested findings: `source` / `signal` / `outcome` / `evidence` (observational runs omit `signal`/`outcome`) |
57
62
  | `transformedPayload` | The payload as rewritten by in-flight masking, `null` when untouched |
58
63
  | `traceId` / `requestId` | Correlation ids for TrustGuard telemetry |
59
64
 
@@ -65,7 +70,7 @@ Non-2xx responses throw `TrustGuardAPIError` with `status`, `traceId` and `reque
65
70
  import { TrustGuardAPIError } from "@neuraltrust/trustguard-sdk";
66
71
 
67
72
  try {
68
- await client.guard({ input: { prompt: "..." } });
73
+ await client.guard({ payload: { input: "..." } });
69
74
  } catch (err) {
70
75
  if (err instanceof TrustGuardAPIError && err.status === 401) {
71
76
  // bad API key
@@ -73,6 +78,17 @@ try {
73
78
  }
74
79
  ```
75
80
 
81
+ ## Documentation
82
+
83
+ The full guide is at [docs.neuraltrust.ai](https://docs.neuraltrust.ai/sdks/trustguard/node): setting up the collector
84
+ and its key, guarding input and output, configuration, the attributes
85
+ an evaluation carries, and troubleshooting. The [Evaluate API](https://docs.neuraltrust.ai/trustguard/api/evaluate)
86
+ is the contract every SDK wraps, and [SDKs](https://docs.neuraltrust.ai/sdks/overview) says when to reach
87
+ for TrustGuard and when for TrustGate.
88
+
89
+ The same client in other languages: [Python](https://pypi.org/project/trustguard-sdk/), [Go](https://pkg.go.dev/github.com/NeuralTrust/trustguard-sdk/go). Source, examples and issues:
90
+ [github.com/NeuralTrust/trustguard-sdk](https://github.com/NeuralTrust/trustguard-sdk).
91
+
76
92
  ## Development
77
93
 
78
94
  ```bash
package/dist/index.cjs CHANGED
@@ -40,7 +40,7 @@ var TrustGuardAPIError = class extends Error {
40
40
  };
41
41
 
42
42
  // src/client.ts
43
- var GUARD_PATH = "/v1/guard";
43
+ var EVALUATE_PATH = "/v1/evaluate";
44
44
  var DEFAULT_TIMEOUT_MS = 1e4;
45
45
  var TrustGuard = class {
46
46
  #baseUrl;
@@ -65,10 +65,10 @@ var TrustGuard = class {
65
65
  * returns the verdict. Throws TrustGuardAPIError on non-2xx responses.
66
66
  */
67
67
  async guard(request) {
68
- if (!request.input) {
69
- throw new Error("TrustGuard: request input is required");
68
+ if (!request.payload) {
69
+ throw new Error("TrustGuard: request payload is required");
70
70
  }
71
- const response = await this.#fetch(this.#baseUrl + GUARD_PATH, {
71
+ const response = await this.#fetch(this.#baseUrl + EVALUATE_PATH, {
72
72
  method: "POST",
73
73
  headers: {
74
74
  Authorization: `Bearer ${this.#apiKey}`,
@@ -85,44 +85,69 @@ var TrustGuard = class {
85
85
  }
86
86
  };
87
87
  function serializeRequest(request) {
88
- const body = { input: request.input };
88
+ let payload = request.payload;
89
+ if (request.attachments?.length) {
90
+ payload = { ...payload, attachments: request.attachments.map(serializeAttachment) };
91
+ }
92
+ const body = { payload };
89
93
  if (request.direction) body.direction = request.direction;
94
+ if (request.protocol) body.protocol = request.protocol;
90
95
  if (request.sessionId) body.session_id = request.sessionId;
91
96
  if (request.consumerId) body.consumer_id = request.consumerId;
92
- let metadata = request.metadata;
93
- if (request.attachments?.length) {
94
- metadata = { ...metadata, attachments: request.attachments.map(serializeAttachment) };
95
- }
96
- if (metadata && Object.keys(metadata).length > 0) body.metadata = metadata;
97
+ if (request.attributes && Object.keys(request.attributes).length > 0) body.attributes = request.attributes;
97
98
  return body;
98
99
  }
99
100
  function serializeAttachment(attachment) {
100
- const bytes = typeof attachment.data === "string" ? Buffer.from(attachment.data, "utf-8") : Buffer.from(attachment.data);
101
- return {
101
+ const entry = {
102
102
  filename: attachment.filename,
103
- content_type: attachment.contentType,
104
- data: bytes.toString("base64")
103
+ content_type: attachment.contentType
105
104
  };
105
+ if (attachment.data !== void 0) {
106
+ const bytes = typeof attachment.data === "string" ? Buffer.from(attachment.data, "utf-8") : Buffer.from(attachment.data);
107
+ entry.data = bytes.toString("base64");
108
+ }
109
+ if (attachment.url !== void 0) entry.url = attachment.url;
110
+ return entry;
106
111
  }
107
112
  function deserializeResponse(wire) {
113
+ const status = wire.status ?? "";
108
114
  return {
109
- isFlagged: wire.is_flagged ?? false,
115
+ status,
116
+ isBlocked: status === "block",
110
117
  transformedPayload: wire.transformed_payload ?? null,
111
- findings: (wire.findings ?? []).map(
112
- (f) => ({
113
- detectionType: f.detection_type,
114
- confidence: f.confidence,
115
- ruleName: f.rule_name,
116
- details: f.details
117
- })
118
- ),
118
+ findings: (wire.findings ?? []).map(deserializeFinding),
119
119
  traceId: wire.trace_id ?? "",
120
120
  requestId: wire.request_id ?? ""
121
121
  };
122
122
  }
123
+ function deserializeFinding(f) {
124
+ const sourceWire = f.source ?? {};
125
+ const source = {
126
+ kind: sourceWire.kind ?? ""
127
+ };
128
+ if (sourceWire.plugin !== void 0) source.plugin = sourceWire.plugin;
129
+ if (sourceWire.detector_id !== void 0) source.detectorId = sourceWire.detector_id;
130
+ if (sourceWire.detector_name !== void 0) source.detectorName = sourceWire.detector_name;
131
+ if (sourceWire.policy_id !== void 0) source.policyId = sourceWire.policy_id;
132
+ if (sourceWire.gate_name !== void 0) source.gateName = sourceWire.gate_name;
133
+ const finding = { source };
134
+ if (f.signal?.type) {
135
+ const signal = { type: f.signal.type };
136
+ if (f.signal.confidence !== void 0) signal.confidence = f.signal.confidence;
137
+ finding.signal = signal;
138
+ }
139
+ if (f.outcome?.action) {
140
+ const outcome = { action: f.outcome.action };
141
+ finding.outcome = outcome;
142
+ }
143
+ if (f.evidence && Object.keys(f.evidence).length > 0) {
144
+ finding.evidence = f.evidence;
145
+ }
146
+ return finding;
147
+ }
123
148
  function apiError(status, text) {
124
149
  const payload = parseJson(text);
125
- const message = payload?.error || text.trim() || `HTTP ${status}`;
150
+ const message = payload?.error || payload?.message || text.trim() || `HTTP ${status}`;
126
151
  return new TrustGuardAPIError(status, message, payload?.trace_id ?? "", payload?.request_id ?? "");
127
152
  }
128
153
  function parseJson(text) {
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["export { TrustGuard } from \"./client.js\";\nexport { TrustGuardAPIError } from \"./errors.js\";\nexport type {\n Attachment,\n Direction,\n Finding,\n GuardRequest,\n GuardResponse,\n TrustGuardOptions,\n} from \"./types.js\";\n","/**\n * A non-2xx response from the TrustGuard API, carrying the status code and the\n * correlation ids needed to chase the request in telemetry. Transport-level\n * failures (network errors, timeouts) are thrown as-is instead.\n */\nexport class TrustGuardAPIError extends Error {\n readonly status: number;\n readonly traceId: string;\n readonly requestId: string;\n\n constructor(status: number, message: string, traceId: string, requestId: string) {\n super(`TrustGuard API error ${status}: ${message} (trace_id=${traceId}, request_id=${requestId})`);\n this.name = \"TrustGuardAPIError\";\n this.status = status;\n this.traceId = traceId;\n this.requestId = requestId;\n }\n}\n","import { TrustGuardAPIError } from \"./errors.js\";\nimport type { Attachment, Finding, GuardRequest, GuardResponse, TrustGuardOptions } from \"./types.js\";\n\nconst GUARD_PATH = \"/v1/guard\";\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\ninterface WireFinding {\n detection_type?: string;\n confidence?: number;\n rule_name?: string;\n details?: unknown;\n}\n\ninterface WireResponse {\n is_flagged?: boolean;\n transformed_payload?: Record<string, unknown> | null;\n findings?: WireFinding[];\n trace_id?: string;\n request_id?: string;\n}\n\n/** Client for the TrustGuard runtime guard API. */\nexport class TrustGuard {\n readonly #baseUrl: string;\n readonly #apiKey: string;\n readonly #timeoutMs: number;\n readonly #fetch: typeof fetch;\n\n constructor(options: TrustGuardOptions) {\n const baseUrl = options.baseUrl?.trim().replace(/\\/+$/, \"\");\n if (!baseUrl) {\n throw new Error(\"TrustGuard: baseUrl is required\");\n }\n if (!options.apiKey?.trim()) {\n throw new Error(\"TrustGuard: apiKey is required\");\n }\n this.#baseUrl = baseUrl;\n this.#apiKey = options.apiKey;\n this.#timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.#fetch = options.fetch ?? globalThis.fetch;\n }\n\n /**\n * Evaluates the request against the policy attached to the API key and\n * returns the verdict. Throws TrustGuardAPIError on non-2xx responses.\n */\n async guard(request: GuardRequest): Promise<GuardResponse> {\n if (!request.input) {\n throw new Error(\"TrustGuard: request input is required\");\n }\n\n const response = await this.#fetch(this.#baseUrl + GUARD_PATH, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.#apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(serializeRequest(request)),\n signal: AbortSignal.timeout(this.#timeoutMs),\n });\n\n const text = await response.text();\n if (!response.ok) {\n throw apiError(response.status, text);\n }\n\n return deserializeResponse(parseJson(text) ?? {});\n }\n}\n\n/** Maps the camelCase request onto the snake_case wire format, omitting empty optionals (the server rejects unknown top-level fields). */\nfunction serializeRequest(request: GuardRequest): Record<string, unknown> {\n const body: Record<string, unknown> = { input: request.input };\n if (request.direction) body.direction = request.direction;\n if (request.sessionId) body.session_id = request.sessionId;\n if (request.consumerId) body.consumer_id = request.consumerId;\n\n let metadata = request.metadata;\n if (request.attachments?.length) {\n metadata = { ...metadata, attachments: request.attachments.map(serializeAttachment) };\n }\n if (metadata && Object.keys(metadata).length > 0) body.metadata = metadata;\n return body;\n}\n\nfunction serializeAttachment(attachment: Attachment): Record<string, string> {\n const bytes =\n typeof attachment.data === \"string\" ? Buffer.from(attachment.data, \"utf-8\") : Buffer.from(attachment.data);\n return {\n filename: attachment.filename,\n content_type: attachment.contentType,\n data: bytes.toString(\"base64\"),\n };\n}\n\nfunction deserializeResponse(wire: WireResponse): GuardResponse {\n return {\n isFlagged: wire.is_flagged ?? false,\n transformedPayload: wire.transformed_payload ?? null,\n findings: (wire.findings ?? []).map(\n (f): Finding => ({\n detectionType: f.detection_type,\n confidence: f.confidence,\n ruleName: f.rule_name,\n details: f.details,\n }),\n ),\n traceId: wire.trace_id ?? \"\",\n requestId: wire.request_id ?? \"\",\n };\n}\n\nfunction apiError(status: number, text: string): TrustGuardAPIError {\n const payload = parseJson(text) as { error?: string; trace_id?: string; request_id?: string } | undefined;\n const message = payload?.error || text.trim() || `HTTP ${status}`;\n return new TrustGuardAPIError(status, message, payload?.trace_id ?? \"\", payload?.request_id ?? \"\");\n}\n\nfunction parseJson(text: string): WireResponse | undefined {\n try {\n return JSON.parse(text) as WireResponse;\n } catch {\n return undefined;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/errors.ts","../src/client.ts"],"sourcesContent":["export { TrustGuard } from \"./client.js\";\nexport { TrustGuardAPIError } from \"./errors.js\";\nexport type {\n Attachment,\n Direction,\n Finding,\n FindingOutcome,\n FindingSignal,\n FindingSource,\n GuardRequest,\n GuardResponse,\n Protocol,\n TrustGuardOptions,\n} from \"./types.js\";\n","/**\n * A non-2xx response from the TrustGuard API, carrying the status code and the\n * correlation ids needed to chase the request in telemetry. Transport-level\n * failures (network errors, timeouts) are thrown as-is instead.\n */\nexport class TrustGuardAPIError extends Error {\n readonly status: number;\n readonly traceId: string;\n readonly requestId: string;\n\n constructor(status: number, message: string, traceId: string, requestId: string) {\n super(`TrustGuard API error ${status}: ${message} (trace_id=${traceId}, request_id=${requestId})`);\n this.name = \"TrustGuardAPIError\";\n this.status = status;\n this.traceId = traceId;\n this.requestId = requestId;\n }\n}\n","import { TrustGuardAPIError } from \"./errors.js\";\nimport type {\n Attachment,\n Finding,\n FindingOutcome,\n FindingSignal,\n FindingSource,\n GuardRequest,\n GuardResponse,\n TrustGuardOptions,\n} from \"./types.js\";\n\nconst EVALUATE_PATH = \"/v1/evaluate\";\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\ninterface WireFindingSource {\n kind?: string;\n plugin?: string;\n detector_id?: string;\n detector_name?: string;\n policy_id?: string;\n gate_name?: string;\n}\n\ninterface WireFindingSignal {\n type?: string;\n confidence?: number;\n}\n\ninterface WireFindingOutcome {\n action?: string;\n}\n\ninterface WireFinding {\n source?: WireFindingSource;\n signal?: WireFindingSignal;\n outcome?: WireFindingOutcome;\n evidence?: Record<string, unknown>;\n}\n\ninterface WireResponse {\n status?: string;\n transformed_payload?: Record<string, unknown> | null;\n findings?: WireFinding[];\n trace_id?: string;\n request_id?: string;\n}\n\n/** Client for the TrustGuard runtime evaluate API. */\nexport class TrustGuard {\n readonly #baseUrl: string;\n readonly #apiKey: string;\n readonly #timeoutMs: number;\n readonly #fetch: typeof fetch;\n\n constructor(options: TrustGuardOptions) {\n const baseUrl = options.baseUrl?.trim().replace(/\\/+$/, \"\");\n if (!baseUrl) {\n throw new Error(\"TrustGuard: baseUrl is required\");\n }\n if (!options.apiKey?.trim()) {\n throw new Error(\"TrustGuard: apiKey is required\");\n }\n this.#baseUrl = baseUrl;\n this.#apiKey = options.apiKey;\n this.#timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.#fetch = options.fetch ?? globalThis.fetch;\n }\n\n /**\n * Evaluates the request against the policy attached to the API key and\n * returns the verdict. Throws TrustGuardAPIError on non-2xx responses.\n */\n async guard(request: GuardRequest): Promise<GuardResponse> {\n if (!request.payload) {\n throw new Error(\"TrustGuard: request payload is required\");\n }\n\n const response = await this.#fetch(this.#baseUrl + EVALUATE_PATH, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.#apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(serializeRequest(request)),\n signal: AbortSignal.timeout(this.#timeoutMs),\n });\n\n const text = await response.text();\n if (!response.ok) {\n throw apiError(response.status, text);\n }\n\n return deserializeResponse(parseJson(text) ?? {});\n }\n}\n\n/** Maps the camelCase request onto the snake_case wire format, omitting empty optionals (the server rejects unknown top-level fields). */\nfunction serializeRequest(request: GuardRequest): Record<string, unknown> {\n let payload = request.payload;\n if (request.attachments?.length) {\n payload = { ...payload, attachments: request.attachments.map(serializeAttachment) };\n }\n const body: Record<string, unknown> = { payload };\n if (request.direction) body.direction = request.direction;\n if (request.protocol) body.protocol = request.protocol;\n if (request.sessionId) body.session_id = request.sessionId;\n if (request.consumerId) body.consumer_id = request.consumerId;\n if (request.attributes && Object.keys(request.attributes).length > 0) body.attributes = request.attributes;\n return body;\n}\n\nfunction serializeAttachment(attachment: Attachment): Record<string, string> {\n const entry: Record<string, string> = {\n filename: attachment.filename,\n content_type: attachment.contentType,\n };\n if (attachment.data !== undefined) {\n const bytes =\n typeof attachment.data === \"string\" ? Buffer.from(attachment.data, \"utf-8\") : Buffer.from(attachment.data);\n entry.data = bytes.toString(\"base64\");\n }\n if (attachment.url !== undefined) entry.url = attachment.url;\n return entry;\n}\n\nfunction deserializeResponse(wire: WireResponse): GuardResponse {\n const status = wire.status ?? \"\";\n return {\n status,\n isBlocked: status === \"block\",\n transformedPayload: wire.transformed_payload ?? null,\n findings: (wire.findings ?? []).map(deserializeFinding),\n traceId: wire.trace_id ?? \"\",\n requestId: wire.request_id ?? \"\",\n };\n}\n\nfunction deserializeFinding(f: WireFinding): Finding {\n const sourceWire = f.source ?? {};\n const source: FindingSource = {\n kind: sourceWire.kind ?? \"\",\n };\n if (sourceWire.plugin !== undefined) source.plugin = sourceWire.plugin;\n if (sourceWire.detector_id !== undefined) source.detectorId = sourceWire.detector_id;\n if (sourceWire.detector_name !== undefined) source.detectorName = sourceWire.detector_name;\n if (sourceWire.policy_id !== undefined) source.policyId = sourceWire.policy_id;\n if (sourceWire.gate_name !== undefined) source.gateName = sourceWire.gate_name;\n\n const finding: Finding = { source };\n if (f.signal?.type) {\n const signal: FindingSignal = { type: f.signal.type };\n if (f.signal.confidence !== undefined) signal.confidence = f.signal.confidence;\n finding.signal = signal;\n }\n if (f.outcome?.action) {\n const outcome: FindingOutcome = { action: f.outcome.action };\n finding.outcome = outcome;\n }\n if (f.evidence && Object.keys(f.evidence).length > 0) {\n finding.evidence = f.evidence;\n }\n return finding;\n}\n\nfunction apiError(status: number, text: string): TrustGuardAPIError {\n const payload = parseJson(text) as { error?: string; message?: string; trace_id?: string; request_id?: string } | undefined;\n const message = payload?.error || payload?.message || text.trim() || `HTTP ${status}`;\n return new TrustGuardAPIError(status, message, payload?.trace_id ?? \"\", payload?.request_id ?? \"\");\n}\n\nfunction parseJson(text: string): WireResponse | undefined {\n try {\n return JSON.parse(text) as WireResponse;\n } catch {\n return undefined;\n }\n}\n"],"mappings":"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","names":[]}
package/dist/index.d.cts CHANGED
@@ -1,47 +1,73 @@
1
1
  /** Traffic side being evaluated; rules are scoped per side. Defaults to "input" server-side. */
2
2
  type Direction = "input" | "output";
3
+ /** Traffic protocol the policy rules are scoped to. Defaults to "all" server-side. */
4
+ type Protocol = "all" | "llm" | "mcp" | "a2a";
3
5
  /** A document evaluated alongside the payload by file-aware plugins. */
4
6
  interface Attachment {
5
7
  filename: string;
6
8
  contentType: string;
7
- /** Raw file content; strings are encoded as UTF-8. Base64 encoding happens on the wire. */
8
- data: Uint8Array | string;
9
+ /** Raw file content; strings are encoded as UTF-8, then base64 on the wire. Provide `data` or `url`. */
10
+ data?: Uint8Array | string;
11
+ /** URL for the server to fetch instead of inlining `data`. */
12
+ url?: string;
9
13
  }
10
- /** Payload for a guard evaluation. */
14
+ /** Payload for a guard evaluation (`POST /v1/evaluate`). */
11
15
  interface GuardRequest {
12
- /** The payload to evaluate. Required. */
13
- input: Record<string, unknown>;
16
+ /** The content to evaluate, e.g. `{ input: "..." }` or provider-shaped fields. Required. */
17
+ payload: Record<string, unknown>;
14
18
  /** Traffic side; the server defaults to "input" when omitted. */
15
19
  direction?: Direction;
20
+ /** Traffic protocol; the server defaults to "all" when omitted. */
21
+ protocol?: Protocol;
16
22
  /** Groups multi-turn traffic; the server synthesises one when omitted. */
17
23
  sessionId?: string;
18
24
  /** Identifies the end user on whose behalf the request runs. */
19
25
  consumerId?: string;
20
- /**
21
- * Optional routing hints. Server-side key: `content_type` (overrides the
22
- * payload content type, default application/json).
23
- */
24
- metadata?: Record<string, unknown>;
25
- /** Documents to evaluate; folded into `metadata.attachments` on the wire. */
26
+ /** Optional routing hints. Server-side key: `content_type` (overrides the payload content type). */
27
+ attributes?: Record<string, unknown>;
28
+ /** Documents to evaluate; folded into `payload.attachments` on the wire. */
26
29
  attachments?: Attachment[];
27
30
  }
28
- /** A single plugin's contribution to the guard response. */
29
- interface Finding {
30
- detectionType?: string;
31
+ /** Who produced the finding — a detector or a gate. */
32
+ interface FindingSource {
33
+ kind: string;
34
+ plugin?: string;
35
+ detectorId?: string;
36
+ detectorName?: string;
37
+ policyId?: string;
38
+ gateName?: string;
39
+ }
40
+ /** Detection signal when the finding fired (omitted for observational-only runs). */
41
+ interface FindingSignal {
42
+ type: string;
31
43
  confidence?: number;
32
- ruleName?: string;
33
- details?: unknown;
44
+ }
45
+ /** Applied execution-rule action when the finding enforced an outcome. */
46
+ interface FindingOutcome {
47
+ action: string;
48
+ }
49
+ /**
50
+ * A single finding from the evaluate response.
51
+ * Observational (below-threshold) runs keep `source` + `evidence` only.
52
+ */
53
+ interface Finding {
54
+ source: FindingSource;
55
+ signal?: FindingSignal;
56
+ outcome?: FindingOutcome;
57
+ evidence?: Record<string, unknown>;
34
58
  }
35
59
  /**
36
- * Verdict returned by POST /v1/guard. TrustGuard detects; the caller enforces:
37
- * block when `isFlagged` is true.
60
+ * Verdict returned by POST /v1/evaluate. TrustGuard detects; the caller enforces:
61
+ * block when `status` is "block" (`isBlocked` is the convenience signal).
38
62
  */
39
63
  interface GuardResponse {
40
- /** The enforcement signal: true when the policy flagged the payload. */
41
- isFlagged: boolean;
64
+ /** Most restrictive verdict: "allow", "block", "transform", "report", or "" when omitted. */
65
+ status: string;
66
+ /** Convenience flag: true when `status === "block"`. */
67
+ isBlocked: boolean;
42
68
  /** The payload as rewritten by in-flight masking, null when untouched. */
43
69
  transformedPayload: Record<string, unknown> | null;
44
- /** What every plugin in the policy chain reported. */
70
+ /** What every plugin / gate in the policy chain reported. */
45
71
  findings: Finding[];
46
72
  /** Correlation ids for TrustGuard telemetry. */
47
73
  traceId: string;
@@ -49,7 +75,7 @@ interface GuardResponse {
49
75
  }
50
76
  /** Configuration for the TrustGuard client. */
51
77
  interface TrustGuardOptions {
52
- /** Base URL of the TrustGuard deployment, e.g. https://guard.neuraltrust.ai */
78
+ /** Base URL of the TrustGuard deployment, e.g. https://trustguard.neuraltrust.ai */
53
79
  baseUrl: string;
54
80
  /** Collector API key, sent as a Bearer token. */
55
81
  apiKey: string;
@@ -59,7 +85,7 @@ interface TrustGuardOptions {
59
85
  fetch?: typeof fetch;
60
86
  }
61
87
 
62
- /** Client for the TrustGuard runtime guard API. */
88
+ /** Client for the TrustGuard runtime evaluate API. */
63
89
  declare class TrustGuard {
64
90
  #private;
65
91
  constructor(options: TrustGuardOptions);
@@ -82,4 +108,4 @@ declare class TrustGuardAPIError extends Error {
82
108
  constructor(status: number, message: string, traceId: string, requestId: string);
83
109
  }
84
110
 
85
- export { type Attachment, type Direction, type Finding, type GuardRequest, type GuardResponse, TrustGuard, TrustGuardAPIError, type TrustGuardOptions };
111
+ export { type Attachment, type Direction, type Finding, type FindingOutcome, type FindingSignal, type FindingSource, type GuardRequest, type GuardResponse, type Protocol, TrustGuard, TrustGuardAPIError, type TrustGuardOptions };
package/dist/index.d.ts CHANGED
@@ -1,47 +1,73 @@
1
1
  /** Traffic side being evaluated; rules are scoped per side. Defaults to "input" server-side. */
2
2
  type Direction = "input" | "output";
3
+ /** Traffic protocol the policy rules are scoped to. Defaults to "all" server-side. */
4
+ type Protocol = "all" | "llm" | "mcp" | "a2a";
3
5
  /** A document evaluated alongside the payload by file-aware plugins. */
4
6
  interface Attachment {
5
7
  filename: string;
6
8
  contentType: string;
7
- /** Raw file content; strings are encoded as UTF-8. Base64 encoding happens on the wire. */
8
- data: Uint8Array | string;
9
+ /** Raw file content; strings are encoded as UTF-8, then base64 on the wire. Provide `data` or `url`. */
10
+ data?: Uint8Array | string;
11
+ /** URL for the server to fetch instead of inlining `data`. */
12
+ url?: string;
9
13
  }
10
- /** Payload for a guard evaluation. */
14
+ /** Payload for a guard evaluation (`POST /v1/evaluate`). */
11
15
  interface GuardRequest {
12
- /** The payload to evaluate. Required. */
13
- input: Record<string, unknown>;
16
+ /** The content to evaluate, e.g. `{ input: "..." }` or provider-shaped fields. Required. */
17
+ payload: Record<string, unknown>;
14
18
  /** Traffic side; the server defaults to "input" when omitted. */
15
19
  direction?: Direction;
20
+ /** Traffic protocol; the server defaults to "all" when omitted. */
21
+ protocol?: Protocol;
16
22
  /** Groups multi-turn traffic; the server synthesises one when omitted. */
17
23
  sessionId?: string;
18
24
  /** Identifies the end user on whose behalf the request runs. */
19
25
  consumerId?: string;
20
- /**
21
- * Optional routing hints. Server-side key: `content_type` (overrides the
22
- * payload content type, default application/json).
23
- */
24
- metadata?: Record<string, unknown>;
25
- /** Documents to evaluate; folded into `metadata.attachments` on the wire. */
26
+ /** Optional routing hints. Server-side key: `content_type` (overrides the payload content type). */
27
+ attributes?: Record<string, unknown>;
28
+ /** Documents to evaluate; folded into `payload.attachments` on the wire. */
26
29
  attachments?: Attachment[];
27
30
  }
28
- /** A single plugin's contribution to the guard response. */
29
- interface Finding {
30
- detectionType?: string;
31
+ /** Who produced the finding — a detector or a gate. */
32
+ interface FindingSource {
33
+ kind: string;
34
+ plugin?: string;
35
+ detectorId?: string;
36
+ detectorName?: string;
37
+ policyId?: string;
38
+ gateName?: string;
39
+ }
40
+ /** Detection signal when the finding fired (omitted for observational-only runs). */
41
+ interface FindingSignal {
42
+ type: string;
31
43
  confidence?: number;
32
- ruleName?: string;
33
- details?: unknown;
44
+ }
45
+ /** Applied execution-rule action when the finding enforced an outcome. */
46
+ interface FindingOutcome {
47
+ action: string;
48
+ }
49
+ /**
50
+ * A single finding from the evaluate response.
51
+ * Observational (below-threshold) runs keep `source` + `evidence` only.
52
+ */
53
+ interface Finding {
54
+ source: FindingSource;
55
+ signal?: FindingSignal;
56
+ outcome?: FindingOutcome;
57
+ evidence?: Record<string, unknown>;
34
58
  }
35
59
  /**
36
- * Verdict returned by POST /v1/guard. TrustGuard detects; the caller enforces:
37
- * block when `isFlagged` is true.
60
+ * Verdict returned by POST /v1/evaluate. TrustGuard detects; the caller enforces:
61
+ * block when `status` is "block" (`isBlocked` is the convenience signal).
38
62
  */
39
63
  interface GuardResponse {
40
- /** The enforcement signal: true when the policy flagged the payload. */
41
- isFlagged: boolean;
64
+ /** Most restrictive verdict: "allow", "block", "transform", "report", or "" when omitted. */
65
+ status: string;
66
+ /** Convenience flag: true when `status === "block"`. */
67
+ isBlocked: boolean;
42
68
  /** The payload as rewritten by in-flight masking, null when untouched. */
43
69
  transformedPayload: Record<string, unknown> | null;
44
- /** What every plugin in the policy chain reported. */
70
+ /** What every plugin / gate in the policy chain reported. */
45
71
  findings: Finding[];
46
72
  /** Correlation ids for TrustGuard telemetry. */
47
73
  traceId: string;
@@ -49,7 +75,7 @@ interface GuardResponse {
49
75
  }
50
76
  /** Configuration for the TrustGuard client. */
51
77
  interface TrustGuardOptions {
52
- /** Base URL of the TrustGuard deployment, e.g. https://guard.neuraltrust.ai */
78
+ /** Base URL of the TrustGuard deployment, e.g. https://trustguard.neuraltrust.ai */
53
79
  baseUrl: string;
54
80
  /** Collector API key, sent as a Bearer token. */
55
81
  apiKey: string;
@@ -59,7 +85,7 @@ interface TrustGuardOptions {
59
85
  fetch?: typeof fetch;
60
86
  }
61
87
 
62
- /** Client for the TrustGuard runtime guard API. */
88
+ /** Client for the TrustGuard runtime evaluate API. */
63
89
  declare class TrustGuard {
64
90
  #private;
65
91
  constructor(options: TrustGuardOptions);
@@ -82,4 +108,4 @@ declare class TrustGuardAPIError extends Error {
82
108
  constructor(status: number, message: string, traceId: string, requestId: string);
83
109
  }
84
110
 
85
- export { type Attachment, type Direction, type Finding, type GuardRequest, type GuardResponse, TrustGuard, TrustGuardAPIError, type TrustGuardOptions };
111
+ export { type Attachment, type Direction, type Finding, type FindingOutcome, type FindingSignal, type FindingSource, type GuardRequest, type GuardResponse, type Protocol, TrustGuard, TrustGuardAPIError, type TrustGuardOptions };
package/dist/index.js CHANGED
@@ -13,7 +13,7 @@ var TrustGuardAPIError = class extends Error {
13
13
  };
14
14
 
15
15
  // src/client.ts
16
- var GUARD_PATH = "/v1/guard";
16
+ var EVALUATE_PATH = "/v1/evaluate";
17
17
  var DEFAULT_TIMEOUT_MS = 1e4;
18
18
  var TrustGuard = class {
19
19
  #baseUrl;
@@ -38,10 +38,10 @@ var TrustGuard = class {
38
38
  * returns the verdict. Throws TrustGuardAPIError on non-2xx responses.
39
39
  */
40
40
  async guard(request) {
41
- if (!request.input) {
42
- throw new Error("TrustGuard: request input is required");
41
+ if (!request.payload) {
42
+ throw new Error("TrustGuard: request payload is required");
43
43
  }
44
- const response = await this.#fetch(this.#baseUrl + GUARD_PATH, {
44
+ const response = await this.#fetch(this.#baseUrl + EVALUATE_PATH, {
45
45
  method: "POST",
46
46
  headers: {
47
47
  Authorization: `Bearer ${this.#apiKey}`,
@@ -58,44 +58,69 @@ var TrustGuard = class {
58
58
  }
59
59
  };
60
60
  function serializeRequest(request) {
61
- const body = { input: request.input };
61
+ let payload = request.payload;
62
+ if (request.attachments?.length) {
63
+ payload = { ...payload, attachments: request.attachments.map(serializeAttachment) };
64
+ }
65
+ const body = { payload };
62
66
  if (request.direction) body.direction = request.direction;
67
+ if (request.protocol) body.protocol = request.protocol;
63
68
  if (request.sessionId) body.session_id = request.sessionId;
64
69
  if (request.consumerId) body.consumer_id = request.consumerId;
65
- let metadata = request.metadata;
66
- if (request.attachments?.length) {
67
- metadata = { ...metadata, attachments: request.attachments.map(serializeAttachment) };
68
- }
69
- if (metadata && Object.keys(metadata).length > 0) body.metadata = metadata;
70
+ if (request.attributes && Object.keys(request.attributes).length > 0) body.attributes = request.attributes;
70
71
  return body;
71
72
  }
72
73
  function serializeAttachment(attachment) {
73
- const bytes = typeof attachment.data === "string" ? Buffer.from(attachment.data, "utf-8") : Buffer.from(attachment.data);
74
- return {
74
+ const entry = {
75
75
  filename: attachment.filename,
76
- content_type: attachment.contentType,
77
- data: bytes.toString("base64")
76
+ content_type: attachment.contentType
78
77
  };
78
+ if (attachment.data !== void 0) {
79
+ const bytes = typeof attachment.data === "string" ? Buffer.from(attachment.data, "utf-8") : Buffer.from(attachment.data);
80
+ entry.data = bytes.toString("base64");
81
+ }
82
+ if (attachment.url !== void 0) entry.url = attachment.url;
83
+ return entry;
79
84
  }
80
85
  function deserializeResponse(wire) {
86
+ const status = wire.status ?? "";
81
87
  return {
82
- isFlagged: wire.is_flagged ?? false,
88
+ status,
89
+ isBlocked: status === "block",
83
90
  transformedPayload: wire.transformed_payload ?? null,
84
- findings: (wire.findings ?? []).map(
85
- (f) => ({
86
- detectionType: f.detection_type,
87
- confidence: f.confidence,
88
- ruleName: f.rule_name,
89
- details: f.details
90
- })
91
- ),
91
+ findings: (wire.findings ?? []).map(deserializeFinding),
92
92
  traceId: wire.trace_id ?? "",
93
93
  requestId: wire.request_id ?? ""
94
94
  };
95
95
  }
96
+ function deserializeFinding(f) {
97
+ const sourceWire = f.source ?? {};
98
+ const source = {
99
+ kind: sourceWire.kind ?? ""
100
+ };
101
+ if (sourceWire.plugin !== void 0) source.plugin = sourceWire.plugin;
102
+ if (sourceWire.detector_id !== void 0) source.detectorId = sourceWire.detector_id;
103
+ if (sourceWire.detector_name !== void 0) source.detectorName = sourceWire.detector_name;
104
+ if (sourceWire.policy_id !== void 0) source.policyId = sourceWire.policy_id;
105
+ if (sourceWire.gate_name !== void 0) source.gateName = sourceWire.gate_name;
106
+ const finding = { source };
107
+ if (f.signal?.type) {
108
+ const signal = { type: f.signal.type };
109
+ if (f.signal.confidence !== void 0) signal.confidence = f.signal.confidence;
110
+ finding.signal = signal;
111
+ }
112
+ if (f.outcome?.action) {
113
+ const outcome = { action: f.outcome.action };
114
+ finding.outcome = outcome;
115
+ }
116
+ if (f.evidence && Object.keys(f.evidence).length > 0) {
117
+ finding.evidence = f.evidence;
118
+ }
119
+ return finding;
120
+ }
96
121
  function apiError(status, text) {
97
122
  const payload = parseJson(text);
98
- const message = payload?.error || text.trim() || `HTTP ${status}`;
123
+ const message = payload?.error || payload?.message || text.trim() || `HTTP ${status}`;
99
124
  return new TrustGuardAPIError(status, message, payload?.trace_id ?? "", payload?.request_id ?? "");
100
125
  }
101
126
  function parseJson(text) {
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/errors.ts","../src/client.ts"],"sourcesContent":["/**\n * A non-2xx response from the TrustGuard API, carrying the status code and the\n * correlation ids needed to chase the request in telemetry. Transport-level\n * failures (network errors, timeouts) are thrown as-is instead.\n */\nexport class TrustGuardAPIError extends Error {\n readonly status: number;\n readonly traceId: string;\n readonly requestId: string;\n\n constructor(status: number, message: string, traceId: string, requestId: string) {\n super(`TrustGuard API error ${status}: ${message} (trace_id=${traceId}, request_id=${requestId})`);\n this.name = \"TrustGuardAPIError\";\n this.status = status;\n this.traceId = traceId;\n this.requestId = requestId;\n }\n}\n","import { TrustGuardAPIError } from \"./errors.js\";\nimport type { Attachment, Finding, GuardRequest, GuardResponse, TrustGuardOptions } from \"./types.js\";\n\nconst GUARD_PATH = \"/v1/guard\";\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\ninterface WireFinding {\n detection_type?: string;\n confidence?: number;\n rule_name?: string;\n details?: unknown;\n}\n\ninterface WireResponse {\n is_flagged?: boolean;\n transformed_payload?: Record<string, unknown> | null;\n findings?: WireFinding[];\n trace_id?: string;\n request_id?: string;\n}\n\n/** Client for the TrustGuard runtime guard API. */\nexport class TrustGuard {\n readonly #baseUrl: string;\n readonly #apiKey: string;\n readonly #timeoutMs: number;\n readonly #fetch: typeof fetch;\n\n constructor(options: TrustGuardOptions) {\n const baseUrl = options.baseUrl?.trim().replace(/\\/+$/, \"\");\n if (!baseUrl) {\n throw new Error(\"TrustGuard: baseUrl is required\");\n }\n if (!options.apiKey?.trim()) {\n throw new Error(\"TrustGuard: apiKey is required\");\n }\n this.#baseUrl = baseUrl;\n this.#apiKey = options.apiKey;\n this.#timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.#fetch = options.fetch ?? globalThis.fetch;\n }\n\n /**\n * Evaluates the request against the policy attached to the API key and\n * returns the verdict. Throws TrustGuardAPIError on non-2xx responses.\n */\n async guard(request: GuardRequest): Promise<GuardResponse> {\n if (!request.input) {\n throw new Error(\"TrustGuard: request input is required\");\n }\n\n const response = await this.#fetch(this.#baseUrl + GUARD_PATH, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.#apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(serializeRequest(request)),\n signal: AbortSignal.timeout(this.#timeoutMs),\n });\n\n const text = await response.text();\n if (!response.ok) {\n throw apiError(response.status, text);\n }\n\n return deserializeResponse(parseJson(text) ?? {});\n }\n}\n\n/** Maps the camelCase request onto the snake_case wire format, omitting empty optionals (the server rejects unknown top-level fields). */\nfunction serializeRequest(request: GuardRequest): Record<string, unknown> {\n const body: Record<string, unknown> = { input: request.input };\n if (request.direction) body.direction = request.direction;\n if (request.sessionId) body.session_id = request.sessionId;\n if (request.consumerId) body.consumer_id = request.consumerId;\n\n let metadata = request.metadata;\n if (request.attachments?.length) {\n metadata = { ...metadata, attachments: request.attachments.map(serializeAttachment) };\n }\n if (metadata && Object.keys(metadata).length > 0) body.metadata = metadata;\n return body;\n}\n\nfunction serializeAttachment(attachment: Attachment): Record<string, string> {\n const bytes =\n typeof attachment.data === \"string\" ? Buffer.from(attachment.data, \"utf-8\") : Buffer.from(attachment.data);\n return {\n filename: attachment.filename,\n content_type: attachment.contentType,\n data: bytes.toString(\"base64\"),\n };\n}\n\nfunction deserializeResponse(wire: WireResponse): GuardResponse {\n return {\n isFlagged: wire.is_flagged ?? false,\n transformedPayload: wire.transformed_payload ?? null,\n findings: (wire.findings ?? []).map(\n (f): Finding => ({\n detectionType: f.detection_type,\n confidence: f.confidence,\n ruleName: f.rule_name,\n details: f.details,\n }),\n ),\n traceId: wire.trace_id ?? \"\",\n requestId: wire.request_id ?? \"\",\n };\n}\n\nfunction apiError(status: number, text: string): TrustGuardAPIError {\n const payload = parseJson(text) as { error?: string; trace_id?: string; request_id?: string } | undefined;\n const message = payload?.error || text.trim() || `HTTP ${status}`;\n return new TrustGuardAPIError(status, message, payload?.trace_id ?? \"\", payload?.request_id ?? \"\");\n}\n\nfunction parseJson(text: string): WireResponse | undefined {\n try {\n return JSON.parse(text) as WireResponse;\n } catch {\n return undefined;\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/errors.ts","../src/client.ts"],"sourcesContent":["/**\n * A non-2xx response from the TrustGuard API, carrying the status code and the\n * correlation ids needed to chase the request in telemetry. Transport-level\n * failures (network errors, timeouts) are thrown as-is instead.\n */\nexport class TrustGuardAPIError extends Error {\n readonly status: number;\n readonly traceId: string;\n readonly requestId: string;\n\n constructor(status: number, message: string, traceId: string, requestId: string) {\n super(`TrustGuard API error ${status}: ${message} (trace_id=${traceId}, request_id=${requestId})`);\n this.name = \"TrustGuardAPIError\";\n this.status = status;\n this.traceId = traceId;\n this.requestId = requestId;\n }\n}\n","import { TrustGuardAPIError } from \"./errors.js\";\nimport type {\n Attachment,\n Finding,\n FindingOutcome,\n FindingSignal,\n FindingSource,\n GuardRequest,\n GuardResponse,\n TrustGuardOptions,\n} from \"./types.js\";\n\nconst EVALUATE_PATH = \"/v1/evaluate\";\nconst DEFAULT_TIMEOUT_MS = 10_000;\n\ninterface WireFindingSource {\n kind?: string;\n plugin?: string;\n detector_id?: string;\n detector_name?: string;\n policy_id?: string;\n gate_name?: string;\n}\n\ninterface WireFindingSignal {\n type?: string;\n confidence?: number;\n}\n\ninterface WireFindingOutcome {\n action?: string;\n}\n\ninterface WireFinding {\n source?: WireFindingSource;\n signal?: WireFindingSignal;\n outcome?: WireFindingOutcome;\n evidence?: Record<string, unknown>;\n}\n\ninterface WireResponse {\n status?: string;\n transformed_payload?: Record<string, unknown> | null;\n findings?: WireFinding[];\n trace_id?: string;\n request_id?: string;\n}\n\n/** Client for the TrustGuard runtime evaluate API. */\nexport class TrustGuard {\n readonly #baseUrl: string;\n readonly #apiKey: string;\n readonly #timeoutMs: number;\n readonly #fetch: typeof fetch;\n\n constructor(options: TrustGuardOptions) {\n const baseUrl = options.baseUrl?.trim().replace(/\\/+$/, \"\");\n if (!baseUrl) {\n throw new Error(\"TrustGuard: baseUrl is required\");\n }\n if (!options.apiKey?.trim()) {\n throw new Error(\"TrustGuard: apiKey is required\");\n }\n this.#baseUrl = baseUrl;\n this.#apiKey = options.apiKey;\n this.#timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;\n this.#fetch = options.fetch ?? globalThis.fetch;\n }\n\n /**\n * Evaluates the request against the policy attached to the API key and\n * returns the verdict. Throws TrustGuardAPIError on non-2xx responses.\n */\n async guard(request: GuardRequest): Promise<GuardResponse> {\n if (!request.payload) {\n throw new Error(\"TrustGuard: request payload is required\");\n }\n\n const response = await this.#fetch(this.#baseUrl + EVALUATE_PATH, {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${this.#apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify(serializeRequest(request)),\n signal: AbortSignal.timeout(this.#timeoutMs),\n });\n\n const text = await response.text();\n if (!response.ok) {\n throw apiError(response.status, text);\n }\n\n return deserializeResponse(parseJson(text) ?? {});\n }\n}\n\n/** Maps the camelCase request onto the snake_case wire format, omitting empty optionals (the server rejects unknown top-level fields). */\nfunction serializeRequest(request: GuardRequest): Record<string, unknown> {\n let payload = request.payload;\n if (request.attachments?.length) {\n payload = { ...payload, attachments: request.attachments.map(serializeAttachment) };\n }\n const body: Record<string, unknown> = { payload };\n if (request.direction) body.direction = request.direction;\n if (request.protocol) body.protocol = request.protocol;\n if (request.sessionId) body.session_id = request.sessionId;\n if (request.consumerId) body.consumer_id = request.consumerId;\n if (request.attributes && Object.keys(request.attributes).length > 0) body.attributes = request.attributes;\n return body;\n}\n\nfunction serializeAttachment(attachment: Attachment): Record<string, string> {\n const entry: Record<string, string> = {\n filename: attachment.filename,\n content_type: attachment.contentType,\n };\n if (attachment.data !== undefined) {\n const bytes =\n typeof attachment.data === \"string\" ? Buffer.from(attachment.data, \"utf-8\") : Buffer.from(attachment.data);\n entry.data = bytes.toString(\"base64\");\n }\n if (attachment.url !== undefined) entry.url = attachment.url;\n return entry;\n}\n\nfunction deserializeResponse(wire: WireResponse): GuardResponse {\n const status = wire.status ?? \"\";\n return {\n status,\n isBlocked: status === \"block\",\n transformedPayload: wire.transformed_payload ?? null,\n findings: (wire.findings ?? []).map(deserializeFinding),\n traceId: wire.trace_id ?? \"\",\n requestId: wire.request_id ?? \"\",\n };\n}\n\nfunction deserializeFinding(f: WireFinding): Finding {\n const sourceWire = f.source ?? {};\n const source: FindingSource = {\n kind: sourceWire.kind ?? \"\",\n };\n if (sourceWire.plugin !== undefined) source.plugin = sourceWire.plugin;\n if (sourceWire.detector_id !== undefined) source.detectorId = sourceWire.detector_id;\n if (sourceWire.detector_name !== undefined) source.detectorName = sourceWire.detector_name;\n if (sourceWire.policy_id !== undefined) source.policyId = sourceWire.policy_id;\n if (sourceWire.gate_name !== undefined) source.gateName = sourceWire.gate_name;\n\n const finding: Finding = { source };\n if (f.signal?.type) {\n const signal: FindingSignal = { type: f.signal.type };\n if (f.signal.confidence !== undefined) signal.confidence = f.signal.confidence;\n finding.signal = signal;\n }\n if (f.outcome?.action) {\n const outcome: FindingOutcome = { action: f.outcome.action };\n finding.outcome = outcome;\n }\n if (f.evidence && Object.keys(f.evidence).length > 0) {\n finding.evidence = f.evidence;\n }\n return finding;\n}\n\nfunction apiError(status: number, text: string): TrustGuardAPIError {\n const payload = parseJson(text) as { error?: string; message?: string; trace_id?: string; request_id?: string } | undefined;\n const message = payload?.error || payload?.message || text.trim() || `HTTP ${status}`;\n return new TrustGuardAPIError(status, message, payload?.trace_id ?? \"\", payload?.request_id ?? \"\");\n}\n\nfunction parseJson(text: string): WireResponse | undefined {\n try {\n return JSON.parse(text) as WireResponse;\n } catch {\n return undefined;\n }\n}\n"],"mappings":";AAKO,IAAM,qBAAN,cAAiC,MAAM;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,QAAgB,SAAiB,SAAiB,WAAmB;AAC/E,UAAM,wBAAwB,MAAM,KAAK,OAAO,cAAc,OAAO,gBAAgB,SAAS,GAAG;AACjG,SAAK,OAAO;AACZ,SAAK,SAAS;AACd,SAAK,UAAU;AACf,SAAK,YAAY;AAAA,EACnB;AACF;;;ACLA,IAAM,gBAAgB;AACtB,IAAM,qBAAqB;AAoCpB,IAAM,aAAN,MAAiB;AAAA,EACb;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EAET,YAAY,SAA4B;AACtC,UAAM,UAAU,QAAQ,SAAS,KAAK,EAAE,QAAQ,QAAQ,EAAE;AAC1D,QAAI,CAAC,SAAS;AACZ,YAAM,IAAI,MAAM,iCAAiC;AAAA,IACnD;AACA,QAAI,CAAC,QAAQ,QAAQ,KAAK,GAAG;AAC3B,YAAM,IAAI,MAAM,gCAAgC;AAAA,IAClD;AACA,SAAK,WAAW;AAChB,SAAK,UAAU,QAAQ;AACvB,SAAK,aAAa,QAAQ,aAAa;AACvC,SAAK,SAAS,QAAQ,SAAS,WAAW;AAAA,EAC5C;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,MAAM,SAA+C;AACzD,QAAI,CAAC,QAAQ,SAAS;AACpB,YAAM,IAAI,MAAM,yCAAyC;AAAA,IAC3D;AAEA,UAAM,WAAW,MAAM,KAAK,OAAO,KAAK,WAAW,eAAe;AAAA,MAChE,QAAQ;AAAA,MACR,SAAS;AAAA,QACP,eAAe,UAAU,KAAK,OAAO;AAAA,QACrC,gBAAgB;AAAA,MAClB;AAAA,MACA,MAAM,KAAK,UAAU,iBAAiB,OAAO,CAAC;AAAA,MAC9C,QAAQ,YAAY,QAAQ,KAAK,UAAU;AAAA,IAC7C,CAAC;AAED,UAAM,OAAO,MAAM,SAAS,KAAK;AACjC,QAAI,CAAC,SAAS,IAAI;AAChB,YAAM,SAAS,SAAS,QAAQ,IAAI;AAAA,IACtC;AAEA,WAAO,oBAAoB,UAAU,IAAI,KAAK,CAAC,CAAC;AAAA,EAClD;AACF;AAGA,SAAS,iBAAiB,SAAgD;AACxE,MAAI,UAAU,QAAQ;AACtB,MAAI,QAAQ,aAAa,QAAQ;AAC/B,cAAU,EAAE,GAAG,SAAS,aAAa,QAAQ,YAAY,IAAI,mBAAmB,EAAE;AAAA,EACpF;AACA,QAAM,OAAgC,EAAE,QAAQ;AAChD,MAAI,QAAQ,UAAW,MAAK,YAAY,QAAQ;AAChD,MAAI,QAAQ,SAAU,MAAK,WAAW,QAAQ;AAC9C,MAAI,QAAQ,UAAW,MAAK,aAAa,QAAQ;AACjD,MAAI,QAAQ,WAAY,MAAK,cAAc,QAAQ;AACnD,MAAI,QAAQ,cAAc,OAAO,KAAK,QAAQ,UAAU,EAAE,SAAS,EAAG,MAAK,aAAa,QAAQ;AAChG,SAAO;AACT;AAEA,SAAS,oBAAoB,YAAgD;AAC3E,QAAM,QAAgC;AAAA,IACpC,UAAU,WAAW;AAAA,IACrB,cAAc,WAAW;AAAA,EAC3B;AACA,MAAI,WAAW,SAAS,QAAW;AACjC,UAAM,QACJ,OAAO,WAAW,SAAS,WAAW,OAAO,KAAK,WAAW,MAAM,OAAO,IAAI,OAAO,KAAK,WAAW,IAAI;AAC3G,UAAM,OAAO,MAAM,SAAS,QAAQ;AAAA,EACtC;AACA,MAAI,WAAW,QAAQ,OAAW,OAAM,MAAM,WAAW;AACzD,SAAO;AACT;AAEA,SAAS,oBAAoB,MAAmC;AAC9D,QAAM,SAAS,KAAK,UAAU;AAC9B,SAAO;AAAA,IACL;AAAA,IACA,WAAW,WAAW;AAAA,IACtB,oBAAoB,KAAK,uBAAuB;AAAA,IAChD,WAAW,KAAK,YAAY,CAAC,GAAG,IAAI,kBAAkB;AAAA,IACtD,SAAS,KAAK,YAAY;AAAA,IAC1B,WAAW,KAAK,cAAc;AAAA,EAChC;AACF;AAEA,SAAS,mBAAmB,GAAyB;AACnD,QAAM,aAAa,EAAE,UAAU,CAAC;AAChC,QAAM,SAAwB;AAAA,IAC5B,MAAM,WAAW,QAAQ;AAAA,EAC3B;AACA,MAAI,WAAW,WAAW,OAAW,QAAO,SAAS,WAAW;AAChE,MAAI,WAAW,gBAAgB,OAAW,QAAO,aAAa,WAAW;AACzE,MAAI,WAAW,kBAAkB,OAAW,QAAO,eAAe,WAAW;AAC7E,MAAI,WAAW,cAAc,OAAW,QAAO,WAAW,WAAW;AACrE,MAAI,WAAW,cAAc,OAAW,QAAO,WAAW,WAAW;AAErE,QAAM,UAAmB,EAAE,OAAO;AAClC,MAAI,EAAE,QAAQ,MAAM;AAClB,UAAM,SAAwB,EAAE,MAAM,EAAE,OAAO,KAAK;AACpD,QAAI,EAAE,OAAO,eAAe,OAAW,QAAO,aAAa,EAAE,OAAO;AACpE,YAAQ,SAAS;AAAA,EACnB;AACA,MAAI,EAAE,SAAS,QAAQ;AACrB,UAAM,UAA0B,EAAE,QAAQ,EAAE,QAAQ,OAAO;AAC3D,YAAQ,UAAU;AAAA,EACpB;AACA,MAAI,EAAE,YAAY,OAAO,KAAK,EAAE,QAAQ,EAAE,SAAS,GAAG;AACpD,YAAQ,WAAW,EAAE;AAAA,EACvB;AACA,SAAO;AACT;AAEA,SAAS,SAAS,QAAgB,MAAkC;AAClE,QAAM,UAAU,UAAU,IAAI;AAC9B,QAAM,UAAU,SAAS,SAAS,SAAS,WAAW,KAAK,KAAK,KAAK,QAAQ,MAAM;AACnF,SAAO,IAAI,mBAAmB,QAAQ,SAAS,SAAS,YAAY,IAAI,SAAS,cAAc,EAAE;AACnG;AAEA,SAAS,UAAU,MAAwC;AACzD,MAAI;AACF,WAAO,KAAK,MAAM,IAAI;AAAA,EACxB,QAAQ;AACN,WAAO;AAAA,EACT;AACF;","names":[]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@neuraltrust/trustguard-sdk",
3
- "version": "0.1.0",
4
- "description": "Official Node.js SDK for the TrustGuard runtime guard API (POST /v1/guard)",
3
+ "version": "0.1.4",
4
+ "description": "Official Node.js SDK for the TrustGuard runtime evaluate API (POST /v1/evaluate)",
5
5
  "license": "MIT",
6
6
  "author": "NeuralTrust",
7
7
  "repository": {
@@ -9,6 +9,10 @@
9
9
  "url": "git+https://github.com/NeuralTrust/trustguard-sdk.git",
10
10
  "directory": "node"
11
11
  },
12
+ "homepage": "https://docs.neuraltrust.ai/sdks/trustguard/node",
13
+ "bugs": {
14
+ "url": "https://github.com/NeuralTrust/trustguard-sdk/issues"
15
+ },
12
16
  "keywords": [
13
17
  "neuraltrust",
14
18
  "trustguard",
@@ -44,6 +48,6 @@
44
48
  "@types/node": "^22.10.2",
45
49
  "tsup": "^8.3.5",
46
50
  "typescript": "^5.7.2",
47
- "vitest": "^2.1.8"
51
+ "vitest": "^4.1.9"
48
52
  }
49
53
  }