Files
wehub-resource-sync 3cd11ababe
Check Markdown links / linkChecker (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:38:56 +08:00

112 lines
2.8 KiB
TypeScript

import {
HookEventType,
PluginContext,
PluginHandler,
PluginParameters,
} from '../types';
import { post, getText, HttpError } from '../utils';
import { VERSION } from './version';
export const handler: PluginHandler = async (
context: PluginContext,
parameters: PluginParameters,
eventType: HookEventType
) => {
let error = null;
let verdict = true;
let data = null;
if (!parameters.credentials?.domain) {
return {
error: `'parameters.credentials.domain' must be set`,
verdict: true,
data,
};
}
if (!parameters.credentials?.apiKey) {
return {
error: `'parameters.credentials.apiKey' must be set`,
verdict: true,
data,
};
}
// TODO: Update to v1 once released
const url = `https://ai-guard.${parameters.credentials.domain}/v1/text/guard`;
const text = getText(context, eventType);
if (!text) {
return {
error: 'request or response text is empty',
verdict: true,
data,
};
}
const requestOptions = {
headers: {
'Content-Type': 'application/json',
'User-Agent': 'portkey-ai-plugin/' + VERSION,
Authorization: `Bearer ${parameters.credentials.apiKey}`,
},
};
// Avoid sending empty strings
const recipe = parameters.recipe ? parameters.recipe : undefined;
const request = {
text: text,
recipe: recipe,
debug: parameters.debug,
overrides: parameters.overrides,
};
let response;
try {
response = await post(url, request, requestOptions, parameters.timeout);
} catch (e) {
if (e instanceof HttpError) {
error = `${e.message}. body: ${e.response.body}`;
} else {
error = e as Error;
}
}
if (response) {
if (response.status == 'Success') {
data = response.result;
const detectors = data.detectors;
if (
detectors?.prompt_injection?.detected ||
detectors?.pii_entity?.detected ||
detectors?.malicious_entity?.detected ||
detectors?.custom_entity?.detected ||
detectors?.secrets_detection?.detected ||
detectors?.profanity_and_toxicity?.detected
) {
verdict = false;
}
} else {
error = errorToString(response);
}
}
return {
error, // or error object if an error occurred
verdict, // or false to indicate if the guardrail passed or failed
data, // any additional data you want to return
};
};
function errorToString(response: any): string {
let ret = `Summary: ${response.summary}\n`;
ret += `status: ${response.status}\n`;
ret += `request_id: ${response.request_id}\n`;
ret += `request_time: ${response.request_time}\n`;
ret += `response_time: ${response.response_time}\n`;
(response.result?.errors || []).forEach((ef: any) => {
ret += `\t${ef.source} ${ef.code}: ${ef.detail}\n`;
});
return ret;
}