Axiom Lattice React SDK
React hooks for interacting with the Axiom Lattice Agent Service API.
Overview
This package provides React hooks that wrap the Axiom Lattice Client SDK, making it easy to integrate agent capabilities into your React applications. It includes hooks for managing threads, sending and receiving messages, monitoring agent state, and more.
Architecture
flowchart TD
subgraph "Client SDK"
ClientSDK["@axiom-lattice/client-sdk"]
Client["Client Class"]
ClientTypes["Types"]
ClientSDK --> Client
ClientSDK --> ClientTypes
end
subgraph "React SDK"
ReactSDK["@axiom-lattice/react-sdk"]
subgraph "Context"
Provider["AxiomLatticeProvider"]
useAxiomLattice["useAxiomLattice()"]
end
subgraph "Hooks"
useThread["useThread()"]
useChat["useChat()"]
useAgentState["useAgentState()"]
useAgentGraph["useAgentGraph()"]
end
ReactTypes["Types"]
Examples["Example Components"]
ReactSDK --> Provider
ReactSDK --> useAxiomLattice
ReactSDK --> useThread
ReactSDK --> useChat
ReactSDK --> useAgentState
ReactSDK --> useAgentGraph
ReactSDK --> ReactTypes
ReactSDK --> Examples
end
Client --> useAxiomLattice
useAxiomLattice --> useThread
useAxiomLattice --> useChat
useAxiomLattice --> useAgentState
useAxiomLattice --> useAgentGraph
subgraph "React Application"
AppComponent["App Component"]
ChatComponent["Chat Component"]
ThreadList["Thread List"]
StateMonitor["State Monitor"]
end
Provider --> AppComponent
useThread --> ThreadList
useChat --> ChatComponent
useAgentState --> StateMonitor
Installation
npm install @axiom-lattice/react-sdk
# or
yarn add @axiom-lattice/react-sdk
# or
pnpm add @axiom-lattice/react-sdk
Features
- React hooks for all client SDK functionality
- React context provider for configuration
- TypeScript support
- Simplified state management for threads and messages
- Streaming support with React state updates
- Dedicated external Agent Web App provider, composable widget components, and hooks
Agent Web Apps
Import external publication integrations from the separate entry point and include its stylesheet:
import { AgentWebAppProvider, WidgetComposer, WidgetMessageList } from "@axiom-lattice/react-sdk/web-app";
import "@axiom-lattice/react-sdk/web-app/styles.css";
interface PublishedAgentProps { currentUser: { id: string; name?: string } }
export function PublishedAgent({ currentUser }: PublishedAgentProps) {
return (
<AgentWebAppProvider
gatewayUrl="http://localhost:4001"
webAppId="support-web-app"
identity={{ mode: "unverified", userId: currentUser.id, displayName: currentUser.name }}
>
<main>
<WidgetMessageList />
<WidgetComposer />
</main>
</AgentWebAppProvider>
);
}
React and React DOM 18+ are peer dependencies. The composed widgets use bundled Ant Design-based UI dependencies; for the complete Console chat experience use AgentChatApp from the root entry. The Web App's Agent, project/model allowlists, features, and appearance are managed server-side; browser props cannot widen them.
Security: the current userId is sent in an unverified browser header and is impersonable. It provides logical thread grouping only, not authentication or security isolation. Do not expose sensitive history or privileged Agents publicly. Use the vendor integration handoff for cross-team delivery and the complete Agent Web Apps documentation for reference.
Usage
Provider Setup
First, wrap your application with the AxiomLatticeProvider to provide the client configuration:
import { AxiomLatticeProvider } from "@axiom-lattice/react-sdk";
function App() {
return (
<AxiomLatticeProvider
config={{
baseURL: "https://api.example.com",
apiKey: "your-api-key",
assistantId: "your-assistant-id",
transport: "sse",
}}
>
<YourApp />
</AxiomLatticeProvider>
);
}
Thread Management
Use the useThread hook to manage threads:
import { useThread } from "@axiom-lattice/react-sdk";
function ThreadManager() {
const {
threads,
currentThread,
isLoading,
error,
createThread,
getThread,
listThreads,
deleteThread,
selectThread,
} = useThread();
useEffect(() => {
// Load all threads on component mount
listThreads();
}, [listThreads]);
const handleCreateThread = async () => {
try {
const threadId = await createThread();
console.log(`Created thread: ${threadId}`);
} catch (error) {
console.error("Failed to create thread:", error);
}
};
return (
<div>
<h2>Threads</h2>
<button onClick={handleCreateThread} disabled={isLoading}>
Create New Thread
</button>
{error && <div className="error">{error.message}</div>}
<ul>
{threads.map((thread) => (
<li key={thread.id}>
Thread #{thread.id.substring(0, 8)}
<button onClick={() => selectThread(thread.id)}>Select</button>
<button onClick={() => deleteThread(thread.id)}>Delete</button>
</li>
))}
</ul>
{currentThread && (
<div>
<h3>Current Thread: {currentThread.id.substring(0, 8)}</h3>
</div>
)}
</div>
);
}
Chat Functionality
Use the useChat hook to send and receive messages:
import { useChat } from "@axiom-lattice/react-sdk";
function ChatInterface({ threadId }) {
const {
messages,
streamingMessage,
isLoading,
error,
sendMessage,
stopStreaming,
loadMessages,
} = useChat(threadId, { streaming: true });
const [inputValue, setInputValue] = useState("");
const handleSend = async () => {
if (!inputValue.trim()) return;
try {
await sendMessage(inputValue);
setInputValue("");
} catch (error) {
console.error("Failed to send message:", error);
}
};
return (
<div>
<div className="messages">
{messages.map((message) => (
<div key={message.id} className={`message ${message.role}`}>
<div className="role">{message.role}</div>
<div className="content">{message.content}</div>
</div>
))}
{streamingMessage && (
<div className="message assistant streaming">
<div className="role">assistant</div>
<div className="content">{streamingMessage.content}</div>
</div>
)}
</div>
{error && <div className="error">{error.message}</div>}
<div className="input-area">
<input
type="text"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
disabled={isLoading}
placeholder="Type your message..."
onKeyDown={(e) => {
if (e.key === "Enter") {
handleSend();
}
}}
/>
<button onClick={handleSend} disabled={isLoading}>
Send
</button>
{isLoading && <button onClick={stopStreaming}>Stop</button>}
</div>
</div>
);
}
Agent State Monitoring
Use the useAgentState hook to monitor agent state:
import { useAgentState } from "@axiom-lattice/react-sdk";
function AgentStateMonitor({ threadId }) {
const { agentState, isLoading, error, startPolling, stopPolling, refresh } =
useAgentState(threadId, {
pollingInterval: 3000,
autoStart: true,
});
if (isLoading && !agentState) {
return <div>Loading agent state...</div>;
}
if (error) {
return <div className="error">Error: {error.message}</div>;
}
if (!agentState) {
return <div>No agent state available</div>;
}
return (
<div>
<h3>Agent State</h3>
<button onClick={refresh}>Refresh</button>
<button onClick={startPolling}>Start Polling</button>
<button onClick={stopPolling}>Stop Polling</button>
<div>
<h4>Messages</h4>
<pre>{JSON.stringify(agentState.values.messages, null, 2)}</pre>
</div>
<div>
<h4>Tasks</h4>
<pre>{JSON.stringify(agentState.tasks, null, 2)}</pre>
</div>
</div>
);
}
Agent Graph Visualization
Use the useAgentGraph hook to fetch and display the agent graph:
import { useAgentGraph } from "@axiom-lattice/react-sdk";
function AgentGraph() {
const { graphImage, isLoading, error, fetchGraph } = useAgentGraph();
useEffect(() => {
fetchGraph();
}, [fetchGraph]);
if (isLoading && !graphImage) {
return <div>Loading graph...</div>;
}
if (error) {
return <div className="error">Error: {error.message}</div>;
}
return (
<div>
<h3>Agent Graph</h3>
<button onClick={fetchGraph}>Refresh Graph</button>
{graphImage && (
<div className="graph-container">
<img
src={`data:image/svg+xml;base64,${graphImage}`}
alt="Agent Graph"
/>
</div>
)}
</div>
);
}
File Explorer Component
Use the FileExplorer component to display and explore files from the agent state:
import { FileExplorer, useChat } from "@axiom-lattice/react-sdk";
function AgentFiles({ threadId }) {
// Ensure enableReturnStateWhenStreamCompleted is true to get the agent state
const { agentState } = useChat(threadId, {
streaming: true,
enableReturnStateWhenStreamCompleted: true,
});
// Extract files from agent state values
// Assuming agent returns files in agentState.values.files
const files = agentState?.values?.files || [];
return (
<div style={{ height: "500px" }}>
<h3>Agent Files</h3>
<FileExplorer files={files} />
</div>
);
}
Complete Example
See the examples directory for a complete example of a chat application using the React SDK.
API Reference
Hooks
useThread: Thread managementuseChat: Chat functionalityuseAgentState: Agent state monitoringuseAgentGraph: Agent graph visualization
Context
AxiomLatticeProvider: Provider component for the clientuseAxiomLattice: Hook to access the client instance
Contributing
Contributions are welcome! Please feel free to submit a Pull Request.