Dynamic Control

Managing context helpers at runtime

Context helpers can be dynamically managed using the useTamboContextHelpers hook.

Available Functions

import { useTamboContextHelpers } from "@tambo-ai/react";

const {
  getContextHelpers, // Get the current map of helpers
  addContextHelper, // Add or replace a helper
  removeContextHelper, // Remove a helper
} = useTamboContextHelpers();

Note:

  • Helpers are just functions; to “disable” a helper, replace it with a function that returns null.
  • You can also configure helpers declaratively using TamboContextHelpersProvider; both approaches write to the same global registry.

Add/Replace Helpers at Runtime

Useful when context depends on user actions or app state:

function ProjectContextController({ projectId }: { projectId: string }) {
  const { addContextHelper, removeContextHelper } = useTamboContextHelpers();

  useEffect(() => {
    if (!projectId) return;

    addContextHelper("currentProject", async () => ({
      projectId,
      projectName: await getProjectName(projectId),
      projectData: await getProjectData(projectId),
    }));

    return () => {
      removeContextHelper("currentProject");
    };
  }, [projectId]);

  return null;
}

Removing Helpers

const { removeContextHelper } = useTamboContextHelpers();

// User logs out
removeContextHelper("session");

Building a Settings UI

getContextHelpers returns the current map of helper functions keyed by name. You can build toggles by swapping in a real function or a no-op function that returns null:

function ContextSettings() {
  const { getContextHelpers, addContextHelper } = useTamboContextHelpers();
  const helpers = getContextHelpers();

  return (
    <div>
      <h3>Privacy Settings</h3>
      {Object.keys(helpers).map((key) => (
        <div key={key}>
          <span>{key}</span>
          <button onClick={() => addContextHelper(key, () => null)}>
            Disable
          </button>
        </div>
      ))}
    </div>
  );
}

Register helpers from multiple pages using the Provider

You can also register helpers declaratively at the page or layout level with TamboContextHelpersProvider. Helpers are registered when the provider mounts and are active only while that provider remains mounted (for example, while you’re on that page/layout). If the same key is registered multiple times at different times, the most recently mounted provider takes effect for as long as it’s mounted.

App layout (optional global helpers):

app/layout.tsx
import { TamboProvider, TamboContextHelpersProvider } from "@tambo-ai/react";
import { currentTimeContextHelper } from "@tambo-ai/react";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <TamboProvider
      apiKey={process.env.NEXT_PUBLIC_TAMBO_API_KEY!}
      contextHelpers={{
        // Global helper available across pages
        userTime: currentTimeContextHelper,
      }}
    ></TamboProvider>
  );
}

Page A (adds a page-specific helper):

app/dashboard/page.tsx
"use client";

import { TamboContextHelpersProvider } from "@tambo-ai/react";
import { currentPageContextHelper } from "@tambo-ai/react";
import { MessageThreadFull } from "@/components/tambo/message-thread-full";

export default function DashboardPage() {
  return (
    <TamboContextHelpersProvider
      contextHelpers={{
        // Page-specific helper; overrides any existing "userPage" key
        userPage: currentPageContextHelper,
      }}
    >
      <MessageThreadFull contextKey="dashboard" />
    </TamboContextHelpersProvider>
  );
}

Page B (adds a different helper or overrides a key):

app/settings/page.tsx
"use client";

import { TamboContextHelpersProvider } from "@tambo-ai/react";

const getUserSettingsContext = async () => ({
  theme: "dark",
  notifications: true,
});

export default function SettingsPage() {
  return (
    <TamboContextHelpersProvider
      contextHelpers={{
        // Different key; active only while this page is mounted
        userSettings: getUserSettingsContext,
        // Optionally override userPage for this page's context
        // userPage: () => ({ url: "/settings", title: "Settings" }),
      }}
    >
      {/* Components that send messages */}
    </TamboContextHelpersProvider>
  );
}
  • If you only want a helper active while a page is mounted, register it in that page’s provider (like above), or use the hook with add/remove in a useEffect with cleanup.
  • Consider namespacing keys if multiple parts of the app might register the same context (e.g., dashboard:userPage).

What Happens Behind the Scenes

When you send a message, Tambo automatically:

  1. Calls all configured helper functions.
  2. Filters out null/undefined results.
  3. Merges the results with any manual additionalContext.
  4. Sends everything with the message.