Skip to content

Commit

Permalink
Merge pull request #15 from mrsteele/feature/client
Browse files Browse the repository at this point in the history
Feature/client
  • Loading branch information
mrsteele authored Aug 16, 2023
2 parents 73985d0 + 3c389ee commit 935454b
Show file tree
Hide file tree
Showing 6 changed files with 489 additions and 4 deletions.
139 changes: 136 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,31 @@ This package was written by an author who actively uses OpenAI and was running i
npm i openai-tokens
```

## Quick Start

If you are looking for all the bells and whistles provided out of the box, it is recommended to use the `client`.

```js
import { createClient } = from 'openai-tokens'

const client = createClient({
key: 'your-openai-key-here',
limit: 1000 // Maybe add a limit if you want
})

const response = await client.gpt('Is this working?')
console.log(response.content)
// 'Yes, it seems like we are connected!'
```

## Use-Cases

### Automatically swapping models based on token size

If you have too much content in your request, you can change your model dynamically so you use an appropriate size for each request.

```js
const { dynamicWrapper } = require('openai-tokens')
import { dynamicWrapper } from 'openai-tokens'

const chat = async (messages = []) => {
const body = await fetch('https://api.openai.com/v1/chat/completions', {
Expand Down Expand Up @@ -99,6 +116,122 @@ await fetch('https://api.openai.com/v1/embeddings', {
## Complete Usage
### createClient
In an effort to streamline all the utilities into a single opinionated service, you can create a `client` that will determine waht is the best model and truncate if needed to fit your needs.
```js
import { createClient } = from 'openai-tokens'

const client = createClient({
// put in your OpenAI key here
key: 'your-openai-key-here',
// (optional - defaults to 'null') - A limit on the prompts. If `null` it will be the model limit.
limit: 1000,
// (optional - defaults to `null`) - A buffer on the token count to let GPT respond
buffer: 1000,
// (optional - defaults below) Pass multiple models for adaptive models based on prompt size
gptModels: ['gpt-3.5-turbo', 'gpt-3.5-turbo-16k']
})

// single
await client.gpt('Is this working?')
// '{ content: 'Yes, it seems like we are connected!' }

// multi
await client.gpt([{
role: 'system',
content: 'You are a bot'
}, {
role: 'user',
content: 'What is your name?!'
}])
// '{ content: 'I am a bot using the model gpt-3.5-turbo.' }

// configurable on an individual basis
await client.gpt({
opts: {
// this overrides what was on the client in this instance only
buffer: 500
},
messages: [{
role: 'system',
content: 'You are a bot'
}, {
role: 'user',
content: 'What is your name?!'
}]
})
// '{ content: 'A bot using 3.5 turbo!' }
```
#### Options
The client itself can be created and configured with the following options:
* **key** (String) - REQUIRED. This is your key that is provided from OpenAI. Used for all your prompts.
* **limit** (Int) - The token limit you want to enforce on the messages/input. This is the aggregated results for messages (GPT/Completions), and the individual results for inputs/embeddings which is how they are calculated by OpenAI. Defaults to the model maximum.
* **buffer** (Int) - The amount of additional restriction you want to apply to the limit. The math equates to `max = limit - buffer`. Defaults to `0`.
* **json** (Bool) - Automatically returns the response as json. Defaults to `true`.
* **truncate** (Bool) - Uses some advanced logic to ensure that the prompts fit with the respective models and considers your limits and buffers. Defaults to `true`.
* **gptModels**: (String[]) - An array of models used for GPT completions. Uses the `validationWrapper` to find the best model to use. Defaults to `['gpt-3.5-turbo', 'gpt-3.5-turbo-4k']`.
* **embeddingModels**: (String[]) - An array of models used for Embeddings. There is only one at the moment. Defaults to `['ada-embeddings']`.
#### Returns
The client will return two properties:
* **gpt** - Run a GPT completion. Supports a `String`, `Array`, or an `Object` as the argument (see examples below):
```js
// String
await client.gpt('Is this working?')

// Array
await client.gpt([{
role: 'system',
content: 'You are a bot'
}, {
role: 'user',
content: 'What is your name?!'
}])

// Object
await client.gpt({
opts: {
limit: 500,
},
messages: [{
role: 'system',
content: 'You are a bot'
}, {
role: 'user',
content: 'What is your name?!'
}]
})
```
* **embed** - Run an Embedding. Supports a `String`, `Array` or an `Object`. See examples below:
```js
// String
await client.embed('Is this working?')

// Array
await client.embed([
'You are a bot',
'What is your name?!'
])

// Object
await client.embed({
opts: {
limit: 500,
},
input: [
'You are a bot',
'What is your name?!'
]
})
```
### Truncate
You can use the truncate tools to enforce cutoffs of sentences that are too large. This can be automatically detected or you can provide your own limits. The truncation is programmed to break on a word, not in the middle.
Expand Down Expand Up @@ -196,7 +329,7 @@ You can pass options to the validate wrapper as seen in the examples above. The
A dynamic router has been provided for convenience. This allows you to pass multiple models. The module will choose the first valid model, so you can always maintain the smallest possible (and save some money 💰).
```js
const { dynamicWrapper } = require('openai-tokens')
import { dynamicWrapper } = from 'openai-tokens'

const chat = async (messages = []) => {
const body = await fetch('https://api.openai.com/v1/chat/completions', {
Expand Down Expand Up @@ -240,7 +373,7 @@ If you provide a model that is not supported, you will get a console message as
YES! A good example of this would be using the `dynamicWrapper` and the `truncateWrapper` together like so:
```js
const { dynamicWrapper, truncateWrapper } = require('openai-tokens')
import { dynamicWrapper, truncateWrapper } from 'openai-tokens'

const chat = async (messages = []) => {
const body = await fetch('https://api.openai.com/v1/chat/completions', {
Expand Down
53 changes: 53 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
"author": "Matt Steele <[email protected]>",
"license": "MIT",
"dependencies": {
"isomorphic-fetch": "^3.0.0",
"js-tiktoken": "^1.0.7"
},
"devDependencies": {
Expand Down
Loading

0 comments on commit 935454b

Please sign in to comment.