retort-js
Version:
Intuitive, production-ready prompt chaining in Javascript
222 lines (142 loc) • 10.3 kB
Markdown
# RetortJS
>)
Intuitive prompt chaining in Javascript. Designed for production.
## Usage
```js
module.exports = require('retort-js').retort(async ($) => {
$.system`You are 'Retorter', an AI that responds in a quick & witty manner.`;
await $.user.input({query: "Ask a question: "});
await $.assistant.generation();
});
```
Refer to the [examples](#examples) section below for more details.
## Getting Started
### Installation
To install via NPM, run:
```sh
npm i retort-js
```
### Give Retort a try
The quickest way to try Retort is in our playground:
<a href="https://stackblitz.com/fork/github/retort-js/playground?file=retort%2Fscript-template.rt.js&hideNavigation=1&showSidebar=0" style="display: inline-block; background-color: #9146FF; color: white; padding: 10px 20px; text-decoration: none; border-radius: 5px; font-weight: bold" target="_blank">RetortJS Playground</a>
This will open a development project with an example script you can modify, and a UI where you can run your script and see the output of each message in the conversation. You will need to add your own OpenAI API key.
### How to run your first Retort script
#### API key setup
> [!NOTE]
> Currently only setup to use with OpenAI's API.
Add your OpenAI API key to the following environment variable:
```
OPENAI_API_KEY=<your key>
```
#### Setup 'retort' directory
Create a `retort` directory within your project to store your Retort scripts. This isn't required but is recommended as [@retort-js/dev-server](https://www.npmjs.com/package/@retort-js/dev-server) will search for scripts here.
#### Create first file
Create a new `example.rt.js` file and copy and paste the following code:
```js
module.exports = require('retort-js').retort(async ($) => {
$.system`You are 'Retorter', an AI that responds in a quick & witty manner.`;
await $.user.input({query: "Ask a question: "});
await $.assistant.generation();
});
```
#### Run the script
You can see the output of the conversation directly in your console by running the following command:
```sh
node retort/example.rt.js
```
This will show you each message in the conversation so you can easily see what happens at each step of the conversation.
#### What's going on here?
`module.exports = require('retort-js').retort(async ($) => { ... })` imports the Retort library, defines a Retort script with the retort() function, and exports it. You don't need to import/export like this, but it's recommended for simplicity. In the script we are passing a simple instruction to the system and then waiting for the user to input their message before finally awaiting the response from the LLM.
##### The $
This is a RetortConversation. It keeps track of all the messages in a script and exposes methods for creating a message for each role type (system, user and assistant), and allows you to build a chain of prompts.
These can be called with a string or with a tagged template literal:
```js
// valid
$.system("Write a haiku about Large Language Models.");
// also valid
$.system`Write a haiku about Large Language Models.`;
```
In your terminal you should see the initial system message. You can now enter your own message for the assistant to reply to. Once you've entered your message the `assistant.generation()` function will interface with the OpenAI API and return the response.
You can now see exactly what happened each step of the way.
The [RetortConversation](#retortconversation-properties) object also exposes various settings such as the model, temperature and topP.
## retort()
The retort function creates a Retort object. This object represents a conversation that can be run. The function takes a chatFunction as an argument, which is a function that defines the conversation (ie, your script).
The chatFunction takes a RetortConversation ($) as an argument. It can also take any number of additional arguments but we don't need those for this example.
The retort function then returns a Retort object that includes a unique ID, a _run function, and a retortType property. You can then call this _run function on the exported Retort object wherever you're using it in your codebase. It allows you to run the file as either a script or a module:
```js
const retorter = retort(async ($) => {/* script goes here */});
// as a script
retorter._run();
// as a retort module
retort(async ($) => {
await $.run(retorter);
});
```
# Examples
A script that keeps a conversation open with an LLM until the user is ready to end the conversation:
```js
module.exports = require("retort-js").retort(async $ => {
$.system`
You are 'Retorter', an AI that responds in a quick & witty manner.
If the user wishes to end the conversation, say "DONE" in all caps.
`;
let reply;
while (!reply?.content.includes("DONE")) {
await $.user.input();
reply = await $.assistant.generation();
}
});
```
The script will wait for your input into the console before calling the assistant.generation() function.
Passing parameters to a conversation:
```js
module.exports = require("retort-js").retort(async ($, { age }) => {
$.user`A birthday message for someone ${age} years old`;
await $.assistant.generation();
});
```
A script that imports and runs another script:
```js
// script.rt.js
module.exports = require("retort-js").retort(async ($) => {
const imported = await $.run(require("./example-2.rt.js"));
// use the imported conversation here
});
```
If you're using ESM:
```js
import { retort } from "retort-js";
const retorter = retort(async ($) => {
$.system`You are 'Retorter', an AI that responds in a quick & witty manner.`;
await $.user.input();
await $.assistant.generation();
});
retorter._run(); // run the conversation
```
## RetortConversation Properties
| Property | Description |
| ----------------- |--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `id` | A unique identifier for the conversation. |
| `chat` | A reference to the conversation itself. |
| `messagePromises` | An array of messages or promises of messages in the conversation. |
| `settings` | An object containing settings for the conversation, including the model used, temperature, and topP. |
| `model` | A getter and setter for the model used in the conversation. |
| `temperature` | A getter and setter for the temperature setting of the conversation. |
| `topP` | A getter and setter for the topP setting of the conversation. |
| `messages` | A getter for the messages in the conversation. Throws an error if any message promises have not yet resolved. |
| `user` | An agent representing the user in the conversation. |
| `input` | A getter for the user's input in the conversation. A getter for the user's input in the conversation. It takes an object ```{query: string}``` as an argument. This defines what input query the user will see in the console. |
| `assistant` | An agent representing the assistant in the conversation. |
| `system` | An agent representing the system in the conversation. |
| `generation` | A getter for the assistant's generation in the conversation. |
| `prompt` | A getter for the user's prompt in the conversation. |
| `run` | A function that runs a conversation. It takes a Retort object as an argument. |
# Join our Community
Join us in the [RetortJS](https://discord.gg/YdZBFfWpYz) Discord to share your experiences, ask questions, contribute, and get help from the creators.