Skip to content

Commit 20b6e0c

Browse files
committed
Copy over helicone config to server action
1 parent 2d9ee4d commit 20b6e0c

2 files changed

Lines changed: 10 additions & 163 deletions

File tree

app/(main)/actions.ts

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,15 @@ import { notFound } from "next/navigation";
77
import Together from "together-ai";
88
import { z } from "zod";
99

10-
const together = new Together();
10+
let options: ConstructorParameters<typeof Together>[0] = {};
11+
if (process.env.HELICONE_API_KEY) {
12+
options.baseURL = "https://together.helicone.ai/v1";
13+
options.defaultHeaders = {
14+
"Helicone-Auth": `Bearer ${process.env.HELICONE_API_KEY}`,
15+
};
16+
}
17+
18+
let together = new Together(options);
1119

1220
export async function createChat(
1321
prompt: string,
@@ -80,33 +88,6 @@ export async function createMessage(
8088
return newMessage;
8189
}
8290

83-
export async function streamNextCompletion(messageId: string, model: string) {
84-
const message = await prisma.message.findUnique({ where: { id: messageId } });
85-
if (!message) notFound();
86-
87-
const messagesRes = await prisma.message.findMany({
88-
where: { chatId: message.chatId, position: { lte: message.position } },
89-
orderBy: { position: "asc" },
90-
});
91-
92-
const messages = z
93-
.array(
94-
z.object({
95-
role: z.enum(["system", "user", "assistant"]),
96-
content: z.string(),
97-
}),
98-
)
99-
.parse(messagesRes);
100-
101-
const res = await together.chat.completions.create({
102-
model,
103-
messages: messages.map((m) => ({ role: m.role, content: m.content })),
104-
stream: true,
105-
});
106-
107-
return res.toReadableStream();
108-
}
109-
11091
export async function getNextCompletionStreamPromise(
11192
messageId: string,
11293
model: string,
@@ -134,6 +115,7 @@ export async function getNextCompletionStreamPromise(
134115
model,
135116
messages: messages.map((m) => ({ role: m.role, content: m.content })),
136117
stream: true,
118+
temperature: 0.2,
137119
});
138120

139121
resolve(res.toReadableStream());
Lines changed: 0 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,3 @@
1-
import shadcnDocs from "@/lib/shadcn-docs";
2-
import dedent from "dedent";
3-
import Together from "together-ai";
4-
import { z } from "zod";
5-
6-
let options: ConstructorParameters<typeof Together>[0] = {};
7-
if (process.env.HELICONE_API_KEY) {
8-
options.baseURL = "https://together.helicone.ai/v1";
9-
options.defaultHeaders = {
10-
"Helicone-Auth": `Bearer ${process.env.HELICONE_API_KEY}`,
11-
// "Helicone-Property-Local": "true",
12-
};
13-
}
14-
15-
let together = new Together(options);
16-
17-
export async function POST(req: Request) {
18-
let json = await req.json();
19-
let result = z
20-
.object({
21-
model: z.string(),
22-
shadcn: z.boolean().default(false),
23-
messages: z.array(
24-
z.object({
25-
role: z.enum(["user", "assistant"]),
26-
content: z.string(),
27-
}),
28-
),
29-
})
30-
.safeParse(json);
31-
32-
if (result.error) {
33-
return new Response(result.error.message, { status: 422 });
34-
}
35-
36-
let { model, messages, shadcn } = result.data;
37-
let systemPrompt = getSystemPrompt(shadcn);
38-
39-
let res = await together.chat.completions.create({
40-
model,
41-
messages: [
42-
{
43-
role: "system",
44-
content: systemPrompt,
45-
},
46-
...messages.map((message) => ({
47-
...message,
48-
content:
49-
message.role === "user"
50-
? message.content +
51-
"\nPlease ONLY return code, NO backticks or language names."
52-
: message.content,
53-
})),
54-
],
55-
stream: true,
56-
temperature: 0.2,
57-
});
58-
59-
return new Response(res.toReadableStream());
60-
}
61-
621
let examples = [
632
{
643
prompt: "Build a landing page for a healthcare company",
@@ -202,77 +141,3 @@ export default function HealthcareLandingPage() {
202141
`,
203142
},
204143
];
205-
206-
function getSystemPrompt(shadcn: boolean) {
207-
let systemPrompt = `
208-
You are an expert frontend React engineer who is also a great UI/UX designer. Follow the instructions carefully, I will tip you $1 million if you do a good job:
209-
210-
- Think carefully step by step.
211-
- Create a React component for whatever the user asked you to create and make sure it can run by itself by using a default export
212-
- Make sure the React app is interactive and functional by creating state when needed and having no required props
213-
- If you use any imports from React like useState or useEffect, make sure to import them directly
214-
- Use TypeScript as the language for the React component
215-
- Use Tailwind classes for styling. DO NOT USE ARBITRARY VALUES (e.g. \`h-[600px]\`). Make sure to use a consistent color palette.
216-
- Use Tailwind margin and padding classes to style the components and ensure the components are spaced out nicely
217-
- Please ONLY return the full React code starting with the imports, nothing else. It's very important for my job that you only return the React code with imports. DO NOT START WITH \`\`\`typescript or \`\`\`javascript or \`\`\`tsx or \`\`\`.
218-
- ONLY IF the user asks for a dashboard, graph or chart, the recharts library is available to be imported, e.g. \`import { LineChart, XAxis, ... } from "recharts"\` & \`<LineChart ...><XAxis dataKey="name"> ...\`. Please only use this when needed.
219-
- For placeholder images, please use a <div className="bg-gray-200 border-2 border-dashed rounded-xl w-16 h-16" />
220-
`;
221-
222-
// - The lucide-react library is also available to be imported IF NECCESARY ONLY FOR THE FOLLOWING ICONS: Heart, Shield, Clock, Users, Play, Home, Search, Menu, User, Settings, Mail, Bell, Calendar, Clock, Heart, Star, Upload, Download, Trash, Edit, Plus, Minus, Check, X, ArrowRight.
223-
// - Here's an example of importing and using one: import { Heart } from "lucide-react"\` & \`<Heart className="" />\`.
224-
// - PLEASE ONLY USE THE ICONS LISTED ABOVE IF AN ICON IS NEEDED IN THE USER'S REQUEST. Please DO NOT use the lucide-react library if it's not needed.
225-
226-
if (shadcn) {
227-
systemPrompt += `
228-
There are some prestyled components available for use. Please use your best judgement to use any of these components if the app calls for one.
229-
230-
Here are the components that are available, along with how to import them, and how to use them:
231-
232-
${shadcnDocs
233-
.map(
234-
(component) => `
235-
<component>
236-
<name>
237-
${component.name}
238-
</name>
239-
<import-instructions>
240-
${component.importDocs}
241-
</import-instructions>
242-
<usage-instructions>
243-
${component.usageDocs}
244-
</usage-instructions>
245-
</component>
246-
`,
247-
)
248-
.join("\n")}
249-
`;
250-
}
251-
252-
systemPrompt += `
253-
NO OTHER LIBRARIES (e.g. zod, hookform) ARE INSTALLED OR ABLE TO BE IMPORTED.
254-
`;
255-
256-
// systemPrompt += `
257-
// Here are some examples of a good response:
258-
259-
// ${examples
260-
// .map(
261-
// (example) => `
262-
// <example>
263-
// <prompt>
264-
// ${example.prompt}
265-
// </prompt>
266-
// <response>
267-
// ${example.response}
268-
// </response>
269-
// </example>
270-
// `,
271-
// )
272-
// .join("\n")}
273-
// `;
274-
275-
return dedent(systemPrompt);
276-
}
277-
278-
export const runtime = "edge";

0 commit comments

Comments
 (0)