Documents
assistant-frame
assistant-frame
Type
External
Status
Published
Created
Mar 17, 2026
Updated
Mar 17, 2026

The Assistant Frame API enables iframes to provide model context (tools and instructions) to a parent window's assistant. This is particularly useful for embedded applications, plugins, or sandboxed components that need to contribute capabilities to the main assistant.

Overview#

The Assistant Frame system consists of two main components:

  • AssistantFrameProvider: Runs inside the iframe and provides model context
  • AssistantFrameHost: Runs in the parent window and consumes context from iframes

Basic Usage#

In the iframe (Provider)#

The iframe acts as a provider of model context using AssistantFrameProvider:

// iframe.tsx
import { AssistantFrameProvider } from "@assistant-ui/react";
import { ModelContextRegistry } from "@assistant-ui/react";
import { z } from "zod";

// Create a registry to manage your model context
const registry = new ModelContextRegistry();

// Expose the registry to the parent window
AssistantFrameProvider.addModelContextProvider(registry);

// Add tools that will be available to the parent assistant
registry.addTool({
  toolName: "searchProducts",
  description: "Search for products in the catalog",
  parameters: z.object({
    query: z.string(),
    category: z.string().optional(),
  }),
  execute: async ({ query, category }) => {
    // Tool implementation runs in the iframe
    const results = await searchAPI(query, category);
    return { products: results };
  },
});

// Add system instructions
const instructionHandle = registry.addInstruction(
  "You are a helpful assistant.",
);

// update the instruction
instructionHandle.update("You have access to a product catalog search tool.");

In the parent window (Host)#

The parent window consumes the iframe's context using AssistantFrameHost:

// parent.tsx
import { useAssistantFrameHost } from "@assistant-ui/react";
import { useRef } from "react";

function ParentComponent() {
  const iframeRef = useRef<HTMLIFrameElement>(null);

  // Connect to the iframe's model context
  useAssistantFrameHost({
    iframeRef,
    targetOrigin: "https://trusted-iframe-domain.com", // optional for increased security
  });

  return (
    <div>
      <Thread /> {/* Your assistant-ui */}
      <iframe
        ref={iframeRef}
        src="https://trusted-iframe-domain.com/embed"
        title="Embedded App"
      />
    </div>
  );
}

Advanced Usage#

ModelContextRegistry#

The ModelContextRegistry provides a flexible way to manage model context dynamically:

const registry = new ModelContextRegistry();

// Add a tool with handle for updates
const toolHandle = registry.addTool({
  toolName: "convertCurrency",
  description: "Convert between currencies",
  parameters: z.object({
    amount: z.number(),
    from: z.string(),
    to: z.string(),
  }),
  execute: async ({ amount, from, to }) => {
    const rate = await fetchExchangeRate(from, to);
    return { result: amount * rate, currency: to };
  },
});

// Update the tool later
toolHandle.update({
  toolName: "convertCurrency",
  description: "Convert between currencies with live rates", // Updated description
  parameters: z.object({
    amount: z.number(),
    from: z.string(),
    to: z.string(),
    includesFees: z.boolean().optional(),
  }),
  execute: async ({ amount, from, to, includesFees }) => {
    const rate = await fetchExchangeRate(from, to);
    const fee = includesFees ? 0.02 : 0; // 2% fee
    return {
      result: amount * rate * (1 - fee),
      currency: to,
      fee: includesFees ? amount * rate * fee : 0,
    };
  },
});

// Remove the tool when no longer needed
toolHandle.remove();

// Add multiple instructions
const instruction1 = registry.addInstruction("Be helpful and concise.");
const instruction2 = registry.addInstruction("Use metric units.");

// Remove instructions
instruction1.remove();

Multiple Providers#

You can register multiple model context providers in the same iframe:

const catalogRegistry = new ModelContextRegistry();
const analyticsRegistry = new ModelContextRegistry();

// Add different tools to each registry
catalogRegistry.addTool({
  /* ... */
});
analyticsRegistry.addTool({
  /* ... */
});

// Register both providers
const unsubscribe1 =
  AssistantFrameProvider.addModelContextProvider(catalogRegistry);
const unsubscribe2 =
  AssistantFrameProvider.addModelContextProvider(analyticsRegistry);

// Later, unsubscribe if needed
unsubscribe1();
unsubscribe2();

