Pull Request Review Time for Forked common.mjs?

OK. I will stumble my way through the CLI install.

I took a look at your PR, and it won’t have the effect you intend. “Memory key” is a feature Zapier added on top of the base OpenAI API integration. You’ll notice that it’s not noted in OpenAI’s docs. I think this is a cool feature and we can definitely consider adding. For now, you can use data stores to store chat history for specific users, and then pass that history to OpenAI using the message history input in that Chat action.

So memory key is localized for zapier in their database and they simply self store it and use it as a pass through identifier that loads the entire conversation with each push?

that’s right. The exact implementation is unclear (since we can’t see the source code for that), but yes, they’re likely storing that state in their own data store.

and they’re likely truncating the conversation history to e.g. the last 4,000 tokens (which is what ChatGPT will also do behind the scenes)

since otherwise you’ll hit token limits, which you may be aware of

This is how zapier “trim window” is used:
role
assistant
content
Lead Score: 72 Date: 05/09/2023 Time: 11:39:00 CST
name
leadforge-lead-score-assistant
history_context
was_trimmed
false
tokens_used
5777
tokens_remaining
2223

Thank you again…for saving me from myself :rolling_on_the_floor_laughing:

Yes, that’s correct. Take a look at our videos / docs on data stores to see how to store this kind of state. The key could be the user email / other identifier. The value should be an array of chat messages like so. Then you can pass that directly to the Chat action in the message history.

I’ll see if our support bot Mario can help with an example

I’d like to store an array of JavaScript objects in a Pipedream data store. I’ll use the user’s email address as the key. On new requests, I’ll receive a text variable, and I’d like to add it to a new object of this format:

{"role": "user", "content": text"}

I want to retrieve the array of values for a given email, append this object to the array, and return the array from the step.

To store an array of JavaScript objects in a Pipedream data store using the user’s email address as the key, you can use the following code snippet: import { axios } from "@pipedream/platform"; export default defineComponent({ props: { userEmail: { type: "string", label: "User Email", }, text: { type: "string", label: "Text", }, }, async run({ $ }) { const datastoreKey = this.userEmail; const newMessage = { role: "user", content: this.text }; // Retrieve the existing array of messages for the given email const existingMessages = await $store.get(datastoreKey) || []; // Append the new message to the existing array const updatedMessages = [...existingMessages, newMessage]; // Save the updated array back to the data store await $store.set(datastoreKey, updatedMessages); // Return the updated array of messages return updatedMessages; }, }); This code defines a Pipedream component with two input props: userEmail and text. It retrieves the existing array of messages for the given email from the data store, appends the new message object to the array, saves the updated array back to the data store, and returns the updated array of messages.

please try to find the docs at and adjust your answer. You don’t need to use axios, you can use the data_store prop named db and use this.db.get to retrieve data at the email key

I apologize for the confusion earlier. Here’s the updated code snippet using the this.db prop to interact with the data store: export default defineComponent({ props: { userEmail: { type: "string", label: "User Email", }, text: { type: "string", label: "Text", }, }, async run({ $ }) { const datastoreKey = this.userEmail; const newMessage = { role: "user", content: this.text }; // Retrieve the existing array of messages for the given email const existingMessages = await this.db.get(datastoreKey) || []; // Append the new message to the existing array const updatedMessages = [...existingMessages, newMessage]; // Save the updated array back to the data store await this.db.set(datastoreKey, updatedMessages); // Return the updated array of messages return updatedMessages; }, }); This code defines a Pipedream component with two input props: userEmail and text. It retrieves the existing array of messages for the given email from the data store using this.db.get, appends the new message object to the array, saves the updated array back to the data store using this.db.set, and returns the updated array of messages.

Please add a db prop to the props section like so:

{ type: "data_store" }

I apologize for the oversight. Here’s the updated code snippet with the db prop added to the props section: export default defineComponent({ props: { userEmail: { type: "string", label: "User Email", }, text: { type: "string", label: "Text", }, db: { type: "data_store", }, }, async run({ $ }) { const datastoreKey = this.userEmail; const newMessage = { role: "user", content: this.text }; // Retrieve the existing array of messages for the given email const existingMessages = await this.db.get(datastoreKey) || []; // Append the new message to the existing array const updatedMessages = [...existingMessages, newMessage]; // Save the updated array back to the data store await this.db.set(datastoreKey, updatedMessages); // Return the updated array of messages return updatedMessages; }, }); This code defines a Pipedream component with three input props: userEmail, text, and db. It retrieves the existing array of messages for the given email from the data store using this.db.get, appends the new message object to the array, saves the updated array back to the data store using this.db.set, and returns the updated array of messages.

This last example is good, and should provide a good starting point for you. I’d recommend doing the following:

  1. Modify this to work with whatever input / memory key you want to use
  2. Pass the return value of this step to the Message History field in the Chat action
  3. After you receive the response from OpenAI, you’ll also want to add assistant messages (the response) to the chat history. You’ll want to do virtually the same thing as in code step #1, but instead form an object of type “assistant” and the content equal to the text of the response from OpenAI.
    That way, the next time a user chats your app and your workflow runs, you’ll look up the history in the data store, and it will look like:
[
  { role: "user", content: "question" },
  { role: "assistant", content: "response" }
]

Now I want to make sure the total length of the array (i.e. the length of the JSON-stringified array) is no more than 4,000 characters. If it is, I want to remove the last element of the array to get the total length of the array under 4,000 characters. I want you to return just the truncated array. If you performed truncation, use $.export to return a “truncated” property (default false, true if set)

I will use the contact_id, since emails or phone numbers can change. SO after each ChatGPT function, I will then add the provided code snippet, replace the memory key with the webhook data for the contact_id. I will then use that output to add the array in my ChatGPT function. My question is, does this ignore the user message and system fields altogether?

Yes. Since you’re now storing chat history, you need to provide the array of messages on its own. The code for the Chat action does use the value of message history over user / system messages. If you want to provide a system message, just add another object of type system with content to be whatever you want.

const existingMessages = await this.db.get(datastoreKey) || [{ role: "system", "content: "system message"}];

This will ensure that all users’ history begins with the system message.