Prompt API Documentation

repository·main·Indexed 20 days ago

https://github.com/webmachinelearning/prompt-api

A proposed web platform API providing direct access to built-in, on-device, or cloud-based language models within the browser. It features a uniform JavaScript API for tasks like text classification, summarization, and translation, supporting zero-shot and N-shot prompting, system prompts, tool use, multimodal inputs (images and audio), and response constraints via JSON schema or Regular Expressions.

Tokens
8.4K
Snippets
22
Records
27
Agent score
23%

What's inside Prompt API

  1. Overview of the Prompt API

    main

    The Prompt API provides a uniform JavaScript API for accessing language models provided by the browser or operating system. It allows web developers to perform general-purpose tasks like text classification, summarization, translation, and question answering directly through the web platform.

    Key benefits include:

    • Local processing: Enables privacy-preserving AI by keeping sensitive data on-device.
    • Performance: Potentially faster results by avoiding server round-trips.
    • Offline capability: Enables AI features without an internet connection.
    • Cost efficiency: Reduces API costs for developers by leveraging built-in models.
    • Resource optimization: Uses models optimized for the specific device, saving user bandwidth and storage.
  2. Use System Prompts to set context

    main

    A system prompt provides context for the entire session. It must be the very first message in the sequence. You can provide it in three ways:

    1. Via the initialPrompts option in LanguageModel.create().
    2. By calling session.append() with a system role message immediately after creation.
    3. By including the system role as the first object in the array passed to session.prompt().

    Note: Placing a { role: "system" } prompt anywhere other than the 0th position in the first message sequence will result in a TypeError.

    // Option 1: Create a new session with a system prompt as the first message.
    const session1 = await LanguageModel.create({
      initialPrompts: [{ role: "system", content: "Pretend to be an eloquent hamster." }]
    });
    console.log(await session1.prompt("What is your favorite food?"));
    
    // Option 2: Create a new session and append a system prompt as the first message.
    const session2 = await LanguageModel.create();
    await session2.append([{ role: "system", content: "Pretend to be an eloquent hamster." }]);
    console.log(await session2.prompt("What is your favorite food?"));
    
    // Option 3: Create a new session and prompt with a system prompt as the first message.
    const session3 = await LanguageModel.create();
    console.log(await session3.prompt([
      { role: "system", content: "Pretend to be an eloquent hamster." },
      { role: "user", content: "What is your favorite food?" }
    ]));
  3. How the Prompt API lifecycle works

    main

    The Prompt API manages the model lifecycle through a session-based model. The process typically involves these stages:

    1. Download: The model is downloaded if it is not already present on the device.
    2. Establish Session: A session is created using LanguageModel.create(), which includes configuring per-session options.
    3. Context/Prompting: You can add an initial prompt to establish context (without generating a response) or execute a prompt directly using session.prompt() or session.promptStreaming() to receive a response.

    This session-based design is intended to be more efficient for on-device models compared to a stateless design where the developer must manually pass the entire conversation history with every request.

  4. Understand Prompt API availability in Workers

    main
    The Prompt API is currently not available in web platform workers. This restriction is due to the complexity of establishing a responsible document for permission policy checks within a worker context. While it may not be available in standard web platform workers, browser implementations may expose it to extension service workers (which follow a different permissions model).
  5. Manage language model session persistence and cloning

    main

    A LanguageModel session maintains a persistent history of interactions. You can create a session with initialPrompts to set a system role or context. To create multiple independent continuations of the same session state, use the .clone() method. Cloning can be controlled using an AbortSignal.

    const session = await LanguageModel.create({
      initialPrompts: [{
        role: "system",
        content: "You are a friendly, helpful assistant specialized in clothing choices."
      }]
    });
    
    const result = await session.prompt("What should I wear today?");
    
    // Create an independent continuation of this session
    const session2 = await session.clone();
    
    // Clone with an abort signal
    const controller = new AbortController();
    const session3 = await session.clone({ signal: controller.signal });
  6. Monitor and manage context window limits and overflow

    main

    Language model sessions have a maximum token capacity (the contextWindow).

    Monitoring usage:

    • Use session.contextUsage to see current tokens used.
    • Use session.contextWindow to see total available tokens.
    • Use session.measureContextUsage(input) to estimate token consumption of a potential prompt without sending it.

    Handling overflow: If a prompt exceeds the remaining capacity, the session automatically removes the oldest conversation history (excluding initialPrompts) to make room. You can listen for the "contextoverflow" event to detect this.

    If the prompt is so large that even after removing history it cannot fit, the call will fail with a QuotaExceededError.

    // Check current usage
    console.log(`${session.contextUsage} tokens used, out of ${session.contextWindow} tokens available.`);
    
    // Estimate usage for a string
    const stringUsage = await session.measureContextUsage(promptString);
    
    // Estimate usage for multimodal input
    const audioUsage = await session.measureContextUsage([{
      role: "user",
      content: [
        { type: "text", value: "My response:" },
        { type: "audio", value: audioBlob }
      ]
    }]);
    
    // Listen for overflow events
    session.addEventListener("contextoverflow", () => {
      console.log("Context window exceeded; old messages dropped.");
    });
  7. Configure expected input and output languages

    main

    To ensure the browser downloads necessary fine-tunings or safety models, provide expectedInputs and expectedOutputs when calling LanguageModel.create(). This allows the browser to fail-fast if the requested languages are unsupported.

    expectedInputs is an array of objects specifying the type (e.g., "text", "audio", "image") and an optional languages array.

    const session = await LanguageModel.create({
      initialPrompts: [{
        role: "system",
        content: "You are a Japanese tutor."
      }],
      expectedInputs: [
        { type: "text", languages: ["en", "ja"] },
        { type: "audio" }, // Best-effort based on base model
        { type: "image", languages: ["fr"] }
      ],
      expectedOutputs: [{
        type: "text",
        languages: ["ja", "ko"]
      }]
    });
  8. Abort specific prompts or append operations

    main

    You can abort individual calls to .prompt(), .promptStreaming(), or .append() by passing an AbortSignal.

    Behavior based on state:

    • Queued: If the operation is still in the queue, it is removed and the promise rejects with "AbortError".
    • Ongoing: If the model is currently responding, the operation is aborted, the prompt/response pair is removed from the session, and the promise rejects with "AbortError".
    • Completed: If the operation has already finished, attempting to abort does nothing.
    const controller = new AbortController();
    const result = await session.prompt("Write me a poem", { signal: controller.signal });
    
    // To abort:
    controller.abort();
  9. Constrain model responses with JSON schema or RegExp

    main

    To ensure programmatic processing of model responses, you can use the responseConstraint option in session.prompt(). This allows you to force the model to adhere to a specific structure or pattern.

    JSON Schema

    Pass a valid JSON schema object. The returned string can be parsed with JSON.parse(). If the model cannot produce a compliant response, a SyntaxError is thrown.

    Regular Expressions

    Pass a RegExp object. The returned string will match the pattern. If the model cannot produce a matching response, a SyntaxError is thrown.

    Optimizing Context Usage

    By default, the constraint is included in the prompt, consuming tokens. To avoid this, use omitResponseConstraintInput: true and include the instructions manually in your prompt string.

    Note: If omitResponseConstraintInput is true but responseConstraint is not set, a TypeError occurs.

    // Using JSON Schema
    const schema = {
      type: "object",
      required: ["rating"],
      additionalProperties: false,
      properties: {
        rating: { type: "number", minimum: 0, maximum: 5 },
      },
    };
    
    const result = await session.prompt("Summarize this feedback into a rating between 0-5: The food was delicious.", {
      responseConstraint: schema
    });
    const { rating } = JSON.parse(result);
    
    // Using RegExp
    const emailRegExp = /^[a-zA-Z0-9.!#$%&'*+\/:=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9]{0,61}[a-zA-Z0-9])?$/;
    const emailAddress = await session.prompt(
      `Create a fictional email address for ${characterName}.`,
      { responseConstraint: emailRegExp }
    );
    
    // Using omitResponseConstraintInput to save tokens
    const result = await session.prompt(
      `Summarize this feedback into a rating between 0-5, only outputting a JSON object { rating }, with a single property whose value is a number: The food was delicious.`,
      { responseConstraint: schema, omitResponseConstraintInput: true }
    );
  10. Implement Tool Use

    main

    The Prompt API supports tool use via the tools option in LanguageModel.create(). This allows the model to invoke external JavaScript functions.

    Each tool object requires:

    • name: A unique identifier.
    • description: A description of what the tool does.
    • inputSchema: A JSON schema defining the arguments.
    • execute: An async function that performs the task and returns a result (e.g., a JSON string).

    Concurrency Note: The model may call tools multiple times concurrently (e.g., if a user asks about multiple locations). The user agent handles these calls using internal Promise.all() logic before the model generates its final response.

    const session = await LanguageModel.create({
      initialPrompts: [
        { role: "system", content: "You are a helpful assistant. You can use tools to help the user." },
      ],
      expectedInputs: [{ type: "text", languages: ["en"] }, { type: "tool-response" }],
      expectedOutputs: [{ type: "text", languages: ["en"] }, { type: "tool-call" }],
      tools: [
        {
          name: "getWeather",
          description: "Get the weather in a location.",
          inputSchema: {
            type: "object",
            properties: {
              location: {
                type: "string",
                description: "The city to check for the weather condition.",
              },
            },
            required: ["location"],
          },
          async execute({ location }) {
            const res = await fetch("https://weatherapi.example/?location=" + location);
            return JSON.stringify(await res.json());
          },
        },
      ],
    });
    
    const result = await session.prompt("What is the weather in Seattle?");
  11. Use Multimodal Inputs (Images and Audio)

    main

    To use multimodal inputs, you must configure the session using the expectedInputs option during LanguageModel.create(). This ensures necessary downloads occur and validates model capability.

    Format Changes for Multimodal Prompts: When using multimodal content, you cannot use the string shorthand. You must use the explicit array-of-objects format:

    1. prompt() must receive an array of messages.
    2. Each message must have a role property.
    3. The content property must be an array of content objects (e.g., { type: 'text', value: '...' }, { type: 'image', value: ... }).

    Supported Types:

    • Images: Blob, ImageData, ImageBitmap, VideoFrame, OffscreenCanvas, HTMLImageElement, SVGImageElement, HTMLCanvasElement, HTMLVideoElement, or BufferSource.
    • Audio: Blob, AudioBuffer, or BufferSource.

    Security Note: Cross-origin data (like images from another domain) that lacks Access-Control-Allow-Origin headers will cause a SecurityError DOMException.

    const session = await LanguageModel.create({
      expectedInputs: [
        { type: "audio" },
        { type: "image" }
      ]
    });
    
    const referenceImage = await (await fetch("/reference-image.jpeg")).blob();
    const userDrawnImage = document.querySelector("canvas");
    
    const response1 = await session.prompt([{
      role: "user",
      content: [
        { type: "text", value: "Give a helpful artistic critique of how well the second image matches the first:" },
        { type: "image", value: referenceImage },
        { type: "image", value: userDrawnImage }
      ]
    }]);