Skip to content

Commit 1edaf19

Browse files
waleedlatif1claude
andauthored
fix(azure): add azure-anthropic support to router, evaluator, copilot, and tokenization (#3158)
* fix(azure): add azure-anthropic support to router, evaluator, copilot, and tokenization * added azure anthropic values to env * fix(azure): make anthropic-version configurable for azure-anthropic provider * fix(azure): thread provider credentials through guardrails and fix translate missing bedrockAccessKeyId * updated guardrails * ack'd PR comments * fix(azure): unify credential passing pattern across all LLM handlers - Pass all provider credentials unconditionally in router, evaluator (matching agent pattern) - Remove conditional if-branching on providerId for credential fields - Thread workspaceId through guardrails → hallucination validator for BYOK key resolution - Remove getApiKey() from hallucination validator, let executeProviderRequest handle it - Resolve vertex OAuth credentials in hallucination validator matching agent handler pattern Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 474b1af commit 1edaf19

File tree

15 files changed

+171
-78
lines changed

15 files changed

+171
-78
lines changed

apps/sim/app/api/copilot/chat/route.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,14 @@ export async function POST(req: NextRequest) {
285285
apiVersion: 'preview',
286286
endpoint: env.AZURE_OPENAI_ENDPOINT,
287287
}
288+
} else if (providerEnv === 'azure-anthropic') {
289+
providerConfig = {
290+
provider: 'azure-anthropic',
291+
model: envModel,
292+
apiKey: env.AZURE_ANTHROPIC_API_KEY,
293+
apiVersion: env.AZURE_ANTHROPIC_API_VERSION,
294+
endpoint: env.AZURE_ANTHROPIC_ENDPOINT,
295+
}
288296
} else if (providerEnv === 'vertex') {
289297
providerConfig = {
290298
provider: 'vertex',

apps/sim/app/api/guardrails/validate/route.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,16 @@ export async function POST(request: NextRequest) {
2323
topK,
2424
model,
2525
apiKey,
26+
azureEndpoint,
27+
azureApiVersion,
28+
vertexProject,
29+
vertexLocation,
30+
vertexCredential,
31+
bedrockAccessKeyId,
32+
bedrockSecretKey,
33+
bedrockRegion,
2634
workflowId,
35+
workspaceId,
2736
piiEntityTypes,
2837
piiMode,
2938
piiLanguage,
@@ -110,7 +119,18 @@ export async function POST(request: NextRequest) {
110119
topK,
111120
model,
112121
apiKey,
122+
{
123+
azureEndpoint,
124+
azureApiVersion,
125+
vertexProject,
126+
vertexLocation,
127+
vertexCredential,
128+
bedrockAccessKeyId,
129+
bedrockSecretKey,
130+
bedrockRegion,
131+
},
113132
workflowId,
133+
workspaceId,
114134
piiEntityTypes,
115135
piiMode,
116136
piiLanguage,
@@ -178,7 +198,18 @@ async function executeValidation(
178198
topK: string | undefined,
179199
model: string,
180200
apiKey: string | undefined,
201+
providerCredentials: {
202+
azureEndpoint?: string
203+
azureApiVersion?: string
204+
vertexProject?: string
205+
vertexLocation?: string
206+
vertexCredential?: string
207+
bedrockAccessKeyId?: string
208+
bedrockSecretKey?: string
209+
bedrockRegion?: string
210+
},
181211
workflowId: string | undefined,
212+
workspaceId: string | undefined,
182213
piiEntityTypes: string[] | undefined,
183214
piiMode: string | undefined,
184215
piiLanguage: string | undefined,
@@ -219,7 +250,9 @@ async function executeValidation(
219250
topK: topK ? Number.parseInt(topK) : 10, // Default topK is 10
220251
model: model,
221252
apiKey,
253+
providerCredentials,
222254
workflowId,
255+
workspaceId,
223256
requestId,
224257
})
225258
}

apps/sim/blocks/blocks/agent.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -333,11 +333,11 @@ Return ONLY the JSON array.`,
333333
id: 'azureApiVersion',
334334
title: 'Azure API Version',
335335
type: 'short-input',
336-
placeholder: '2024-07-01-preview',
336+
placeholder: 'Enter API version',
337337
connectionDroppable: false,
338338
condition: {
339339
field: 'model',
340-
value: providers['azure-openai'].models,
340+
value: [...providers['azure-openai'].models, ...providers['azure-anthropic'].models],
341341
},
342342
},
343343
{
@@ -715,7 +715,7 @@ Example 3 (Array Input):
715715
},
716716
model: { type: 'string', description: 'AI model to use' },
717717
apiKey: { type: 'string', description: 'Provider API key' },
718-
azureEndpoint: { type: 'string', description: 'Azure OpenAI endpoint URL' },
718+
azureEndpoint: { type: 'string', description: 'Azure endpoint URL' },
719719
azureApiVersion: { type: 'string', description: 'Azure API version' },
720720
vertexProject: { type: 'string', description: 'Google Cloud project ID for Vertex AI' },
721721
vertexLocation: { type: 'string', description: 'Google Cloud location for Vertex AI' },

apps/sim/blocks/blocks/translate.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,9 @@ export const TranslateBlock: BlockConfig = {
7676
vertexProject: params.vertexProject,
7777
vertexLocation: params.vertexLocation,
7878
vertexCredential: params.vertexCredential,
79-
bedrockRegion: params.bedrockRegion,
79+
bedrockAccessKeyId: params.bedrockAccessKeyId,
8080
bedrockSecretKey: params.bedrockSecretKey,
81+
bedrockRegion: params.bedrockRegion,
8182
}),
8283
},
8384
},

apps/sim/blocks/utils.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ export function getApiKeyCondition() {
8080

8181
/**
8282
* Returns the standard provider credential subblocks used by LLM-based blocks.
83-
* This includes: Vertex AI OAuth, API Key, Azure OpenAI, Vertex AI config, and Bedrock config.
83+
* This includes: Vertex AI OAuth, API Key, Azure (OpenAI + Anthropic), Vertex AI config, and Bedrock config.
8484
*
8585
* Usage: Spread into your block's subBlocks array after block-specific fields
8686
*/
@@ -111,25 +111,25 @@ export function getProviderCredentialSubBlocks(): SubBlockConfig[] {
111111
},
112112
{
113113
id: 'azureEndpoint',
114-
title: 'Azure OpenAI Endpoint',
114+
title: 'Azure Endpoint',
115115
type: 'short-input',
116116
password: true,
117-
placeholder: 'https://your-resource.openai.azure.com',
117+
placeholder: 'https://your-resource.services.ai.azure.com',
118118
connectionDroppable: false,
119119
condition: {
120120
field: 'model',
121-
value: providers['azure-openai'].models,
121+
value: [...providers['azure-openai'].models, ...providers['azure-anthropic'].models],
122122
},
123123
},
124124
{
125125
id: 'azureApiVersion',
126126
title: 'Azure API Version',
127127
type: 'short-input',
128-
placeholder: '2024-07-01-preview',
128+
placeholder: 'Enter API version',
129129
connectionDroppable: false,
130130
condition: {
131131
field: 'model',
132-
value: providers['azure-openai'].models,
132+
value: [...providers['azure-openai'].models, ...providers['azure-anthropic'].models],
133133
},
134134
},
135135
{
@@ -202,7 +202,7 @@ export function getProviderCredentialSubBlocks(): SubBlockConfig[] {
202202
*/
203203
export const PROVIDER_CREDENTIAL_INPUTS = {
204204
apiKey: { type: 'string', description: 'Provider API key' },
205-
azureEndpoint: { type: 'string', description: 'Azure OpenAI endpoint URL' },
205+
azureEndpoint: { type: 'string', description: 'Azure endpoint URL' },
206206
azureApiVersion: { type: 'string', description: 'Azure API version' },
207207
vertexProject: { type: 'string', description: 'Google Cloud project ID for Vertex AI' },
208208
vertexLocation: { type: 'string', description: 'Google Cloud location for Vertex AI' },

apps/sim/executor/handlers/evaluator/evaluator-handler.ts

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -121,26 +121,17 @@ export class EvaluatorBlockHandler implements BlockHandler {
121121

122122
temperature: EVALUATOR.DEFAULT_TEMPERATURE,
123123
apiKey: finalApiKey,
124+
azureEndpoint: inputs.azureEndpoint,
125+
azureApiVersion: inputs.azureApiVersion,
126+
vertexProject: evaluatorConfig.vertexProject,
127+
vertexLocation: evaluatorConfig.vertexLocation,
128+
bedrockAccessKeyId: evaluatorConfig.bedrockAccessKeyId,
129+
bedrockSecretKey: evaluatorConfig.bedrockSecretKey,
130+
bedrockRegion: evaluatorConfig.bedrockRegion,
124131
workflowId: ctx.workflowId,
125132
workspaceId: ctx.workspaceId,
126133
}
127134

128-
if (providerId === 'vertex') {
129-
providerRequest.vertexProject = evaluatorConfig.vertexProject
130-
providerRequest.vertexLocation = evaluatorConfig.vertexLocation
131-
}
132-
133-
if (providerId === 'azure-openai') {
134-
providerRequest.azureEndpoint = inputs.azureEndpoint
135-
providerRequest.azureApiVersion = inputs.azureApiVersion
136-
}
137-
138-
if (providerId === 'bedrock') {
139-
providerRequest.bedrockAccessKeyId = evaluatorConfig.bedrockAccessKeyId
140-
providerRequest.bedrockSecretKey = evaluatorConfig.bedrockSecretKey
141-
providerRequest.bedrockRegion = evaluatorConfig.bedrockRegion
142-
}
143-
144135
const response = await fetch(url.toString(), {
145136
method: 'POST',
146137
headers: await buildAuthHeaders(),

apps/sim/executor/handlers/router/router-handler.ts

Lines changed: 14 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -96,26 +96,17 @@ export class RouterBlockHandler implements BlockHandler {
9696
context: JSON.stringify(messages),
9797
temperature: ROUTER.INFERENCE_TEMPERATURE,
9898
apiKey: finalApiKey,
99+
azureEndpoint: inputs.azureEndpoint,
100+
azureApiVersion: inputs.azureApiVersion,
101+
vertexProject: routerConfig.vertexProject,
102+
vertexLocation: routerConfig.vertexLocation,
103+
bedrockAccessKeyId: routerConfig.bedrockAccessKeyId,
104+
bedrockSecretKey: routerConfig.bedrockSecretKey,
105+
bedrockRegion: routerConfig.bedrockRegion,
99106
workflowId: ctx.workflowId,
100107
workspaceId: ctx.workspaceId,
101108
}
102109

103-
if (providerId === 'vertex') {
104-
providerRequest.vertexProject = routerConfig.vertexProject
105-
providerRequest.vertexLocation = routerConfig.vertexLocation
106-
}
107-
108-
if (providerId === 'azure-openai') {
109-
providerRequest.azureEndpoint = inputs.azureEndpoint
110-
providerRequest.azureApiVersion = inputs.azureApiVersion
111-
}
112-
113-
if (providerId === 'bedrock') {
114-
providerRequest.bedrockAccessKeyId = routerConfig.bedrockAccessKeyId
115-
providerRequest.bedrockSecretKey = routerConfig.bedrockSecretKey
116-
providerRequest.bedrockRegion = routerConfig.bedrockRegion
117-
}
118-
119110
const response = await fetch(url.toString(), {
120111
method: 'POST',
121112
headers: await buildAuthHeaders(),
@@ -234,6 +225,13 @@ export class RouterBlockHandler implements BlockHandler {
234225
context: JSON.stringify(messages),
235226
temperature: ROUTER.INFERENCE_TEMPERATURE,
236227
apiKey: finalApiKey,
228+
azureEndpoint: inputs.azureEndpoint,
229+
azureApiVersion: inputs.azureApiVersion,
230+
vertexProject: routerConfig.vertexProject,
231+
vertexLocation: routerConfig.vertexLocation,
232+
bedrockAccessKeyId: routerConfig.bedrockAccessKeyId,
233+
bedrockSecretKey: routerConfig.bedrockSecretKey,
234+
bedrockRegion: routerConfig.bedrockRegion,
237235
workflowId: ctx.workflowId,
238236
workspaceId: ctx.workspaceId,
239237
responseFormat: {
@@ -257,22 +255,6 @@ export class RouterBlockHandler implements BlockHandler {
257255
},
258256
}
259257

260-
if (providerId === 'vertex') {
261-
providerRequest.vertexProject = routerConfig.vertexProject
262-
providerRequest.vertexLocation = routerConfig.vertexLocation
263-
}
264-
265-
if (providerId === 'azure-openai') {
266-
providerRequest.azureEndpoint = inputs.azureEndpoint
267-
providerRequest.azureApiVersion = inputs.azureApiVersion
268-
}
269-
270-
if (providerId === 'bedrock') {
271-
providerRequest.bedrockAccessKeyId = routerConfig.bedrockAccessKeyId
272-
providerRequest.bedrockSecretKey = routerConfig.bedrockSecretKey
273-
providerRequest.bedrockRegion = routerConfig.bedrockRegion
274-
}
275-
276258
const response = await fetch(url.toString(), {
277259
method: 'POST',
278260
headers: await buildAuthHeaders(),

apps/sim/lib/copilot/config.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ const VALID_PROVIDER_IDS: readonly ProviderId[] = [
1212
'openai',
1313
'azure-openai',
1414
'anthropic',
15+
'azure-anthropic',
1516
'google',
1617
'deepseek',
1718
'xai',

apps/sim/lib/copilot/types.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,13 @@ export type CopilotProviderConfig =
147147
apiVersion?: string
148148
endpoint?: string
149149
}
150+
| {
151+
provider: 'azure-anthropic'
152+
model: string
153+
apiKey?: string
154+
apiVersion?: string
155+
endpoint?: string
156+
}
150157
| {
151158
provider: 'vertex'
152159
model: string
@@ -155,7 +162,7 @@ export type CopilotProviderConfig =
155162
vertexLocation?: string
156163
}
157164
| {
158-
provider: Exclude<ProviderId, 'azure-openai' | 'vertex'>
165+
provider: Exclude<ProviderId, 'azure-openai' | 'azure-anthropic' | 'vertex'>
159166
model?: string
160167
apiKey?: string
161168
}

apps/sim/lib/core/config/env.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ export const env = createEnv({
9595
AZURE_OPENAI_ENDPOINT: z.string().url().optional(), // Shared Azure OpenAI service endpoint
9696
AZURE_OPENAI_API_VERSION: z.string().optional(), // Shared Azure OpenAI API version
9797
AZURE_OPENAI_API_KEY: z.string().min(1).optional(), // Shared Azure OpenAI API key
98+
AZURE_ANTHROPIC_ENDPOINT: z.string().url().optional(), // Azure Anthropic service endpoint
99+
AZURE_ANTHROPIC_API_KEY: z.string().min(1).optional(), // Azure Anthropic API key
100+
AZURE_ANTHROPIC_API_VERSION: z.string().min(1).optional(), // Azure Anthropic API version (e.g. 2023-06-01)
98101
KB_OPENAI_MODEL_NAME: z.string().optional(), // Knowledge base OpenAI model name (works with both regular OpenAI and Azure OpenAI)
99102
WAND_OPENAI_MODEL_NAME: z.string().optional(), // Wand generation OpenAI model name (works with both regular OpenAI and Azure OpenAI)
100103
OCR_AZURE_ENDPOINT: z.string().url().optional(), // Azure Mistral OCR service endpoint

0 commit comments

Comments
 (0)