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/langchain/destination advice #506

Merged
merged 3 commits into from
Dec 24, 2023
Merged
Changes from all commits
Commits
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
107 changes: 107 additions & 0 deletions server/src/controllers/openAi/langchain/destinationAdvice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { OpenAI } from "langchain/llms/openai";
import { AIMessage, HumanMessage, SystemMessage } from "langchain/schema";
import { checkAPIKey } from ".";

const llm: OpenAI = new OpenAI({
openAIApiKey: process.env.OPENAI_API_KEY,
temperature: 0.7,
maxTokens: 150,
});

export async function destinationAdvice(month: string, destination: string) {
await checkAPIKey()
const tripDetails: string = `${destination} in ${month}`
const systemMessage: string = `You are a helpful Outdoor Adventure Planning assistant for PackRat. The user is planning a trip to ${tripDetails}.`;
try {
const adviceTypes = getAdviceTypes(tripDetails);
const advicePromises: Promise<Record<string, string>>[] = adviceTypes.map((advice: { key: string; prompt: string }) =>
getResponse(advice.prompt, systemMessage).then(response => ({ [advice.key as string]: response as string }))
);
const adviceResults: Record<string, string>[] = await Promise.all(advicePromises);
const result: DestinationAdviceResponse = adviceResults.reduce((acc, current) => ({ ...acc, ...current }), {} as DestinationAdviceResponse)
return <DestinationAdviceResponse>result
} catch (error) {
console.error("Error in DestinationAdvice:", error);
return <DestinationAdviceResponse>{
error: "Sorry, I'm unable to provide travel advice at the moment."
};
}
}

async function getResponse(userMessage: string, systemMessage: string): Promise<string> {
const messages = [new HumanMessage({ content: userMessage }), new SystemMessage({ content: systemMessage })];
try {

Check failure on line 33 in server/src/controllers/openAi/langchain/destinationAdvice.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Always prefer const x: T = { ... }

Check failure on line 33 in server/src/controllers/openAi/langchain/destinationAdvice.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Always prefer const x: T = { ... }

Check failure on line 33 in server/src/controllers/openAi/langchain/destinationAdvice.ts

View workflow job for this annotation

GitHub Actions / build (18.x)

Always prefer const x: T = { ... }

Check failure on line 33 in server/src/controllers/openAi/langchain/destinationAdvice.ts

View workflow job for this annotation

GitHub Actions / build (20.x)

Always prefer const x: T = { ... }
const response: string = await predictMessages(messages);
return <string>response.trim();
} catch (error) {
console.error("Error in getResponse:", error);
throw new Error("Error obtaining response from OpenAI");
}
}

async function predictMessages(messages: (AIMessage | HumanMessage | SystemMessage)[]): Promise<string> {
try {
return <string>(await llm.predictMessages(messages)).content.toString().trim();
} catch (error) {
console.error("Error in predictMessages:", error);
throw new Error("Error predicting messages with OpenAI");
}
}

export interface DestinationAdviceResponse {
tripAdvice: string;
avoidPlaces: string;
weatherAdvice: string;
placesToVisit: string;
costAdvice: string;
transportationAdvice: string;
packingAdvice: string;
activitiesAdvice: string;
foodAdvice: string;
entertainmentAdvice: string;
shoppingAdvice: string;
safetyHealthAdvice: string;
culturalEtiquette: string;
languageAssistance: string;
emergencyContacts: string;
localTransportOptions: string;
visaEntryRequirements: string;
culinarySpecialties: string;
festivalsEvents: string;
accommodationTips: string;
localLaws: string;
connectivityCommunication: string;
ecoFriendlyTravel: string;
travelInsurance: string;
error?: string;
}

function getAdviceTypes(tripDetails: string) {
const adviceTypes = [
{ key: 'tripAdvice', prompt: `Provide general travel advice for ${tripDetails}.` },
{ key: 'avoidPlaces', prompt: `What are the places to avoid in ${tripDetails}?` },
{ key: 'weatherAdvice', prompt: `Provide weather advice for ${tripDetails}.` },
{ key: 'placesToVisit', prompt: `Recommend top places to visit in ${tripDetails}.` },
{ key: 'costAdvice', prompt: `Provide cost and budgeting advice for visiting ${tripDetails}.` },
{ key: 'transportationAdvice', prompt: `Provide transportation advice for visiting ${tripDetails}.` },
{ key: 'packingAdvice', prompt: `Provide packing advice for visiting ${tripDetails}.` },
{ key: 'activitiesAdvice', prompt: `Provide activities advice for visiting ${tripDetails}.` },
{ key: 'foodAdvice', prompt: `Provide food advice for visiting ${tripDetails}.` },
{ key: 'entertainmentAdvice', prompt: `Provide entertainment advice for visiting ${tripDetails}.` },
{ key: 'shoppingAdvice', prompt: `Provide shopping advice for visiting ${tripDetails}.` },
{ key: 'safetyHealthAdvice', prompt: `Provide safety and health advice for visiting ${tripDetails}.` },
{ key: 'culturalEtiquette', prompt: `Provide advice on local customs and cultural etiquette for visiting ${tripDetails}.` },
{ key: 'languageAssistance', prompt: `Provide language assistance and communication tips for visiting ${tripDetails}.` },
{ key: 'emergencyContacts', prompt: `Provide emergency contact information and advice for dealing with emergencies in ${tripDetails}.` },
{ key: 'localTransportOptions', prompt: `Detail local transportation options and tips for getting around in ${tripDetails}.` },
{ key: 'visaEntryRequirements', prompt: `Explain visa and entry requirements for travelers visiting ${tripDetails}.` },
{ key: 'culinarySpecialties', prompt: `Discuss culinary specialties and dietary advice for ${tripDetails}.` },
{ key: 'festivalsEvents', prompt: `Highlight any festivals or special events happening in ${tripDetails}.` },
{ key: 'accommodationTips', prompt: `Provide advice on choosing accommodations in ${tripDetails}.` },
{ key: 'localLaws', prompt: `Inform about local laws and regulations that travelers should be aware of in ${tripDetails}.` },
{ key: 'connectivityCommunication', prompt: `Offer advice on connectivity and communication options in ${tripDetails}.` },
{ key: 'ecoFriendlyTravel', prompt: `Give tips on eco-friendly and sustainable travel practices in ${tripDetails}.` },
{ key: 'travelInsurance', prompt: `Advise on travel insurance options and considerations for visiting ${tripDetails}.` }
];
return adviceTypes;
}
Loading