Skip to main content

Initializing DistriProvider in React

The DistriProvider is a React context provider that makes Distri functionality available throughout your React component tree. It manages the connection to the Distri server and provides hooks for interacting with agents.

Embedded Agent Chat


Basic Setup

Wrap your application (or the portion that uses Distri) with DistriProvider:

import { DistriProvider } from '@distri/react';

function App() {
return (
<DistriProvider>
<YourComponents />
</DistriProvider>
);
}

Configuration

Pass configuration options to customize the provider:

import { DistriProvider } from '@distri/react';

const config = {
baseUrl: 'http://localhost:8787/api/v1',
// Optional: API key for authentication
apiKey: process.env.DISTRI_API_KEY,
// Optional: Enable debug logging
debug: true,
};

function App() {
return (
<DistriProvider config={config}>
<YourComponents />
</DistriProvider>
);
}

Cloud Configuration

When using Distri Cloud, pass authentication tokens and workspace context:

import { DistriProvider } from '@distri/react';

function App() {
return (
<DistriProvider
config={{
baseUrl: 'https://api.distri.dev',
accessToken: tokens.access_token,
refreshToken: tokens.refresh_token,
workspaceId: 'your-workspace-id',
authReady: !!tokens, // Gate rendering until tokens arrive
onTokenRefresh: async () => {
const res = await fetch('/distri/token', { method: 'POST' });
const { access_token } = await res.json();
return access_token;
},
}}
>
<YourComponents />
</DistriProvider>
);
}

Full Configuration Interface

interface DistriClientConfig {
baseUrl: string; // Distri API URL
accessToken?: string; // Short-lived access token
refreshToken?: string; // Long-lived refresh token
workspaceId?: string; // Workspace UUID
clientId?: string; // Public client ID (for embeds)
authReady?: boolean; // Gate rendering until auth is ready
onTokenRefresh?: () => Promise<string | null>; // Refresh callback
headers?: Record<string, string>; // Custom headers
debug?: boolean; // Enable debug logging
}

useAgent Hook

Load an agent by ID or definition:

import { useAgent } from '@distri/react';

function MyComponent() {
const { agent, loading, error } = useAgent({
agentIdOrDef: 'your-agent-id', // Agent ID string or AgentDefinition object
enabled: true, // Optional: disable loading
});

if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
if (!agent) return null;

// Use agent with Chat component or invoke directly
}

Chat Component Props

The Chat component renders a complete chat interface:

import { Chat, useAgent } from '@distri/react';

function ChatInterface() {
const { agent } = useAgent({ agentIdOrDef: 'my-agent' });
if (!agent) return null;

return (
<Chat
threadId="conversation-123"
agent={agent}
externalTools={myTools}
enableHistory
maxWidth="800px"
getMetadata={async () => ({
dynamic_sections: {
current_state: getAppState(),
},
})}
onChatInstanceReady={(instance) => {
chatRef.current = instance;
}}
/>
);
}
PropTypeDescription
threadIdstringUnique conversation thread identifier
agentAgentAgent instance from useAgent()
externalToolsDistriAnyTool[]Custom tools the agent can call
enableHistorybooleanLoad previous messages for this thread
maxWidthstringCSS max-width for the chat container
getMetadata() => Promise<object>Inject dynamic context into each message
onChatInstanceReady(instance) => voidCallback with chat instance reference

Context Hooks

Access provider state from child components:

import { useDistri, useDistriToken, useWorkspace } from '@distri/react';

// Full client access
const { client, isLoading, error } = useDistri();

// Token state
const { token, isLoading } = useDistriToken();

// Workspace context
const { workspaceId, setWorkspaceId, isLoading } = useWorkspace();

Available Hooks

Once DistriProvider is set up, you can use these hooks in child components:

HookDescription
useAgent()Load an agent by ID or definition
useChat()Full chat state management (messages, streaming, tools)
useChatMessages()Access chat message history
useDistri()Access the Distri client, loading state, and errors
useDistriToken()Get current auth token state
useWorkspace()Get and set workspace context
useAgentDefinitions()List all available agents
useThreads()List and manage conversation threads

Complete Example

Here's a complete example showing how to set up DistriProvider with a chat interface:

import { useState } from 'react';
import { DistriProvider, Chat, useAgent } from '@distri/react';

function App() {
const config = {
baseUrl: import.meta.env.VITE_DISTRI_API_URL || 'http://localhost:8787/api/v1',
};

return (
<DistriProvider config={config}>
<ChatInterface />
</DistriProvider>
);
}

function ChatInterface() {
const { agent } = useAgent({ agentIdOrDef: 'my_agent' });
const [threadId] = useState(() => crypto.randomUUID());

if (!agent) {
return <div>Loading agent...</div>;
}

return (
<div className="chat-container">
<Chat agent={agent} threadId={threadId} />
</div>
);
}

Using with External Tools

When using external tools, you can access the provider context:

import { DistriProvider, Chat, useAgent } from '@distri/react';
import { createMapTools } from './tools';

function App() {
const config = {
baseUrl: import.meta.env.VITE_DISTRI_API_URL,
};

return (
<DistriProvider config={config}>
<MapsContent />
</DistriProvider>
);
}

function MapsContent() {
const { agent } = useAgent({ agentIdOrDef: 'maps_agent' });
const [threadId] = useState(() => crypto.randomUUID());
const mapRef = useRef<GoogleMapsManagerRef>(null);
const [tools, setTools] = useState<DistriAnyTool[]>([]);

useEffect(() => {
if (mapRef.current) {
setTools(createMapTools(mapRef.current));
}
}, []);

if (!agent) return null;

return (
<div className="maps-layout">
<GoogleMapsManager ref={mapRef} />
<Chat
agent={agent}
threadId={threadId}
externalTools={tools}
/>
</div>
);
}

Error Handling

The provider handles connection errors gracefully. You can add error boundaries:

import { ErrorBoundary } from 'react-error-boundary';

function App() {
return (
<ErrorBoundary fallback={<div>Something went wrong</div>}>
<DistriProvider config={config}>
<YourComponents />
</DistriProvider>
</ErrorBoundary>
);
}

References