Skip to content

Commit 402137a

Browse files
authored
Merge branch 'main' into feat/models-endpoint
2 parents ba72cc2 + 25a09c6 commit 402137a

File tree

8 files changed

+782
-69
lines changed

8 files changed

+782
-69
lines changed

plugins/azure/azure.test.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,29 @@ describe('Azure Plugins', () => {
4545
expect(result.error).toBeNull();
4646
expect(result.verdict).toBe(true);
4747
expect(result.transformed).toBe(true);
48+
}, 10000);
49+
50+
it('should not redact anything if text has no PII', async () => {
51+
const context = structuredClone(mockContext);
52+
context.request.text = "hello, I'm a harmless string";
53+
context.request.json = {
54+
messages: [{ role: 'user', content: "hello, I'm a harmless string" }],
55+
};
56+
const result = await piiHandler(context, params, 'beforeRequestHook');
57+
expect(result.error).toBeNull();
58+
expect(result.verdict).toBe(true);
59+
expect(result.transformed).toBe(false);
60+
});
61+
62+
it('should not redact anything if redact is false', async () => {
63+
const result = await piiHandler(
64+
mockContext,
65+
{ ...params, redact: false },
66+
'beforeRequestHook'
67+
);
68+
expect(result.error).toBeNull();
69+
expect(result.verdict).toBe(false);
70+
expect(result.transformed).toBe(false);
4871
});
4972

5073
it('should handle API errors gracefully', async () => {

plugins/azure/contentSafety.ts

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ export const handler: PluginHandler<{
1717
context: PluginContext,
1818
parameters: PluginParameters<{ contentSafety: AzureCredentials }>,
1919
eventType: HookEventType,
20-
options
20+
pluginOptions?: Record<string, any>
2121
) => {
2222
let error = null;
2323
let verdict = true;
@@ -69,8 +69,8 @@ export const handler: PluginHandler<{
6969
const { token, error: tokenError } = await getAccessToken(
7070
credentials as any,
7171
'contentSafety',
72-
options,
73-
options?.env
72+
pluginOptions,
73+
pluginOptions?.env
7474
);
7575

7676
if (tokenError) {
@@ -110,14 +110,13 @@ export const handler: PluginHandler<{
110110
};
111111

112112
const timeout = parameters.timeout || 5000;
113+
const requestOptions: Record<string, any> = { headers };
114+
if (agent) {
115+
requestOptions.dispatcher = agent;
116+
}
113117
let response;
114118
try {
115-
response = await post(
116-
url,
117-
request,
118-
{ headers, dispatcher: agent },
119-
timeout
120-
);
119+
response = await post(url, request, requestOptions, timeout);
121120
} catch (e) {
122121
return { error: e, verdict: true, data };
123122
}

plugins/azure/pii.ts

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import { getAccessToken } from './utils';
1212
const redact = async (
1313
documents: any[],
1414
parameters: PluginParameters<{ pii: AzureCredentials }>,
15-
options?: Record<string, any>
15+
pluginOptions?: Record<string, any>
1616
) => {
1717
const body = {
1818
kind: 'PiiEntityRecognition',
@@ -35,8 +35,8 @@ const redact = async (
3535
const { token, error: tokenError } = await getAccessToken(
3636
credentials as any,
3737
'pii',
38-
options,
39-
options?.env
38+
pluginOptions,
39+
pluginOptions?.env
4040
);
4141

4242
const headers: Record<string, string> = {
@@ -66,20 +66,19 @@ const redact = async (
6666
}
6767

6868
const timeout = parameters.timeout || 5000;
69-
const response = await post(
70-
url,
71-
body,
72-
{ headers, dispatcher: agent },
73-
timeout
74-
);
69+
const requestOptions: Record<string, any> = { headers };
70+
if (agent) {
71+
requestOptions.dispatcher = agent;
72+
}
73+
const response = await post(url, body, requestOptions, timeout);
7574
return response;
7675
};
7776

7877
export const handler: PluginHandler<{ pii: AzureCredentials }> = async (
7978
context: PluginContext,
8079
parameters: PluginParameters<{ pii: AzureCredentials }>,
8180
eventType: HookEventType,
82-
options?: Record<string, any>
81+
pluginOptions?: Record<string, any>
8382
) => {
8483
let error = null;
8584
let verdict = true;
@@ -134,9 +133,18 @@ export const handler: PluginHandler<{ pii: AzureCredentials }> = async (
134133
}));
135134

136135
try {
137-
const response = await redact(documents, parameters, options);
136+
const response = await redact(documents, parameters, pluginOptions);
137+
if (!response?.results?.documents) {
138+
throw new Error('Invalid response from Azure PII API');
139+
}
138140
data = response.results.documents;
139-
if (parameters.redact) {
141+
const containsPII =
142+
data.length > 0 && data.some((doc: any) => doc.entities.length > 0);
143+
if (containsPII) {
144+
verdict = false;
145+
}
146+
if (parameters.redact && containsPII) {
147+
verdict = true;
140148
const redactedData = (response.results.documents ?? []).map(
141149
(doc: any) => doc.redactedText
142150
);

src/providers/google-vertex-ai/chatComplete.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ import type {
4949
import {
5050
getMimeType,
5151
recursivelyDeleteUnsupportedParameters,
52+
transformGeminiToolParameters,
5253
transformVertexLogprobs,
5354
} from './utils';
5455

@@ -301,6 +302,11 @@ export const VertexGoogleChatCompleteConfig: ProviderConfig = {
301302
) {
302303
tools.push(buildGoogleSearchRetrievalTool(tool));
303304
} else {
305+
if (tool.function?.parameters) {
306+
tool.function.parameters = transformGeminiToolParameters(
307+
tool.function.parameters
308+
);
309+
}
304310
functionDeclarations.push(tool.function);
305311
}
306312
}

src/providers/google-vertex-ai/transformGenerationConfig.ts

Lines changed: 6 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import { Params } from '../../types/requestBody';
2-
import { derefer, recursivelyDeleteUnsupportedParameters } from './utils';
2+
import {
3+
recursivelyDeleteUnsupportedParameters,
4+
transformGeminiToolParameters,
5+
} from './utils';
36
import { GoogleEmbedParams } from './embed';
47
import { EmbedInstancesData } from './types';
58
/**
@@ -39,20 +42,11 @@ export function transformGenerationConfig(params: Params) {
3942
}
4043
if (params?.response_format?.type === 'json_schema') {
4144
generationConfig['responseMimeType'] = 'application/json';
42-
recursivelyDeleteUnsupportedParameters(
43-
params?.response_format?.json_schema?.schema
44-
);
4545
let schema =
4646
params?.response_format?.json_schema?.schema ??
4747
params?.response_format?.json_schema;
48-
if (Object.keys(schema).includes('$defs')) {
49-
schema = derefer(schema);
50-
delete schema['$defs'];
51-
}
52-
if (Object.hasOwn(schema, '$schema')) {
53-
delete schema['$schema'];
54-
}
55-
generationConfig['responseSchema'] = schema;
48+
recursivelyDeleteUnsupportedParameters(schema);
49+
generationConfig['responseSchema'] = transformGeminiToolParameters(schema);
5650
}
5751

5852
if (params?.thinking) {

0 commit comments

Comments
 (0)