veto-sdk 1.1.0 → 1.3.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 +105 -273
- package/dist/cli/templates.d.ts +2 -2
- package/dist/cli/templates.d.ts.map +1 -1
- package/dist/cli/templates.js +30 -1
- package/dist/cli/templates.js.map +1 -1
- package/dist/cloud/client.d.ts +40 -0
- package/dist/cloud/client.d.ts.map +1 -0
- package/dist/cloud/client.js +263 -0
- package/dist/cloud/client.js.map +1 -0
- package/dist/cloud/types.d.ts +102 -0
- package/dist/cloud/types.d.ts.map +1 -0
- package/dist/cloud/types.js +7 -0
- package/dist/cloud/types.js.map +1 -0
- package/dist/compiler/ast.d.ts +46 -0
- package/dist/compiler/ast.d.ts.map +1 -0
- package/dist/compiler/ast.js +22 -0
- package/dist/compiler/ast.js.map +1 -0
- package/dist/compiler/evaluator.d.ts +12 -0
- package/dist/compiler/evaluator.d.ts.map +1 -0
- package/dist/compiler/evaluator.js +214 -0
- package/dist/compiler/evaluator.js.map +1 -0
- package/dist/compiler/index.d.ts +33 -0
- package/dist/compiler/index.d.ts.map +1 -0
- package/dist/compiler/index.js +33 -0
- package/dist/compiler/index.js.map +1 -0
- package/dist/compiler/lexer.d.ts +17 -0
- package/dist/compiler/lexer.d.ts.map +1 -0
- package/dist/compiler/lexer.js +193 -0
- package/dist/compiler/lexer.js.map +1 -0
- package/dist/compiler/parser.d.ts +26 -0
- package/dist/compiler/parser.d.ts.map +1 -0
- package/dist/compiler/parser.js +211 -0
- package/dist/compiler/parser.js.map +1 -0
- package/dist/compiler/type-checker.d.ts +23 -0
- package/dist/compiler/type-checker.d.ts.map +1 -0
- package/dist/compiler/type-checker.js +220 -0
- package/dist/compiler/type-checker.js.map +1 -0
- package/dist/core/veto.d.ts +96 -44
- package/dist/core/veto.d.ts.map +1 -1
- package/dist/core/veto.js +510 -87
- package/dist/core/veto.js.map +1 -1
- package/dist/custom/client.d.ts +61 -0
- package/dist/custom/client.d.ts.map +1 -0
- package/dist/custom/client.js +155 -0
- package/dist/custom/client.js.map +1 -0
- package/dist/custom/index.d.ts +9 -0
- package/dist/custom/index.d.ts.map +1 -0
- package/dist/custom/index.js +9 -0
- package/dist/custom/index.js.map +1 -0
- package/dist/custom/prompt.d.ts +49 -0
- package/dist/custom/prompt.d.ts.map +1 -0
- package/dist/custom/prompt.js +69 -0
- package/dist/custom/prompt.js.map +1 -0
- package/dist/custom/providers/anthropic.d.ts +18 -0
- package/dist/custom/providers/anthropic.d.ts.map +1 -0
- package/dist/custom/providers/anthropic.js +46 -0
- package/dist/custom/providers/anthropic.js.map +1 -0
- package/dist/custom/providers/gemini.d.ts +18 -0
- package/dist/custom/providers/gemini.d.ts.map +1 -0
- package/dist/custom/providers/gemini.js +62 -0
- package/dist/custom/providers/gemini.js.map +1 -0
- package/dist/custom/providers/openai.d.ts +18 -0
- package/dist/custom/providers/openai.d.ts.map +1 -0
- package/dist/custom/providers/openai.js +47 -0
- package/dist/custom/providers/openai.js.map +1 -0
- package/dist/custom/providers/openrouter.d.ts +22 -0
- package/dist/custom/providers/openrouter.d.ts.map +1 -0
- package/dist/custom/providers/openrouter.js +22 -0
- package/dist/custom/providers/openrouter.js.map +1 -0
- package/dist/custom/types.d.ts +103 -0
- package/dist/custom/types.d.ts.map +1 -0
- package/dist/custom/types.js +89 -0
- package/dist/custom/types.js.map +1 -0
- package/dist/index.d.ts +7 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -1
- package/dist/kernel/client.d.ts.map +1 -1
- package/dist/kernel/client.js +2 -0
- package/dist/kernel/client.js.map +1 -1
- package/dist/rules/expression-validator.d.ts +48 -0
- package/dist/rules/expression-validator.d.ts.map +1 -0
- package/dist/rules/expression-validator.js +180 -0
- package/dist/rules/expression-validator.js.map +1 -0
- package/dist/rules/index.d.ts +3 -0
- package/dist/rules/index.d.ts.map +1 -1
- package/dist/rules/index.js +3 -0
- package/dist/rules/index.js.map +1 -1
- package/dist/rules/loader.d.ts +13 -0
- package/dist/rules/loader.d.ts.map +1 -1
- package/dist/rules/loader.js +91 -13
- package/dist/rules/loader.js.map +1 -1
- package/dist/rules/policy-ir-schema.d.ts +161 -0
- package/dist/rules/policy-ir-schema.d.ts.map +1 -0
- package/dist/rules/policy-ir-schema.js +160 -0
- package/dist/rules/policy-ir-schema.js.map +1 -0
- package/dist/rules/schema-validator.d.ts +11 -0
- package/dist/rules/schema-validator.d.ts.map +1 -0
- package/dist/rules/schema-validator.js +49 -0
- package/dist/rules/schema-validator.js.map +1 -0
- package/dist/rules/types.d.ts +11 -20
- package/dist/rules/types.d.ts.map +1 -1
- package/dist/rules/types.js +0 -214
- package/dist/rules/types.js.map +1 -1
- package/package.json +21 -1
package/README.md
CHANGED
|
@@ -4,17 +4,16 @@ A guardrail system for AI agent tool calls. Veto intercepts and validates tool c
|
|
|
4
4
|
|
|
5
5
|
## How It Works
|
|
6
6
|
|
|
7
|
-
1.
|
|
8
|
-
2. Wrap
|
|
9
|
-
3. Pass
|
|
10
|
-
4. Execute tool calls using `implementations` - validation happens automatically
|
|
7
|
+
1. **Initialize** Veto.
|
|
8
|
+
2. **Wrap** your tools using `veto.wrap()`.
|
|
9
|
+
3. **Pass** the wrapped tools to your AI agent/model.
|
|
11
10
|
|
|
12
|
-
When a tool
|
|
13
|
-
1.
|
|
14
|
-
2.
|
|
15
|
-
3. Blocks or
|
|
11
|
+
When the AI model calls a tool, Veto automatically:
|
|
12
|
+
1. Intercepts the call.
|
|
13
|
+
2. Validates arguments against your rules (via YAML & LLM).
|
|
14
|
+
3. Blocks or Allows execution based on the result.
|
|
16
15
|
|
|
17
|
-
The AI model remains unaware of the guardrail - tool
|
|
16
|
+
The AI model remains unaware of the guardrail - the tool interface is preserved.
|
|
18
17
|
|
|
19
18
|
## Installation
|
|
20
19
|
|
|
@@ -24,84 +23,57 @@ npm install veto
|
|
|
24
23
|
|
|
25
24
|
## Quick Start
|
|
26
25
|
|
|
27
|
-
### 1. Initialize Veto
|
|
26
|
+
### 1. Initialize Veto
|
|
28
27
|
|
|
28
|
+
Run the CLI to create configuration:
|
|
29
29
|
```bash
|
|
30
30
|
npx veto init
|
|
31
31
|
```
|
|
32
|
+
This creates a `veto/` directory with `veto.config.yaml` and default rules.
|
|
32
33
|
|
|
33
|
-
|
|
34
|
+
### 2. Wrap Your Tools
|
|
34
35
|
|
|
35
|
-
|
|
36
|
+
Veto's `wrap()` method is provider-agnostic. It works with LangChain, Vercel AI SDK, or any custom tool object.
|
|
36
37
|
|
|
37
38
|
```typescript
|
|
38
|
-
import { Veto
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
inputSchema: {
|
|
46
|
-
type: 'object',
|
|
47
|
-
properties: { path: { type: 'string' } },
|
|
48
|
-
required: ['path']
|
|
49
|
-
},
|
|
50
|
-
handler: async (args) => {
|
|
51
|
-
return fs.readFileSync(args.path, 'utf-8');
|
|
52
|
-
}
|
|
53
|
-
},
|
|
54
|
-
{
|
|
55
|
-
name: 'write_file',
|
|
56
|
-
description: 'Write a file',
|
|
57
|
-
inputSchema: {
|
|
58
|
-
type: 'object',
|
|
59
|
-
properties: {
|
|
60
|
-
path: { type: 'string' },
|
|
61
|
-
content: { type: 'string' }
|
|
62
|
-
},
|
|
63
|
-
required: ['path', 'content']
|
|
64
|
-
},
|
|
65
|
-
handler: async (args) => {
|
|
66
|
-
fs.writeFileSync(args.path, args.content);
|
|
67
|
-
return 'OK';
|
|
68
|
-
}
|
|
69
|
-
}
|
|
39
|
+
import { Veto } from 'veto';
|
|
40
|
+
import { tool } from '@langchain/core/tools'; // Example with LangChain
|
|
41
|
+
|
|
42
|
+
// 1. Define your tools normally
|
|
43
|
+
const myTools = [
|
|
44
|
+
tool(async (args) => { ... }, { name: 'my_tool', ... }),
|
|
45
|
+
// ...
|
|
70
46
|
];
|
|
71
47
|
|
|
72
|
-
// Initialize Veto
|
|
48
|
+
// 2. Initialize Veto
|
|
73
49
|
const veto = await Veto.init();
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
//
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
}
|
|
50
|
+
|
|
51
|
+
// 3. Wrap tools (Validation logic is injected)
|
|
52
|
+
// Types are preserved: wrappedTools has same type as myTools
|
|
53
|
+
const wrappedTools = veto.wrap(myTools);
|
|
54
|
+
|
|
55
|
+
// 4. Pass to your Agent/LLM
|
|
56
|
+
const agent = createAgent({
|
|
57
|
+
tools: wrappedTools,
|
|
58
|
+
// ...
|
|
59
|
+
});
|
|
85
60
|
```
|
|
86
61
|
|
|
87
|
-
### 3. Configure
|
|
62
|
+
### 3. Configure Rules
|
|
88
63
|
|
|
89
|
-
Edit `veto/rules/
|
|
64
|
+
Edit `veto/rules/financial.yaml` (example):
|
|
90
65
|
|
|
91
66
|
```yaml
|
|
92
67
|
rules:
|
|
93
|
-
- id:
|
|
94
|
-
name:
|
|
95
|
-
enabled: true
|
|
96
|
-
severity: critical
|
|
68
|
+
- id: limit-transfers
|
|
69
|
+
name: Limit large transfers
|
|
97
70
|
action: block
|
|
98
71
|
tools:
|
|
99
|
-
-
|
|
100
|
-
- write_file
|
|
72
|
+
- transfer_funds
|
|
101
73
|
conditions:
|
|
102
|
-
- field: arguments.
|
|
103
|
-
operator:
|
|
104
|
-
value:
|
|
74
|
+
- field: arguments.amount
|
|
75
|
+
operator: greater_than
|
|
76
|
+
value: 1000
|
|
105
77
|
```
|
|
106
78
|
|
|
107
79
|
## Configuration
|
|
@@ -114,16 +86,18 @@ version: "1.0"
|
|
|
114
86
|
# Operating mode
|
|
115
87
|
mode: "strict" # "strict" blocks calls, "log" only logs them
|
|
116
88
|
|
|
117
|
-
# Validation
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
89
|
+
# Validation Backend
|
|
90
|
+
validation:
|
|
91
|
+
mode: "custom" # "api", "kernel", or "custom"
|
|
92
|
+
|
|
93
|
+
# Custom Provider (if mode is custom)
|
|
94
|
+
custom:
|
|
95
|
+
provider: "gemini" # or openai, anthropic
|
|
96
|
+
model: "gemini-3-flash-preview"
|
|
123
97
|
|
|
124
98
|
# Logging
|
|
125
99
|
logging:
|
|
126
|
-
level: "info"
|
|
100
|
+
level: "info"
|
|
127
101
|
|
|
128
102
|
# Rules
|
|
129
103
|
rules:
|
|
@@ -131,223 +105,49 @@ rules:
|
|
|
131
105
|
recursive: true
|
|
132
106
|
```
|
|
133
107
|
|
|
134
|
-
### Operating Modes
|
|
135
|
-
|
|
136
|
-
| Mode | Behavior |
|
|
137
|
-
|------|----------|
|
|
138
|
-
| `strict` | Blocks tool calls when the validation API returns a block decision |
|
|
139
|
-
| `log` | Logs block decisions but allows all tool calls to proceed |
|
|
140
|
-
|
|
141
|
-
Override mode programmatically:
|
|
142
|
-
|
|
143
|
-
```typescript
|
|
144
|
-
const veto = await Veto.init({ mode: 'log' });
|
|
145
|
-
```
|
|
146
|
-
|
|
147
|
-
## Validation API
|
|
148
|
-
|
|
149
|
-
Veto sends a POST request to your validation API with the tool call context and applicable rules.
|
|
150
|
-
|
|
151
|
-
### Request
|
|
152
|
-
|
|
153
|
-
```
|
|
154
|
-
POST /tool/call/check
|
|
155
|
-
Content-Type: application/json
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
```json
|
|
159
|
-
{
|
|
160
|
-
"context": {
|
|
161
|
-
"call_id": "call_abc123",
|
|
162
|
-
"tool_name": "read_file",
|
|
163
|
-
"arguments": { "path": "/etc/passwd" },
|
|
164
|
-
"timestamp": "2024-01-15T10:30:00Z",
|
|
165
|
-
"call_history": []
|
|
166
|
-
},
|
|
167
|
-
"rules": [
|
|
168
|
-
{
|
|
169
|
-
"id": "block-system-paths",
|
|
170
|
-
"name": "Block system path access",
|
|
171
|
-
"severity": "critical",
|
|
172
|
-
"conditions": [
|
|
173
|
-
{
|
|
174
|
-
"field": "arguments.path",
|
|
175
|
-
"operator": "starts_with",
|
|
176
|
-
"value": "/etc"
|
|
177
|
-
}
|
|
178
|
-
]
|
|
179
|
-
}
|
|
180
|
-
]
|
|
181
|
-
}
|
|
182
|
-
```
|
|
183
|
-
|
|
184
|
-
### Response
|
|
185
|
-
|
|
186
|
-
```json
|
|
187
|
-
{
|
|
188
|
-
"should_pass_weight": 0.1,
|
|
189
|
-
"should_block_weight": 0.9,
|
|
190
|
-
"decision": "block",
|
|
191
|
-
"reasoning": "Access to /etc is blocked by security policy"
|
|
192
|
-
}
|
|
193
|
-
```
|
|
194
|
-
|
|
195
|
-
The `decision` field must be either `"pass"` or `"block"`.
|
|
196
|
-
|
|
197
|
-
## Rule Format
|
|
198
|
-
|
|
199
|
-
```yaml
|
|
200
|
-
rules:
|
|
201
|
-
- id: unique-rule-id
|
|
202
|
-
name: Human readable name
|
|
203
|
-
description: What this rule does
|
|
204
|
-
enabled: true
|
|
205
|
-
severity: critical # critical, high, medium, low, info
|
|
206
|
-
action: block # block, warn, log, allow
|
|
207
|
-
tools: # tools this applies to (empty = all tools)
|
|
208
|
-
- read_file
|
|
209
|
-
- write_file
|
|
210
|
-
conditions: # all conditions must match
|
|
211
|
-
- field: arguments.path
|
|
212
|
-
operator: starts_with
|
|
213
|
-
value: /etc
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
### Condition Operators
|
|
217
|
-
|
|
218
|
-
| Operator | Description |
|
|
219
|
-
|----------|-------------|
|
|
220
|
-
| `equals` | Exact match |
|
|
221
|
-
| `not_equals` | Not equal |
|
|
222
|
-
| `contains` | String contains substring |
|
|
223
|
-
| `not_contains` | String does not contain substring |
|
|
224
|
-
| `starts_with` | String starts with prefix |
|
|
225
|
-
| `ends_with` | String ends with suffix |
|
|
226
|
-
| `matches` | Regex pattern match |
|
|
227
|
-
| `greater_than` | Numeric greater than |
|
|
228
|
-
| `less_than` | Numeric less than |
|
|
229
|
-
| `in` | Value in list |
|
|
230
|
-
| `not_in` | Value not in list |
|
|
231
|
-
|
|
232
|
-
## Provider Integration
|
|
233
|
-
|
|
234
|
-
### OpenAI
|
|
235
|
-
|
|
236
|
-
```typescript
|
|
237
|
-
import { Veto, toOpenAITools, fromOpenAIToolCall } from 'veto';
|
|
238
|
-
|
|
239
|
-
const veto = await Veto.init();
|
|
240
|
-
const { definitions, implementations } = veto.wrapTools(myTools);
|
|
241
|
-
|
|
242
|
-
// Pass definitions to OpenAI
|
|
243
|
-
const response = await openai.chat.completions.create({
|
|
244
|
-
model: 'gpt-4',
|
|
245
|
-
tools: toOpenAITools(definitions),
|
|
246
|
-
messages: [...]
|
|
247
|
-
});
|
|
248
|
-
|
|
249
|
-
// Execute tool calls using implementations
|
|
250
|
-
for (const call of response.choices[0].message.tool_calls ?? []) {
|
|
251
|
-
const args = JSON.parse(call.function.arguments);
|
|
252
|
-
try {
|
|
253
|
-
const result = await implementations[call.function.name](args);
|
|
254
|
-
console.log('Result:', result);
|
|
255
|
-
} catch (error) {
|
|
256
|
-
if (error instanceof ToolCallDeniedError) {
|
|
257
|
-
console.log('Blocked:', error.reason);
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
### Anthropic
|
|
264
|
-
|
|
265
|
-
```typescript
|
|
266
|
-
import { Veto, toAnthropicTools, fromAnthropicToolUse } from 'veto';
|
|
267
|
-
|
|
268
|
-
const veto = await Veto.init();
|
|
269
|
-
const { definitions, implementations } = veto.wrapTools(myTools);
|
|
270
|
-
|
|
271
|
-
// Pass definitions to Anthropic
|
|
272
|
-
const response = await anthropic.messages.create({
|
|
273
|
-
model: 'claude-3-opus-20240229',
|
|
274
|
-
tools: toAnthropicTools(definitions),
|
|
275
|
-
messages: [...]
|
|
276
|
-
});
|
|
277
|
-
|
|
278
|
-
// Execute tool calls using implementations
|
|
279
|
-
for (const block of response.content) {
|
|
280
|
-
if (block.type === 'tool_use') {
|
|
281
|
-
try {
|
|
282
|
-
const result = await implementations[block.name](block.input);
|
|
283
|
-
console.log('Result:', result);
|
|
284
|
-
} catch (error) {
|
|
285
|
-
if (error instanceof ToolCallDeniedError) {
|
|
286
|
-
console.log('Blocked:', error.reason);
|
|
287
|
-
}
|
|
288
|
-
}
|
|
289
|
-
}
|
|
290
|
-
}
|
|
291
|
-
```
|
|
292
|
-
|
|
293
108
|
## API Reference
|
|
294
109
|
|
|
295
|
-
### Veto.init(options?)
|
|
110
|
+
### `Veto.init(options?)`
|
|
296
111
|
|
|
297
|
-
Initialize Veto
|
|
112
|
+
Initialize Veto. Loads configuration from `./veto` by default.
|
|
298
113
|
|
|
299
114
|
```typescript
|
|
300
115
|
const veto = await Veto.init();
|
|
301
|
-
|
|
302
|
-
// With options
|
|
303
|
-
const veto = await Veto.init({
|
|
304
|
-
configDir: './my-veto-config',
|
|
305
|
-
mode: 'log',
|
|
306
|
-
logLevel: 'debug'
|
|
307
|
-
});
|
|
308
116
|
```
|
|
309
117
|
|
|
310
|
-
### veto.
|
|
118
|
+
### `veto.wrap<T>(tools: T[]): T[]`
|
|
311
119
|
|
|
312
|
-
|
|
120
|
+
Wraps an array of tools. The returned tools have Veto validation injected into their execution handler. Preserves the original tool types for full compatibility with your AI framework.
|
|
313
121
|
|
|
314
122
|
```typescript
|
|
315
|
-
const
|
|
316
|
-
|
|
317
|
-
// definitions: Tool schemas to pass to AI models (no handlers)
|
|
318
|
-
// implementations: Object with wrapped handler functions keyed by tool name
|
|
123
|
+
const wrappedForLangChain = veto.wrap(langChainTools);
|
|
124
|
+
const wrappedForVercel = veto.wrap(vercelTools);
|
|
319
125
|
```
|
|
320
126
|
|
|
321
|
-
### veto.
|
|
127
|
+
### `veto.wrapTool<T>(tool: T): T`
|
|
322
128
|
|
|
323
|
-
|
|
129
|
+
Wraps a single tool instance.
|
|
324
130
|
|
|
325
131
|
```typescript
|
|
326
|
-
const
|
|
327
|
-
id: 'call_123',
|
|
328
|
-
name: 'read_file',
|
|
329
|
-
arguments: { path: '/some/path' }
|
|
330
|
-
});
|
|
331
|
-
|
|
332
|
-
if (result.allowed) {
|
|
333
|
-
// Execute
|
|
334
|
-
}
|
|
132
|
+
const safeTool = veto.wrapTool(myTool);
|
|
335
133
|
```
|
|
336
134
|
|
|
337
|
-
### veto.
|
|
135
|
+
### `veto.getHistoryStats()`
|
|
338
136
|
|
|
339
|
-
|
|
137
|
+
Returns statistics about allowed vs blocked calls.
|
|
340
138
|
|
|
341
139
|
```typescript
|
|
342
|
-
const
|
|
140
|
+
const stats = veto.getHistoryStats();
|
|
141
|
+
console.log(stats);
|
|
142
|
+
// { totalCalls: 5, allowedCalls: 4, deniedCalls: 1, ... }
|
|
343
143
|
```
|
|
344
144
|
|
|
345
|
-
### veto.
|
|
145
|
+
### `veto.clearHistory()`
|
|
346
146
|
|
|
347
|
-
|
|
147
|
+
Resets the history statistics.
|
|
348
148
|
|
|
349
149
|
```typescript
|
|
350
|
-
|
|
150
|
+
veto.clearHistory();
|
|
351
151
|
```
|
|
352
152
|
|
|
353
153
|
## CLI Commands
|
|
@@ -355,17 +155,49 @@ const rules = veto.getLoadedRules();
|
|
|
355
155
|
| Command | Description |
|
|
356
156
|
|---------|-------------|
|
|
357
157
|
| `npx veto init` | Initialize Veto in current directory |
|
|
358
|
-
| `npx veto init --force` | Reinitialize, overwriting existing files |
|
|
359
|
-
| `npx veto help` | Show help |
|
|
360
158
|
| `npx veto version` | Show version |
|
|
361
159
|
|
|
362
|
-
##
|
|
160
|
+
## General Rule YAML Format
|
|
161
|
+
|
|
162
|
+
Each rule file (e.g., `veto/rules/policy.yaml`) can contain one or more rules.
|
|
163
|
+
|
|
164
|
+
```yaml
|
|
165
|
+
rules:
|
|
166
|
+
- id: unique-rule-id # [Required] Unique identifier for the rule
|
|
167
|
+
name: Human readable name # [Required] Descriptive name for logging
|
|
168
|
+
enabled: true # [Optional] Default: true
|
|
169
|
+
severity: high # [Optional] critical, high, medium, low, info. Default: medium
|
|
170
|
+
action: block # [Required] block, warn, log, allow.
|
|
171
|
+
|
|
172
|
+
# Scope: Which tools does this rule apply to?
|
|
173
|
+
tools: # [Optional] List of tool names.
|
|
174
|
+
- make_payment # If omitted or empty, applies to ALL tools (Global Rule).
|
|
175
|
+
|
|
176
|
+
# Static Conditions (Optional):
|
|
177
|
+
# Evaluated locally before LLM validation. Fast checks for specific values.
|
|
178
|
+
conditions:
|
|
179
|
+
- field: arguments.amount # Dot notation for nested arguments
|
|
180
|
+
operator: greater_than # equals, contains, starts_with, ends_with, greater_than, less_than
|
|
181
|
+
value: 1000
|
|
182
|
+
|
|
183
|
+
# description (Optional):
|
|
184
|
+
# Natural language guidance for the validation LLM.
|
|
185
|
+
description: "Ensure the payment recipient is a verified vendor."
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
## Rule Matching Logic
|
|
189
|
+
|
|
190
|
+
Veto uses a two-step process to determine if a tool call is safe:
|
|
191
|
+
|
|
192
|
+
### 1. Rule Selection (Which rules apply?)
|
|
193
|
+
Veto selects rules based on the `tools` list in your YAML:
|
|
194
|
+
* **Tool-Specific Rules**: If a rule lists specific tools (e.g., `tools: [make_payment]`), it ONLY applies when those tools are called.
|
|
195
|
+
* **Global Rules**: If `tools` is missing or empty `[]`, the rule activates for **EVERY** tool call. Use this for universal policies (e.g., "Do not reveal internal file paths").
|
|
363
196
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
| `VETO_AGENT_ID` | Agent ID for tracking |
|
|
197
|
+
### 2. Validation Execution
|
|
198
|
+
For each intercepted tool call, Veto aggregates all applicable rules (Global + Specific) and validates them:
|
|
199
|
+
* **Static Conditions**: If `conditions` are defined, they are checked first by the Validation Engine. If a condition matches (e.g., `amount > 1000`), the rule triggers immediately.
|
|
200
|
+
* **Semantic Validation**: If no static conditions are matched (or none exist), the rule's `name` and `description` are passed to the LLM (via API, Kernel, or Custom provider) to semantically verify if the tool call violates the rule context.
|
|
369
201
|
|
|
370
202
|
## License
|
|
371
203
|
|
package/dist/cli/templates.d.ts
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
/**
|
|
7
7
|
* Default veto.config.yaml content.
|
|
8
8
|
*/
|
|
9
|
-
export declare const DEFAULT_CONFIG = "# Veto Configuration\n# See README.md for documentation\n\nversion: \"1.0\"\n\n# Operating mode:\n# \"strict\" - Block tool calls when validation fails\n# \"log\" - Only log validation failures, allow calls to proceed\nmode: \"strict\"\n\n# Validation API endpoint (
|
|
9
|
+
export declare const DEFAULT_CONFIG = "# Veto Configuration\n# See README.md for documentation\n\nversion: \"1.0\"\n\n# Operating mode:\n# \"strict\" - Block tool calls when validation fails\n# \"log\" - Only log validation failures, allow calls to proceed\nmode: \"strict\"\n\n# Validation mode:\n# \"api\" - Use external HTTP API (default)\n# \"kernel\" - Use local Ollama model\n# \"custom\" - Use specified LLM provider\nvalidation:\n mode: \"api\"\n\n# Validation API endpoint (for mode: \"api\")\napi:\n baseUrl: \"http://localhost:8080\"\n endpoint: \"/tool/call/check\"\n timeout: 10000\n retries: 2\n retryDelay: 1000\n\n# Kernel configuration (for mode: \"kernel\")\n# kernel:\n# baseUrl: \"http://localhost:11434/v1\"\n# model: \"hf.co/ycaleb/veto-warden-4b-GGUF:Q4_K_M\"\n# temperature: 0.1\n# maxTokens: 256\n\n# Custom LLM provider (for mode: \"custom\")\n# custom:\n# provider: \"openai\" # openai | anthropic | gemini | openrouter\n# model: \"gpt-4o\"\n# # apiKey: \"sk-...\" # Or set OPENAI_API_KEY env var\n# temperature: 0.1\n# maxTokens: 500\n# # baseUrl: \"https://api.openai.com/v1\" # Optional override\n\n# Logging\nlogging:\n level: \"info\" # debug, info, warn, error, silent\n\n# Rules configuration\nrules:\n directory: \"./rules\"\n recursive: true\n";
|
|
10
10
|
/**
|
|
11
11
|
* Default rules/defaults.yaml content.
|
|
12
12
|
*/
|
|
@@ -18,5 +18,5 @@ export declare const GITIGNORE_ADDITIONS = "\n# Veto\nveto/.env\nveto/*.local.ya
|
|
|
18
18
|
/**
|
|
19
19
|
* Example .env file content.
|
|
20
20
|
*/
|
|
21
|
-
export declare const ENV_EXAMPLE = "# Veto Environment Variables\n# Copy this to .env and fill in values\n\n# Override log level (debug, info, warn, error, silent)\n# VETO_LOG_LEVEL=debug\n\n# Session/Agent tracking (optional)\n# VETO_SESSION_ID=\n# VETO_AGENT_ID=\n";
|
|
21
|
+
export declare const ENV_EXAMPLE = "# Veto Environment Variables\n# Copy this to .env and fill in values\n\n# Override log level (debug, info, warn, error, silent)\n# VETO_LOG_LEVEL=debug\n\n# Session/Agent tracking (optional)\n# VETO_SESSION_ID=\n# VETO_AGENT_ID=\n\n# Custom LLM Provider API Keys (for validation.mode: \"custom\")\n# OPENAI_API_KEY=sk-...\n# ANTHROPIC_API_KEY=sk-ant-...\n# GEMINI_API_KEY=...\n# OPENROUTER_API_KEY=sk-or-...\n";
|
|
22
22
|
//# sourceMappingURL=templates.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/cli/templates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc
|
|
1
|
+
{"version":3,"file":"templates.d.ts","sourceRoot":"","sources":["../../src/cli/templates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,eAAO,MAAM,cAAc,8wCAiD1B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,aAAa,oqDAuEzB,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,mBAAmB,6CAI/B,CAAC;AAEF;;GAEG;AACH,eAAO,MAAM,WAAW,8ZAevB,CAAC"}
|
package/dist/cli/templates.js
CHANGED
|
@@ -16,7 +16,14 @@ version: "1.0"
|
|
|
16
16
|
# "log" - Only log validation failures, allow calls to proceed
|
|
17
17
|
mode: "strict"
|
|
18
18
|
|
|
19
|
-
# Validation
|
|
19
|
+
# Validation mode:
|
|
20
|
+
# "api" - Use external HTTP API (default)
|
|
21
|
+
# "kernel" - Use local Ollama model
|
|
22
|
+
# "custom" - Use specified LLM provider
|
|
23
|
+
validation:
|
|
24
|
+
mode: "api"
|
|
25
|
+
|
|
26
|
+
# Validation API endpoint (for mode: "api")
|
|
20
27
|
api:
|
|
21
28
|
baseUrl: "http://localhost:8080"
|
|
22
29
|
endpoint: "/tool/call/check"
|
|
@@ -24,6 +31,22 @@ api:
|
|
|
24
31
|
retries: 2
|
|
25
32
|
retryDelay: 1000
|
|
26
33
|
|
|
34
|
+
# Kernel configuration (for mode: "kernel")
|
|
35
|
+
# kernel:
|
|
36
|
+
# baseUrl: "http://localhost:11434/v1"
|
|
37
|
+
# model: "hf.co/ycaleb/veto-warden-4b-GGUF:Q4_K_M"
|
|
38
|
+
# temperature: 0.1
|
|
39
|
+
# maxTokens: 256
|
|
40
|
+
|
|
41
|
+
# Custom LLM provider (for mode: "custom")
|
|
42
|
+
# custom:
|
|
43
|
+
# provider: "openai" # openai | anthropic | gemini | openrouter
|
|
44
|
+
# model: "gpt-4o"
|
|
45
|
+
# # apiKey: "sk-..." # Or set OPENAI_API_KEY env var
|
|
46
|
+
# temperature: 0.1
|
|
47
|
+
# maxTokens: 500
|
|
48
|
+
# # baseUrl: "https://api.openai.com/v1" # Optional override
|
|
49
|
+
|
|
27
50
|
# Logging
|
|
28
51
|
logging:
|
|
29
52
|
level: "info" # debug, info, warn, error, silent
|
|
@@ -128,5 +151,11 @@ export const ENV_EXAMPLE = `# Veto Environment Variables
|
|
|
128
151
|
# Session/Agent tracking (optional)
|
|
129
152
|
# VETO_SESSION_ID=
|
|
130
153
|
# VETO_AGENT_ID=
|
|
154
|
+
|
|
155
|
+
# Custom LLM Provider API Keys (for validation.mode: "custom")
|
|
156
|
+
# OPENAI_API_KEY=sk-...
|
|
157
|
+
# ANTHROPIC_API_KEY=sk-ant-...
|
|
158
|
+
# GEMINI_API_KEY=...
|
|
159
|
+
# OPENROUTER_API_KEY=sk-or-...
|
|
131
160
|
`;
|
|
132
161
|
//# sourceMappingURL=templates.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/cli/templates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG
|
|
1
|
+
{"version":3,"file":"templates.js","sourceRoot":"","sources":["../../src/cli/templates.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH;;GAEG;AACH,MAAM,CAAC,MAAM,cAAc,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAiD7B,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAuE5B,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG;;;;CAIlC,CAAC;AAEF;;GAEG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG;;;;;;;;;;;;;;;CAe1B,CAAC"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Veto Cloud API client.
|
|
3
|
+
*
|
|
4
|
+
* Handles communication with the Veto Cloud API for:
|
|
5
|
+
* - Tool registration (sends tool signatures for policy template generation)
|
|
6
|
+
* - Tool call validation (validates tool calls against cloud-managed policies)
|
|
7
|
+
* - Approval polling (polls approval records until resolved)
|
|
8
|
+
*
|
|
9
|
+
* @module cloud/client
|
|
10
|
+
*/
|
|
11
|
+
import type { Logger } from '../utils/logger.js';
|
|
12
|
+
import type { VetoCloudConfig, CloudToolRegistration, CloudToolRegistrationResponse, CloudValidationResponse, ApprovalData, ApprovalPollOptions } from './types.js';
|
|
13
|
+
export interface VetoCloudClientOptions {
|
|
14
|
+
config?: VetoCloudConfig;
|
|
15
|
+
logger: Logger;
|
|
16
|
+
}
|
|
17
|
+
export declare class VetoCloudClient {
|
|
18
|
+
private readonly config;
|
|
19
|
+
private readonly logger;
|
|
20
|
+
private readonly registeredTools;
|
|
21
|
+
constructor(options: VetoCloudClientOptions);
|
|
22
|
+
private resolveConfig;
|
|
23
|
+
private getHeaders;
|
|
24
|
+
registerTools(tools: CloudToolRegistration[]): Promise<CloudToolRegistrationResponse>;
|
|
25
|
+
validate(toolName: string, args: Record<string, unknown>, context?: Record<string, unknown>): Promise<CloudValidationResponse>;
|
|
26
|
+
pollApproval(approvalId: string, options?: ApprovalPollOptions): Promise<ApprovalData>;
|
|
27
|
+
isToolRegistered(toolName: string): boolean;
|
|
28
|
+
clearRegistrationCache(): void;
|
|
29
|
+
private fetchWithTimeout;
|
|
30
|
+
private delay;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Error thrown when an approval poll times out.
|
|
34
|
+
*/
|
|
35
|
+
export declare class ApprovalTimeoutError extends Error {
|
|
36
|
+
readonly approvalId: string;
|
|
37
|
+
readonly timeoutMs: number;
|
|
38
|
+
constructor(approvalId: string, timeoutMs: number);
|
|
39
|
+
}
|
|
40
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/cloud/client.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EACV,eAAe,EAEf,qBAAqB,EACrB,6BAA6B,EAC7B,uBAAuB,EACvB,YAAY,EACZ,mBAAmB,EACpB,MAAM,YAAY,CAAC;AAEpB,MAAM,WAAW,sBAAsB;IACrC,MAAM,CAAC,EAAE,eAAe,CAAC;IACzB,MAAM,EAAE,MAAM,CAAC;CAChB;AAID,qBAAa,eAAe;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAsB;IAC7C,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,eAAe,CAAqB;gBAEzC,OAAO,EAAE,sBAAsB;IAK3C,OAAO,CAAC,aAAa;IAUrB,OAAO,CAAC,UAAU;IAUZ,aAAa,CACjB,KAAK,EAAE,qBAAqB,EAAE,GAC7B,OAAO,CAAC,6BAA6B,CAAC;IAwFnC,QAAQ,CACZ,QAAQ,EAAE,MAAM,EAChB,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC7B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAChC,OAAO,CAAC,uBAAuB,CAAC;IAuF7B,YAAY,CAChB,UAAU,EAAE,MAAM,EAClB,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,YAAY,CAAC;IAqDxB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAI3C,sBAAsB,IAAI,IAAI;YAIhB,gBAAgB;IAuB9B,OAAO,CAAC,KAAK;CAGd;AAED;;GAEG;AACH,qBAAa,oBAAqB,SAAQ,KAAK;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;gBAEf,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM;CAQlD"}
|