@aichatkit/localstorage-adapter
v0.0.0-alpha.6
Published
LocalStorage adapter for Hypermode ChatKit
Downloads
15
Maintainers
Readme
@aichatkit/localstorage-adapter
LocalStorage implementation of the storage adapter for Hypermode ChatKit with backend synchronization support and rich response items.
Installation
npm install @aichatkit/localstorage-adapterUsage
import { LocalStorageAdapter } from "@aichatkit/localstorage-adapter";
import { ApolloAdapter } from "@aichatkit/apollo-adapter";
import { ChatInterface } from "@aichatkit/ui";
// Create and initialize the adapter
const storageAdapter = new LocalStorageAdapter({
// Optional custom configuration
conversationPrefix: "my-app-chat_",
conversationIdsKey: "my-app-conversation-ids",
activeConversationKey: "my-app-active-conversation",
});
// Initialize the adapter
await storageAdapter.initialize();
// Set up network callbacks for backend synchronization
const networkAdapter = new ApolloAdapter();
storageAdapter.setNetworkCallbacks({
getConversationItems: (agentId) =>
networkAdapter.getConversationItems(agentId),
clearConversationHistory: (agentId) =>
networkAdapter.clearConversationHistory(agentId),
});
// Use with ChatInterface
function ChatApp() {
return (
<ChatInterface
storageAdapter={storageAdapter}
networkAdapter={networkAdapter}
// other props...
/>
);
}Configuration Options
The LocalStorageAdapter constructor accepts an optional configuration object:
conversationPrefix: Key prefix for conversations in localStorage (default: 'chatkitconversation')conversationIdsKey: Key for storing the list of conversation IDs (default: 'chatkit_conversation_ids')activeConversationKey: Key for storing the active conversation ID (default: 'chatkit_active_conversation')agentMappingKey: Key for storing conversation-to-agent ID mapping (default: 'chatkit_agent_mapping')
API Methods
Core Storage Methods
saveConversation(conversation: Conversation): Promise
Saves a conversation with all its response items to localStorage.
await storageAdapter.saveConversation({
id: "conv-1",
title: "My Conversation",
items: [
{
id: "msg_1",
type: "message",
content: "Hello",
role: "user",
},
{
id: "tool_1",
type: "tool_call",
toolCall: {
id: "call_1",
name: "get_weather",
arguments: { location: "NYC" },
status: "completed",
result: { temperature: "22°C" },
},
},
],
})getConversation(id: string): Promise<Conversation | null>
Retrieves a conversation by ID with all its response items.
const conversation = await storageAdapter.getConversation("conv-1")
// Returns conversation with messages, tool calls, cards, etc.getAllConversations(): Promise<Conversation[]>
Retrieves all conversations with their complete response items.
const conversations = await storageAdapter.getAllConversations()deleteConversation(id: string): Promise
Deletes a conversation and its associated agent mapping.
const success = await storageAdapter.deleteConversation("conv-1")addItem(conversationId: string, item: ChatResponseItem): Promise<Conversation | null>
Adds any type of response item to a conversation.
// Add a message
await storageAdapter.addItem("conv-1", {
id: "msg-2",
type: "message",
content: "Hello",
role: "user",
timestamp: new Date().toISOString(),
})
// Add a tool call
await storageAdapter.addItem("conv-1", {
id: "tool-2",
type: "tool_call",
toolCall: {
id: "call-2",
name: "search_web",
arguments: { query: "AI news" },
status: "executing",
},
})
// Add a card
await storageAdapter.addItem("conv-1", {
id: "card-1",
type: "card",
card: {
id: "weather-card",
type: "weather",
title: "Current Weather",
content: { temperature: "22°C", condition: "Sunny" },
actions: [
{
id: "forecast",
label: "View Forecast",
type: "button",
action: "show_forecast",
},
],
},
})addMessage(conversationId: string, message: Message): Promise<Conversation | null>
Convenience method for adding message items.
await storageAdapter.addMessage("conv-1", {
id: "msg-1",
content: "Hello",
role: "user",
timestamp: new Date().toISOString(),
})Active Conversation Management
getActiveConversationId(): string
Gets the currently active conversation ID.
const activeId = storageAdapter.getActiveConversationId()setActiveConversationId(id: string): void
Sets the active conversation ID.
storageAdapter.setActiveConversationId("conv-1")Agent Mapping
setConversationAgent(conversationId: string, agentId: string): Promise
Maps a conversation to a backend agent ID.
await storageAdapter.setConversationAgent("conv-1", "agent-123")getConversationAgent(conversationId: string): Promise<string | null>
Gets the agent ID for a conversation.
const agentId = await storageAdapter.getConversationAgent("conv-1")Backend Synchronization
getConversationItems(conversationId: string): Promise<ChatResponseItem[]>
Gets all conversation items, syncing with backend if available.
const items = await storageAdapter.getConversationItems("conv-1")
// Returns array of messages, tool calls, cards, etc.getConversationHistory(conversationId: string): Promise<Message[]>
Gets only message items, syncing with backend if available.
const messages = await storageAdapter.getConversationHistory("conv-1")
// Returns only message items, filtered from all response itemsclearConversationHistory(conversationId: string): Promise
Clears conversation history both locally and on backend.
await storageAdapter.clearConversationHistory("conv-1")syncAllConversationsWithBackend(): Promise
Syncs all conversations with backend on app initialization.
await storageAdapter.syncAllConversationsWithBackend()Setting Network Callbacks
The adapter supports automatic synchronization with backend agents:
import { NetworkAdapter } from "@aichatkit/network-adapter"
// Set callbacks for backend communication
storageAdapter.setNetworkCallbacks({
getConversationItems: async (agentId: string) => {
// Fetch all response items from your backend
return await networkAdapter.getConversationItems(agentId)
},
clearConversationHistory: async (agentId: string) => {
// Clear on your backend
await networkAdapter.clearConversationHistory(agentId)
},
})Sync Behavior
- On App Load:
syncAllConversationsWithBackend()is called to get the latest state - On Conversation Switch: Items are synced when switching between conversations
- On Items Request: Backend is queried for latest items if agent ID exists
- Fallback: Falls back to local storage if backend sync fails
Data Structure
Conversation
interface Conversation {
id: string
title: string
items: ChatResponseItem[] // Mixed array of messages, tool calls, cards, etc.
}ChatResponseItem
Union type supporting multiple item types:
type ChatResponseItem = MessageItem | ToolCallItem | CardItem
interface MessageItem {
id: string | number
type: "message"
content: string
role: "user" | "assistant"
timestamp?: string
}
interface ToolCallItem {
id: string | number
type: "tool_call"
toolCall: {
id: string
name: string
arguments: Record<string, any>
status: "pending" | "executing" | "completed" | "error"
result?: any
error?: string
}
}
interface CardItem {
id: string | number
type: "card"
card: {
id: string
type: string
title?: string
content: Record<string, any>
actions?: CardAction[]
}
}Storage Keys
Default localStorage keys used:
chatkit_conversation_ids: Array of conversation IDschatkit_active_conversation: Currently active conversation IDchatkit_agent_mapping: Object mapping conversation IDs to agent IDschatkit_conversation_{id}: Individual conversation data with all item types
Error Handling
The adapter includes robust error handling:
try {
await storageAdapter.saveConversation(conversation)
} catch (error) {
console.error("Failed to save conversation:", error)
// Handle error appropriately
}
// Backend sync failures fall back to local storage
const items = await storageAdapter.getConversationItems("conv-1")
// Will return local items if backend sync failsBrowser Support
Requires browsers with localStorage support:
- Chrome 4+
- Firefox 3.5+
- Safari 4+
- Internet Explorer 8+
- All modern browsers
Advanced Usage
Custom Storage Keys
const adapter = new LocalStorageAdapter({
conversationPrefix: "myapp_chat_",
conversationIdsKey: "myapp_conversations",
activeConversationKey: "myapp_active_chat",
agentMappingKey: "myapp_agents",
})Manual Sync
// Manually sync a specific conversation
const agentId = await storageAdapter.getConversationAgent("conv-1")
if (agentId && networkAdapter) {
const latestItems = await networkAdapter.getConversationItems(agentId)
// Update local storage with latest items
const conversation = await storageAdapter.getConversation("conv-1")
if (conversation) {
conversation.items = latestItems
await storageAdapter.saveConversation(conversation)
}
}Cleanup
// Clear all data
await storageAdapter.clearAllConversations()
// Remove specific conversation and agent
await storageAdapter.deleteConversation("conv-1")License
MIT © Hypermode
