@driftgard/node 1.9.0 → 1.11.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 +56 -5
- package/dist/index.d.ts +1 -1
- package/dist/index.js +10 -2
- package/dist/types.d.ts +13 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @driftgard/node
|
|
2
2
|
|
|
3
|
-
Official Node.js SDK for [
|
|
3
|
+
Official Node.js SDK for [DriftGard](https://driftgard.com) — evaluate LLM interactions against your compliance policy.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -51,7 +51,54 @@ const result = await dg.evaluate({
|
|
|
51
51
|
});
|
|
52
52
|
```
|
|
53
53
|
|
|
54
|
-
This enables chain depth protection (prevents infinite agent loops) and lets you trace evaluation lineage in the dashboard. When `sequence_no` is provided,
|
|
54
|
+
This enables chain depth protection (prevents infinite agent loops) and lets you trace evaluation lineage in the dashboard. When `sequence_no` is provided, DriftGard enforces ordering — if an eval arrives out of order, the response includes a `sequence_warning`.
|
|
55
|
+
|
|
56
|
+
## Agent identity
|
|
57
|
+
|
|
58
|
+
Identify which agent made a decision using `agent_id` and `agent_role`:
|
|
59
|
+
|
|
60
|
+
```typescript
|
|
61
|
+
const result = await dg.evaluate({
|
|
62
|
+
project_id: "your-project-id",
|
|
63
|
+
prompt: "Transfer $500",
|
|
64
|
+
response: "Transfer initiated.",
|
|
65
|
+
model_id: "gpt-4o",
|
|
66
|
+
agent_id: "agent_payments_prod", // which agent instance
|
|
67
|
+
agent_role: "payments_agent", // agent's role for policy scoping
|
|
68
|
+
on_behalf_of: "user_12345", // which end-user triggered this
|
|
69
|
+
// parent_agent_id: "agent_orchestrator", // optional — which parent agent delegated
|
|
70
|
+
session_id: "sess_abc123",
|
|
71
|
+
});
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Agent identity fields are stored on the evaluation record and visible in the Live Activity detail dialog. The `on_behalf_of` field tracks which end-user triggered the agent action. The `parent_agent_id` field identifies which orchestrator agent delegated to this one in multi-agent systems.
|
|
75
|
+
|
|
76
|
+
### Per-tool identity rules
|
|
77
|
+
|
|
78
|
+
Control packs support `identity_rules` on each tool — restricting which agents, roles, users, or parent agents can call it. Rules use OR logic across entries and AND logic within each entry:
|
|
79
|
+
|
|
80
|
+
```json
|
|
81
|
+
{
|
|
82
|
+
"tool_rules": {
|
|
83
|
+
"tool_policy": "deny_unlisted",
|
|
84
|
+
"rules": {
|
|
85
|
+
"transfer_money": {
|
|
86
|
+
"parameters": { ... },
|
|
87
|
+
"identity_rules": [
|
|
88
|
+
{ "allowed_roles": ["payments_agent"], "allowed_users": ["user_alice", "user_bob"] },
|
|
89
|
+
{ "allowed_roles": ["admin_agent"] }
|
|
90
|
+
]
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
In this example, `transfer_money` is allowed when:
|
|
98
|
+
- The caller has `agent_role=payments_agent` AND `on_behalf_of` is `user_alice` or `user_bob`, OR
|
|
99
|
+
- The caller has `agent_role=admin_agent` (any user)
|
|
100
|
+
|
|
101
|
+
If no `identity_rules` are defined on a tool, any caller can use it (subject to parameter validation). All four fields are optional within each rule — only specified fields are checked.
|
|
55
102
|
|
|
56
103
|
## A/B experiments
|
|
57
104
|
|
|
@@ -67,7 +114,7 @@ const result = await dg.evaluate({
|
|
|
67
114
|
});
|
|
68
115
|
```
|
|
69
116
|
|
|
70
|
-
View experiment results on the Experiments page in the
|
|
117
|
+
View experiment results on the Experiments page in the DriftGard dashboard.
|
|
71
118
|
|
|
72
119
|
## Cost attribution
|
|
73
120
|
|
|
@@ -117,6 +164,10 @@ const result = await dg.evaluateToolCall({
|
|
|
117
164
|
tool_name: "transfer_money",
|
|
118
165
|
parameters: { amount: 500, to_account: "account_123" },
|
|
119
166
|
session_id: "sess_abc123",
|
|
167
|
+
agent_id: "agent_payments_prod",
|
|
168
|
+
agent_role: "payments_agent",
|
|
169
|
+
on_behalf_of: "user_12345",
|
|
170
|
+
// parent_agent_id: "agent_orchestrator",
|
|
120
171
|
});
|
|
121
172
|
|
|
122
173
|
if (!result.evaluation.allowed) {
|
|
@@ -196,7 +247,7 @@ console.log(dg.circuitBreakerState);
|
|
|
196
247
|
// { state: "closed", failures: 0, openedAt: 0 }
|
|
197
248
|
```
|
|
198
249
|
|
|
199
|
-
With `failureMode: "open"` (default), the SDK allows requests through when
|
|
250
|
+
With `failureMode: "open"` (default), the SDK allows requests through when DriftGard is unavailable. With `failureMode: "closed"`, it blocks them with a fallback message.
|
|
200
251
|
|
|
201
252
|
## Error handling
|
|
202
253
|
|
|
@@ -222,7 +273,7 @@ try {
|
|
|
222
273
|
## Requirements
|
|
223
274
|
|
|
224
275
|
- Node.js 18+ (uses native `fetch`)
|
|
225
|
-
- API key from
|
|
276
|
+
- API key from DriftGard (Settings → API Keys)
|
|
226
277
|
- Compliance or Enterprise tier for API evaluation
|
|
227
278
|
|
|
228
279
|
## License
|
package/dist/index.d.ts
CHANGED
|
@@ -31,7 +31,7 @@ export declare class Driftgard {
|
|
|
31
31
|
*/
|
|
32
32
|
reportOutcome(evaluationId: string, projectId: string, outcome: OutcomeRequest): Promise<any>;
|
|
33
33
|
/**
|
|
34
|
-
* Wrap a tool function with
|
|
34
|
+
* Wrap a tool function with DriftGard policy check.
|
|
35
35
|
* Returns a guarded version that evaluates before executing.
|
|
36
36
|
*/
|
|
37
37
|
guard<T extends (...args: any[]) => any>(toolFn: T, toolName: string, projectId: string, opts?: {
|
package/dist/index.js
CHANGED
|
@@ -61,6 +61,10 @@ class Driftgard {
|
|
|
61
61
|
...(req.eval_mode ? { eval_mode: req.eval_mode } : {}),
|
|
62
62
|
...(req.tool_call ? { tool_call: req.tool_call } : {}),
|
|
63
63
|
...(req.sequence_no != null ? { sequence_no: req.sequence_no } : {}),
|
|
64
|
+
...(req.agent_id ? { agent_id: req.agent_id } : {}),
|
|
65
|
+
...(req.agent_role ? { agent_role: req.agent_role } : {}),
|
|
66
|
+
...(req.on_behalf_of ? { on_behalf_of: req.on_behalf_of } : {}),
|
|
67
|
+
...(req.parent_agent_id ? { parent_agent_id: req.parent_agent_id } : {}),
|
|
64
68
|
...(req.usage ? { usage: req.usage } : {}),
|
|
65
69
|
}, idempotencyKey);
|
|
66
70
|
// Success — reset circuit breaker
|
|
@@ -105,7 +109,7 @@ class Driftgard {
|
|
|
105
109
|
clause_id: "DRIFTGARD_UNAVAILABLE",
|
|
106
110
|
severity: "critical",
|
|
107
111
|
category: "system",
|
|
108
|
-
reason: `
|
|
112
|
+
reason: `DriftGard API unavailable — fail-closed policy applied (${source})`,
|
|
109
113
|
}],
|
|
110
114
|
},
|
|
111
115
|
...(allowed ? {} : {
|
|
@@ -135,6 +139,10 @@ class Driftgard {
|
|
|
135
139
|
parent_evaluation_id: req.parent_evaluation_id,
|
|
136
140
|
idempotency_key: req.idempotency_key,
|
|
137
141
|
sequence_no: req.sequence_no,
|
|
142
|
+
agent_id: req.agent_id,
|
|
143
|
+
agent_role: req.agent_role,
|
|
144
|
+
on_behalf_of: req.on_behalf_of,
|
|
145
|
+
parent_agent_id: req.parent_agent_id,
|
|
138
146
|
});
|
|
139
147
|
}
|
|
140
148
|
/**
|
|
@@ -147,7 +155,7 @@ class Driftgard {
|
|
|
147
155
|
});
|
|
148
156
|
}
|
|
149
157
|
/**
|
|
150
|
-
* Wrap a tool function with
|
|
158
|
+
* Wrap a tool function with DriftGard policy check.
|
|
151
159
|
* Returns a guarded version that evaluates before executing.
|
|
152
160
|
*/
|
|
153
161
|
guard(toolFn, toolName, projectId, opts) {
|
package/dist/types.d.ts
CHANGED
|
@@ -9,7 +9,7 @@ export interface DriftgardConfig {
|
|
|
9
9
|
baseUrl?: string;
|
|
10
10
|
timeout?: number;
|
|
11
11
|
maxRetries?: number;
|
|
12
|
-
/** What to do when
|
|
12
|
+
/** What to do when DriftGard API is unreachable. "open" = allow, "closed" = block. Default "open". */
|
|
13
13
|
failureMode?: "open" | "closed";
|
|
14
14
|
/** Circuit breaker config. Skips API calls after consecutive failures. */
|
|
15
15
|
circuitBreaker?: CircuitBreakerConfig;
|
|
@@ -35,6 +35,14 @@ export interface EvaluateRequest {
|
|
|
35
35
|
idempotency_key?: string;
|
|
36
36
|
/** Sequence number within a session for ordering. Optional — if sent, ordering is enforced. */
|
|
37
37
|
sequence_no?: number;
|
|
38
|
+
/** Agent identity — who or what is making this decision. */
|
|
39
|
+
agent_id?: string;
|
|
40
|
+
/** Agent role — scopes what the agent is allowed to do. */
|
|
41
|
+
agent_role?: string;
|
|
42
|
+
/** End-user ID — which human triggered this agent action. */
|
|
43
|
+
on_behalf_of?: string;
|
|
44
|
+
/** Parent agent ID — which orchestrator agent delegated to this one. */
|
|
45
|
+
parent_agent_id?: string;
|
|
38
46
|
usage?: {
|
|
39
47
|
prompt_tokens?: number;
|
|
40
48
|
completion_tokens?: number;
|
|
@@ -141,6 +149,10 @@ export interface ToolCallRequest {
|
|
|
141
149
|
parent_evaluation_id?: string;
|
|
142
150
|
idempotency_key?: string;
|
|
143
151
|
sequence_no?: number;
|
|
152
|
+
agent_id?: string;
|
|
153
|
+
agent_role?: string;
|
|
154
|
+
on_behalf_of?: string;
|
|
155
|
+
parent_agent_id?: string;
|
|
144
156
|
}
|
|
145
157
|
export interface OutcomeRequest {
|
|
146
158
|
execution_status: "success" | "failed" | "rolled_back";
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@driftgard/node",
|
|
3
|
-
"version": "1.
|
|
4
|
-
"description": "Official
|
|
3
|
+
"version": "1.11.0",
|
|
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",
|
|
7
7
|
"files": ["dist", "README.md"],
|