3fbbd7970c
Code Quality / Python Lint & Format (push) Has been cancelled
Code Quality / Python Tests (push) Has been cancelled
Code Quality / JavaScript/TypeScript Lint (advisory) (push) Has been cancelled
Security Scan / CodeQL Analysis (python) (push) Has been cancelled
Security Scan / Dependency Review (push) Has been cancelled
Security Scan / CodeQL Analysis (javascript-typescript) (push) Has been cancelled
190 lines
6.9 KiB
JavaScript
190 lines
6.9 KiB
JavaScript
import ModelClient from "@azure-rest/ai-inference";
|
|
import { AzureKeyCredential } from "@azure/core-auth";
|
|
|
|
// Get these from your Microsoft Foundry project's "Overview" page
|
|
// (GitHub Models is retiring end of July 2026 - see https://ai.azure.com/catalog/models)
|
|
const token = process.env["AZURE_INFERENCE_CREDENTIAL"];
|
|
if (!token) {
|
|
throw new Error("AZURE_INFERENCE_CREDENTIAL environment variable is required. Please set it before running this application.");
|
|
}
|
|
const endpoint = process.env["AZURE_INFERENCE_ENDPOINT"];
|
|
if (!endpoint) {
|
|
throw new Error("AZURE_INFERENCE_ENDPOINT environment variable is required. Please set it before running this application.");
|
|
}
|
|
|
|
/* By using the Azure AI Inference SDK, you can easily experiment with different models
|
|
by modifying the value of `modelName` in the code below. For this code sample
|
|
you need a model supporting tools. The following compatible models are
|
|
available in the Microsoft Foundry Models catalog:
|
|
|
|
Cohere: Cohere-command-r-08-2024, Cohere-command-r-plus-08-2024
|
|
Mistral AI: Mistral-large-2411, Mistral-small-2503
|
|
OpenAI: gpt-4o-mini, gpt-4o, gpt-4.1, gpt-4.1-mini */
|
|
const modelName = "gpt-4o-mini";
|
|
|
|
function getFlightInfo({ originCity, destinationCity }) {
|
|
if (originCity === "Seattle" && destinationCity === "Miami") {
|
|
return JSON.stringify({
|
|
airline: "Delta",
|
|
flight_number: "DL123",
|
|
flight_date: "May 7th, 2024",
|
|
flight_time: "10:00AM"
|
|
});
|
|
}
|
|
return JSON.stringify({ error: "No flights found between the cities" });
|
|
}
|
|
|
|
function getHotelInfo({ destination }) {
|
|
if ( destination === "Miami") {
|
|
return JSON.stringify({
|
|
hotelName: "Contoso Suites"
|
|
});
|
|
}
|
|
return JSON.stringify({ error: "No available hotels found in this city" });
|
|
}
|
|
|
|
const namesToFunctions = {
|
|
getFlightInfo: (data) =>
|
|
getFlightInfo(data),
|
|
getHotelInfo: (data) =>
|
|
getHotelInfo(data)
|
|
};
|
|
|
|
export async function main() {
|
|
|
|
const tool = {
|
|
"type": "function",
|
|
"function": {
|
|
name: "getFlightInfo",
|
|
description: "Returns information about the next flight between two cities." +
|
|
"This includes the name of the airline, flight number and the date and time" +
|
|
"of the next flight",
|
|
parameters: {
|
|
"type": "object",
|
|
"properties": {
|
|
"originCity": {
|
|
"type": "string",
|
|
"description": "The name of the city where the flight originates",
|
|
},
|
|
"destinationCity": {
|
|
"type": "string",
|
|
"description": "The flight destination city",
|
|
},
|
|
},
|
|
"required": [
|
|
"originCity",
|
|
"destinationCity"
|
|
],
|
|
},
|
|
|
|
}
|
|
};
|
|
|
|
const hotels ={
|
|
"type": "function",
|
|
"function": {
|
|
name: "getHotelInfo",
|
|
description: "Returns information about the hotel of the destination city.",
|
|
parameters: {
|
|
"type": "object",
|
|
"properties": {
|
|
"destination": {
|
|
"type": "string",
|
|
"description": "The city that the traveller would like to stay",
|
|
},
|
|
},
|
|
"required": [
|
|
"destination"
|
|
],
|
|
},
|
|
}
|
|
|
|
}
|
|
|
|
const client = new ModelClient(endpoint, new AzureKeyCredential(token));
|
|
|
|
let messages = [
|
|
{ role: "system", content: "You an assistant that helps users find flight and hotel information." },
|
|
{ role: "user", content: "I'm interested in going to Miami and staying in a hotel." },
|
|
// { role: "user", content: "I'm interested in going to Seattle. Are there flights to Denver?" },
|
|
|
|
|
|
|
|
|
|
];
|
|
|
|
let response = await client.path("/chat/completions").post({
|
|
body: {
|
|
messages: messages,
|
|
tools: [tool, hotels],
|
|
model: modelName
|
|
}
|
|
});
|
|
if (response.status !== "200") {
|
|
throw response.body.error;
|
|
}
|
|
|
|
// We expect the model to ask for a tool call
|
|
if (response.body.choices[0].finish_reason === "tool_calls") {
|
|
|
|
// Append the model response to the chat history
|
|
messages.push(response.body.choices[0].message);
|
|
|
|
// We expect a single tool call
|
|
if (response.body.choices[0].message && response.body.choices[0].message.tool_calls.length === 1) {
|
|
|
|
const toolCall = response.body.choices[0].message.tool_calls[0];
|
|
// We expect the tool to be a function call
|
|
if (toolCall.type === "function") {
|
|
const toolCall = response.body.choices[0].message.tool_calls[0];
|
|
|
|
// SECURITY: Validate function name exists in allowed functions map
|
|
const functionName = toolCall.function.name;
|
|
if (!Object.prototype.hasOwnProperty.call(namesToFunctions, functionName)) {
|
|
throw new Error(`Unknown function requested: ${functionName}. Only allowed functions are: ${Object.keys(namesToFunctions).join(', ')}`);
|
|
}
|
|
|
|
// SECURITY: Safely parse JSON with error handling
|
|
let functionArgs;
|
|
try {
|
|
functionArgs = JSON.parse(toolCall.function.arguments);
|
|
} catch (parseError) {
|
|
throw new Error(`Failed to parse function arguments: ${parseError.message}`);
|
|
}
|
|
|
|
// Log function call (avoid logging sensitive data in production)
|
|
console.log(`Calling function \`${functionName}\` with arguments ${toolCall.function.arguments}`);
|
|
|
|
const callableFunc = namesToFunctions[functionName];
|
|
const functionReturn = callableFunc(functionArgs);
|
|
console.log(`Function returned = ${functionReturn}`);
|
|
|
|
// Append the function call result fo the chat history
|
|
messages.push(
|
|
{
|
|
"tool_call_id": toolCall.id,
|
|
"role": "tool",
|
|
"name": toolCall.function.name,
|
|
"content": functionReturn,
|
|
}
|
|
)
|
|
|
|
response = await client.path("/chat/completions").post({
|
|
body: {
|
|
messages: messages,
|
|
tools: [tool, hotels],
|
|
model: modelName
|
|
}
|
|
});
|
|
if (response.status !== "200") {
|
|
throw response.body.error;
|
|
}
|
|
console.log(`Model response = ${response.body.choices[0].message.content}`);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error("The sample encountered an error:", err);
|
|
}); |