npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@aichatkit/localstorage-adapter

v0.0.0-alpha.6

Published

LocalStorage adapter for Hypermode ChatKit

Downloads

15

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-adapter

Usage

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 items

clearConversationHistory(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 IDs
  • chatkit_active_conversation: Currently active conversation ID
  • chatkit_agent_mapping: Object mapping conversation IDs to agent IDs
  • chatkit_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 fails

Browser 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