Skip to content

Commit 267a3e5

Browse files
authored
Merge pull request #986 from Portkey-AI/feat/default-guardrails
feat: add support for default guardrails
2 parents 68f0209 + 0dc320f commit 267a3e5

File tree

2 files changed

+62
-2
lines changed

2 files changed

+62
-2
lines changed

src/handlers/handlerUtils.ts

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -283,8 +283,14 @@ export async function tryPost(
283283
metadata,
284284
provider,
285285
isStreamingMode,
286-
providerOption.beforeRequestHooks || [],
287-
providerOption.afterRequestHooks || [],
286+
[
287+
...(providerOption.beforeRequestHooks || []),
288+
...(providerOption.defaultInputGuardrails || []),
289+
],
290+
[
291+
...(providerOption.afterRequestHooks || []),
292+
...(providerOption.defaultOutputGuardrails || []),
293+
],
288294
null,
289295
fn
290296
);
@@ -586,8 +592,33 @@ export async function tryTargetsRecursively(
586592
? { ...currentTarget.cache }
587593
: { ...inheritedConfig.cache },
588594
requestTimeout: null,
595+
defaultInputGuardrails: inheritedConfig.defaultInputGuardrails,
596+
defaultOutputGuardrails: inheritedConfig.defaultOutputGuardrails,
589597
};
590598

599+
// Inherited config can be empty only for the base case of recursive call.
600+
// To avoid redundant conversion of guardrails to hooks, we do this check.
601+
if (Object.keys(inheritedConfig).length === 0) {
602+
if (currentTarget.defaultInputGuardrails) {
603+
currentInheritedConfig.defaultInputGuardrails = [
604+
...convertHooksShorthand(
605+
currentTarget.defaultInputGuardrails,
606+
'input',
607+
HookType.GUARDRAIL
608+
),
609+
];
610+
}
611+
if (currentTarget.defaultOutputGuardrails) {
612+
currentInheritedConfig.defaultOutputGuardrails = [
613+
...convertHooksShorthand(
614+
currentTarget.defaultOutputGuardrails,
615+
'output',
616+
HookType.GUARDRAIL
617+
),
618+
];
619+
}
620+
}
621+
591622
if (typeof currentTarget.strictOpenAiCompliance === 'boolean') {
592623
currentInheritedConfig.strictOpenAiCompliance =
593624
currentTarget.strictOpenAiCompliance;
@@ -694,6 +725,13 @@ export async function tryTargetsRecursively(
694725
currentTarget.cache = {
695726
...currentInheritedConfig.cache,
696727
};
728+
729+
currentTarget.defaultInputGuardrails = [
730+
...currentInheritedConfig.defaultInputGuardrails,
731+
];
732+
currentTarget.defaultOutputGuardrails = [
733+
...currentInheritedConfig.defaultOutputGuardrails,
734+
];
697735
// end: merge inherited config with current target config (preference given to current)
698736

699737
let response;
@@ -1034,8 +1072,20 @@ export function constructConfigFromRequestHeaders(
10341072
}
10351073
}
10361074

1075+
const defaultsConfig = {
1076+
input_guardrails: requestHeaders[`x-portkey-default-input-guardrails`]
1077+
? JSON.parse(requestHeaders[`x-portkey-default-input-guardrails`])
1078+
: [],
1079+
output_guardrails: requestHeaders[`x-portkey-default-output-guardrails`]
1080+
? JSON.parse(requestHeaders[`x-portkey-default-output-guardrails`])
1081+
: [],
1082+
};
1083+
10371084
if (requestHeaders[`x-${POWERED_BY}-config`]) {
10381085
let parsedConfigJson = JSON.parse(requestHeaders[`x-${POWERED_BY}-config`]);
1086+
parsedConfigJson.default_input_guardrails = defaultsConfig.input_guardrails;
1087+
parsedConfigJson.default_output_guardrails =
1088+
defaultsConfig.output_guardrails;
10391089

10401090
if (!parsedConfigJson.provider && !parsedConfigJson.targets) {
10411091
parsedConfigJson.provider = requestHeaders[`x-${POWERED_BY}-provider`];
@@ -1131,12 +1181,16 @@ export function constructConfigFromRequestHeaders(
11311181
'conditions',
11321182
'input_guardrails',
11331183
'output_guardrails',
1184+
'default_input_guardrails',
1185+
'default_output_guardrails',
11341186
]) as any;
11351187
}
11361188

11371189
return {
11381190
provider: requestHeaders[`x-${POWERED_BY}-provider`],
11391191
apiKey: requestHeaders['authorization']?.replace('Bearer ', ''),
1192+
defaultInputGuardrails: defaultsConfig.input_guardrails,
1193+
defaultOutputGuardrails: defaultsConfig.output_guardrails,
11401194
...(requestHeaders[`x-${POWERED_BY}-provider`] === AZURE_OPEN_AI &&
11411195
azureConfig),
11421196
...([BEDROCK, SAGEMAKER].includes(

src/types/requestBody.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -124,6 +124,9 @@ export interface Options {
124124

125125
afterRequestHooks?: HookObject[];
126126
beforeRequestHooks?: HookObject[];
127+
defaultInputGuardrails?: HookObject[];
128+
defaultOutputGuardrails?: HookObject[];
129+
127130
/** OpenAI specific */
128131
openaiProject?: string;
129132
openaiOrganization?: string;
@@ -188,6 +191,9 @@ export interface Targets {
188191

189192
/** This is used to determine if the request should be transformed to formData Example: Stability V2 */
190193
transformToFormData?: boolean;
194+
195+
defaultInputGuardrails?: HookObject[];
196+
defaultOutputGuardrails?: HookObject[];
191197
}
192198

193199
/**

0 commit comments

Comments
 (0)