diff --git a/src/models/ChatChromeAi.ts b/src/models/ChatChromeAi.ts index 0a5aac7..e0b48fe 100644 --- a/src/models/ChatChromeAi.ts +++ b/src/models/ChatChromeAi.ts @@ -10,15 +10,9 @@ import { import { BaseMessage, AIMessageChunk } from "@langchain/core/messages" import { ChatGenerationChunk } from "@langchain/core/outputs" import { IterableReadableStream } from "@langchain/core/utils/stream" +import { AITextSession, checkChromeAIAvailability, createAITextSession } from "./utils/chrome" -export interface AITextSession { - prompt(input: string): Promise - promptStreaming(input: string): ReadableStream - destroy(): void - clone(): AITextSession -} - export interface AITextSessionOptions { topK: number temperature: number @@ -45,10 +39,6 @@ function formatPrompt(messages: BaseMessage[]): string { return messages .map((message) => { if (typeof message.content !== "string") { - // console.log(message.content) - // throw new Error( - // "ChatChromeAI does not support non-string message content." - // ) if (message.content.length > 0) { //@ts-ignore return message.content[0]?.text || "" @@ -61,25 +51,6 @@ function formatPrompt(messages: BaseMessage[]): string { .join("\n") } -/** - * To use this model you need to have the `Built-in AI Early Preview Program` - * for Chrome. You can find more information about the program here: - * @link https://developer.chrome.com/docs/ai/built-in - * - * @example - * ```typescript - * // Initialize the ChatChromeAI model. - * const model = new ChatChromeAI({ - * temperature: 0.5, // Optional. Default is 0.5. - * topK: 40, // Optional. Default is 40. - * }); - * - * // Call the model with a message and await the response. - * const response = await model.invoke([ - * new HumanMessage({ content: "My name is John." }), - * ]); - * ``` - */ export class ChatChromeAI extends SimpleChatModel { session?: AITextSession @@ -115,18 +86,16 @@ export class ChatChromeAI extends SimpleChatModel { throw new Error("ChatChromeAI can only be used in the browser.") } - const { ai } = window as any - const capabilities = await ai?.assistant?.capabilities() - const canCreateTextSession = capabilities?.available + const canCreateTextSession = await checkChromeAIAvailability() if (canCreateTextSession === AIModelAvailability.No) { throw new Error("The AI model is not available.") } else if (canCreateTextSession === AIModelAvailability.AfterDownload) { throw new Error("The AI model is not yet downloaded.") } - this.session = await ai?.assistant?.create({ - temperature: this.temperature, - topK: this.topK + this.session = await createAITextSession({ + topK: this.topK, + temperature: this.temperature }) } diff --git a/src/models/utils/chrome.ts b/src/models/utils/chrome.ts new file mode 100644 index 0000000..16e0b8b --- /dev/null +++ b/src/models/utils/chrome.ts @@ -0,0 +1,54 @@ + +export const checkChromeAIAvailability = async (): Promise<"readily" | "no" | "after-download"> => { + try { + const ai = (window as any).ai; + + // upcoming version change + if (ai?.assistant?.capabilities) { + const capabilities = await ai.assistant.capabilities(); + return capabilities?.available ?? "no"; + } + + // old version + if (ai?.canCreateTextSession) { + const available = await ai.canCreateTextSession(); + return available ?? "no"; + } + + return "no"; + } catch (e) { + console.error("Error checking Chrome AI availability:", e); + return "no"; + } +} + +export interface AITextSession { + prompt(input: string): Promise + promptStreaming(input: string): ReadableStream + destroy(): void + clone(): AITextSession +} + + +export const createAITextSession = async (data: any): Promise => { + const ai = (window as any).ai; + + // upcoming version change + if (ai?.assistant?.create) { + const session = await ai.assistant.create({ + ...data + }) + return session + } + + // old version + if (ai.createTextSession) { + const session = await ai.createTextSession({ + ...data + }) + + return session + } + + throw new Error("Chrome AI is not available.") +} \ No newline at end of file diff --git a/src/utils/chrome.ts b/src/utils/chrome.ts index ec6ed68..c0c898b 100644 --- a/src/utils/chrome.ts +++ b/src/utils/chrome.ts @@ -1,3 +1,5 @@ +import { checkChromeAIAvailability } from "@/models/utils/chrome" + export const getChromeAISupported = async () => { try { let browserInfo = navigator.userAgent.match(/Chrom(e|ium)\/([0-9]+)\./) @@ -11,9 +13,8 @@ export const getChromeAISupported = async () => { return "ai_not_supported" } - //@ts-ignore - const capabilities = await ai?.assistant?.capabilities() - if (capabilities?.available !== "readily") { + const capabilities = await checkChromeAIAvailability() + if (capabilities !== "readily") { return "ai_not_ready" }