Error: SyntaxError: The requested module 'openai' does not provide an export named 'Configuration'

270 views Asked by At

I had this workflow on pipedream that worked perfect but then it didn't. I followed this tutorial on youtube: Video (The code heavy version)

This is the code that i have now.

import { Configuration, OpenAIApi } from "openai"
import { encode, decode } from "gpt-3-encoder"

export default defineComponent({
  props: {
    openai: {
      type: "app",
      app: "openai",
    }
  },
  async run({steps, $}) {

    // Import the transcript from the previous step
    const transcript = steps.create_transcription.$return_value.transcription

    // Set the max number of input tokens
    const maxTokens = 2000

    // Initialize OpenAI
    const openAIkey = this.openai.$auth.api_key
    const configuration = new Configuration({
      apiKey: openAIkey,
    });
    const openai = new OpenAIApi(configuration);

    // Split the transcript into shorter strings if needed, based on GPT token limit
    function splitTranscript(encodedTranscript, maxTokens) {
      const stringsArray = []
      let currentIndex = 0

      while (currentIndex < encodedTranscript.length) {
        let endIndex = Math.min(currentIndex + maxTokens, encodedTranscript.length)

        // Find the next period
        while (endIndex < encodedTranscript.length && decode([encodedTranscript[endIndex]]) !== ".") {
          endIndex++
        }

        // Include the period in the current string
        if (endIndex < encodedTranscript.length) {
          endIndex++
        }

        // Add the current chunk to the stringsArray
        const chunk = encodedTranscript.slice(currentIndex, endIndex)
        stringsArray.push(decode(chunk))

        currentIndex = endIndex
      }

      return stringsArray
    }

    const encoded = encode(transcript)

    const stringsArray = splitTranscript(encoded, maxTokens)
    const result = await sendToChat(stringsArray)
    return result

    // Function to send transcript string(s) to Chat API
    async function sendToChat (stringsArray) {

      const resultsArray = []

      for (let arr of stringsArray) {

        // Define the prompt
        const prompt = `Analyze the transcript provided below, then provide the following:
Key "title:" - add a title.
Key "summary" - create a summary.
Key "main_points" - add an array of the main points. Limit each item to 100 words, and limit the list to 10 items.
Key "action_items:" - add an array of action items. Limit each item to 100 words, and limit the list to 5 items.
Key "follow_up:" - add an array of follow-up questions. Limit each item to 100 words, and limit the list to 5 items.
Key "stories:" - add an array of an stories, examples, or cited works found in the transcript. Limit each item to 200 words, and limit the list to 5 items.
Key "arguments:" - add an array of potential arguments against the transcript. Limit each item to 100 words, and limit the list to 5 items.
Key "related_topics:" - add an array of topics related to the transcript. Limit each item to 100 words, and limit the list to 5 items.
Key "sentiment" - add a sentiment analysis

Ensure that the final element of any array within the JSON object is not followed by a comma.

Write all responses in Dutch.

Transcript:
        
        ${arr}`

        let retries = 3
        while (retries > 0) {
          try {
            const completion = await openai.createChatCompletion({
              model: "gpt-3.5-turbo",
              messages: [{role: "user", content: prompt}, {role: "system", content: `You are an assistant that only speaks Dutch, formatted in Markdown. Do not write text that is not formatted as markdown. Do not write in any language other than Dutch.
Example formatting:

{
    "title": "Notion Buttons",
    "summary": "A collection of buttons for Notion",
    "action_items": [
        "item 1",
        "item 2",
        "item 3"
    ],
    "follow_up": [
        "item 1",
        "item 2",
        "item 3"
    ],
    "arguments": [
        "item 1",
        "item 2",
        "item 3"
    ],
    "related_topics": [
        "item 1",
        "item 2",
        "item 3"
    ]
    "sentiment": "positive"
}
              `}],
              temperature: 0.2
            });

            resultsArray.push(completion)
            break
          } catch (error) {
            if(error.response && error.response.status === 500) {
              retries--
              if (retries == 0) {
                throw new Error("Failed to get a response from OpenAI Chat API after 3 attempts.")
              }
              console.log("OpenAI Chat API returned a 500 error. Retrying...")
            } else {
              throw error
            }
          }
        }

      }

      return resultsArray
    }

  },
})

