Closed transitive-bullshit closed 1 year ago
It seems like maybe this is from the beta message object, which has a bit more indirect content
access. I don't think this should be affecting the non-beta normal chat completion types, though.
Hey Travis, sorry for the confusion here and I agree this can be a suboptimal typing experience. This is the team's intended behavior at this time.
What's going on here is that ChatCompletionUserMessageParam
is something you can send to the API, but not something you can receive from the API (hence Param
in the type name). The type is set to be multimodal (allow content: string | Array<{type: text, text: string} | {type: image_url, image_url: string}> | null
) for all messages, even though it applies only to the gpt-4-vision-preview
model right now.
it doesn't seem to be consistent w/ the OpenAI docs as far as I can tell (source)
This is a message that is returned from the API, and right now the chat completions API only responds with text, not images, so there's no array in that type.
I agree this lends some new annoyances to working with the types. If you have suggestions for how to make this better in the SDK, I'm all ears!
Thanks for the thorough response, Alex 🙏
You bet! If this continues to cause headaches, sharing code samples and feedback would be welcome!
I am getting reponse of undefined when i use 'key={String(message.content)}' Please help me fix my code.
"use client";
import { useState } from "react";
import axios from "axios";
import { z } from "zod";
import { cn } from "@/lib/utils";
import Heading from "@/components/heading";
import { MessageSquare } from "lucide-react";
import { useForm } from "react-hook-form";
import { formSchema } from "./constants";
import { zodResolver } from "@hookform/resolvers/zod";
import { Form, FormControl, FormField, FormItem } from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { useRouter } from "next/navigation";
import { Empty } from "@/components/empty";
import Loader from "@/components/loader";
import { UserAvatar } from "@/components/user-avatar";
import { BotAvatar } from "@/components/bot-avatar";
import { ChatCompletionMessageParam } from "openai/resources/chat/completions.mjs";
const ConversationPage = () => {
const router = useRouter();
const [messages, setmessages] = useState<ChatCompletionMessageParam[]>([]);
//solved this issue from github repo:https://github.com/openai/openai-node/discussions/217
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
prompt: "",
},
});
const isLoading = form.formState.isSubmitting;
const onSubmit = async (values: z.infer<typeof formSchema>) => {
try {
const userMessage: ChatCompletionMessageParam = {
role: "user",
content: values.prompt,
};
const newMessages = [...messages, userMessage];
const response = await axios.post("/api/conversation", {
messages: newMessages,
});
setmessages((current) => [...current, userMessage, response.data]);
form.reset();
} catch (error: any) {
console.log(error);
} finally {
router.refresh();
}
};
return (
<div>
<Heading
title="Conversation"
description="Seamless Messaging, Endless Possibilities"
icon={MessageSquare}
iconColor="text-violet-500"
bgColor="bg-violet-500/10"
/>
<div className="px-4 lg:px-8 ">
<div>
<Form {...form}>
<form
onSubmit={form.handleSubmit(onSubmit)}
className="rounded-lg border w-full p-4 px-3 md:px-6 focus-within:shadow-sm grid grid-cols-12 gap-2"
>
<FormField
name="prompt"
render={({ field }) => (
<FormItem className="col-span-12 lg:col-span-10">
<FormControl className="m-0 p-0">
<Input
className="border-0 outline-none focus-visible:ring-0 focus-visible:ring-transparent"
disabled={isLoading}
placeholder="How do I calculate radius of a circle ?"
{...field}
/>
</FormControl>
</FormItem>
)}
/>
<Button
className="col-span-12 lg:col-span-2 w-full"
disabled={isLoading}
>
Generate
</Button>
</form>
</Form>
</div>
<div className="space-y-4 mt-4">
{isLoading && (
<div className="p-8 rounded-lg w-full flex items-center justify-center bg-muted">
<Loader />
</div>
)}
{messages.length === 0 && !isLoading && (
<Empty label="No convo started" />
)}
<div className="flex flex-col-reverse gap-y-4">
{messages.map((message) => (
<div
key={String(message.content)}
className={cn(
"p-8 w-full flex items-start gap-x-8 rounded-full",
message.role == "user"
? "bg-white border border-black/10"
: "bg-muted"
)}
>
{message.role === "user" ? <UserAvatar /> : <BotAvatar />}
<p className="text-sm">{String(message.content)}</p>
</div>
))}
</div>
</div>
</div>
</div>
);
};
export default ConversationPage;
Please ask for help debugging your code on the community forum or the OpenAI discord.
Confirm this is a Node library issue and not an underlying OpenAI API issue
Describe the bug
According to the OpenAI docs,
ChatCompletionMessageParam.content
should always be either astring
ornull
.But currently, this typing is broken due to:
What is
ChatCompletionContentPart
? It doesn't seem to be referenced anywhere in the OpenAI docs, and it breaks the very common TS usage ofmessage.content
being astring
if truthy.If this change is intended, then it doesn't seem to be consistent w/ the OpenAI docs as far as I can tell (source), and it makes for a much more awkward DX.
To Reproduce
Code snippets
No response
OS
macOS
Node version
any node
Library version
latest