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):
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):
"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):
"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:
- Calls all configured helper functions.
- Filters out null/undefined results.
- Merges the results with any manual
additionalContext
. - Sends everything with the message.