realcoloride/node_characterai

Chat.sendAndAwaitResponse throws TypeError: Cannot read properties of undefined (reading 'status')

Closed this issue · 4 comments

Version: 1.2.7

I found the closed issue #26 which describes the exact same issue, but it seems like it's not resolved yet.

Error log

[2024-03-14T17:42:25.905] [ERROR] default - TypeError: Cannot read properties of undefined (reading 'status')
    at Chat.sendAndAwaitResponse (/app/node_modules/node_characterai/chat.js:62:21)
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
/app/node_modules/puppeteer-core/lib/cjs/puppeteer/util/assert.js:28
        throw new Error(message);
              ^

Error: Request Interception is not enabled!
    at assert (/app/node_modules/puppeteer-core/lib/cjs/puppeteer/util/assert.js:28:15)
    at HTTPRequest.continue (/app/node_modules/puppeteer-core/lib/cjs/puppeteer/common/HTTPRequest.js:155:32)
    at /app/node_modules/node_characterai/requester.js:204:41
    at onceHandler (/app/node_modules/puppeteer-core/lib/cjs/puppeteer/common/EventEmitter.js:98:13)
    at /app/node_modules/puppeteer-core/lib/cjs/puppeteer/api/Page.js:114:32
    at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
    at async HTTPRequest.finalizeInterceptions (/app/node_modules/puppeteer-core/lib/cjs/puppeteer/common/HTTPRequest.js:99:9)

Looks like the problem is that it throws this error when you send another request before getting a response from the previous request.

I think it would be awesome if the library implements queuing requests if sendAndAwaitResponse() is called again before the previous sendAndAwaitResponse returns the response, or at least throws an error saying you can't call sendAndAwaitResponse() before the previous sendAndAwaitResponse() returns.

Hello,
I don't quite know how that would work. The reason being that request interception (see requester.js) requires data to be checked in as blocks you keep checking until they're ended (data).

(I think that) the reason you get this error is that it was loading data for a response and got another response so it mixed and did something wrong.

A solution would be to swap to neo endpoints (the ones with the websocket) or find another solution for puppeteer (that i'm not aware of).

I found a workaround. I used async-mutex to implement the Monitor design pattern, which prevents race conditions and ensures data consistency.

A minimum working example:

import CharacterAI from "node_characterai";
import {Mutex} from "async-mutex";

let chat;
const mutex = new Mutex();

(async () => {
  const characterAI = new CharacterAI();

  await characterAI.authenticateWithToken("TOKEN");
  chat = await characterAI.createOrContinueChat("8_1NyR8w1dOXmI1uWaieQcd147hecbdIK7CeEAIrdJw");
})();

/**
 * Send a message to the AI and get the response
 * @param id {string} chat ID
 * @param message {string} message to send
 * @returns {Promise<Reply>} response from the AI
 */
export async function sendMessage(id, message) {
  return await mutex.runExclusive(async () => {
    await chat.changeToConversationId(id);
    return await chat.sendAndAwaitResponse(message, true);
  });
}

Although I used another library for mutex, implementing it from scratch shouldn't be super difficult

This is interesting! Thank you for the sample @SeoulSKY

Hello there,
I've included a link to your sample in the README.md. Commit: 5089995

Thank you for the contribution!