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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@ixo/oracles-ui

v4.0.3

Published

Client SDK for interacting with IXO Oracles

Readme

@ixo/oracles-ui

Introduction

@ixo/oracles-ui is a set of React hooks and utilities designed to integrate conversational AI (e.g., Guru AI) into your applications. It helps developers:

  • Manage and switch between multiple AI chat sessions.
  • Send messages and receive real-time streamed responses.
  • Dynamically render custom UI components (e.g., cards, forms, data viewers) driven by the AI’s output.
  • Maintain a seamless and interactive user experience across both web and mobile (React Native) platforms.

Installation

pnpm add @ixo/oracles-ui

(You may also use npm or yarn.)

Getting Started

To start, wrap your application in the UseOraclesProvider component:

import { UseOraclesProvider } from '@ixo/oracles-ui';

function App() {
  return (
   <UseOraclesProvider
      apiKey="key"
      apiURL="url">
      {/* Your application code */}
    </UseOraclesProvider>
  );
}

This sets up the necessary context for the hooks and components.


Core Hooks Overview

The package provides several core hooks to handle sessions, messages, and direct communication with the AI.

1. useChatSessionsList

Purpose: Fetch and manage a list of available chat sessions, as well as create new sessions.

Returned Values:

  • sessions: An array of session objects, each containing an id, title, and oracleName.
  • isLoading: Boolean indicating if sessions are currently loading.
  • error: Any error that occurred during the session fetch.
  • revalidate: A function to manually refresh the session list.
  • createSession: A function to create a new session.

Endpoints:

  • POST <API_URL>/sessions/list (fetch sessions)
  • POST <API_URL>/sessions/create (create new session)

Usage Example:

const {
  sessions,
  isLoading,
  error,
  revalidate,
  createSession,
} = useChatSessionsList({
  apiURL: 'https://api.example.com',
  apiKey: 'your-api-key',
  did: 'your-did',
  matrixAccessToken: 'your-matrix-access-token',
  oracle: 'guru',
});

2. useAskOracle

Purpose: Send messages to the AI and receive responses in real-time.

Returned Values:

  • sendMessage: An async function to send a message to the Oracle.
  • isSending: Boolean indicating if a message is currently being sent.
  • error: Any error encountered while sending the message.

Endpoints:

  • POST apiURL/<oracle>/stream (send messages and receive streamed responses)

Usage Example:

const { sendMessage, isSending, error } = useAskOracle({
  apiURL: 'https://api.example.com',
  apiKey: 'your-api-key',
  did: 'your-did',
  matrixAccessToken: 'your-matrix-access-token',
  sessionId: 'your-session-id',
  oracle: 'guru',
});

Then you can call:

await sendMessage('Hello, Guru!');

3. useListMessages

Purpose: Retrieve and maintain a list of messages for a specific session, including real-time updates over WebSockets.

Returned Values:

  • messages: An array of messages that may include text or dynamically rendered components.
  • isLoading: Boolean indicating if messages are being fetched.
  • error: Any error encountered while fetching messages.
  • connectionId: The current WebSocket connection ID.

Endpoints:

  • GET apiURL/<oracle>/messages (fetch messages)
  • WebSocket: socketURL (connect for live updates)

Usage Example:

const { messages, isLoading, error, connectionId } = useListMessages({
  apiURL: 'https://api.example.com',
  apiKey: 'your-api-key',
  did: 'your-did',
  matrixAccessToken: 'your-matrix-access-token',
  sessionId: 'your-session-id',
  oracle: 'guru',
  uiComponents: {
    // Register your custom UI components here
    'credential_card': CredentialCard,
    'CoinCard': CoinCard,
  },
  socketURL: 'http://localhost:3000', // Socket.io server URL
});

Dynamic UI Components

One of the core features of @ixo/oracles-ui is the ability to dynamically render custom UI components in response to AI events (tool calls).

  • When the AI emits a tool call (e.g., CoinCard), the resolveUIComponent function returns a React node that can be displayed directly in your UI.
  • If the tool call is “running,” the component can indicate a loading state if it supports it. Otherwise, a placeholder UI will be shown until it’s complete.

How to Integrate Components:

  1. Create a Custom UI Component that matches the tool’s name. For instance, a CoinCard component that displays cryptocurrency data.

  2. Export a Loading-Aware Component (Optional):
    If your component can handle loading states, set Component.prototype.canHandleLoadingState = true;. This tells the resolver to render the component with an isLoading prop when the AI tool is still running.

  3. Register the Component in uiComponents prop passed to useListMessages:

    const components = {
      'CoinCard': CoinCard,
    };
       
    const { messages } = useListMessages({
      ...config,
      uiComponents: components,
    });

Note on Rendering:
You don’t need to manually call resolveUIComponent yourself. The useListMessages hook handles it internally. When a tool call message appears, it will automatically resolve the appropriate component and return a React node in messages.

Example of Rendering Messages and Components

Below is a simplified web-based chat interface example. Notice that we directly render message.content. If message.content is a React node (from a resolved UI component), it will be displayed as such.

function ChatInterface({ messages, ...props }) {
  return (
    <div className="chat-container">
      <div className="messages">
        {messages.map((message) => (
          <div key={message.id} className={message.type === 'human' ? 'human' : 'ai'}>
            {/* If the content is a string, show text. If it's a component, it's already a React node. */}
            {typeof message.content === 'string' ? (
              <Markdown>{message.content}</Markdown>
            ) : (
              message.content
            )}
          </div>
        ))}
      </div>
      {/* Input and other UI elements */}
    </div>
  );
}

Building Components for the Library

To leverage the library’s dynamic rendering:

  1. Define Props and Loading States: Your component should accept props corresponding to the tool’s args, and optionally an isLoading prop if it can show a loading skeleton or spinner.

  2. Handle Loading Gracefully: If isLoading is true, return a loading state. If false, render the full component UI.

  3. Export Your Component and Register it:

    CoinCard.prototype.canHandleLoadingState = true;
    export function CoinCard(props) {
      if (props.isLoading) {
        return <CoinCardSkeleton />;
      }
      return <div>Your card content here...</div>;
    }

    Then pass it in uiComponents:

    useListMessages({
      ...config,
      uiComponents: {
        'CoinCard': CoinCard,
      },
    });

Platform Differences (Web vs. Mobile)

Code and Hooks Are the Same:
The hooks (useAskOracle, useChatSessionsList, useListMessages) and core logic are platform-agnostic. They work the same in React DOM and React Native/Expo environments.

UI Components and Rendering:

  • Web (React DOM): Use standard web components like <div>, <button>, and <input>.
  • Mobile (React Native / Expo): Use <View>, <Text>, <TouchableOpacity>, <TextInput>, and so forth.

Example for Mobile:

// Similar logic as web, just different UI components
const { messages } = useListMessages({...config, uiComponents: { 'CoinCard': CoinCard }});

// When rendering messages:
messages.map((message) => (
  <View key={message.id}>
    {typeof message.content === 'string' ? (
      <Text>{message.content}</Text>
    ) : (
      // message.content is a React node (e.g., <CoinCard ... />)
      message.content
    )}
  </View>
));