Skip to content

Instantly share code, notes, and snippets.

@shelling
Created January 21, 2024 01:40
Show Gist options
  • Save shelling/118e44b2de0f5f193b11231adbd807cd to your computer and use it in GitHub Desktop.
Save shelling/118e44b2de0f5f193b11231adbd807cd to your computer and use it in GitHub Desktop.
import { readFileSync } from 'fs'
import OpenAI from 'openai';
import { ChatCompletionMessageParam } from 'openai/resources/chat';
import inquirer from 'inquirer';
import input from '@inquirer/input';
import {
Product,
LineItem,
Card,
} from './types';
import {
searchItem,
addToCart,
removeFromCart,
updateItemInCart,
listCart,
checkout,
payment,
goodbye,
} from './functions';
import { tools } from './tools';
const menu: Product[] = JSON.parse(readFileSync("./menu.json", 'utf-8')).map((item: any) => ({ name: item.english, price: item.price }));
const cart: LineItem[] = [];
(async () => {
const openai: OpenAI = new OpenAI({
apiKey: process.apiKey,
});
const greeting = "What can I do for you today?";
const messages: ChatCompletionMessageParam[] = [
{
role: "system",
content: `You are a restaurant cashier taking order from customers. identify available items and place orders for customers. If the item is not avilable, tell customers. Available items are ${JSON.stringify(menu)}.`,
},
{
role: 'assistant',
content: greeting,
},
{
role: 'user',
content: await input({ message: greeting }),
},
]
while (true) {
const completions = await openai.chat.completions.create({
model: "gpt-3.5-turbo",
messages: messages,
tools: tools,
tool_choice: "auto",
});
console.log(`completion: ${JSON.stringify(completions, null, 2)}`)
const message = completions.choices[0].message
messages.push(message)
if (message.tool_calls) {
// console.log(JSON.stringify(message, null, 2));
let invoked: number = 0;
message.tool_calls.map((tool_call: any) => {
switch (tool_call.function.name) {
case "addToCart": {
console.log(JSON.stringify(tool_call));
const item = JSON.parse(tool_call.function.arguments).item;
const response = addToCart(item, cart, menu);
messages.push({
tool_call_id: tool_call.id,
role: 'tool',
content: JSON.stringify(response),
});
invoked += 1;
break;
}
case "removeFromCart": {
const item = JSON.parse(tool_call.function.arguments).item;
const removed = removeFromCart(item, cart);
messages.push({
tool_call_id: tool_call.id,
role: 'tool',
content: JSON.stringify({ status: 200, body: { removed, description: "successfully removed" } }),
});
invoked += 1;
break;
}
case "updateItemInCart": {
const { item, quantity } = JSON.parse(tool_call.function.arguments);
// console.log("udpate ", item, quantity);
const updated = updateItemInCart(item, quantity, cart);
messages.push({
tool_call_id: tool_call.id,
role: 'tool',
content: JSON.stringify({ status: 200, body: { updated, description: "successfully updated" } }),
})
invoked += 1;
break;
}
case "listCart": {
// console.log(JSON.stringify(cart, null, 2));
messages.push({
tool_call_id: tool_call.id,
role: 'tool',
content: JSON.stringify({ status: 200, body: listCart(cart) }),
})
invoked += 1;
break;
}
case "checkout": {
// console.log(tool_call.function.arguments + " in checkout");
// console.log(JSON.stringify(cart, null, 2));
checkout(cart);
const total = cart.map((lineItem: LineItem) => (lineItem.price * lineItem.quantity)).reduce((a: number, b: number) => (a + b), 0);
messages.push({
tool_call_id: tool_call.id,
role: 'tool',
content: JSON.stringify({ status: 200, body: { total: total, prompt: "cart has been sent to kitchen, ask customers card number to pay"} }),
});
invoked += 1;
break;
}
case "payment": {
// console.log(tool_call.function.arguments + " in payment");
const { number, expiration, cvv } = JSON.parse(tool_call.function.arguments);
const response = payment(number, expiration, cvv);
messages.push({
tool_call_id: tool_call.id,
role: 'tool',
content: JSON.stringify({ status: 200, body: response }),
});
invoked += 1;
break;
}
case "searchItem": {
// console.log(tool_call.function.arguments);
const result = searchItem(JSON.parse(tool_call.function.arguments).item, menu);
messages.push({
tool_call_id: tool_call.id,
role: 'tool',
content: JSON.stringify({ status: 200, body: result}),
});
invoked += 1;
break;
}
case "goodbye": {
// console.log(tool_call.function.arguments + " in goodbye");
input({ message: "thank you for dining with us. enjoy your meal!\n" }).then(() => { process.exit(0) });
break;
}
}
// console.log(JSON.stringify(messages, null, 2));
})
if (invoked == 0) {
messages.push({
tool_call_id: message.tool_calls[0].id,
role: 'tool',
content: JSON.stringify({ status: 400, body: "sorry, function is not available" }),
})
}
} else {
const assistantMessage: string = message.content as string;
const userMessage = await input({ message: assistantMessage });
messages.push({ role: 'user', content: userMessage });
}
}
})()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment