Skip to content

Official Node.js SDK for RecallrAI - Revolutionary contextual memory system that enables AI assistants to form meaningful connections between conversations, just like human memory."

Notifications You must be signed in to change notification settings

recallrai/sdk-node

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RecallrAI Node.js SDK

Official Node.js SDK for RecallrAI – a revolutionary contextual memory system that enables AI assistants to form meaningful connections between conversations, just like human memory.

Installation

Install the SDK using npm or yarn:

npm install recallrai
# or
yarn add recallrai

Initialization

Create a client instance with your API key and project ID:

import { RecallrAI } from 'recallrai';

const apiKey = "rai_yourapikey"; 
const projectId = "project-uuid";
const client = new RecallrAI({ apiKey, projectId });

User Management

Create a User

import { UserAlreadyExistsError } from 'recallrai/errors';

try {
  const user = await client.createUser("user123", { name: "John Doe" });
  console.log(`Created user: ${user.userId}`);
  console.log(`User metadata: ${JSON.stringify(user.metadata)}`);
  console.log(`Created at: ${user.createdAt}`);
} catch (error) {
  if (error instanceof UserAlreadyExistsError) {
    console.log(`Error: ${error.message}`);
  } else {
    console.error(`Unexpected error: ${error}`);
  }
}

Get a User

import { UserNotFoundError } from 'recallrai/errors';

try {
  const user = await client.getUser("user123");
  console.log(`User metadata: ${JSON.stringify(user.metadata)}`);
  console.log(`Last active: ${user.lastActiveAt}`);
} catch (error) {
  if (error instanceof UserNotFoundError) {
    console.log(`Error: ${error.message}`);
  } else {
    console.error(`Unexpected error: ${error}`);
  }
}

List Users

const userList = await client.listUsers(0, 10);
console.log(`Total users: ${userList.total}`);
console.log(`Has more users: ${userList.hasMore}`);

for (const user of userList.users) {
  console.log(`User ID: ${user.userId}`);
  console.log(`Metadata: ${JSON.stringify(user.metadata)}`);
  console.log(`Created at: ${user.createdAt}`);
  console.log(`Last active: ${user.lastActiveAt}`);
  console.log("---");
}

Update a User

import { UserNotFoundError, UserAlreadyExistsError } from 'recallrai/errors';

try {
  const user = await client.getUser("user123");
  const updatedUser = await user.update(
    { name: "John Doe", role: "admin" },  // new metadata
    "john_doe"  // new user ID
  );
  console.log(`Updated user ID: ${updatedUser.userId}`);
  console.log(`Updated metadata: ${JSON.stringify(updatedUser.metadata)}`);
} catch (error) {
  if (error instanceof UserNotFoundError) {
    console.log(`Error: ${error.message}`);
  } else if (error instanceof UserAlreadyExistsError) {
    console.log(`Error: ${error.message}`);
  } else {
    console.error(`Unexpected error: ${error}`);
  }
}

Delete a User

import { UserNotFoundError } from 'recallrai/errors';

try {
  const user = await client.getUser("john_doe");
  await user.delete();
  console.log("User deleted successfully");
} catch (error) {
  if (error instanceof UserNotFoundError) {
    console.log(`Error: ${error.message}`);
  } else {
    console.error(`Unexpected error: ${error}`);
  }
}

Session Management

Create a Session

import { UserNotFoundError } from 'recallrai/errors';
import { Session } from 'recallrai';

try {
  // First, get the user
  const user = await client.getUser("user123");
  
  // Create a session for the user; autoProcessAfterMinutes set to -1 disables auto-processing
  const session = await user.createSession(5);
  console.log("Created session id:", session.sessionId);
} catch (error) {
  if (error instanceof UserNotFoundError) {
    console.log(`Error: ${error.message}`);
  } else {
    console.error(`Unexpected error: ${error}`);
  }
}

Get an Existing Session

import { UserNotFoundError, SessionNotFoundError } from 'recallrai/errors';

try {
  // First, get the user
  const user = await client.getUser("user123");
  
  // Retrieve an existing session by its ID
  const session = await user.getSession("session-uuid");
  const status = await session.getStatus();
  console.log("Session status:", status);
} catch (error) {
  if (error instanceof UserNotFoundError) {
    console.log(`Error: ${error.message}`);
  } else if (error instanceof SessionNotFoundError) {
    console.log(`Error: ${error.message}`);
  } else {
    console.error(`Unexpected error: ${error}`);
  }
}

List Sessions

import { UserNotFoundError } from 'recallrai/errors';

try {
  // First, get the user
  const user = await client.getUser("user123");
  
  // List sessions for this user
  const sessionList = await user.listSessions(0, 10);
  for (const session of sessionList.sessions) {
    console.log(session.sessionId, session.status);
  }
} catch (error) {
  if (error instanceof UserNotFoundError) {
    console.log(`Error: ${error.message}`);
  } else {
    console.error(`Unexpected error: ${error}`);
  }
}

Session – Adding Messages

import { 
  UserNotFoundError, 
  SessionNotFoundError, 
  InvalidSessionStateError 
} from 'recallrai/errors';

try {
  // Add a user message
  await session.addUserMessage("Hello! How are you?");
  
  // Add an assistant message
  await session.addAssistantMessage("I'm an assistant. How can I help you?");
} catch (error) {
  if (error instanceof UserNotFoundError) {
    console.log(`Error: ${error.message}`);
  } else if (error instanceof SessionNotFoundError) {
    console.log(`Error: ${error.message}`);
  } else if (error instanceof InvalidSessionStateError) {
    console.log(`Error: ${error.message}`);
  } else {
    console.error(`Unexpected error: ${error}`);
  }
}

Session – Retrieving Context

import { UserNotFoundError, SessionNotFoundError } from 'recallrai/errors';

try {
  const context = await session.getContext();
  console.log("Memory used:", context.memoryUsed);
  console.log("Context:", context.context);
} catch (error) {
  if (error instanceof UserNotFoundError) {
    console.log(`Error: ${error.message}`);
  } else if (error instanceof SessionNotFoundError) {
    console.log(`Error: ${error.message}`);
  } else {
    console.error(`Unexpected error: ${error}`);
  }
}

Session – Process Session

import { 
  UserNotFoundError, 
  SessionNotFoundError, 
  InvalidSessionStateError 
} from 'recallrai/errors';

try {
  await session.process();
} catch (error) {
  if (error instanceof UserNotFoundError) {
    console.log(`Error: ${error.message}`);
  } else if (error instanceof SessionNotFoundError) {
    console.log(`Error: ${error.message}`);
  } else if (error instanceof InvalidSessionStateError) {
    console.log(`Error: ${error.message}`);
  } else {
    console.error(`Unexpected error: ${error}`);
  }
}

Session – Get Status and Messages

import { UserNotFoundError, SessionNotFoundError } from 'recallrai/errors';
import { SessionStatus } from 'recallrai';

try {
  const status = await session.getStatus();
  console.log("Session status:", status);
  
  // Check if the session is in a specific state
  if (status === SessionStatus.PROCESSED) {
    console.log("Session has been processed");
  }
  
  const messages = await session.getMessages();
  for (const message of messages) {
    console.log(`${message.role}: ${message.content} at ${message.timestamp}`);
  }
} catch (error) {
  if (error instanceof UserNotFoundError) {
    console.log(`Error: ${error.message}`);
  } else if (error instanceof SessionNotFoundError) {
    console.log(`Error: ${error.message}`);
  } else {
    console.error(`Unexpected error: ${error}`);
  }
}

Example Usage with LLMs

import { RecallrAI, User, Session } from 'recallrai';
import OpenAI from 'openai';
import { UserNotFoundError, SessionNotFoundError } from 'recallrai/errors';
import * as readline from 'readline';

// Initialize the clients
const raiClient = new RecallrAI({
  apiKey: 'rai_yourapikey',
  projectId: 'your-project-uuid'
});
const oaiClient = new OpenAI({ apiKey: 'your-openai-api-key' });

// Create a readline interface for user input
const rl = readline.createInterface({
  input: process.stdin,
  output: process.stdout
});

// Helper function to ask questions
function askQuestion(question: string): Promise<string> {
  return new Promise((resolve) => {
    rl.question(question, (answer) => {
      resolve(answer);
    });
  });
}

