Skip to content

Commit

Permalink
Merge pull request #904 from Portkey-AI/chore/return-transformed-flag…
Browse files Browse the repository at this point in the history
…-in-redaction-check-result

Chore: return transformed flag in redaction check result
  • Loading branch information
VisargD authored Jan 30, 2025
2 parents bb5859d + 3cbcad2 commit a10d0ca
Show file tree
Hide file tree
Showing 15 changed files with 101 additions and 29 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -141,3 +141,4 @@ build
.idea
plugins/**/.creds.json
plugins/**/creds.json
plugins/**/.parameters.json
44 changes: 26 additions & 18 deletions plugins/bedrock/bedrock.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@ import { HookEventType, PluginContext, PluginParameters } from '../types';
import { pluginHandler } from './index';
import testCreds from './.creds.json';
import { BedrockParameters } from './type';
import parametersCreds from './.parameters.json';

/**
* @example Parameters object
*
* {
"credentials": {
"accessKeyId": "keyId",
"accessKeySecret": "keysecret",
"region": "us-east-1"
"awsAccessKeyId": "keyId",
"awsSecretAccessKey": "keysecret",
"awsRegion": "us-east-1"
},
"guardrailId": "xyxyxyx",
"guardrailVersion": "1"
Expand Down Expand Up @@ -53,6 +54,7 @@ describe('Credentials check', () => {
expect(result.verdict).toBe(true);
expect(result.error).toBeDefined();
expect(result.data).toBeNull();
expect(result.transformed).toBe(false);
});

test('Should fail with wrong creds', async () => {
Expand Down Expand Up @@ -91,6 +93,7 @@ describe('Credentials check', () => {
expect(result.verdict).toBe(true);
expect(result.error).toBeDefined();
expect(result.data).toBeNull();
expect(result.transformed).toBe(false);
});

it('should only detect PII', async () => {
Expand All @@ -110,9 +113,9 @@ describe('Credentials check', () => {
requestType: 'chatComplete',
};
const parameters = {
credentials: testCreds,
guardrailId: testCreds.guardrailId,
guardrailVersion: testCreds.guardrailVersion,
credentials: testCreds as BedrockParameters['credentials'],
guardrailId: parametersCreds.guardrailId,
guardrailVersion: parametersCreds.guardrailVersion,
};

const result = await pluginHandler(
Expand All @@ -128,6 +131,7 @@ describe('Credentials check', () => {
expect(result.error).toBeNull();
expect(result.data).toBeDefined();
expect(result.transformedData?.request?.json).toBeNull();
expect(result.transformed).toBe(false);
});

it('should detect and redact PII in request text', async () => {
Expand All @@ -146,10 +150,10 @@ describe('Credentials check', () => {
requestType: 'chatComplete',
};
const parameters = {
credentials: testCreds,
credentials: testCreds as BedrockParameters['credentials'],
redact: true,
guardrailId: testCreds.guardrailId,
guardrailVersion: testCreds.guardrailVersion,
guardrailId: parametersCreds.guardrailId,
guardrailVersion: parametersCreds.guardrailVersion,
};

const result = await pluginHandler(
Expand All @@ -166,6 +170,7 @@ describe('Credentials check', () => {
expect(result.transformedData?.request?.json?.messages?.[0]?.content).toBe(
'My SSN is {US_SOCIAL_SECURITY_NUMBER} and some random text'
);
expect(result.transformed).toBe(true);
});

it('should detect and redact PII in request text with multiple content parts', async () => {
Expand Down Expand Up @@ -193,10 +198,10 @@ describe('Credentials check', () => {
requestType: 'chatComplete',
};
const parameters = {
credentials: testCreds,
credentials: testCreds as BedrockParameters['credentials'],
redact: true,
guardrailId: testCreds.guardrailId,
guardrailVersion: testCreds.guardrailVersion,
guardrailId: parametersCreds.guardrailId,
guardrailVersion: parametersCreds.guardrailVersion,
};

const result = await pluginHandler(
Expand All @@ -217,6 +222,7 @@ describe('Credentials check', () => {
expect(
result.transformedData?.request?.json?.messages?.[0]?.content?.[1]?.text
).toBe('My SSN is {US_SOCIAL_SECURITY_NUMBER} and some random text');
expect(result.transformed).toBe(true);
});

it('should detect and redact PII in response text', async () => {
Expand All @@ -237,10 +243,10 @@ describe('Credentials check', () => {
requestType: 'chatComplete',
};
const parameters = {
credentials: testCreds,
credentials: testCreds as BedrockParameters['credentials'],
redact: true,
guardrailId: testCreds.guardrailId,
guardrailVersion: testCreds.guardrailVersion,
guardrailId: parametersCreds.guardrailId,
guardrailVersion: parametersCreds.guardrailVersion,
};

const result = await pluginHandler(
Expand All @@ -258,6 +264,7 @@ describe('Credentials check', () => {
expect(
result.transformedData?.response?.json?.choices?.[0]?.message?.content
).toBe('My SSN is {US_SOCIAL_SECURITY_NUMBER} and some random text');
expect(result.transformed).toBe(true);
});

it('should pass text without PII', async () => {
Expand All @@ -279,9 +286,9 @@ describe('Credentials check', () => {
requestType: 'chatComplete',
};
const parameters = {
credentials: testCreds,
guardrailId: testCreds.guardrailId,
guardrailVersion: testCreds.guardrailVersion,
credentials: testCreds as BedrockParameters['credentials'],
guardrailId: parametersCreds.guardrailId,
guardrailVersion: parametersCreds.guardrailVersion,
};

const result = await pluginHandler(
Expand All @@ -297,5 +304,6 @@ describe('Credentials check', () => {
expect(result.error).toBeNull();
expect(result.data).toBeDefined();
expect(result.transformedData?.response?.json).toBeNull();
expect(result.transformed).toBe(false);
});
});
6 changes: 6 additions & 0 deletions plugins/bedrock/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ export const pluginHandler: PluginHandler<
json: null,
},
};
let transformed = false;
const credentials = parameters.credentials;

const validate = validateCreds(credentials);
Expand All @@ -48,6 +49,8 @@ export const pluginHandler: PluginHandler<
verdict,
error: { message: 'Missing required credentials' },
data,
transformed,
transformedData,
};
}

Expand All @@ -68,6 +71,7 @@ export const pluginHandler: PluginHandler<
verdict: true,
data: null,
transformedData,
transformed,
};
}

Expand Down Expand Up @@ -118,6 +122,7 @@ export const pluginHandler: PluginHandler<
);

setCurrentContentPart(context, eventType, transformedData, maskedTexts);
transformed = true;
}

if (hasPii && flaggedCategories.size === 1 && redact) {
Expand All @@ -138,5 +143,6 @@ export const pluginHandler: PluginHandler<
error,
data,
transformedData,
transformed,
};
};
5 changes: 5 additions & 0 deletions plugins/pangea/pangea.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -235,6 +235,7 @@ describe('pii handler', () => {
expect(result.error).toBeNull();
expect(result.data).toBeDefined();
expect(result.transformedData?.request?.json).toBeNull();
expect(result.transformed).toBe(false);
});

it('should detect and redact PII in request text', async () => {
Expand Down Expand Up @@ -271,6 +272,7 @@ describe('pii handler', () => {
expect(result.transformedData?.request?.json?.messages?.[0]?.content).toBe(
'My email is <EMAIL_ADDRESS> and some random text'
);
expect(result.transformed).toBe(true);
});

it('should detect and redact PII in request text with multiple content parts', async () => {
Expand Down Expand Up @@ -320,6 +322,7 @@ describe('pii handler', () => {
expect(
result.transformedData?.request?.json?.messages?.[0]?.content?.[1]?.text
).toBe('My email is <EMAIL_ADDRESS> and some random text');
expect(result.transformed).toBe(true);
});

it('should detect and redact PII in response text', async () => {
Expand Down Expand Up @@ -359,6 +362,7 @@ describe('pii handler', () => {
expect(
result.transformedData?.response?.json?.choices?.[0]?.message?.content
).toBe('My email is <EMAIL_ADDRESS> and some random text');
expect(result.transformed).toBe(true);
});

it('should pass text without PII', async () => {
Expand Down Expand Up @@ -393,5 +397,6 @@ describe('pii handler', () => {
expect(result.verdict).toBe(true);
expect(result.error).toBeNull();
expect(result.data).toBeDefined();
expect(result.transformed).toBe(false);
});
});
10 changes: 10 additions & 0 deletions plugins/pangea/pii.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export const handler: PluginHandler = async (
json: null,
},
};
let transformed = false;
const redact = parameters.redact || false;

try {
Expand All @@ -29,6 +30,7 @@ export const handler: PluginHandler = async (
verdict: true,
data: null,
transformedData,
transformed,
};
}

Expand All @@ -37,6 +39,8 @@ export const handler: PluginHandler = async (
error: `'parameters.credentials.domain' must be set`,
verdict: true,
data: null,
transformedData,
transformed,
};
}

Expand All @@ -45,6 +49,8 @@ export const handler: PluginHandler = async (
error: `'parameters.credentials.apiKey' must be set`,
verdict: true,
data: null,
transformedData,
transformed,
};
}

Expand All @@ -58,6 +64,7 @@ export const handler: PluginHandler = async (
verdict: true,
data: null,
transformedData,
transformed,
};
}

Expand Down Expand Up @@ -87,6 +94,7 @@ export const handler: PluginHandler = async (
response.result.redacted_data
);
shouldBlock = false;
transformed = true;
}

return {
Expand All @@ -96,13 +104,15 @@ export const handler: PluginHandler = async (
summary: response.summary,
},
transformedData,
transformed,
};
} catch (e) {
return {
error: e as Error,
verdict: true,
data: null,
transformedData,
transformed,
};
}
};
12 changes: 11 additions & 1 deletion plugins/patronus/patronus.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { handler as piiHandler } from './pii';
import { handler as toxicityHandler } from './toxicity';
import { handler as retrievalAnswerRelevanceHandler } from './retrievalAnswerRelevance';
import { handler as customHandler } from './custom';
import { HookEventType, PluginContext } from '../types';
import { PluginContext } from '../types';

describe('phi handler', () => {
it('should pass when text is clean', async () => {
Expand Down Expand Up @@ -35,6 +35,7 @@ describe('phi handler', () => {
expect(result.verdict).toBe(true);
expect(result.error).toBeNull();
expect(result.data).toBeDefined();
expect(result.transformed).toBe(false);
});

it('should fail when text contains PHI', async () => {
Expand Down Expand Up @@ -67,6 +68,7 @@ describe('phi handler', () => {
expect(result.data).toBeDefined();
expect(result.transformedData?.response?.json).toBeNull();
expect(result.transformedData?.request?.json).toBeNull();
expect(result.transformed).toBe(false);
});

it('should detect and redact PII in request text', async () => {
Expand Down Expand Up @@ -104,6 +106,7 @@ describe('phi handler', () => {
expect(result.transformedData?.request?.json?.messages?.[0]?.content).toBe(
'J******e has a history of heart disease'
);
expect(result.transformed).toBe(true);
});

it('should detect and redact PII in request text with multiple content parts', async () => {
Expand Down Expand Up @@ -153,6 +156,7 @@ describe('phi handler', () => {
expect(
result.transformedData?.request?.json?.messages?.[0]?.content?.[1]?.text
).toBe('J******e has a history of heart disease and some random text');
expect(result.transformed).toBe(true);
});

it('should detect and redact PHI in response text', async () => {
Expand Down Expand Up @@ -193,6 +197,7 @@ describe('phi handler', () => {
expect(
result.transformedData?.response?.json?.choices?.[0]?.message?.content
).toBe('J******e has a history of heart disease and some random text');
expect(result.transformed).toBe(true);
});
});

Expand Down Expand Up @@ -225,6 +230,7 @@ describe('pii handler', () => {
expect(result.verdict).toBe(true);
expect(result.error).toBeNull();
expect(result.data).toBeDefined();
expect(result.transformed).toBe(false);
});

it('should fail when text contains PII', async () => {
Expand Down Expand Up @@ -257,6 +263,7 @@ describe('pii handler', () => {
expect(result.data).toBeDefined();
expect(result.transformedData?.response?.json).toBeNull();
expect(result.transformedData?.request?.json).toBeNull();
expect(result.transformed).toBe(false);
});

it('should detect and redact PII in request text', async () => {
Expand Down Expand Up @@ -294,6 +301,7 @@ describe('pii handler', () => {
expect(result.transformedData?.request?.json?.messages?.[0]?.content).toBe(
'My email is a*********m and some random text'
);
expect(result.transformed).toBe(true);
});

it('should detect and redact PII in request text with multiple content parts', async () => {
Expand Down Expand Up @@ -343,6 +351,7 @@ describe('pii handler', () => {
expect(
result.transformedData?.request?.json?.messages?.[0]?.content?.[1]?.text
).toBe('My email is a*********m and some random text');
expect(result.transformed).toBe(true);
});

it('should detect and redact PII in response text', async () => {
Expand Down Expand Up @@ -382,6 +391,7 @@ describe('pii handler', () => {
expect(
result.transformedData?.response?.json?.choices?.[0]?.message?.content
).toBe('My email is a*********m and some random text');
expect(result.transformed).toBe(true);
});
});

Expand Down
Loading

0 comments on commit a10d0ca

Please sign in to comment.