openai-api-mock 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.github/workflows/npm-publish.yml +33 -0
- package/main.js +22 -0
- package/package.json +18 -0
- package/readme.md +43 -0
- package/src/responce.js +99 -0
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# This workflow will run tests using node and then publish a package to GitHub Packages when a release is created
|
|
2
|
+
# For more information see: https://docs.github.com/en/actions/publishing-packages/publishing-nodejs-packages
|
|
3
|
+
|
|
4
|
+
name: Node.js Package
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
release:
|
|
8
|
+
types: [created]
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
build:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v3
|
|
15
|
+
- uses: actions/setup-node@v3
|
|
16
|
+
with:
|
|
17
|
+
node-version: 16
|
|
18
|
+
- run: npm ci
|
|
19
|
+
- run: npm test
|
|
20
|
+
|
|
21
|
+
publish-npm:
|
|
22
|
+
needs: build
|
|
23
|
+
runs-on: ubuntu-latest
|
|
24
|
+
steps:
|
|
25
|
+
- uses: actions/checkout@v3
|
|
26
|
+
- uses: actions/setup-node@v3
|
|
27
|
+
with:
|
|
28
|
+
node-version: 16
|
|
29
|
+
registry-url: https://registry.npmjs.org/
|
|
30
|
+
- run: npm ci
|
|
31
|
+
- run: npm publish
|
|
32
|
+
env:
|
|
33
|
+
NODE_AUTH_TOKEN: ${{secrets.npm_token}}
|
package/main.js
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
const nock = require('nock');
|
|
2
|
+
const { getResponce } = require('./src/responce.js');
|
|
3
|
+
|
|
4
|
+
function mockOpenAIResponse(force = false) {
|
|
5
|
+
// Define the OpenAI endpoint
|
|
6
|
+
const openaiEndpoint = 'https://api.openai.com/v1/chat/completions';
|
|
7
|
+
var env = process.env.NODE_ENV || 'development'
|
|
8
|
+
// Intercept the HTTP call and return the mock response
|
|
9
|
+
if (env === 'development' || force) {
|
|
10
|
+
nock(openaiEndpoint)
|
|
11
|
+
.post('')
|
|
12
|
+
.reply(
|
|
13
|
+
function (uri, requestBody) {
|
|
14
|
+
return [200, getResponce(requestBody)];
|
|
15
|
+
}
|
|
16
|
+
);
|
|
17
|
+
}
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
module.exports = {
|
|
21
|
+
mockOpenAIResponse
|
|
22
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "openai-api-mock",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "A Node.js module for mocking OpenAI API responses in a development environment",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"openai",
|
|
7
|
+
"mock",
|
|
8
|
+
"api",
|
|
9
|
+
"development",
|
|
10
|
+
"testing"
|
|
11
|
+
],
|
|
12
|
+
"author": "Chiheb Nabil",
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@faker-js/faker": "^8.4.0",
|
|
16
|
+
"nock": "^13.5.1"
|
|
17
|
+
}
|
|
18
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# OpenAI API Mock
|
|
2
|
+
|
|
3
|
+
This is a Node.js module for mocking OpenAI API responses in a development environment.
|
|
4
|
+
It's useful for testing and development purposes when you don't want to make actual API calls.
|
|
5
|
+
The module also supports mocking function_calling
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
You can install this module using npm as a dev dependency :
|
|
10
|
+
|
|
11
|
+
```sh
|
|
12
|
+
npm install -D openai-api-mock
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Usage
|
|
16
|
+
```js
|
|
17
|
+
const { mockOpenAIResponse } = require('openai-api-mock');
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
Then, call the mockOpenAIResponse function to set up the mock response:
|
|
22
|
+
|
|
23
|
+
```js
|
|
24
|
+
mockOpenAIResponse();
|
|
25
|
+
```
|
|
26
|
+
This function intercepts HTTP calls to the OpenAI endpoint and returns a mock response. The mock response is generated based on the requestBody of the code , and it supports complex (function call) requestBody structures like arrays and nested objects.
|
|
27
|
+
|
|
28
|
+
```js
|
|
29
|
+
mockOpenAIResponse(force = true);
|
|
30
|
+
```
|
|
31
|
+
The force parameter is a boolean that determines whether the mock response should be used regardless of the environment.
|
|
32
|
+
If force is true, the mock response will be used regardless of the environment. If force is false or not provided, the mock response will only be used if the <code>NODE_ENV</code> environment variable is set to 'development'.
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
## Dependencies
|
|
37
|
+
This module depends on the following npm packages:
|
|
38
|
+
|
|
39
|
+
- nock : For intercepting HTTP calls.
|
|
40
|
+
- @faker-js/faker : For generating fake data.
|
|
41
|
+
|
|
42
|
+
## License
|
|
43
|
+
This project is licensed under the MIT License.
|
package/src/responce.js
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
const { faker } = require('@faker-js/faker');
|
|
2
|
+
|
|
3
|
+
function getResponce(requestBody) {
|
|
4
|
+
const created = Math.floor(Date.now() / 1000)
|
|
5
|
+
if (!requestBody.functions) {
|
|
6
|
+
return {
|
|
7
|
+
choices: [
|
|
8
|
+
{
|
|
9
|
+
finish_reason: 'stop',
|
|
10
|
+
index: 0,
|
|
11
|
+
message: {
|
|
12
|
+
content: faker.lorem.words(5),
|
|
13
|
+
role: 'assistant',
|
|
14
|
+
},
|
|
15
|
+
logprobs: null,
|
|
16
|
+
},
|
|
17
|
+
],
|
|
18
|
+
created: created,
|
|
19
|
+
id: `chatcmpl-${faker.string.alphanumeric(30)}`,
|
|
20
|
+
model: `gpt-3.5-mock`,
|
|
21
|
+
object: 'chat.completion',
|
|
22
|
+
usage: {
|
|
23
|
+
completion_tokens: 17,
|
|
24
|
+
prompt_tokens: 57,
|
|
25
|
+
total_tokens: 74,
|
|
26
|
+
},
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
let functionCallingResponse = {
|
|
31
|
+
id: `chatcmpl-${faker.string.alphanumeric(30)}`,
|
|
32
|
+
object: 'chat.completion',
|
|
33
|
+
created: created,
|
|
34
|
+
model: 'gpt-3.5-mock',
|
|
35
|
+
choices: [
|
|
36
|
+
{
|
|
37
|
+
index: 0,
|
|
38
|
+
message: {
|
|
39
|
+
role: 'assistant',
|
|
40
|
+
content: null,
|
|
41
|
+
function_call: {
|
|
42
|
+
name: `${requestBody.functions[0].name}`,
|
|
43
|
+
arguments: `${generateFunctionCallArguments(requestBody)}`,
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
finish_reason: 'function_call'
|
|
47
|
+
}
|
|
48
|
+
],
|
|
49
|
+
usage: {
|
|
50
|
+
prompt_tokens: 81,
|
|
51
|
+
completion_tokens: 19,
|
|
52
|
+
total_tokens: 100
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
return functionCallingResponse;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function generateFakeData(type, properties) {
|
|
59
|
+
if (type === 'string') {
|
|
60
|
+
return faker.lorem.words(5);
|
|
61
|
+
} else if (type === 'number') {
|
|
62
|
+
return faker.random.number();
|
|
63
|
+
} else if (type === 'array') {
|
|
64
|
+
const arrayItemsType = properties.items.type;
|
|
65
|
+
let arrayItems = [];
|
|
66
|
+
if (arrayItemsType === 'string') {
|
|
67
|
+
arrayItems = Array.from({ length: 5 }, () => faker.lorem.words(1));
|
|
68
|
+
} else if (arrayItemsType === 'object') {
|
|
69
|
+
const itemProperties = properties.items.properties;
|
|
70
|
+
arrayItems = Array.from({ length: 5 }, () => generateFakeData('object', { properties: itemProperties }));
|
|
71
|
+
}
|
|
72
|
+
return arrayItems;
|
|
73
|
+
} else if (type === 'object') {
|
|
74
|
+
const itemObject = {};
|
|
75
|
+
Object.entries(properties.properties).forEach(([itemName, itemDetails]) => {
|
|
76
|
+
itemObject[itemName] = generateFakeData(itemDetails.type, itemDetails);
|
|
77
|
+
});
|
|
78
|
+
return itemObject;
|
|
79
|
+
} else {
|
|
80
|
+
return faker.lorem.words(1);
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
/*
|
|
84
|
+
* Generate function call arguments
|
|
85
|
+
*/
|
|
86
|
+
function generateFunctionCallArguments(requestBody) {
|
|
87
|
+
const { parameters } = requestBody.functions[0];
|
|
88
|
+
const argumentsObject = {};
|
|
89
|
+
|
|
90
|
+
Object.entries(parameters.properties).forEach(([paramName, paramDetails]) => {
|
|
91
|
+
argumentsObject[paramName] = generateFakeData(paramDetails.type, paramDetails);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
return JSON.stringify(argumentsObject, null, 2);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
module.exports = {
|
|
98
|
+
getResponce
|
|
99
|
+
}
|