### Install Dependencies Source: https://github.com/jakobhoeg/browser-ai/blob/main/CONTRIBUTING.md Run this command from the root folder to install all project dependencies. ```bash npm install ``` -------------------------------- ### Basic Agent Example with Tools Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/core/agents.mdx Create an agent that can search the web and analyze content using predefined tools. This example defines tools for getting weather information and converting temperatures, and then uses them to answer a user's prompt. ```typescript import { ToolLoopAgent, stepCountIs, tool } from 'ai'; import { browserAI } from "@browser-ai/core"; import { z } from 'zod'; const weatherAgent = new ToolLoopAgent({ model: browserAI(), instructions: 'You are a weather assistant.', tools: { weather: tool({ description: 'Get the weather in a location (in Fahrenheit)', inputSchema: z.object({ location: z.string().describe('The location to get the weather for'), }), execute: async ({ location }) => ({ location, temperature: 72 + Math.floor(Math.random() * 21) - 10, }), }), convertFahrenheitToCelsius: tool({ description: 'Convert temperature from Fahrenheit to Celsius', inputSchema: z.object({ temperature: z.number().describe('Temperature in Fahrenheit'), }), execute: async ({ temperature }) => { const celsius = Math.round((temperature - 32) * (5 / 9)); return { celsius }; }, }), }, // Agent's default behavior is to stop after a maximum of 20 steps // stopWhen: stepCountIs(20), }); const result = await weatherAgent.generate({ prompt: 'What is the weather in San Francisco in celsius?', }); console.log(result.text); // agent's final answer console.log(result.steps); // steps taken by the agent ``` -------------------------------- ### Run Development Server Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/README.md Commands to start the development server using npm, pnpm, or yarn. ```bash npm run dev # or pnpm dev # or yarn dev ``` -------------------------------- ### Basic Agent Example with Tools Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/transformers-js/agents.mdx Create an agent that can search the web and analyze content using predefined tools. This example defines a weather agent with tools for fetching weather data and converting temperatures. Ensure you use reasoning models like Qwen3 for better multi-step reasoning. ```typescript import { ToolLoopAgent, stepCountIs, tool } from 'ai'; import { transformersJS } from "@browser-ai/transformers-js"; import { z } from 'zod'; const weatherAgent = new ToolLoopAgent({ model: transformersJS("onnx-community/Qwen3-0.6B-ONNX"), instructions: 'You are a weather assistant.', tools: { weather: tool({ description: 'Get the weather in a location (in Fahrenheit)', inputSchema: z.object({ location: z.string().describe('The location to get the weather for'), }), execute: async ({ location }) => ({ location, temperature: 72 + Math.floor(Math.random() * 21) - 10, }), }), convertFahrenheitToCelsius: tool({ description: 'Convert temperature from Fahrenheit to Celsius', inputSchema: z.object({ temperature: z.number().describe('Temperature in Fahrenheit'), }), execute: async ({ temperature }) => { const celsius = Math.round((temperature - 32) * (5 / 9)); return { celsius }; }, }), }, // Agent's default behavior is to stop after a maximum of 20 steps // stopWhen: stepCountIs(20), }); const result = await weatherAgent.generate({ prompt: 'What is the weather in San Francisco in celsius?', }); console.log(result.text); // agent's final answer console.log(result.steps); // steps taken by the agent ``` -------------------------------- ### Install @browser-ai/web-llm Package Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/web-llm/installation.mdx Use npm to install the @browser-ai/web-llm package. This is the primary step for setting up WebLLM for AI SDK v6. ```bash npm i @browser-ai/web-llm ``` -------------------------------- ### Install Transformers.js Package Source: https://github.com/jakobhoeg/browser-ai/blob/main/README.md Install the package for models using Transformers.js. ```bash npm i @browser-ai/transformers-js ``` -------------------------------- ### Install @browser-ai/core Package Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/core/installation.mdx Use npm to install the core package for the AI SDK v6. This command should be run in your project's root directory. ```bash npm i @browser-ai/core ``` -------------------------------- ### Build Project Source: https://github.com/jakobhoeg/browser-ai/blob/main/CONTRIBUTING.md Builds the project. After this, the `dist` folder is updated and new code is picked up in example applications. ```bash npm run build ``` -------------------------------- ### Run Local Development Server Source: https://github.com/jakobhoeg/browser-ai/blob/main/CONTRIBUTING.md Starts the local development server, which will automatically rebuild packages as changes are made. ```bash npm run dev ``` -------------------------------- ### Install @browser-ai Packages Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/getting-started.mdx Install the necessary @browser-ai packages based on your intended use case: core for built-in browser AI, transformers-js for Hugging Face models, or web-llm for MLC models. ```bash # For Chrome/Edge built-in browser AI (Prompt API) npm i @browser-ai/core # For Transformers.js (Hugging Face models) npm i @browser-ai/transformers-js # For WebLLM (MLC models) npm i @browser-ai/web-llm ``` -------------------------------- ### Conventional Commit Examples Source: https://github.com/jakobhoeg/browser-ai/blob/main/CONTRIBUTING.md Examples of conventional commit message formats for pull requests. ```bash feat(@browser-ai/core): description ``` ```bash fix(@browser-ai/core): description ``` ```bash chore(examples/next-hybrid): description ``` -------------------------------- ### Transformers.js Simplified Worker Setup Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/transformers-js/why.mdx This code shows the minimal setup required for a Web Worker when using @browser-ai/transformers-js. It abstracts away the complexities of Transformers.js. ```typescript import { TransformersJSWorkerHandler } from "@browser-ai/transformers-js" const handler = new TransformersJSWorkerHandler() self.onmessage = (msg: MessageEvent) => { handler.onmessage(msg) } ``` -------------------------------- ### Bootstrap Next.js Hybrid AI App with npm Source: https://github.com/jakobhoeg/browser-ai/blob/main/examples/next-hybrid/README.md Use this command to create a new Next.js project with the hybrid AI chat example using npm. ```bash npx create-next-app --example https://github.com/jakobhoeg/browser-ai/tree/main/examples/next-hybrid next-browser-ai-hybrid ``` -------------------------------- ### Bootstrap Next.js Hybrid AI App with pnpm Source: https://github.com/jakobhoeg/browser-ai/blob/main/examples/next-hybrid/README.md Use this command to create a new Next.js project with the hybrid AI chat example using pnpm. ```bash pnpm create next-app --example https://github.com/jakobhoeg/browser-ai/tree/main/examples/next-hybrid next-browser-ai-hybrid ``` -------------------------------- ### Bootstrap Next.js Hybrid AI App with Yarn Source: https://github.com/jakobhoeg/browser-ai/blob/main/examples/next-hybrid/README.md Use this command to create a new Next.js project with the hybrid AI chat example using Yarn. ```bash yarn create next-app --example https://github.com/jakobhoeg/browser-ai/tree/main/examples/next-hybrid next-browser-ai-hybrid ``` -------------------------------- ### Basic Usage with Transformers.js Source: https://github.com/jakobhoeg/browser-ai/blob/main/README.md Stream text using the transformersJS provider with specified Hugging Face models. Ensure @browser-ai/transformers-js is installed. ```typescript import { streamText } from "ai"; import { transformersJS } from "@browser-ai/transformers-js"; const result = streamText({ model: transformersJS("HuggingFaceTB/SmolLM2-360M-Instruct"), prompt: "Invent a new holiday and describe its traditions.", }); for await (const chunk of result.textStream) { console.log(chunk); } ``` -------------------------------- ### After: Using @browser-ai/transformers-js Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/transformers-js/why.mdx This example demonstrates the simplified integration of AI models using the @browser-ai/transformers-js library with the `ai/react` hook. It significantly reduces boilerplate code by abstracting away the complexities of model loading, worker management, and message handling. ```typescript import { useChat } from "ai/react"; import { transformersJS, TransformersUIMessage } from "@browser-ai/transformers-js"; const model = transformersJS("HuggingFaceTB/SmolLM2-360M-Instruct", { device: "webgpu", dtype: "q4", worker: new Worker(new URL("./worker.ts", import.meta.url), { type: "module", }), }); function App() { const { error, status, sendMessage, messages, stop } = useChat({ transport: new TransformersChatTransport(model), }); // ... your UI } ``` -------------------------------- ### Basic Usage with Chrome/Edge AI Source: https://github.com/jakobhoeg/browser-ai/blob/main/README.md Use the browserAI provider with the Vercel AI SDK to stream text. Ensure @browser-ai/core is installed. ```typescript import { streamText } from "ai"; import { browserAI } from "@browser-ai/core"; const result = streamText({ model: browserAI(), prompt: "Invent a new holiday and describe its traditions.", }); for await (const chunk of result.textStream) { console.log(chunk); } ``` -------------------------------- ### Verify Browser WebLLM Support Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/web-llm/installation.mdx After installation, import and call the `doesBrowserSupportWebLLM` function to check if the current browser environment is capable of running WebLLM. This helps in deciding whether to use WebLLM or a server fallback. ```typescript import { doesBrowserSupportWebLLM } from "@browser-ai/web-llm"; if (doesBrowserSupportWebLLM()) { console.log("Browser supports WebLLM!"); } else { console.log("WebLLM not available, use server fallback"); } ``` -------------------------------- ### Transformers.js Web Worker Setup Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/transformers-js/usage.mdx Configure a web worker for Transformers.js to run models off the main thread for improved performance. This snippet shows the worker script setup. ```typescript import { TransformersJSWorkerHandler } from "@browser-ai/transformers-js"; const handler = new TransformersJSWorkerHandler(); self.onmessage = (msg: MessageEvent) => { handler.onmessage(msg); }; ``` -------------------------------- ### Complete WebLLM Chat Transport Example Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/web-llm/usechat-integration.mdx Implements a client-side chat transport for AI SDK v6 using WebLLM. Handles model downloading, streaming responses, and tool usage. Use this to enable in-browser AI capabilities. ```typescript import { ChatTransport, UIMessageChunk, streamText, convertToModelMessages, ChatRequestOptions, createUIMessageStream, tool, stepCountIs, } from "ai"; import { WebLLMUIMessage, WebLLMLanguageModel, } from "@browser-ai/web-llm"; import z from "zod"; export const createTools = () => ({ webSearch: tool({ description: "Search the web for information when you need up-to-date information or facts not in your knowledge base. Use this when the user asks about current events, recent developments, or specific factual information you're unsure about.", inputSchema: z.object({ query: z .string() .describe("The search query to find information on the web"), }), execute: async ({ query }) => { // ... }, }), }); /** * Client-side chat transport AI SDK implementation that handles AI model communication * with in-browser AI capabilities. * * @implements {ChatTransport} */ export class WebLLMChatTransport implements ChatTransport { private readonly model: WebLLMLanguageModel; private tools: ReturnType; constructor(model: WebLLMLanguageModel) { this.model = model; this.tools = createTools(); } async sendMessages( options: { chatId: string; messages: WebLLMUIMessage[]; abortSignal: AbortSignal | undefined; } & { trigger: "submit-message" | "submit-tool-result" | "regenerate-message"; messageId: string | undefined; } & ChatRequestOptions, ): Promise> { const { messages, abortSignal } = options; const prompt = await convertToModelMessages(messages); const model = this.model; return createUIMessageStream({ execute: async ({ writer }) => { let downloadProgressId: string | undefined; const availability = await model.availability(); // Only track progress if model needs downloading if (availability !== "available") { await model.createSessionWithProgress((progress) => { const percent = Math.round(progress * 100); if (progress >= 1) { if (downloadProgressId) { writer.write({ type: "data-modelDownloadProgress", id: downloadProgressId, data: { status: "complete", progress: 100, message: "Model finished downloading! Getting ready for inference...", }, }); } return; } if (!downloadProgressId) { downloadProgressId = `download-${Date.now()}`; } writer.write({ type: "data-modelDownloadProgress", id: downloadProgressId, data: { status: "downloading", progress: percent, message: `Downloading browser AI model... ${percent}%`, }, transient: !downloadProgressId, }); }); } const result = streamText({ model, tools: this.tools, stopWhen: stepCountIs(5), messages: prompt, abortSignal, onChunk: (event) => { if (event.chunk.type === "text-delta" && downloadProgressId) { writer.write({ type: "data-modelDownloadProgress", id: downloadProgressId, data: { status: "complete", progress: 100, message: "" }, }); downloadProgressId = undefined; } }, }); writer.merge(result.toUIMessageStream({ sendStart: false })); }, }); } async reconnectToStream( options: { chatId: string; } & ChatRequestOptions, ): Promise | null> { // Client-side AI doesn't support stream reconnection return null; } } ``` -------------------------------- ### Use useChat with WebLLMChatTransport Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/web-llm/usechat-integration.mdx Integrate the custom WebLLMChatTransport with the useChat hook. This example shows how to initialize the WebLLM model and pass the transport to the hook. ```typescript import { webLLM, WebLLMUIMessage } from "@browser-ai/web-llm"; const model = webLLM("Qwen3-0.6B-q0f16-MLC", { worker: new Worker(new URL("./worker.ts", import.meta.url), { type: "module", }), }); const { sendMessage, messages, stop, } = useChat({ transport: new WebLLMChatTransport(model), }); ``` -------------------------------- ### Stream Text with a Worker Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/web-llm/usage.mdx This example demonstrates how to use a Web Worker with WebLLM to stream text responses from a model. ```APIDOC ## Stream Text with a Worker ### Description This example demonstrates how to use a Web Worker with WebLLM to stream text responses from a model. ### Usage ```typescript import { streamText } from "ai"; import { webLLM } from "@browser-ai/web-llm"; const model = webLLM("Qwen3-0.6B-q0f16-MLC", { worker: new Worker(new URL("./worker.ts", import.meta.url), { type: "module", }), }); const result = streamText({ model, messages: [{ role: "user", content: "Hello!" }], }); for await (const chunk of result.textStream) { console.log(chunk); } ``` ``` -------------------------------- ### Use Chat with Transformers.js Model Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/transformers-js/usechat-integration.mdx Integrate a Transformers.js model with the `useChat` hook. This example assumes a compatible browser environment for WebGPU. ```typescript import { transformersJS, TransformersUIMessage } from "@browser-ai/transformers-js"; const model = transformersJS("HuggingFaceTB/SmolLM2-360M-Instruct", { device: "webgpu", worker: new Worker(new URL("./worker.ts", import.meta.url), { type: "module", }), }); const { sendMessage, messages, stop, } = useChat({ transport: new TransformersChatTransport(model), }); ``` -------------------------------- ### Web Worker Setup for WebLLM Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/web-llm/usage.mdx Configure a Web Worker (`worker.ts`) to handle WebLLM model processing off the main thread. This improves application performance by offloading heavy computations. ```typescript import { WebWorkerMLCEngineHandler } from "@browser-ai/web-llm"; const handler = new WebWorkerMLCEngineHandler(); self.onmessage = (msg: MessageEvent) => { handler.onmessage(msg); }; ``` -------------------------------- ### Before: Direct Transformers.js Usage Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/transformers-js/why.mdx This example shows the extensive state management and event handling required when integrating Transformers.js directly into a React component. It involves over 100 lines of code for managing worker messages, loading states, progress updates, and chat messages. ```typescript function App() { const worker = useRef(null); const textareaRef = useRef(null); const chatContainerRef = useRef(null); const [status, setStatus] = useState(null); const [error, setError] = useState(null); const [loadingMessage, setLoadingMessage] = useState(""); const [progressItems, setProgressItems] = useState([]); const [isRunning, setIsRunning] = useState(false); const [input, setInput] = useState(""); const [messages, setMessages] = useState([]); const [tps, setTps] = useState(null); const [numTokens, setNumTokens] = useState(null); function onEnter(message) { setMessages((prev) => [...prev, { role: "user", content: message }]); setTps(null); setIsRunning(true); setInput(""); } function onInterrupt() { worker.current.postMessage({ type: "interrupt" }); } useEffect(() => { if (!worker.current) { worker.current = new Worker(new URL("./worker.js", import.meta.url), { type: "module", }); worker.current.postMessage({ type: "check" }); } const onMessageReceived = (e) => { switch (e.data.status) { case "loading": setStatus("loading"); setLoadingMessage(e.data.data); break; case "initiate": setProgressItems((prev) => [...prev, e.data]); break; case "progress": setProgressItems((prev) => prev.map((item) => { if (item.file === e.data.file) { return { ...item, ...e.data }; } return item; }), ); break; case "done": setProgressItems((prev) => prev.filter((item) => item.file !== e.data.file), ); break; case "ready": setStatus("ready"); break; case "start": setMessages((prev) => [ ...prev, { role: "assistant", content: "" }, ]); break; case "update": const { output, tps, numTokens } = e.data; setTps(tps); setNumTokens(numTokens); setMessages((prev) => { const cloned = [...prev]; const last = cloned.at(-1); cloned[cloned.length - 1] = { ...last, content: last.content + output, }; return cloned; }); break; case "complete": setIsRunning(false); break; case "error": setError(e.data.data); break; } }; worker.current.addEventListener("message", onMessageReceived); worker.current.addEventListener("error", onErrorReceived); return () => { worker.current.removeEventListener("message", onMessageReceived); worker.current.removeEventListener("error", onErrorReceived); }; }, []); // ... rest of the component } ``` -------------------------------- ### Transformers.js Transcription Web Worker Handler Setup Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/transformers-js/api-reference.mdx Configure a Web Worker for transcription models using TransformersJSTranscriptionWorkerHandler. This enables background processing of audio for transcription tasks. ```typescript import { TransformersJSTranscriptionWorkerHandler } from "@browser-ai/transformers-js"; const handler = new TransformersJSTranscriptionWorkerHandler(); self.onmessage = (msg: MessageEvent) => handler.onmessage(msg); ``` -------------------------------- ### Transformers.js Web Worker Handler Setup Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/transformers-js/api-reference.mdx Set up a Web Worker to handle language model tasks off the main thread using TransformersJSWorkerHandler. This improves UI responsiveness during model inference. ```typescript import { TransformersJSWorkerHandler } from "@browser-ai/transformers-js"; const handler = new TransformersJSWorkerHandler(); self.onmessage = (msg: MessageEvent) => handler.onmessage(msg); ``` -------------------------------- ### Server-side Inference with Transformers.js in Next.js Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/transformers-js/usage.mdx Implement server-side inference using Transformers.js within a Next.js API route. This example demonstrates how to handle incoming JSON requests, instantiate a model, and return a streamed response. Adjust the model name and parameters as needed. ```typescript // In a Next.js API route (app/api/chat/route.ts) import { streamText } from "ai"; import { transformersJS } from "@browser-ai/transformers-js"; export async function POST(req: Request) { const { messages } = await req.json(); const model = transformersJS("HuggingFaceTB/SmolLM2-135M-Instruct"); const result = streamText({ model, messages, temperature: 0.7, }); return result.toUIMessageStreamResponse(); } ``` -------------------------------- ### Conditionally Use Client-Side or Server-Side Transport Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/core/usechat-integration.mdx This example shows how to conditionally select a chat transport based on browser compatibility with local LLMs. It uses `doesBrowserSupportBrowserAI()` to decide between a `ClientSideChatTransport` and a `DefaultChatTransport` pointing to a server API. ```typescript import { doesBrowserSupportBrowserAI } from "@browser-ai/core"; const { sendMessage, messages, stop, addToolApprovalResponse, } = useChat({ transport: doesBrowserSupportBrowserAI() // check for device compatibility ? new ClientSideChatTransport() : new DefaultChatTransport({ api: "/api/chat", }), sendAutomaticallyWhen: lastAssistantMessageIsCompleteWithApprovalResponses, ``` -------------------------------- ### Transformers.js Web Worker Boilerplate Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/transformers-js/why.mdx This code demonstrates the extensive setup required for a Web Worker when using only the base Transformers.js library. It includes handling model loading, generation, streaming, and error states. ```typescript import { AutoTokenizer, AutoModelForCausalLM, TextStreamer, InterruptableStoppingCriteria, } from "@huggingface/transformers" async function check() { try { const adapter = await navigator.gpu.requestAdapter() if (!adapter) { throw new Error("WebGPU is not supported (no adapter found)") } } catch (e) { self.postMessage({ status: "error", data: e.toString(), }) } } class TextGenerationPipeline { static model_id = "HuggingFaceTB/SmolLM2-1.7B-Instruct" static async getInstance(progress_callback = null) { this.tokenizer ??= AutoTokenizer.from_pretrained(this.model_id, { progress_callback, }) this.model ??= AutoModelForCausalLM.from_pretrained(this.model_id, { dtype: "q4f16", device: "webgpu", progress_callback, }) return Promise.all([this.tokenizer, this.model]) } } const stopping_criteria = new InterruptableStoppingCriteria() let past_key_values_cache = null async function generate(messages) { const [tokenizer, model] = await TextGenerationPipeline.getInstance() const inputs = tokenizer.apply_chat_template(messages, { add_generation_prompt: true, return_dict: true, }) let startTime let numTokens = 0 let tps const token_callback_function = () => { startTime ??= performance.now() if (numTokens++ > 0) { tps = (numTokens / (performance.now() - startTime)) * 1000 } } const callback_function = (output) => { self.postMessage({ status: "update", output, tps, numTokens, }) } const streamer = new TextStreamer(tokenizer, { skip_prompt: true, skip_special_tokens: true, callback_function, token_callback_function, }) self.postMessage({ status: "start" }) const { past_key_values, sequences } = await model.generate({ ...inputs, past_key_values: past_key_values_cache, max_new_tokens: 1024, streamer, stopping_criteria, return_dict_in_generate: true, }) past_key_values_cache = past_key_values const decoded = tokenizer.batch_decode(sequences, { skip_special_tokens: true, }) self.postMessage({ status: "complete", output: decoded, }) } async function load() { self.postMessage({ status: "loading", data: "Loading model...", }) const [tokenizer, model] = await TextGenerationPipeline.getInstance((x) => { self.postMessage(x) }) self.postMessage({ status: "loading", data: "Compiling shaders and warming up model...", }) const inputs = tokenizer("a") await model.generate({ ...inputs, max_new_tokens: 1 }) self.postMessage({ status: "ready" }) } self.addEventListener("message", async (e) => { const { type, data } = e.data switch (type) { case "check": check() break case "load": load() break case "generate": stopping_criteria.reset() generate(data) break case "interrupt": stopping_criteria.interrupt() break case "reset": past_key_values_cache = null stopping_criteria.reset() break } }) ``` -------------------------------- ### BrowserAIChatLanguageModel.createSessionWithProgress(onProgress?) Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/core/api-reference.mdx Creates a language model session, with an optional callback to monitor download progress. ```APIDOC ## BrowserAIChatLanguageModel.createSessionWithProgress(onDownloadProgress?) ### Description Creates a language model session with optional download progress monitoring. ### Parameters #### Optional Parameters - **onDownloadProgress** (function) - Optional callback that receives progress values from 0 to 1 during model download ### Returns `Promise` - The configured language model instance ``` -------------------------------- ### BrowserAIChatLanguageModel.getContextUsage() Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/core/api-reference.mdx Gets the current context usage in tokens for the active session, returning undefined if no session is available. ```APIDOC ## BrowserAIChatLanguageModel.getContextUsage() ### Description Gets the current context usage (tokens consumed) of the current session. If the session is not available returns undefined. ### Returns `number | undefined` ``` -------------------------------- ### Run Tests Source: https://github.com/jakobhoeg/browser-ai/blob/main/CONTRIBUTING.md Executes the project's test suite. ```bash npm run test ``` -------------------------------- ### WebLLMLanguageModel.createSessionWithProgress(onProgress?) Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/web-llm/api-reference.mdx Creates a language model session, providing an optional callback to monitor the download progress of the model. ```APIDOC ## WebLLMLanguageModel.createSessionWithProgress(onProgress?) ### Description Creates a language model session with optional download progress monitoring. ### Parameters - **onProgress** ((progress: number) => void) - Optional callback that receives progress values from 0 to 1 during model download ### Returns `Promise` - The configured language model instance ``` -------------------------------- ### Monitor Model Download Progress Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/transformers-js/api-reference.mdx Create a language model session while monitoring the download progress using the createSessionWithProgress method. This is useful for providing user feedback during model loading. ```typescript import { transformersJS } from "@browser-ai/transformers-js"; const model = await transformersJS.createSessionWithProgress((progress) => { console.log("Model download progress:", Math.round(progress * 100)); }); ``` -------------------------------- ### Generate Text Non-streaming with WebLLM Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/web-llm/usage.mdx Use `generateText` to get the complete text response from a WebLLM model after processing. This is suitable when the full output is needed at once. ```typescript import { generateText } from "ai"; import { webLLM } from "@browser-ai/web-llm"; const result = await generateText({ model: webLLM("Qwen3-0.6B-q0f16-MLC"), prompt: "Invent a new holiday and describe its traditions.", }); console.log(result.text); ``` -------------------------------- ### Create and Run a Weather Agent Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/web-llm/agents.mdx Defines a weather assistant agent with tools for fetching weather and converting temperatures. Use reasoning models like Qwen3 for better multi-step reasoning. ```typescript import { ToolLoopAgent, stepCountIs, tool } from 'ai'; import { webLLM } from "@browser-ai/web-llm"; import { z } from 'zod'; const weatherAgent = new ToolLoopAgent({ model: webLLM("Qwen3-1.7B-q4f16_1-MLC"), instructions: 'You are a weather assistant.', tools: { weather: tool({ description: 'Get the weather in a location (in Fahrenheit)', inputSchema: z.object({ location: z.string().describe('The location to get the weather for'), }), execute: async ({ location }) => ({ location, temperature: 72 + Math.floor(Math.random() * 21) - 10, }), }), convertFahrenheitToCelsius: tool({ description: 'Convert temperature from Fahrenheit to Celsius', inputSchema: z.object({ temperature: z.number().describe('Temperature in Fahrenheit'), }), execute: async ({ temperature }) => { const celsius = Math.round((temperature - 32) * (5 / 9)); return { celsius }; }, }), }, // Agent's default behavior is to stop after a maximum of 20 steps // stopWhen: stepCountIs(20), }); const result = await weatherAgent.generate({ prompt: 'What is the weather in San Francisco in celsius?', }); console.log(result.text); // agent's final answer console.log(result.steps); // steps taken by the agent ``` -------------------------------- ### WebLLM Tool Calling with Multi-step Execution Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/web-llm/usage.mdx Implement tool calling with WebLLM models, supporting multi-step execution. For optimal results, use reasoning models like Qwen3. The `stopWhen` option can limit the number of execution steps. ```typescript import { streamText, tool, stepCountIs } from "ai"; import { webLLM } from "@browser-ai/web-llm"; import { z } from "zod"; const result = await streamText({ model: webLLM("Qwen3-0.6B-q0f16-MLC"), messages: [{ role: "user", content: "What's the weather in San Francisco?" }], tools: { weather: tool({ description: "Get the weather in a location", inputSchema: z.object({ location: z.string().describe("The location to get the weather for"), }), execute: async ({ location }) => ({ location, temperature: 72 + Math.floor(Math.random() * 21) - 10, }), }), }, stopWhen: stepCountIs(5), // multiple steps }); ``` -------------------------------- ### webLLM(modelId, settings?) Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/web-llm/api-reference.mdx Creates a WebLLM model instance. This is the primary function for initializing a language model. ```APIDOC ## webLLM(modelId, settings?) ### Description Creates a WebLLM model instance. ### Parameters - **modelId** (string) - Required - The model identifier from the [supported list of models](https://github.com/mlc-ai/web-llm/blob/main/src/config.ts) - **settings** (object) - Optional - Configuration options - **appConfig** (AppConfig) - Custom app configuration for WebLLM - **initProgressCallback** ((progress: number) => void) - Progress callback for model initialization - **engineConfig** (MLCEngineConfig) - Engine configuration options - **worker** (Worker) - A web worker instance to run the model in for better performance ### Returns `WebLLMLanguageModel` ``` -------------------------------- ### doesBrowserSupportWebLLM() Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/web-llm/api-reference.mdx Performs a quick check to determine if the browser environment supports WebLLM, which is crucial for enabling AI features. ```APIDOC ## doesBrowserSupportWebLLM() ### Description Quick check if the browser supports WebLLM. Useful for component-level decisions and feature flags. ### Returns `boolean` - `true` if browser supports WebGPU, `false` otherwise ``` -------------------------------- ### Create Chat Session with Progress Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/core/api-reference.mdx Creates a language model session, optionally providing a callback to monitor download progress. The progress is reported as a number between 0 and 1. ```typescript import { browserAI } from "@browser-ai/core"; const chatModel = browserAI(); const session = await chatModel.createSessionWithProgress( (progress) => { console.log(`Model download progress: ${progress * 100}%`); } ); console.log("Session created:", session); ``` -------------------------------- ### Multimodal Support for Images and Audio Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/core/usage.mdx The Prompt API supports multimodal inputs, including images and audio files, for use with the browser AI model. Ensure correct `mediaType` and `data` are provided. ```typescript import { streamText } from "ai"; import { browserAI } from "@browser-ai/core"; const result = streamText({ model: browserAI(), messages: [ { // Image role: "user", content: [ { type: "text", text: "What's in this image?" }, { type: "file", mediaType: "image/png", data: base64ImageData }, ], }, { // Audio role: "user", content: [{ type: "file", mediaType: "audio/mp3", data: audioData }], }, ], }); for await (const chunk of result.textStream) { console.log(chunk); } ``` -------------------------------- ### Basic Usage with WebLLM Source: https://github.com/jakobhoeg/browser-ai/blob/main/README.md Utilize the webLLM provider for streaming text with specific open-source models. Requires @browser-ai/web-llm. ```typescript import { streamText } from "ai"; import { webLLM } from "@browser-ai/web-llm"; const result = streamText({ model: webLLM("Llama-3.2-3B-Instruct-q4f16_1-MLC"), prompt: "Invent a new holiday and describe its traditions.", }); for await (const chunk of result.textStream) { console.log(chunk); } ``` -------------------------------- ### Track Model Download Progress Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/transformers-js/usage.mdx Track model download progress using `createSessionWithProgress` before using the model. This is crucial for first-time model usage to provide a better user experience. ```typescript import { streamText } from "ai"; import { transformersJS } from "@browser-ai/transformers-js"; const model = transformersJS("HuggingFaceTB/SmolLM2-360M-Instruct"); const availability = await model.availability(); if (availability === "unavailable") { console.log("Browser doesn't support Transformers.js"); return; } if (availability === "downloadable") { await model.createSessionWithProgress((progress) => { console.log(`Download progress: ${Math.round(progress * 100)}%`); }); } // Model is ready const result = streamText({ model, prompt: 'Invent a new holiday and describe its traditions.', }); ``` -------------------------------- ### Tool Calling with Transformers.js Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/transformers-js/usage.mdx Enable tool calling with Transformers.js models, particularly reasoning models like Qwen3. Supports multi-step execution and custom tool definitions with input schemas and execution logic. ```typescript import { streamText, tool, stepCountIs } from "ai"; import { transformersJS } from "@browser-ai/transformers-js"; import { z } from "zod"; const result = await streamText({ model: transformersJS("onnx-community/Qwen3-0.6B-ONNX"), messages: [{ role: "user", content: "What's the weather in San Francisco?" }], tools: { weather: tool({ description: 'Get the weather in a location', inputSchema: z.object({ location: z.string().describe('The location to get the weather for'), }), execute: async ({ location }) => ({ location, temperature: 72 + Math.floor(Math.random() * 21) - 10, }), }), }, stopWhen: stepCountIs(5), // multiple steps }); ``` -------------------------------- ### browserAI(modelId?, settings?) Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/core/api-reference.mdx Creates a browser AI model instance for chat. Allows for optional model ID and settings configuration. ```APIDOC ## browserAI(modelId?, settings?) ### Description Creates a browser AI model instance for chat. ### Parameters #### Optional Parameters - **modelId** (string) - The model identifier, defaults to `'text'` - **settings** (object) - Configuration options - **temperature** (number) - Controls randomness (0-1) - **topK** (number) - Limits vocabulary selection - **onContextOverflow** (function) - Callback for when the model context window is exceeded ### Returns `BrowserAIChatLanguageModel` ``` -------------------------------- ### Monitor Transcription Model Session Creation Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/transformers-js/api-reference.mdx Create a transcription model session and track its progress with createSessionWithProgress. This is helpful for informing users about the model's readiness for transcription tasks. ```typescript import { transformersJS } from "@browser-ai/transformers-js"; const transcriptionModel = await transformersJS.transcription.createSessionWithProgress((progress) => { console.log("Transcription model session progress:", Math.round(progress * 100)); }); ``` -------------------------------- ### Download Progress Tracking Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/web-llm/usage.mdx Tracks the download progress when creating a new model session. ```APIDOC ## Download Progress Tracking ### Description Tracks the download progress when creating a new model session. ### Usage ```typescript import { embed } from "ai"; import { webLLM } from "@browser-ai/web-llm"; const model = webLLM.embeddingModel("snowflake-arctic-embed-m-q0f32-MLC-b32"); if ((await model.availability()) === "downloadable") { await model.createSessionWithProgress((progress) => { console.log(`Download: ${progress.text}`); }); } const { embedding } = await embed({ model, value: "hello" }); ``` ``` -------------------------------- ### BrowserAIChatLanguageModel.availability() Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/core/api-reference.mdx Checks the current availability status of the browser AI model, returning one of four possible states. ```APIDOC ## BrowserAIChatLanguageModel.availability() ### Description Checks the current availability status of the browser AI model. ### Returns `Promise<"unavailable" | "downloadable" | "downloading" | "available">` | Status | Description | |--------|-------------| | `"unavailable"` | Model is not supported in the browser | | `"downloadable"` | Model is supported but needs to be downloaded first | | `"downloading"` | Model is currently being downloaded | | `"available"` | Model is ready to use | ``` -------------------------------- ### TransformersJSLanguageModel.createSessionWithProgress Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/transformers-js/api-reference.mdx Creates a language model session, optionally monitoring the download progress via a callback function. ```APIDOC ## TransformersJSLanguageModel.createSessionWithProgress(onProgress?) Creates a language model session with optional download progress monitoring. **Parameters:** - `onProgress?: (progress: number) => void` - Callback receiving progress values from 0 to 1 **Returns:** `Promise` ``` -------------------------------- ### Generate Changeset Source: https://github.com/jakobhoeg/browser-ai/blob/main/CONTRIBUTING.md Use this command to create a changeset for package releases. Only use patch changesets. ```bash npx changeset ``` -------------------------------- ### WebLLM Tool Calling with Structured Output Agent Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/web-llm/usage.mdx Utilize the `ToolLoopAgent` for tool calling with WebLLM, enabling structured output definition. This approach allows for defining expected output schemas and handling tool execution within an agent framework. ```typescript import { Output, ToolLoopAgent, tool } from "ai"; import { webLLM } from "@browser-ai/web-llm"; import { z } from "zod"; const agent = new ToolLoopAgent({ model: webLLM("Qwen3-0.6B-q0f16-MLC"), tools: { weather: tool({ description: "Get the weather in a location", inputSchema: z.object({ city: z.string() }), execute: async ({ city }) => { // ... }, }), }, output: Output.object({ schema: z.object({ summary: z.string(), temperature: z.number(), recommendation: z.string(), }), }), }); const { output } = await agent.generate({ prompt: "What is the weather in San Francisco and what should I wear?", }); ``` -------------------------------- ### Format Code with Prettier Source: https://github.com/jakobhoeg/browser-ai/blob/main/CONTRIBUTING.md Runs Prettier to format code files. Commit any changes made by this command. ```bash npm run format ``` -------------------------------- ### Check Browser Support for Transformers.js Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/transformers-js/api-reference.mdx Use doesBrowserSupportTransformersJS to quickly determine if the current browser environment is suitable for running Transformers.js with optimal performance, checking for WebGPU or WebAssembly support. ```typescript import { doesBrowserSupportTransformersJS } from "@browser-ai/transformers-js"; if (doesBrowserSupportTransformersJS()) { console.log("Browser supports Transformers.js optimally."); } else { console.log("Browser may not support Transformers.js optimally."); } ``` -------------------------------- ### BrowserAIChatLanguageModel.getContextWindow() Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/core/api-reference.mdx Retrieves the context window size in tokens for the current session, returning undefined if no session is available. ```APIDOC ## BrowserAIChatLanguageModel.getContextWindow() ### Description Gets the context window size (token limit) of the current session. If the session is not available returns undefined. ### Returns `number | undefined` ``` -------------------------------- ### Tool Calling with Multi-step Execution Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/core/usage.mdx Implement tool calling with the `browserAI` model, supporting multi-step execution and custom `stopWhen` conditions. Define tools with schemas and execution logic. ```typescript import { streamText, stepCountIs } from "ai"; import { browserAI } from "@browser-ai/core"; import { z } from "zod"; const result = await streamText({ model: browserAI(), messages: [{ role: "user", content: "What's the weather in San Francisco?" }], tools: { weather: tool({ description: 'Get the weather in a location', inputSchema: z.object({ location: z.string().describe('The location to get the weather for'), }), execute: async ({ location }) => ({ location, temperature: 72 + Math.floor(Math.random() * 21) - 10, }), }), }, stopWhen: stepCountIs(5), // multiple steps }); ``` -------------------------------- ### Track WebLLM Model Download Progress Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/web-llm/usage.mdx Monitor the download progress of WebLLM models to provide user feedback. This is crucial for first-time model usage, as models need to be downloaded before they can be used. ```typescript import { streamText } from "ai"; import { webLLM } from "@browser-ai/web-llm"; const model = webLLM("Qwen3-0.6B-q0f16-MLC"); const availability = await model.availability(); if (availability === "unavailable") { console.log("Browser doesn't support WebLLM"); return; } if (availability === "downloadable") { await model.createSessionWithProgress((progress) => { console.log(`Download progress: ${Math.round(progress * 100)}%`); }); } // Model is ready const result = streamText({ model, messages: [{ role: "user", content: "Hello!" }], }); ``` -------------------------------- ### Track Model Download Progress Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/core/usage.mdx Monitor the download progress of browser AI models for a better user experience. The `model.availability()` and `model.createSessionWithProgress()` methods are used for this purpose. ```typescript import { streamText } from "ai"; import { browserAI } from "@browser-ai/core"; const model = browserAI(); const availability = await model.availability(); if (availability === "unavailable") { console.log("Browser doesn't support built-in AI"); return; } if (availability === "downloadable") { await model.createSessionWithProgress((progress) => { console.log(`Download progress: ${Math.round(progress * 100)}%`); }); } // Model is ready const result = streamText({ model, prompt: 'Invent a new holiday and describe its traditions.', }); ``` -------------------------------- ### Monitor Embedding Model Session Creation Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/transformers-js/api-reference.mdx Initialize an embedding model session and monitor its creation progress using createSessionWithProgress. This allows for displaying download or initialization status to the user. ```typescript import { transformersJS } from "@browser-ai/transformers-js"; const embeddingModel = await transformersJS.textEmbedding.createSessionWithProgress((progress) => { console.log("Embedding model session progress:", Math.round(progress * 100)); }); ``` -------------------------------- ### WebLLMSettings Interface Definition Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/web-llm/api-reference.mdx Defines the configuration options available when initializing a WebLLM model, including custom app configuration, progress callbacks, engine settings, and worker instances. ```typescript interface WebLLMSettings { appConfig?: AppConfig; initProgressCallback?: (progress: number) => void; engineConfig?: MLCEngineConfig; worker?: Worker; } ``` -------------------------------- ### WebLLMLanguageModel.availability() Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/web-llm/api-reference.mdx Checks the current availability status of the WebLLM model, indicating whether it's unavailable, downloadable, or ready to use. ```APIDOC ## WebLLMLanguageModel.availability() ### Description Checks the current availability status of the WebLLM model. ### Returns `Promise<"unavailable" | "downloadable" | "available">` | Status | Description | | ---------------- | --------------------------------------------------- | | `"unavailable"` | Model is not supported in the browser (no WebGPU) | | `"downloadable"` | Model is supported but needs to be downloaded first | | `"available"` | Model is ready to use | ``` -------------------------------- ### doesBrowserSupportBrowserAI() Source: https://github.com/jakobhoeg/browser-ai/blob/main/docs/content/docs/ai-sdk-v6/core/api-reference.mdx Checks if the browser supports the browser AI API, useful for feature flagging. ```APIDOC ## doesBrowserSupportBrowserAI() ### Description Quick check if the browser supports the browser AI API. Useful for component-level decisions and feature flags. ### Returns `boolean` - `true` if browser supports the Prompt API, `false` otherwise ```