Security Considerations#

Origin Validation#

Both the provider and host can specify allowed origins for security:

// In iframe - only accept messages from specific parent
AssistantFrameProvider.addModelContextProvider(
  registry,
  "https://parent-app.com",
);

// In parent - only accept messages from specific iframe
useAssistantFrameHost({
  iframeRef,
  targetOrigin: "https://iframe-app.com",
});

Tool Execution#

Tools are executed in the iframe's context, keeping sensitive operations sandboxed:

registry.addTool({
  toolName: "accessDatabase",
  description: "Query the database",
  parameters: z.object({ query: z.string() }),
  execute: async ({ query }) => {
    // This runs in the iframe with iframe's permissions
    // Parent cannot directly access the database
    const results = await db.query(query);
    return results;
  },
});

API Reference#

AssistantFrameProvider#

Static class that manages model context providers in an iframe.

Methods#

addModelContextProvider(provider, targetOrigin?)#

Registers a model context provider to share with parent windows.

const unsubscribe = AssistantFrameProvider.addModelContextProvider(
  registry,
  "https://parent-domain.com", // Optional origin restriction
);
dispose()#

Cleans up all resources and removes all providers.

AssistantFrameProvider.dispose();

AssistantFrameHost#

Class that connects to an iframe's model context providers.

Constructor#

const host = new AssistantFrameHost(
  iframeWindow,
  targetOrigin? // Optional origin restriction
);

Methods#

getModelContext()#

Returns the current merged model context from the iframe.

const context = host.getModelContext();
// { system: "...", tools: { ... } }
subscribe(callback)#

Subscribes to model context changes.

const unsubscribe = host.subscribe(() => {
  console.log("Context updated:", host.getModelContext());
});
dispose()#

Cleans up the connection to the iframe.

host.dispose();

useAssistantFrameHost#

React hook that manages the lifecycle of an AssistantFrameHost.

useAssistantFrameHost({
  iframeRef: RefObject<HTMLIFrameElement>,
  targetOrigin?: string,
});

ModelContextRegistry#

A flexible registry for managing model context with dynamic updates.

Methods#

addTool(tool)#

Adds a tool and returns a handle for updates/removal.

const handle = registry.addTool({
  toolName: string,
  description?: string,
  parameters: ZodSchema | JSONSchema,
  execute: (args, context) => Promise<any>,
});

handle.update(newTool); // Update the tool
handle.remove(); // Remove the tool
addInstruction(instruction)#

Adds a system instruction and returns a handle.

const handle = registry.addInstruction("Be concise.");
handle.update("Be detailed."); // Update instruction
handle.remove(); // Remove instruction
addProvider(provider)#

Adds another model context provider.

const handle = registry.addProvider(anotherProvider);
handle.remove(); // Remove provider

Use Cases#

Embedded Analytics Dashboard#

An analytics iframe can provide data query tools to the parent assistant:

// In analytics iframe
registry.addTool({
  toolName: "queryMetrics",
  description: "Query analytics data",
  parameters: z.object({
    metric: z.string(),
    timeRange: z.string(),
  }),
  execute: async ({ metric, timeRange }) => {
    const data = await analyticsAPI.query(metric, timeRange);
    return { data, visualization: createChart(data) };
  },
});

Plugin System#

Third-party plugins can extend the assistant's capabilities:

// In plugin iframe
registry.addTool({
  toolName: "translateText",
  description: "Translate text to another language",
  parameters: z.object({
    text: z.string(),
    targetLanguage: z.string(),
  }),
  execute: async ({ text, targetLanguage }) => {
    return await pluginAPI.translate(text, targetLanguage);
  },
});

Data Visualization#

Provide data visualization tools in an iframe:

// In visualization iframe
registry.addTool({
  toolName: "createChart",
  description: "Generate a chart from data",
  parameters: z.object({
    data: z.array(
      z.object({
        label: z.string(),
        value: z.number(),
      }),
    ),
    chartType: z.enum(["bar", "line", "pie"]),
    title: z.string().optional(),
  }),
  execute: async ({ data, chartType, title }) => {
    // Generate chart using a library like Chart.js or D3
    const chartUrl = await generateChart(data, chartType, title);
    return {
      chartUrl,
      summary: `Created ${chartType} chart with ${data.length} data points`,
    };
  },
});