Skip to content

Commit cd34987

Browse files
authored
Merge pull request #2 from riligar/2025-04-20_guardrails
fix: Guardrails
2 parents 4d10b6d + e208a9d commit cd34987

File tree

5 files changed

+78
-161
lines changed

5 files changed

+78
-161
lines changed

examples/guardrail.js

Lines changed: 26 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -2,62 +2,33 @@
22
const { Agent, Runner, Tool, Guardrail } = require('../src/index');
33

44
// Create an input guardrail that checks if the input contains inappropriate content
5-
const inappropriateContentGuardrail = new Guardrail.InputGuardrail({
5+
const inappropriateContentGuardrail = new Guardrail.Input({
66
name: "inappropriate_content_filter",
77
check: async (context, agent, input) => {
8+
89
// In a real implementation, you might use a content moderation API
910
// Here we're just doing a simple check for demonstration
10-
const message = typeof input === 'string' ? input :
11-
(input[0]?.content || '');
11+
const message = typeof input === 'string' ? input : (input[0]?.content || '');
1212

1313
const inappropriateWords = ['hate', 'violence', 'explicit'];
1414
const containsInappropriate = inappropriateWords.some(word =>
1515
message.toLowerCase().includes(word)
1616
);
1717

18-
return {
19-
output_info: {
20-
checked_for: "inappropriate content",
21-
found: containsInappropriate ? "yes" : "no"
22-
},
23-
tripwire_triggered: containsInappropriate
24-
};
18+
return containsInappropriate;
2519
}
2620
});
2721

2822
// Create an output guardrail that ensures the response isn't too short
29-
const minimumLengthGuardrail = new Guardrail.OutputGuardrail({
23+
const minimumLengthGuardrail = new Guardrail.Output({
3024
name: "minimum_length_check",
3125
check: async (context, agent, output) => {
3226
const minimumLength = 20; // characters
3327

34-
// Safely handle null/undefined output
35-
if (!output) {
36-
return {
37-
output_info: {
38-
checked_for: "minimum length",
39-
required_length: minimumLength,
40-
actual_length: 0,
41-
is_too_short: true,
42-
error: "Output is null or undefined"
43-
},
44-
tripwire_triggered: true
45-
};
46-
}
47-
48-
// Convert output to string if it isn't already
4928
const outputStr = String(output);
5029
const isTooShort = outputStr.length < minimumLength;
5130

52-
return {
53-
output_info: {
54-
checked_for: "minimum length",
55-
required_length: minimumLength,
56-
actual_length: outputStr.length,
57-
is_too_short: isTooShort
58-
},
59-
tripwire_triggered: isTooShort
60-
};
31+
return isTooShort;
6132
}
6233
});
6334

@@ -86,45 +57,32 @@ async function main() {
8657
name: "Guarded Assistant",
8758
instructions: "You are a helpful assistant that provides detailed and thoughtful responses.",
8859
tools: [getWeather],
89-
inputGuardrails: [inappropriateContentGuardrail],
90-
outputGuardrails: [minimumLengthGuardrail]
60+
guardrails: { input: [inappropriateContentGuardrail], output: [minimumLengthGuardrail] }
9161
});
9262

93-
try {
94-
// Example 1: Normal input (should work fine)
95-
console.log("Example 1: Normal input");
96-
const result1 = await Runner.run(agent, "Tell me about the weather in Paris");
97-
console.log("Final output:", result1.finalOutput);
98-
console.log("Input guardrail results:", JSON.stringify(result1.inputGuardrailResults, null, 2));
99-
console.log("Output guardrail results:", JSON.stringify(result1.outputGuardrailResults, null, 2));
63+
const tooShortAgent = new Agent({
64+
name: "Brief Assistant",
65+
instructions: "You are an assistant that gives very brief, one-word answers whenever possible.",
66+
guardrails: { output: [minimumLengthGuardrail] }
67+
});
10068

101-
// Example 2: Input that should trigger the input guardrail
102-
console.log("\nExample 2: Inappropriate input");
103-
try {
104-
const result2 = await Runner.run(agent, "I hate the weather in London");
105-
console.log("Final output:", result2.finalOutput);
106-
} catch (error) {
107-
console.log("Error (expected):", error.message);
108-
}
10969

110-
// Example 3: Create an agent that might generate short outputs
111-
const tooShortAgent = new Agent({
112-
name: "Brief Assistant",
113-
instructions: "You are an assistant that gives very brief, one-word answers whenever possible.",
114-
outputGuardrails: [minimumLengthGuardrail]
115-
});
70+
// Example 1: Normal input (should work fine)
71+
console.log("Example 1: Normal input");
72+
const result1 = await Runner.run(agent, "Tell me about the weather in Paris");
73+
console.log("Final output:", result1.finalOutput);
74+
console.log("Guardrails results:", JSON.stringify(result1.guardrails, null, 2));
11675

117-
console.log("\nExample 3: Testing output guardrail");
118-
try {
119-
const result3 = await Runner.run(tooShortAgent, "What color is the sky?");
120-
console.log("Final output:", result3.finalOutput);
121-
} catch (error) {
122-
console.log("Error (expected):", error.message);
123-
}
76+
// Example 2: Input that should trigger the input guardrail
77+
console.log("\nExample 2: Inappropriate input");
78+
const result2 = await Runner.run(agent, "I hate the weather in London");
79+
console.log("Final output:", result2.finalOutput);
80+
console.log("Guardrails results:", JSON.stringify(result2.guardrails, null, 2));
12481

125-
} catch (error) {
126-
console.error("Unexpected error:", error);
127-
}
82+
// Example 3: Create an agent that might generate short outputs
83+
const result3 = await Runner.run(tooShortAgent, "What color is the sky?");
84+
console.log("Final output:", result3.finalOutput);
85+
console.log("Guardrails results:", JSON.stringify(result3.guardrails, null, 2));
12886
}
12987

13088
main().catch(console.error);

src/agent.js

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@ class Agent {
1616
* @param {Object} [config.providerConfig={}] - Provider-specific configuration
1717
* @param {string} [config.model='gpt-4'] - The model to use
1818
* @param {Object} [config.modelSettings={}] - Settings for the model (temperature, etc.)
19-
* @param {Array} [config.inputGuardrails=[]] - Guardrails for input validation
20-
* @param {Array} [config.outputGuardrails=[]] - Guardrails for output validation
19+
* @param {Array} [config.guardrails=[]] - Guardrails para validação de input e output
2120
* @param {Object} [config.outputType=null] - Type definition for structured output
2221
* @param {Array} [config.mcpServers=[]] - URLs dos servidores MCP
2322
*/
@@ -30,8 +29,7 @@ class Agent {
3029
providerConfig = {},
3130
model = 'gpt-4.1-nano',
3231
modelSettings = {},
33-
inputGuardrails = [],
34-
outputGuardrails = [],
32+
guardrails = { input: [], output: [] },
3533
outputType = null,
3634
handoffDescription = null
3735
}) {
@@ -46,15 +44,15 @@ class Agent {
4644
top_p: 1,
4745
...modelSettings
4846
};
49-
this.inputGuardrails = inputGuardrails;
50-
this.outputGuardrails = outputGuardrails;
47+
this.guardrails = guardrails;
5148
this.outputType = outputType;
5249
this.handoffDescription = handoffDescription;
5350

5451
// Inicializa MCPManager se houver MCPs
5552
this.mcpServers = Array.isArray(arguments[0]?.mcpServers) ? arguments[0].mcpServers : [];
5653
this.mcpManager = this.mcpServers.length > 0 ? new MCPManager(this.mcpServers) : null;
5754

55+
5856
// Initialize the provider
5957
this.llmProvider = this.initializeProvider(provider, {
6058
...providerConfig,
@@ -109,7 +107,7 @@ class Agent {
109107
* @returns {LLMProvider} - Initialized provider instance
110108
*/
111109
initializeProvider(provider, config) {
112-
console.log('Initializing provider:', provider, config);
110+
// console.log('Initializing provider:', provider, config);
113111
switch (provider.toLowerCase()) {
114112
case 'openai':
115113
return new OpenAIProvider(config);
@@ -131,8 +129,7 @@ class Agent {
131129
handoffs: this.handoffs,
132130
model: this.model,
133131
modelSettings: this.modelSettings,
134-
inputGuardrails: this.inputGuardrails,
135-
outputGuardrails: this.outputGuardrails,
132+
guardrails: this.guardrails,
136133
outputType: this.outputType,
137134
handoffDescription: this.handoffDescription,
138135
...newProps

src/guardrail.js

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,14 @@
55
* @param {Function} options.check - Function that checks the input
66
* @returns {Object} - An input guardrail object
77
*/
8-
class InputGuardrail {
8+
class Input {
99
constructor({ name, check }) {
1010
this.name = name;
1111
this.check = check;
1212
}
1313

1414
async run(agent, input, context) {
15-
const output = await this.check(context, agent, input);
16-
return {
17-
guardrail: { name: this.name },
18-
output
19-
};
15+
return await this.check(context, agent, input);
2016
}
2117
}
2218

@@ -27,21 +23,15 @@ class InputGuardrail {
2723
* @param {Function} options.check - Function that checks the output
2824
* @returns {Object} - An output guardrail object
2925
*/
30-
class OutputGuardrail {
26+
class Output {
3127
constructor({ name, check }) {
3228
this.name = name;
3329
this.check = check;
3430
}
3531

3632
async run(agent, output, context) {
37-
const result = await this.check(context, agent, output);
38-
return {
39-
guardrail: { name: this.name },
40-
agentOutput: output,
41-
agent,
42-
output: result
43-
};
33+
return await this.check(context, agent, output);
4434
}
4535
}
4636

47-
module.exports = { InputGuardrail, OutputGuardrail };
37+
module.exports = { Input, Output };

src/result.js

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,17 +17,16 @@ class RunResult {
1717
messages,
1818
finalOutput,
1919
lastAgent,
20-
inputGuardrailResults = [],
21-
outputGuardrailResults = []
20+
guardrails = {
21+
input: [],
22+
output: []
23+
}
2224
}) {
2325
this.input = input;
2426
this.messages = messages;
2527
this.finalOutput = finalOutput;
2628
this.lastAgent = lastAgent;
27-
this.guardrails = {
28-
input: inputGuardrailResults,
29-
output: outputGuardrailResults
30-
};
29+
this.guardrails = guardrails;
3130
}
3231
}
3332

0 commit comments

Comments
 (0)