-
Notifications
You must be signed in to change notification settings - Fork 0
/
route.ts
90 lines (76 loc) · 2.78 KB
/
route.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
import { NextRequest, NextResponse } from "next/server";
import { z } from "zod";
import { zodToJsonSchema } from "zod-to-json-schema";
import { ChatOpenAI } from "@langchain/openai";
import { PromptTemplate } from "@langchain/core/prompts";
import { JsonOutputFunctionsParser } from "langchain/output_parsers";
export const runtime = "edge";
const TEMPLATE = `Extract the requested fields from the input.
The field "entity" refers to the first mentioned entity in the input.
Input:
{input}`;
/**
* This handler initializes and calls an OpenAI Functions powered
* structured output chain. See the docs for more information:
*
* https://js.langchain.com/docs/modules/chains/popular/structured_output
*/
export async function POST(req: NextRequest) {
try {
const body = await req.json();
const messages = body.messages ?? [];
const currentMessageContent = messages[messages.length - 1].content;
const prompt = PromptTemplate.fromTemplate(TEMPLATE);
/**
* Function calling is currently only supported with ChatOpenAI models
*/
const model = new ChatOpenAI({
temperature: 0.8,
modelName: "gpt-3.5-turbo-1106",
});
/**
* We use Zod (https://zod.dev) to define our schema for convenience,
* but you can pass JSON Schema directly if desired.
*/
const schema = z.object({
tone: z
.enum(["positive", "negative", "neutral"])
.describe("The overall tone of the input"),
entity: z.string().describe("The entity mentioned in the input"),
word_count: z.number().describe("The number of words in the input"),
chat_response: z.string().describe("A response to the human's input"),
final_punctuation: z
.optional(z.string())
.describe("The final punctuation mark in the input, if any."),
});
/**
* Bind the function and schema to the OpenAI model.
* Future invocations of the returned model will always use these arguments.
*
* Specifying "function_call" ensures that the provided function will always
* be called by the model.
*/
const functionCallingModel = model.bind({
functions: [
{
name: "output_formatter",
description: "Should always be used to properly format output",
parameters: zodToJsonSchema(schema),
},
],
function_call: { name: "output_formatter" },
});
/**
* Returns a chain with the function calling model.
*/
const chain = prompt
.pipe(functionCallingModel)
.pipe(new JsonOutputFunctionsParser());
const result = await chain.invoke({
input: currentMessageContent,
});
return NextResponse.json(result, { status: 200 });
} catch (e: any) {
return NextResponse.json({ error: e.message }, { status: e.status ?? 500 });
}
}