That code now gives back an error like this:

Error: SyntaxError: The requested module 'openai' does not provide an export named 'Configuration'
    at handleError (/var/task/common.js:38:40)
    at Runner.runUserCode (file:///var/task/lambda_handler.mjs:866:9)
    at async Runner.run (file:///var/task/lambda_handler.mjs:697:5)
    at async Runtime.handler (file:///var/task/lambda_handler.mjs:914:22)

I tried to change it according to these instructions: github but I just can't seem to be able to fix it ( since my coding skills are nonexistent). I would apreciate some help.

I tried these instructions: github

4

There are 4 answers

0
Roni Mejia On BEST ANSWER

I adeptly tackled all the issues associated with the workflow demonstrated in the video. Please note that the workflow elucidated in this video is not the one to which I'm referring. My reference pertains to the workflow, described as the "code-heavy method" in the video, and subsequently detailed in this blog post.

The specific hurdle I initially faced was with the "openai_chat" step. As I mentioned in my initial query, I discovered that the API had been upgraded from version 3 to version 4. Consequently, transitioning to version 4 was necessary to ensure continued API usage. Additionally, I encountered challenges with the code used in the "format_chat" step. I diligently addressed these challenges and successfully restored full functionality, matching its previous state.

Here's the code for the "openai_chat" step:

import OpenAI from 'openai';
import { encode, decode } from "gpt-3-encoder"

export default defineComponent({
  props: {
    openai: {
      type: "app",
      app: "openai",
    }
  },
  async run({steps, $}) {

    // Import the transcript from the previous step
    const transcript = steps.create_transcription.$return_value.transcription

    // Set the max number of input tokens
    const maxTokens = 2000

    // Initialize OpenAI
    const openai = new OpenAI({ apiKey: 'your actual API key' })

    // Split the transcript into shorter strings if needed, based on GPT token limit
    function splitTranscript(encodedTranscript, maxTokens) {
      const stringsArray = []
      let currentIndex = 0

      while (currentIndex < encodedTranscript.length) {
        let endIndex = Math.min(currentIndex + maxTokens, encodedTranscript.length)

        // Find the next period
        while (endIndex < encodedTranscript.length && decode([encodedTranscript[endIndex]]) !== ".") {
          endIndex++
        }

        // Include the period in the current string
        if (endIndex < encodedTranscript.length) {
          endIndex++
        }

        // Add the current chunk to the stringsArray
        const chunk = encodedTranscript.slice(currentIndex, endIndex)
        stringsArray.push(decode(chunk))

        currentIndex = endIndex
      }

      return stringsArray
    }

    const encoded = encode(transcript)

    const stringsArray = splitTranscript(encoded, maxTokens)
    const result = await sendToChat(stringsArray)
    return result

    // Function to send transcript string(s) to Chat API
    async function sendToChat (stringsArray) {

      const resultsArray = []

      for (let arr of stringsArray) {

        // Define the prompt
        const prompt = `Analyze the transcript provided below, then provide the following:
Key "title:" - add a title.
Key "summary" - create a summary.
Key "main_points" - add an array of the main points. Limit each item to 100 words, and limit the list to 10 items.
Key "action_items:" - add an array of action items. Limit each item to 100 words, and limit the list to 5 items.
Key "follow_up:" - add an array of follow-up questions. Limit each item to 100 words, and limit the list to 5 items.
Key "stories:" - add an array of an stories, examples, or cited works found in the transcript. Limit each item to 200 words, and limit the list to 5 items.
Key "arguments:" - add an array of potential arguments against the transcript. Limit each item to 100 words, and limit the list to 5 items.
Key "related_topics:" - add an array of topics related to the transcript. Limit each item to 100 words, and limit the list to 5 items.
Key "sentiment" - add a sentiment analysis

Ensure that the final element of any array within the JSON object is not followed by a comma.

Write all responses in Dutch.

Transcript:
        
        ${arr}`

        let retries = 3
        while (retries > 0) {
          try {
            const completion = await openai.chat.completions.create({
              model: "gpt-3.5-turbo",
              messages: [{role: "user", content: prompt}, {role: "system", content: `You are an assistant that only in Markdown. Do not write text that is not formatted as markdown.
Example formatting:

{
    "title": "Notion Buttons",
    "summary": "A collection of buttons for Notion",
    "action_items": [
        "item 1",
        "item 2",
        "item 3"
    ],
    "follow_up": [
        "item 1",
        "item 2",
        "item 3"
    ],
    "arguments": [
        "item 1",
        "item 2",
        "item 3"
    ],
    "related_topics": [
        "item 1",
        "item 2",
        "item 3"
    ]
    "sentiment": "positive"
}
              `}],
              temperature: 0.2
            });

            resultsArray.push(completion)
            break
          } catch (error) {
            if(error.response && error.response.status === 500) {
              retries--
              if (retries == 0) {
                throw new Error("Failed to get a response from OpenAI Chat API after 3 attempts.")
              }
              console.log("OpenAI Chat API returned a 500 error. Retrying...")
            } else {
              throw error
            }
          }
        }

      }

      return resultsArray
    }

  },
})

Here's the code for the "format_chat" step:

export default defineComponent({
  async run({ steps, $ }) {

    const resultsArray = []
    for (let result of steps.openai_chat.$return_value) {

      // ChatGPT loves to occasionally throw commas after the final element in arrays, so let's remove them
      function removeTrailingCommas(jsonString) {
        const regex = /,\s*(?=])/g;
        return jsonString.replace(regex, '');
      }

      // Need some code that will ensure we only get the JSON portion of the response
      // This should be the entire response already, but we can't always trust GPT
      const jsonString = result.choices [0].message.content
        .replace(/^[^\{]*?{/, '{')
        .replace(/\}[^}]*?$/,'}')

      const cleanedJsonString = removeTrailingCommas(jsonString)

      let jsonObj
      try {
        jsonObj = JSON.parse(cleanedJsonString)
      } catch (error) {
        console.error("Error while parsing cleaned JSON string:")
        console.error(error)
        console.log("Original JSON string:", jsonString)
        console.log(cleanedJsonString)
        console.log("Cleaned JSON string:", cleanedJsonString)
        jsonObj = {}
      }

      const response = {
        choice: jsonObj,
        usage: !result.usage.total_tokens ? 0 : result.usage.total_tokens
      }

      resultsArray.push(response)
    }

    const chatResponse = {
      title: resultsArray[0].choice.title,
      sentiment: resultsArray[0].choice.sentiment,
      summary: [],
      main_points: [],
      action_items: [],
      stories: [],
      arguments: [],
      follow_up: [],
      related_topics: [],
      usageArray: []
    }

    for (let arr of resultsArray) {
      chatResponse.summary.push(arr.choice.summary)
      chatResponse.main_points.push(arr.choice.main_points)
      chatResponse.action_items.push(arr.choice.action_items)
      chatResponse.stories.push(arr.choice.stories)
      chatResponse.arguments.push(arr.choice.arguments)
      chatResponse.follow_up.push(arr.choice.follow_up)
      chatResponse.related_topics.push(arr.choice.related_topics)
      chatResponse.usageArray.push(arr.usage)
    }

    console.log(chatResponse.related_topics)

    function arraySum (arr) {
      const init = 0
      const sum = arr.reduce((accumulator, currentValue) => accumulator + currentValue, init)
      return sum
    }

    const finalChatResponse = {
      title: chatResponse.title,
      summary: chatResponse.summary.join(' '),
      sentiment: chatResponse.sentiment,
      main_points: chatResponse.main_points.flat(),
      action_items: chatResponse.action_items.flat(),
      stories: chatResponse.stories.flat(),
      arguments: chatResponse.arguments.flat(),
      follow_up: chatResponse.follow_up.flat(),
      related_topics: Array.from(new Set(chatResponse.related_topics.flat().map(item => item.toLowerCase()))).sort(),
      tokens: arraySum(chatResponse.usageArray)
    }

    return finalChatResponse

  },
})
1
Jiří Cihelka On

The GitHub you linked descibes how to migrate to v4 of the openai API you are using. From my understanding the change that concerns you here is, that the way to create the openai instance changed from

import { Configuration, OpenAIApi } from "openai"

// other code

const configuration = new Configuration({
  apiKey: openAIkey,
});
const openai = new OpenAIApi(configuration);

to

import OpenAI from "openai"

// other code

const openai = new OpenAI({
  apiKey: openAIkey,
});

Changing these lines should solve your issues, if the rest of the code works.

1
High Warlord Occurrence On

I got the same problem. It has worked for me for the last months, but not now. This was the script I was using:

import { Configuration, OpenAIApi } from "openai"
import { encode, decode } from "gpt-3-encoder"

export default defineComponent({
  props: {
    openai: {
      type: "app",
      app: "openai",
    }
  },
  async run({steps, $}) {

    // Import the transcript from the previous step
    const transcript = steps.create_transcription.$return_value.transcription

    // Set the max number of input tokens
    const maxTokens = 2000

    // Initialize OpenAI
    const openAIkey = this.openai.$auth.api_key
    const configuration = new Configuration({
      apiKey: openAIkey,
    });
    const openai = new OpenAIApi(configuration);

    // Split the transcript into shorter strings if needed, based on GPT token limit
    function splitTranscript(encodedTranscript, maxTokens) {
      const stringsArray = []
      let currentIndex = 0

      while (currentIndex < encodedTranscript.length) {
        let endIndex = Math.min(currentIndex + maxTokens, encodedTranscript.length)

        // Find the next period
        while (endIndex < encodedTranscript.length && decode([encodedTranscript[endIndex]]) !== ".") {
          endIndex++
        }

        // Include the period in the current string
        if (endIndex < encodedTranscript.length) {
          endIndex++
        }

        // Add the current chunk to the stringsArray
        const chunk = encodedTranscript.slice(currentIndex, endIndex)
        stringsArray.push(decode(chunk))

        currentIndex = endIndex
      }

      return stringsArray
    }

    const encoded = encode(transcript)

    const stringsArray = splitTranscript(encoded, maxTokens)
    const result = await sendToChat(stringsArray)
    return result

    // Function to send transcript string(s) to Chat API
    async function sendToChat (stringsArray) {

      const resultsArray = []

      for (let arr of stringsArray) {

        // Define the prompt
        const prompt = `Analyze the lecture provided below, then provide the following:
Key "title:" - add a title.
Key "summary" - rewrite the lecture in a clear and engaging way, without omitting any important details.
Key "main_points" - add an array of the main points. add an array of the main points. Limit each item to 100 words, and limit the list to 10 items.
Key "action_items:" - add an array of action items. Limit each item to 100 words, and limit the list to 5 items.
Key "follow_up:" - add an array of follow-up questions. Limit each item to 100 words, and limit the list to 5 items.
Key "stories:" - add an array of an stories, examples, or cited works found in the transcript. Limit each item to 200 words, and limit the list to 5 items.
Key "arguments:" - add an array of potential arguments against the transcript. Limit each item to 100 words, and limit the list to 5 items.
Key "related_topics:" - add an array of topics related to the transcript. Limit each item to 100 words, and limit the list to 5 items.
Key "sentiment" - add a sentiment analysis

Ensure that the final element of any array within the JSON object is not followed by a comma.

Transcript:
        
        ${arr}`

        let retries = 3
        while (retries > 0) {
          try {
            const completion = await openai.createChatCompletion({
              model: "gpt-3.5-turbo",
              messages: [{role: "user", content: prompt}, {role: "system", content: `You are an assistant that only speaks JSON. Do not write normal text.

Example formatting:

{
    "title": "Notion Buttons",
    "summary": "A collection of buttons for Notion",
    "action_items": [
        "item 1",
        "item 2",
        "item 3"
    ],
    "follow_up": [
        "item 1",
        "item 2",
        "item 3"
    ],
    "arguments": [
        "item 1",
        "item 2",
        "item 3"
    ],
    "related_topics": [
        "item 1",
        "item 2",
        "item 3"
    ]
    "sentiment": "positive"
}
              `}],
              temperature: 0.2
            });

            resultsArray.push(completion)
            break
          } catch (error) {
            if(error.response && error.response.status === 500) {
              retries--
              if (retries == 0) {
                throw new Error("Failed to get a response from OpenAI Chat API after 3 attempts.")
              }
              console.log("OpenAI Chat API returned a 500 error. Retrying...")
            } else {
              throw error
            }
          }
        }

      }

      return resultsArray
    }

  },
})
1
High Warlord Occurrence On

Now I got the script to work through conversion, but now the following script fails. With TypeError Cannot read properties of undefined (reading 'choices')

DETAILS at Object.run (file:///tmp/pdg/dist/code/9ce5a039fea762dc8a11470d09d872dba3c859c4187331b9bb613d6e95facc05/component.mjs:15:38) at null.executeComponent (/var/task/launch_worker.js:229:53) at MessagePort.messageHandler (/var/task/launch_worker.js:726:28)

The script:

export default defineComponent({ async run({ steps, $ }) {

const resultsArray = []
for (let result of steps.openai_chat.$return_value) {

  // ChatGPT loves to occasionally throw commas after the final element in arrays, so let's remove them
  function removeTrailingCommas(jsonString) {
    const regex = /,\s*(?=])/g;
    return jsonString.replace(regex, '');
  }

  // Need some code that will ensure we only get the JSON portion of the response
  // This should be the entire response already, but we can't always trust GPT
  const jsonString = result.data.choices[0].message.content
    .replace(/^[^\{]*?{/, '{')
    .replace(/\}[^}]*?$/,'}')

  const cleanedJsonString = removeTrailingCommas(jsonString)

  let jsonObj
  try {
    jsonObj = JSON.parse(cleanedJsonString)
  } catch (error) {
    console.error("Error while parsing cleaned JSON string:")
    console.error(error)
    console.log("Original JSON string:", jsonString)
    console.log(cleanedJsonString)
    console.log("Cleaned JSON string:", cleanedJsonString)
    jsonObj = {}
  }

  const response = {
    choice: jsonObj,
    usage: !result.data.usage.total_tokens ? 0 : result.data.usage.total_tokens
  }

  resultsArray.push(response)
}

const chatResponse = {
  title: resultsArray[0].choice.title,
  sentiment: resultsArray[0].choice.sentiment,
  summary: [],
  main_points: [],
  action_items: [],
  stories: [],
  arguments: [],
  follow_up: [],
  related_topics: [],
  usageArray: []
}

for (let arr of resultsArray) {
  chatResponse.summary.push(arr.choice.summary)
  chatResponse.main_points.push(arr.choice.main_points)
  chatResponse.action_items.push(arr.choice.action_items)
  chatResponse.stories.push(arr.choice.stories)
  chatResponse.arguments.push(arr.choice.arguments)
  chatResponse.follow_up.push(arr.choice.follow_up)
  chatResponse.related_topics.push(arr.choice.related_topics)
  chatResponse.usageArray.push(arr.usage)
}

console.log(chatResponse.related_topics)

function arraySum (arr) {
  const init = 0
  const sum = arr.reduce((accumulator, currentValue) => accumulator + currentValue, init)
  return sum
}

const finalChatResponse = {
  title: chatResponse.title,
  summary: chatResponse.summary.join(' '),
  sentiment: chatResponse.sentiment,
  main_points: chatResponse.main_points.flat(),
  action_items: chatResponse.action_items.flat(),
  stories: chatResponse.stories.flat(),
  arguments: chatResponse.arguments.flat(),
  follow_up: chatResponse.follow_up.flat(),
  related_topics: Array.from(new Set(chatResponse.related_topics.flat().map(item => item.toLowerCase()))).sort(),
  tokens: arraySum(chatResponse.usageArray)
}

return finalChatResponse

}, })