feat: Basic trip planner agent
This commit is contained in:
70
agent/trip-planner/nodes/classify.ts
Normal file
70
agent/trip-planner/nodes/classify.ts
Normal file
@@ -0,0 +1,70 @@
|
||||
import { ChatOpenAI } from "@langchain/openai";
|
||||
import { TripPlannerState } from "../types";
|
||||
import { z } from "zod";
|
||||
import { formatMessages } from "agent/utils/format-messages";
|
||||
|
||||
export async function classify(
|
||||
state: TripPlannerState,
|
||||
): Promise<Partial<TripPlannerState>> {
|
||||
if (!state.tripDetails) {
|
||||
// Can not classify if tripDetails are undefined
|
||||
return {};
|
||||
}
|
||||
|
||||
const schema = z.object({
|
||||
isRelevant: z
|
||||
.boolean()
|
||||
.describe(
|
||||
"Whether the trip details are still relevant to the user's request.",
|
||||
),
|
||||
});
|
||||
|
||||
const model = new ChatOpenAI({ model: "gpt-4o", temperature: 0 }).bindTools(
|
||||
[
|
||||
{
|
||||
name: "classify",
|
||||
description:
|
||||
"A tool to classify whether or not the trip details are still relevant to the user's request.",
|
||||
schema,
|
||||
},
|
||||
],
|
||||
{
|
||||
tool_choice: "classify",
|
||||
},
|
||||
);
|
||||
|
||||
const prompt = `You're an AI assistant for planning trips. The user has already specified the following details for their trip:
|
||||
- location - ${state.tripDetails.location}
|
||||
- startDate - ${state.tripDetails.startDate}
|
||||
- endDate - ${state.tripDetails.endDate}
|
||||
- numberOfGuests - ${state.tripDetails.numberOfGuests}
|
||||
|
||||
Your task is to carefully read over the user's conversation, and determine if their trip details are still relevant to their most recent request.
|
||||
You should set is relevant to false if they are now asking about a new location, trip duration, or number of guests.
|
||||
If they do NOT change their request details (or they never specified them), please set is relevant to true.
|
||||
`;
|
||||
|
||||
const humanMessage = `Here is the entire conversation so far:\n${formatMessages(state.messages)}`;
|
||||
|
||||
const response = await model.invoke([
|
||||
{ role: "system", content: prompt },
|
||||
{ role: "human", content: humanMessage },
|
||||
]);
|
||||
|
||||
const classificationDetails = response.tool_calls?.[0]?.args as
|
||||
| z.infer<typeof schema>
|
||||
| undefined;
|
||||
|
||||
if (!classificationDetails) {
|
||||
throw new Error("Could not classify trip details");
|
||||
}
|
||||
|
||||
if (!classificationDetails.isRelevant) {
|
||||
return {
|
||||
tripDetails: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
// If it is relevant, return the state unchanged
|
||||
return {};
|
||||
}
|
||||
Reference in New Issue
Block a user