async function chatWithMemory(userId: string, sessionId?: string): Promise<string> {
  let user: User;
  let session: Session;
  
  // Get or create user
  try {
    user = await raiClient.getUser(userId);
  } catch (error) {
    if (error instanceof UserNotFoundError) {
      user = await raiClient.createUser(userId);
    } else {
      throw error;
    }
  }
  
  // Create a new session or get an existing one
  if (sessionId) {
    try {
      session = await user.getSession(sessionId);
    } catch (error) {
      if (error instanceof SessionNotFoundError) {
        console.log(`Session ${sessionId} not found. Creating a new session.`);
        session = await user.createSession(30);
      } else {
        throw error;
      }
    }
  } else {
    session = await user.createSession(30);
    console.log(`Created new session: ${session.sessionId}`);
  }
  
  console.log("Chat session started. Type 'exit' to end the conversation.");
  
  while (true) {
    // Get user input
    const userMessage = await askQuestion("You: ");
    if (userMessage.toLowerCase() === 'exit') {
      break;
    }
    
    // Add the user message to RecallrAI
    await session.addUserMessage(userMessage);
    
    // Get context from RecallrAI after adding the user message
    const context = await session.getContext();
    
    // Create a system prompt that includes the context
    const systemPrompt = `You are a helpful assistant with memory of previous conversations.
    
    MEMORIES ABOUT THE USER:
    ${context.context}
    
    You can use the above memories to provide better responses to the user.
    Don't mention that you have access to memories unless you are explicitly asked.`;
    
    // Get previous messages
    const previousMessages = await session.getMessages();
    const formattedMessages = previousMessages.map(message => ({
      role: message.role,
      content: message.content
    }));

    // Call the LLM with the system prompt and conversation history
    const response = await oaiClient.chat.completions.create({
      model: "gpt-4o-mini",
      messages: [
        { role: "system", content: systemPrompt },
        ...formattedMessages,
      ],
      temperature: 0.7
    });
    
    const assistantMessage = response.choices[0].message.content;
    
    // Print the assistant's response
    console.log(`Assistant: ${assistantMessage}`);
    
    // Add the assistant's response to RecallrAI
    await session.addAssistantMessage(assistantMessage);
  }
  
  // Process the session at the end of the conversation
  console.log("Processing session to update memory...");
  await session.process();
  console.log(`Session ended. Session ID: ${session.sessionId}`);
  rl.close();
  return session.sessionId;
}

// Example usage
(async () => {
  try {
    const userId = "user123";
    // To continue a previous session, uncomment below and provide the session ID
    // const previousSessionId = "previously-saved-session-uuid";
    // const sessionId = await chatWithMemory(userId, previousSessionId);
    
    // Start a new session
    const sessionId = await chatWithMemory(userId);
    console.log(`To continue this conversation later, use session ID: ${sessionId}`);
  } catch (error) {
    console.error("Error:", error);
  }
})();

Exception Handling

The RecallrAI SDK implements a comprehensive exception hierarchy to help you handle different error scenarios gracefully:

Base Exception

  • RecallrAIError: The base exception for all SDK-specific errors. All other exceptions inherit from this.

Authentication Errors

  • AuthenticationError: Raised when there's an issue with your API key or project ID authentication.

Network-Related Errors

  • NetworkError: Base exception for all network-related issues.
  • TimeoutError: Occurs when a request takes too long to complete.
  • ConnectionError: Happens when the SDK cannot establish a connection to the RecallrAI API.

Server Errors

  • ServerError: Base class for server-side errors.
  • InternalServerError: Raised when the RecallrAI API returns a 5xx error code.

User-Related Errors

  • UserError: Base for all user-related exceptions.
  • UserNotFoundError: Raised when attempting to access a user that doesn't exist.
  • UserAlreadyExistsError: Occurs when creating a user with an ID that already exists.

Session-Related Errors

  • SessionError: Base for all session-related exceptions.
  • SessionNotFoundError: Raised when attempting to access a non-existent session.
  • InvalidSessionStateError: Occurs when performing an operation that's not valid for the current session state (e.g., adding a message to a processed session).

Input Validation Errors

  • ValidationError: Raised when provided data doesn't meet the required format or constraints.

Importing Exceptions

You can import exceptions directly from the recallrai/errors module:

// Import specific exceptions
import { UserNotFoundError, SessionNotFoundError } from 'recallrai/errors';

// Import all exceptions
import * as errors from 'recallrai/errors';

Best Practices for Error Handling

When implementing error handling with the RecallrAI SDK, consider these best practices:

  1. Handle specific exceptions first: Catch more specific exceptions before general ones.

    try {
      // SDK operation
    } catch (error) {
      if (error instanceof UserNotFoundError) {
        // Specific handling
      } else if (error instanceof RecallrAIError) {
        // General fallback
      } else {
        // Unexpected errors
      }
    }
  2. Implement retry logic for transient errors: Network and timeout errors might be temporary.

  3. Log detailed error information: Exceptions contain useful information for debugging.

  4. Handle common user flows: For example, check if a user exists before operations, or create them if they don't:

    try {
      const user = await client.getUser(userId);
    } catch (error) {
      if (error instanceof UserNotFoundError) {
        const user = await client.createUser(userId);
      }
    }

For more detailed information on specific exceptions, refer to the API documentation.

Conclusion

This README outlines the basic usage of the RecallrAI SDK functions for user and session management. For additional documentation and advanced usage, please see the official documentation or the source code repository on GitHub.

About

Official Node.js SDK for RecallrAI - Revolutionary contextual memory system that enables AI assistants to form meaningful connections between conversations, just like human memory."

Topics

Resources

Stars

Watchers

Forks

Packages

No packages published