llm tools | ask llm about chat conversations | | Search

The code imports various modules and functions, defines two functions getChatHistory and askLlamaToRespondLike, and utilizes file system operations to read and write chat log files. The code has some areas for improvement, including inconsistent use of async/await, blocking file reads, and legacy syntax.

Run example

npm run import -- "llm respond like a personality"

llm respond like a personality

const fs = require('fs')
const path = require('path')
const CHAT_PATH = path.join(__dirname, '..', 'Resources', 'Projects', 'conversations')
const {EMOTIONS} = importer.import("ask llm about emotions")
const { askLlamaAboutConversation, askLlamaAboutCategory } = importer.import("ask llm about chat conversations")
const {askLlamaAboutEmotions} = importer.import("ask llm about emotions")
const {askLlamaAboutFunctions} = importer.import("ask llm about functions")
const {convertMessagesToNoDates, CHAT_DIRECTORIES} = importer.import("how to scan chat logs")

async function getChatHistory(chatLog) {

  let chatHistory = []
  let chatPath
  for(let i = 0; i < CHAT_DIRECTORIES.length; i++) {
    chatPath = path.join(CHAT_DIRECTORIES[i], chatLog + '.log')
    if(fs.existsSync(chatPath)) {
      chatHistory = fs.readFileSync(chatPath).toLocaleString('utf-8').split('\n')
      break
    } else {
      chatPath = void 0
    }
  }

  return chatHistory
}


async function askLlamaToRespondLike(name, conversation) {
  const {llmPrompt} = await importer.import("create llm session")
  if(!name) {
    name = 'Brian/Me'
  }
  if(!conversation) {
    conversation = `David Mc, Dec 5, 9:40 AM
Ok let me know

David Mc, Dec 5, 1:44 PM
ready now?

You, 10:29 AM
do you want to build a music player?
something like this https://github.com/waltonseymour/visualizer
for front end
and my ol php media server for backend
maybe i could convince chris to upgrade to class based system

You, 10:34 AM
https://github.com/briancullinan2/mediaserver/blob/main/modules/encode.module
basically just a parameterized launcher for vlc

David Mc, 10:41 AM
First thing on my list is grafana plug-in

You, 10:45 AM
https://github.com/preziotte/party-mode
grafana for gpt?
`
  }
  if(typeof conversation == 'string') {
    conversation = conversation.split(/\s*\n\s*/gi)
  }

  let chatCache = {}
  let conversations = fs.readdirSync(CHAT_PATH)
  for(let i = 0; i < conversations.length; i++) {
    if(conversations[i][0] == '.') continue
    let chatCacheFile = path.join(CHAT_PATH, conversations[i])
    try {
      Object.assign(chatCache, JSON.parse(fs.readFileSync(chatCacheFile).toString('utf-8')))
    } catch (e) {
      console.log(e)
    }
  }

  // TODO: search for matching emotions
  let allCategories = Object.keys(chatCache).map(k => chatCache[k].category)
    .filter((a, i, arr) => arr.indexOf(a) == i)
  let matchingEmotions = await askLlamaAboutEmotions(conversation.join(', '))
  let category = await askLlamaAboutCategory(conversation)

  let matchingCategories = []
  let functions = []
  for(let i = 0; i < allCategories.length; i++) {
    functions[functions.length] = allCategories[i]

    if(functions.length == 20) {
      let result = await askLlamaAboutFunctions(category, functions, [], true)
      functions = []
      if(result)
        matchingCategories = matchingCategories.concat(result)
    }
  }
  if(functions.length > 0) {
      let result = await askLlamaAboutFunctions(category, functions, [], true)
      functions = []
      if(result)
        matchingCategories = matchingCategories.concat(result)
  }

  console.log(matchingCategories)
  let chatLogs = {}
  let answers = []
  let summaries = []
  // TODO: search for contextual matches in summaries
  let keys = Object.keys(chatCache)
  for(let i = 0; i < keys.length; i++) {
    if(chatCache[keys[i]].emotions
      && chatCache[keys[i]].emotions.filter(e => matchingEmotions.includes(e)).length > 0
      || matchingCategories.includes(chatCache[keys[i]].category)
    ) {
      // TODO: this is where eliza characterization comes in
      let chatLog = path.basename(keys[i]).replace(/\[[0-9]+\]/gi, '').replace('.log', '')
      if(typeof chatLogs[chatLog] == 'undefined') {
        chatLogs[chatLog] = await getChatHistory(chatLog)
      }

      summaries[summaries.length] = chatCache[keys[i]].summary
      let history = chatLogs[chatLog].slice(chatCache[keys[i]].from, chatCache[keys[i]].to)
      let q1 = 'Derive any response style, personality, topics from this conversation:\n' + convertMessagesToNoDates(history).join('\n')
      console.log("User: " + q1)
      const a1 = await llmPrompt(q1)
      console.log("AI: " + a1)
      answers[answers.length] = a1

      /*
      if(summaries.length == 20) {
        let q2 = 'Derive any response style, personality, topics from this conversation:\n' + summaries.join(', ')
        console.log("User: " + q2)
        const a2 = await llmPrompt(q2)
        console.log("AI: " + a2)
        answers[answers.length] = a2
        summaries.length = []
      }
      */
    }
  }
  /*
  if(summaries.length > 0) {
    let q2 = 'Derive any response style, personality, topics from this conversation:\n' + summaries.join(', ')
    console.log("User: " + q2)
    const a2 = await llmPrompt(q2)
    console.log("AI: " + a2)
    answers[answers.length] = a2
    summaries.length = []
  }
  */

  console.log(answers)

  // TODO: coallesce many responses from {name}

  // TODO: finally query llm to act like person

}


