diff --git a/.changeset/slimy-cherries-shake.md b/.changeset/slimy-cherries-shake.md new file mode 100644 index 00000000000..4daed11d0b1 --- /dev/null +++ b/.changeset/slimy-cherries-shake.md @@ -0,0 +1,5 @@ +--- +'ai': patch +--- + +Fix regression with generated ids diff --git a/packages/core/react/use-chat.ts b/packages/core/react/use-chat.ts index 5e0db495cf9..29d7085f9e3 100644 --- a/packages/core/react/use-chat.ts +++ b/packages/core/react/use-chat.ts @@ -1,4 +1,4 @@ -import { useCallback, useEffect, useRef, useState } from 'react' +import { useCallback, useEffect, useId, useRef, useState } from 'react' import useSWRMutation from 'swr/mutation' import useSWR, { KeyedMutator } from 'swr' import { nanoid, createChunkDecoder } from '../shared/utils' @@ -8,9 +8,14 @@ import type { CreateMessage, Message, UseChatOptions, + RequestOptions, ChatRequestOptions } from '../shared/types' -import { ChatCompletionRequestMessageFunctionCall } from 'openai-edge' +import { + ChatCompletionRequestMessageFunctionCall, + CreateChatCompletionRequestFunctionCall +} from 'openai-edge' +import { ChatCompletionFunctions } from 'openai-edge/types/api' export type { Message, CreateMessage, UseChatOptions } export type UseChatHelpers = { @@ -207,7 +212,8 @@ export function useChat({ body }: UseChatOptions = {}): UseChatHelpers { // Generate a unique id for the chat if not provided. - const chatId = id || `chat-${nanoid()}` + const hookId = useId() + const chatId = id || hookId // Store the chat state in SWR, using the chatId as the key to share states. const { data, mutate } = useSWR([api, chatId], null, { diff --git a/packages/core/react/use-completion.ts b/packages/core/react/use-completion.ts index 521dd39323f..8a3336ea8e9 100644 --- a/packages/core/react/use-completion.ts +++ b/packages/core/react/use-completion.ts @@ -1,8 +1,8 @@ -import { useCallback, useEffect, useRef, useState } from 'react' +import { useCallback, useEffect, useId, useRef, useState } from 'react' import useSWRMutation from 'swr/mutation' import useSWR from 'swr' -import { createChunkDecoder, nanoid } from '../shared/utils' +import { createChunkDecoder } from '../shared/utils' import { UseCompletionOptions, RequestOptions } from '../shared/types' export type UseCompletionHelpers = { @@ -67,7 +67,9 @@ export function useCompletion({ onFinish, onError }: UseCompletionOptions = {}): UseCompletionHelpers { - const completionId = id || `completion-${nanoid()}` + // Generate an unique id for the completion if not provided. + const hookId = useId() + const completionId = id || hookId // Store the completion state in SWR, using the completionId as the key to share states. const { data, mutate } = useSWR([api, completionId], null, { diff --git a/packages/core/svelte/use-chat.ts b/packages/core/svelte/use-chat.ts index 51d94c69cec..8d8600144e7 100644 --- a/packages/core/svelte/use-chat.ts +++ b/packages/core/svelte/use-chat.ts @@ -50,6 +50,8 @@ export type UseChatHelpers = { isLoading: Writable } +let uniqueId = 0 + const store: Record = {} export function useChat({ @@ -66,7 +68,7 @@ export function useChat({ body }: UseChatOptions = {}): UseChatHelpers { // Generate a unique ID for the chat if not provided. - const chatId = id || `chat-${nanoid()}` + const chatId = id || `chat-${uniqueId++}` const key = `${api}|${chatId}` const { data, mutate: originalMutate } = useSWR(key, { diff --git a/packages/core/svelte/use-completion.ts b/packages/core/svelte/use-completion.ts index 90ea7be402a..f5840584816 100644 --- a/packages/core/svelte/use-completion.ts +++ b/packages/core/svelte/use-completion.ts @@ -4,7 +4,7 @@ import { Readable, get, writable } from 'svelte/store' import { Writable } from 'svelte/store' import type { UseCompletionOptions, RequestOptions } from '../shared/types' -import { createChunkDecoder, nanoid } from '../shared/utils' +import { createChunkDecoder } from '../shared/utils' export type UseCompletionHelpers = { /** The current completion result */ @@ -42,6 +42,8 @@ export type UseCompletionHelpers = { isLoading: Writable } +let uniqueId = 0 + const store: Record = {} export function useCompletion({ @@ -57,7 +59,7 @@ export function useCompletion({ onError }: UseCompletionOptions = {}): UseCompletionHelpers { // Generate an unique id for the completion if not provided. - const completionId = id || `completion-${nanoid()}` + const completionId = id || `completion-${uniqueId++}` const key = `${api}|${completionId}` const { data, mutate: originalMutate } = useSWR(key, { diff --git a/packages/core/vue/use-chat.ts b/packages/core/vue/use-chat.ts index 0bfd886508d..f6818253c04 100644 --- a/packages/core/vue/use-chat.ts +++ b/packages/core/vue/use-chat.ts @@ -49,6 +49,8 @@ export type UseChatHelpers = { isLoading: Ref } +let uniqueId = 0 + // @ts-expect-error - some issues with the default export of useSWRV const useSWRV = (swrv.default as typeof import('swrv')['default']) || swrv const store: Record = {} @@ -67,7 +69,7 @@ export function useChat({ body }: UseChatOptions = {}): UseChatHelpers { // Generate a unique ID for the chat if not provided. - const chatId = id || `chat-${nanoid()}` + const chatId = id || `chat-${uniqueId++}` const key = `${api}|${chatId}` const { data, mutate: originalMutate } = useSWRV( diff --git a/packages/core/vue/use-completion.ts b/packages/core/vue/use-completion.ts index b0e67d66752..1d49c1f5c3a 100644 --- a/packages/core/vue/use-completion.ts +++ b/packages/core/vue/use-completion.ts @@ -3,7 +3,7 @@ import { ref } from 'vue' import type { Ref } from 'vue' import type { UseCompletionOptions, RequestOptions } from '../shared/types' -import { createChunkDecoder, nanoid } from '../shared/utils' +import { createChunkDecoder } from '../shared/utils' export type UseCompletionHelpers = { /** The current completion result */ @@ -41,6 +41,8 @@ export type UseCompletionHelpers = { isLoading: Ref } +let uniqueId = 0 + // @ts-expect-error - some issues with the default export of useSWRV const useSWRV = (swrv.default as typeof import('swrv')['default']) || swrv const store: Record = {} @@ -58,7 +60,7 @@ export function useCompletion({ onError }: UseCompletionOptions = {}): UseCompletionHelpers { // Generate an unique id for the completion if not provided. - const completionId = id || `completion-${nanoid()}` + const completionId = id || `completion-${uniqueId++}` const key = `${api}|${completionId}` const { data, mutate: originalMutate } = useSWRV(