Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add descriptive constant for Azure content filter configuration #485

Merged
Merged
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
96d7cf4
chore: add descriptive const
KavithaSiva Jan 24, 2025
234f310
chore: remove unneeded type
KavithaSiva Jan 24, 2025
461f2fc
chore: revert convenience functiom changes
KavithaSiva Jan 24, 2025
82bb2b0
chore: tests
KavithaSiva Jan 24, 2025
728685d
fix: type test
KavithaSiva Jan 24, 2025
f28ffda
fix: all tests
KavithaSiva Jan 24, 2025
e47a57c
chore: add test back
KavithaSiva Jan 24, 2025
1b85266
chore: update readme
KavithaSiva Jan 24, 2025
40937e9
fix: build
KavithaSiva Jan 24, 2025
80e7435
chore: fix build
KavithaSiva Jan 24, 2025
3110dca
chore: address review comment
KavithaSiva Jan 29, 2025
8187452
chore: rename contanst
KavithaSiva Jan 29, 2025
12041d5
chore: address review comment
KavithaSiva Jan 30, 2025
1c0f46f
chore: update TSDoc
KavithaSiva Jan 30, 2025
cefde2b
chore: review comments
KavithaSiva Jan 30, 2025
1c77c9e
Merge branch 'refactor-content-filters' into feat/descriptive-const-c…
KavithaSiva Jan 30, 2025
24be108
chore: address review comments
KavithaSiva Jan 30, 2025
067b0ae
fix: typo
KavithaSiva Jan 30, 2025
fc3bca5
Merge branch 'refactor-content-filters' into feat/descriptive-const-c…
KavithaSiva Jan 30, 2025
5d29563
Merge branch 'refs/heads/refactor-content-filters' into feat/descript…
KavithaSiva Jan 31, 2025
5345826
chore: fix conflicts
KavithaSiva Jan 31, 2025
0bb7cb8
chore: update test
KavithaSiva Jan 31, 2025
8ca6617
chore: fix build
KavithaSiva Feb 3, 2025
f740d90
Merge branch 'refactor-content-filters' into feat/descriptive-const-c…
KavithaSiva Feb 3, 2025
a72511f
chore: fix failing build due to spacing
KavithaSiva Feb 3, 2025
c99f424
chore: add internal tag
KavithaSiva Feb 3, 2025
acdd9bb
chore: try excluding exports from index.ts
KavithaSiva Feb 3, 2025
95ecaf5
Merge branch 'refactor-content-filters' into feat/descriptive-const-c…
KavithaSiva Feb 3, 2025
51b46f5
Update packages/orchestration/README.md
KavithaSiva Feb 3, 2025
8bd0210
Merge branch 'refactor-content-filters' into feat/descriptive-const-c…
KavithaSiva Feb 3, 2025
e006987
chore: rename
KavithaSiva Feb 3, 2025
3d8ab58
Update tests/type-tests/test/orchestration.test-d.ts
deekshas8 Feb 3, 2025
ebd7162
chore: export AzureFilterThreshold
KavithaSiva Feb 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 12 additions & 2 deletions packages/orchestration/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -269,7 +269,14 @@ This feature allows filtering both the [input](https://help.sap.com/docs/sap-ai-

Use `buildAzureContentSafetyFilter()` function to build an Azure content filter.
The Azure content filter supports four categories: `Hate`, `Violence`, `Sexual`, and `SelfHarm`.
Each category can be configured with severity levels of 0, 2, 4, or 6.
Each category can be assigned a specific severity level, which corresponds to an Azure threshold value.

| Severity Level | Azure Threshold Value |
| ----------------------- | --------------------- |
| `ALLOW_SAFE` | 0 |
| `ALLOW_SAFE_LOW` | 2 |
| `ALLOW_SAFE_LOW_MEDIUM` | 4 |
| `ALLOW_ALL` | 6 |

Here is a complete example of using an Azure content filter for both input and output:

Expand All @@ -283,7 +290,10 @@ const templating = {
template: [{ role: 'user', content: '{{?input}}' }]
};

const filter = buildAzureContentSafetyFilter({ Hate: 2, Violence: 4 });
const filter = buildAzureContentSafetyFilter({
Hate: 'ALLOW_SAFE_LOW',
Violence: 'ALLOW_SAFE_LOW_MEDIUM'
});
const orchestrationClient = new OrchestrationClient({
llm,
templating,
Expand Down
3 changes: 2 additions & 1 deletion packages/orchestration/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@ export type {
StreamOptions,
DocumentGroundingServiceConfig,
DocumentGroundingServiceFilter,
LlmModelParams
LlmModelParams,
AzureContentFilter
} from './orchestration-types.js';

export { OrchestrationStreamResponse } from './orchestration-stream-response.js';
Expand Down
14 changes: 12 additions & 2 deletions packages/orchestration/src/orchestration-client.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -163,10 +163,20 @@ describe('orchestration service client', () => {
},
filtering: {
input: {
filters: [buildAzureContentSafetyFilter({ Hate: 4, SelfHarm: 2 })]
filters: [
buildAzureContentSafetyFilter({
Hate: 'ALLOW_SAFE_LOW_MEDIUM',
SelfHarm: 'ALLOW_SAFE_LOW'
})
]
},
output: {
filters: [buildAzureContentSafetyFilter({ Sexual: 0, Violence: 4 })]
filters: [
buildAzureContentSafetyFilter({
Sexual: 'ALLOW_SAFE',
Violence: 'ALLOW_SAFE_LOW_MEDIUM'
})
]
}
}
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,12 @@ describe('construct completion post request', () => {
...defaultConfig,
filtering: {
input: {
filters: [buildAzureContentSafetyFilter({ Hate: 4, SelfHarm: 0 })]
filters: [
buildAzureContentSafetyFilter({
Hate: 'ALLOW_SAFE_LOW_MEDIUM',
SelfHarm: 'ALLOW_SAFE'
})
]
}
}
};
Expand Down Expand Up @@ -212,7 +217,12 @@ describe('construct completion post request', () => {
...defaultConfig,
filtering: {
output: {
filters: [buildAzureContentSafetyFilter({ Hate: 4, SelfHarm: 0 })]
filters: [
buildAzureContentSafetyFilter({
Hate: 'ALLOW_SAFE_LOW_MEDIUM',
SelfHarm: 'ALLOW_SAFE'
})
]
}
}
};
Expand Down
39 changes: 39 additions & 0 deletions packages/orchestration/src/orchestration-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,3 +166,42 @@ export interface DocumentGroundingServiceConfig {
*/
output_param: string;
}

/**
* Filter configuration for Azure content safety Filter.
*/
export interface AzureContentFilter {
/**
* The filter category for hate content.
*/
Hate?: AzureFilterThreshold;
/**
* The filter category for self-harm content.
*/
SelfHarm?: AzureFilterThreshold;
/**
* The filter category for sexual content.
*/
Sexual?: AzureFilterThreshold;
/**
* The filter category for violence content.
*/
Violence?: AzureFilterThreshold;
}

/**
* A descriptive constant for Azure content safety filter threshold.
* @internal
*/
export const supportedAzureFilterThresholds = {
ALLOW_SAFE: 0,
ALLOW_SAFE_LOW: 2,
ALLOW_SAFE_LOW_MEDIUM: 4,
ALLOW_ALL: 6
} as const;

/**
* The Azure threshold level supported for each azure content filter category.
* @internal
*/
export type AzureFilterThreshold = keyof typeof supportedAzureFilterThresholds;
KavithaSiva marked this conversation as resolved.
Show resolved Hide resolved
4 changes: 2 additions & 2 deletions packages/orchestration/src/util/filtering.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -184,8 +184,8 @@ describe('Content filter util', () => {
describe('Azure content filter', () => {
it('builds filter config', async () => {
const filterConfig = buildAzureContentSafetyFilter({
Hate: 4,
SelfHarm: 0
Hate: 'ALLOW_SAFE_LOW_MEDIUM',
SelfHarm: 'ALLOW_SAFE'
});
const expectedFilterConfig: FilterConfig = {
type: 'azure_content_safety',
Expand Down
18 changes: 16 additions & 2 deletions packages/orchestration/src/util/filtering.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import { supportedAzureFilterThresholds } from '../orchestration-types.js';
import type {
AzureContentSafety,
AzureContentSafetyFilterConfig,
InputFilteringConfig,
OutputFilteringConfig
} from '../client/api/schema/index.js';
import type {
AzureContentFilter,
AzureFilterThreshold
} from '../orchestration-types.js';

/**
* Convenience function to create Azure content filters.
Expand Down Expand Up @@ -33,13 +38,22 @@ export function buildAzureContentFilter(
* @returns Filter config object.
*/
export function buildAzureContentSafetyFilter(
KavithaSiva marked this conversation as resolved.
Show resolved Hide resolved
config?: AzureContentSafety
config?: AzureContentFilter
): AzureContentSafetyFilterConfig {
if (config && !Object.keys(config).length) {
throw new Error('Filtering configuration cannot be an empty object');
}
return {
type: 'azure_content_safety',
...(config && { config })
...(config && {
config: {
...Object.fromEntries(
Object.entries(config).map(([key, value]) => [
key,
supportedAzureFilterThresholds[value as AzureFilterThreshold]
])
)
}
})
};
}
14 changes: 12 additions & 2 deletions packages/orchestration/src/util/request-config.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,12 @@ describe('stream util tests', () => {
...defaultOrchestrationModuleConfig,
filtering: {
output: {
filters: [buildAzureContentSafetyFilter({ Hate: 4, SelfHarm: 0 })]
filters: [
buildAzureContentSafetyFilter({
Hate: 'ALLOW_SAFE_LOW_MEDIUM',
SelfHarm: 'ALLOW_SAFE'
})
]
}
}
};
Expand All @@ -93,7 +98,12 @@ describe('stream util tests', () => {
...defaultModuleConfigs,
filtering_module_config: {
output: {
filters: [buildAzureContentSafetyFilter({ Hate: 4, SelfHarm: 0 })]
filters: [
buildAzureContentSafetyFilter({
Hate: 'ALLOW_SAFE_LOW_MEDIUM',
SelfHarm: 'ALLOW_SAFE'
})
]
}
}
};
Expand Down
8 changes: 4 additions & 4 deletions sample-code/src/orchestration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,8 +170,8 @@ export async function orchestrationInputFiltering(): Promise<void> {
// create a filter with minimal thresholds for hate and violence
// lower numbers mean more strict filtering
const azureContentFilter = buildAzureContentSafetyFilter({
Hate: 0,
Violence: 0
Hate: 'ALLOW_SAFE',
Violence: 'ALLOW_SAFE'
});
const orchestrationClient = new OrchestrationClient({
llm,
Expand Down Expand Up @@ -207,8 +207,8 @@ export async function orchestrationOutputFiltering(): Promise<OrchestrationRespo
// output filters are build in the same way as input filters
// set the thresholds to the minimum to maximize the chance the LLM output will be filtered
const azureContentFilter = buildAzureContentSafetyFilter({
Hate: 0,
Violence: 0
Hate: 'ALLOW_SAFE',
Violence: 'ALLOW_SAFE'
});
const orchestrationClient = new OrchestrationClient({
llm,
Expand Down
24 changes: 23 additions & 1 deletion tests/type-tests/test/orchestration.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { expectError, expectType, expectAssignable } from 'tsd';
import {
OrchestrationClient,
buildAzureContentSafetyFilter,
buildDocumentGroundingConfig
} from '@sap-ai-sdk/orchestration';
import type {
Expand All @@ -9,7 +10,8 @@ import type {
TokenUsage,
ChatModel,
GroundingModuleConfig,
LlmModelParams
LlmModelParams,
AzureContentSafetyFilterConfig
} from '@sap-ai-sdk/orchestration';

/**
Expand Down Expand Up @@ -244,6 +246,26 @@ expectType<Promise<OrchestrationResponse>>(
expect<ChatModel>('custom-model');
expect<ChatModel>('gemini-1.0-pro');

/**
* FilteringUtil.
deekshas8 marked this conversation as resolved.
Show resolved Hide resolved
*/

expectType<AzureContentSafetyFilterConfig>(
buildAzureContentSafetyFilter({
Hate: 'ALLOW_ALL',
SelfHarm: 'ALLOW_SAFE_LOW',
Sexual: 'ALLOW_SAFE_LOW_MEDIUM',
Violence: 'ALLOW_SAFE'
})
);

expectError<AzureContentSafetyFilterConfig>(
buildAzureContentSafetyFilter({
Hate: 2,
SelfHarm: 4
})
);

/**
* Grounding util.
*/
Expand Down
Loading