@driftgard/node 1.5.1 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -89,6 +89,52 @@ const result = await dg.evaluate({
89
89
 
90
90
  All fields in `usage` are optional. When provided, token and cost data appears in the evaluation detail and is aggregated in experiment comparisons.
91
91
 
92
+ ## Cost alerts
93
+
94
+ When cost alerting is enabled on your project, the response includes a `cost_alert` field if a threshold is exceeded:
95
+
96
+ ```typescript
97
+ const result = await dg.evaluate({ ... });
98
+
99
+ if (result.cost_alert) {
100
+ console.warn(`Cost alert: ${result.cost_alert.scope} spend $${result.cost_alert.actual_usd} exceeds $${result.cost_alert.threshold_usd}`);
101
+ // Throttle the agent, notify the user, etc.
102
+ }
103
+ ```
104
+
105
+ Configure thresholds in Settings — per-project, per-model, or per-session. Session-scoped alerts catch runaway agent loops in real-time.
106
+
107
+ ## Tool call validation
108
+
109
+ Validate AI agent tool/function calls against your control pack's tool rules:
110
+
111
+ ```typescript
112
+ // Direct tool call evaluation
113
+ const result = await dg.evaluateToolCall({
114
+ project_id: "your-project-id",
115
+ model_id: "gpt-4o",
116
+ tool_name: "transfer_money",
117
+ parameters: { amount: 500, to_account: "account_123" },
118
+ session_id: "sess_abc123",
119
+ });
120
+
121
+ if (!result.evaluation.allowed) {
122
+ console.log("Tool blocked:", result.fallback?.message);
123
+ }
124
+
125
+ // Or wrap a tool function — blocks automatically
126
+ const safeTransfer = dg.guard(transferMoney, "transfer_money", "your-project-id");
127
+ await safeTransfer({ amount: 500, to_account: "account_123" }); // throws if blocked
128
+
129
+ // Report execution outcome (optional)
130
+ await dg.reportOutcome(result.evaluation_id, "your-project-id", {
131
+ execution_status: "success",
132
+ duration_ms: 230,
133
+ });
134
+ ```
135
+
136
+ For Strands agents, use the `BeforeToolCallEvent` hook — see the integration guide.
137
+
92
138
  ## Features
93
139
 
94
140
  - Single `evaluate()` method — send prompt/response, get verdict
package/dist/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
- import { DriftgardConfig, EvaluateRequest, EvaluateResponse } from "./types";
2
- export { DriftgardConfig, EvaluateRequest, EvaluateResponse, CircuitBreakerConfig } from "./types";
1
+ import { DriftgardConfig, EvaluateRequest, EvaluateResponse, ToolCallRequest, OutcomeRequest } from "./types";
2
+ export { DriftgardConfig, EvaluateRequest, EvaluateResponse, CircuitBreakerConfig, ToolCallRequest, OutcomeRequest } from "./types";
3
3
  export { Violation, EvaluationResult, FallbackResponse, HitlInfo } from "./types";
4
4
  export { DriftgardError, AuthError, RateLimitError, FeatureNotAvailableError, ChainDepthExceededError } from "./errors";
5
5
  type CircuitState = "closed" | "open" | "half-open";
@@ -22,6 +22,22 @@ export declare class Driftgard {
22
22
  evaluate(req: EvaluateRequest): Promise<EvaluateResponse>;
23
23
  /** Generate a synthetic response based on failure mode. */
24
24
  private syntheticResponse;
25
+ /**
26
+ * Evaluate a tool/function call against your control pack's tool_rules.
27
+ */
28
+ evaluateToolCall(req: ToolCallRequest): Promise<EvaluateResponse>;
29
+ /**
30
+ * Report the outcome of a tool execution after it was allowed.
31
+ */
32
+ reportOutcome(evaluationId: string, projectId: string, outcome: OutcomeRequest): Promise<any>;
33
+ /**
34
+ * Wrap a tool function with Driftgard policy check.
35
+ * Returns a guarded version that evaluates before executing.
36
+ */
37
+ guard<T extends (...args: any[]) => any>(toolFn: T, toolName: string, projectId: string, opts?: {
38
+ modelId?: string;
39
+ sessionId?: string;
40
+ }): (...args: Parameters<T>) => Promise<ReturnType<T>>;
25
41
  /** Get current circuit breaker state (for observability). */
26
42
  get circuitBreakerState(): {
27
43
  state: CircuitState;
package/dist/index.js CHANGED
@@ -58,6 +58,8 @@ class Driftgard {
58
58
  ...(req.control_pack_id ? { control_pack_id: req.control_pack_id } : {}),
59
59
  ...(req.control_pack_version ? { control_pack_version: req.control_pack_version } : {}),
60
60
  ...(req.dry_run ? { dry_run: req.dry_run } : {}),
61
+ ...(req.eval_mode ? { eval_mode: req.eval_mode } : {}),
62
+ ...(req.tool_call ? { tool_call: req.tool_call } : {}),
61
63
  ...(req.usage ? { usage: req.usage } : {}),
62
64
  }, idempotencyKey);
63
65
  // Success — reset circuit breaker
@@ -117,6 +119,52 @@ class Driftgard {
117
119
  }),
118
120
  };
119
121
  }