module.exports = {
  askLlamaToRespondLike
}

What the code could have been:

```javascript
const fs = require('fs');
const path = require('path');

const CHAT_PATH = path.join(__dirname, '..', 'Resources', 'Projects', 'conversations');
const { askLlamaAboutConversation, askLlamaAboutCategory, askLlamaAboutEmotions, askLlamaAboutFunctions } = require('./askLlmAboutConversation');
const { convertMessagesToNoDates, CHAT_DIRECTORIES } = require('./howToScanChatLogs');
const { createLLMSession } = require('./createLLMSession');
const { EMOTIONS } = require('./askLlmAboutEmotions');

const llmPrompt = async (question) => {
  const { llmPrompt } = await createLLMSession();
  return llmPrompt(question);
};

async function getChatHistory(chatLog) {
  try {
    const chatHistory = await fs.promises.readFile(path.join(CHAT_DIRECTORIES[0], chatLog + '.log'), 'utf-8');
    return chatHistory.split('\n');
  } catch (error) {
    console.error(error);
    return [];
  }
}

async function askLlamaToRespondLike(name, conversation) {
  if (!name) name = 'Brian/Me';
  const category = await askLlamaAboutCategory(conversation);
  const matchingEmotions = await askLlamaAboutEmotions(conversation.join(', '));
  const allCategories = Object.keys(chatCache).map((k) => chatCache[k].category).filter((a, i, arr) => arr.indexOf(a) === i);
  const matchingCategories = await askLlamaAboutFunctions(category, allCategories.slice(0, 20), [], true);
  allCategories.splice(0, 20);

  const chatLogs = {};
  const answers = [];

  for (const key of Object.keys(chatCache)) {
    const chatLog = path.basename(key).replace(/\[[0-9]+\]/gi, '').replace('.log', '');
    if (chatCache[key].emotions && chatCache[key].emotions.filter((e) => matchingEmotions.includes(e)).length > 0 || matchingCategories.includes(chatCache[key].category)) {
      if (!chatLogs[chatLog]) {
        chatLogs[chatLog] = await getChatHistory(chatLog);
      }
      const history = chatLogs[chatLog].slice(chatCache[key].from, chatCache[key].to);
      const q1 = 'Derive any response style, personality, topics from this conversation:\n' + convertMessagesToNoDates(history).join('\n');
      const a1 = await llmPrompt(q1);
      answers.push(a1);
    }
  }

  console.log(answers);
  return answers;
}

const chatCache = {};
const conversations = fs.readdirSync(CHAT_PATH);
for (const file of conversations) {
  if (file[0] === '.') continue;
  try {
    const chatCacheFile = path.join(CHAT_PATH, file);
    const data = JSON.parse(fs.readFileSync(chatCacheFile, 'utf-8'));
    Object.assign(chatCache, data);
  } catch (error) {
    console.error(error);
  }
}

module.exports = { askLlamaToRespondLike };
```

Here's a short breakdown of the code:

Requires and Imports

The code requires the following modules:

The code imports various functions and variables from other modules using importer.import. These imports include:

Functions

The code defines two functions:

  1. getChatHistory(chatLog): This function reads a chat log file from disk and returns its contents as an array of strings. It uses a loop to iterate over the CHAT_DIRECTORIES array and find the first file that exists.
  2. askLlamaToRespondLike(name, conversation): This function uses an external module to create an LLM (Large Language Model) session and asks the LLM to respond to a conversation. It takes two parameters: name and conversation. If conversation is a string, it is split into an array of lines. The function also caches conversations in a file.

Other Notes