122
+ /**
123
+ * Evaluate a tool/function call against your control pack's tool_rules.
124
+ */
125
+ async evaluateToolCall(req) {
126
+ return this.evaluate({
127
+ project_id: req.project_id,
128
+ prompt: "",
129
+ response: "",
130
+ model_id: req.model_id,
131
+ eval_mode: "tool_call",
132
+ tool_call: { tool_name: req.tool_name, parameters: req.parameters || {} },
133
+ session_id: req.session_id,
134
+ parent_evaluation_id: req.parent_evaluation_id,
135
+ idempotency_key: req.idempotency_key,
136
+ });
137
+ }
138
+ /**
139
+ * Report the outcome of a tool execution after it was allowed.
140
+ */
141
+ async reportOutcome(evaluationId, projectId, outcome) {
142
+ return this.post(`/audit/evaluations/${encodeURIComponent(evaluationId)}/outcome`, {
143
+ project_id: projectId,
144
+ ...outcome,
145
+ });
146
+ }
147
+ /**
148
+ * Wrap a tool function with Driftgard policy check.
149
+ * Returns a guarded version that evaluates before executing.
150
+ */
151
+ guard(toolFn, toolName, projectId, opts) {
152
+ const dg = this;
153
+ return async (...args) => {
154
+ const parameters = args.length === 1 && typeof args[0] === "object" ? args[0] : { args };
155
+ const result = await dg.evaluateToolCall({
156
+ project_id: projectId,
157
+ model_id: opts?.modelId || "agent",
158
+ tool_name: toolName,
159
+ parameters,
160
+ session_id: opts?.sessionId,
161
+ });
162
+ if (!result.evaluation.allowed) {
163
+ throw new errors_1.DriftgardError(result.fallback?.message || `Tool "${toolName}" blocked by policy`, 403, "tool_blocked");
164
+ }
165
+ return toolFn(...args);
166
+ };
167
+ }
120
168
  /** Get current circuit breaker state (for observability). */
121
169
  get circuitBreakerState() {
122
170
  return { state: this.cbState, failures: this.cbFailures, openedAt: this.cbOpenedAt };
package/dist/types.d.ts CHANGED
@@ -26,6 +26,11 @@ export interface EvaluateRequest {
26
26
  control_pack_id?: string;
27
27
  control_pack_version?: number;
28
28
  dry_run?: boolean;
29
+ eval_mode?: "text" | "tool_call";
30
+ tool_call?: {
31
+ tool_name: string;
32
+ parameters?: Record<string, any>;
33
+ };
29
34
  /** Caller-provided idempotency key. If omitted, the SDK generates one. */
30
35
  idempotency_key?: string;
31
36
  usage?: {
@@ -103,4 +108,36 @@ export interface EvaluateResponse {
103
108
  hitl?: HitlInfo;
104
109
  evaluation: EvaluationResult;
105
110
  fallback?: FallbackResponse;
111
+ cost_alert?: {
112
+ type: string;
113
+ scope: string;
114
+ session_id?: string;
115
+ model_id?: string;
116
+ window: string;
117
+ threshold_usd: number;
118
+ actual_usd: number;
119
+ };
120
+ eval_mode?: string;
121
+ tool_call?: {
122
+ tool_name: string;
123
+ parameters?: Record<string, any>;
124
+ };
125
+ }
126
+ export interface ToolCallRequest {
127
+ project_id: string;
128
+ model_id: string;
129
+ tool_name: string;
130
+ parameters?: Record<string, any>;
131
+ session_id?: string;
132
+ parent_evaluation_id?: string;
133
+ idempotency_key?: string;
134
+ }
135
+ export interface OutcomeRequest {
136
+ execution_status: "success" | "failed" | "rolled_back";
137
+ duration_ms?: number;
138
+ error_code?: string;
139
+ error_message?: string;
140
+ affected_resources?: string[];
141
+ compensation_action?: string;
142
+ external_ref?: string;
106
143
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@driftgard/node",
3
- "version": "1.5.1",
3
+ "version": "1.7.0",
4
4
  "description": "Official Driftgard Node.js SDK — evaluate LLM interactions against your compliance policy",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",