@aj-archipelago/cortex 1.1.2 → 1.1.4-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/.eslintignore +3 -3
- package/README.md +16 -3
- package/config.js +32 -8
- package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/Dockerfile +1 -1
- package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/fileChunker.js +1 -0
- package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/package-lock.json +25 -216
- package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/package.json +2 -2
- package/helper-apps/cortex-whisper-wrapper/.dockerignore +27 -0
- package/helper-apps/cortex-whisper-wrapper/Dockerfile +32 -0
- package/helper-apps/cortex-whisper-wrapper/app.py +104 -0
- package/helper-apps/cortex-whisper-wrapper/docker-compose.debug.yml +12 -0
- package/helper-apps/cortex-whisper-wrapper/docker-compose.yml +10 -0
- package/helper-apps/cortex-whisper-wrapper/models/.gitkeep +0 -0
- package/helper-apps/cortex-whisper-wrapper/requirements.txt +5 -0
- package/lib/cortexRequest.js +117 -0
- package/lib/pathwayTools.js +2 -1
- package/lib/redisSubscription.js +44 -28
- package/lib/requestExecutor.js +360 -0
- package/lib/requestMonitor.js +131 -28
- package/package.json +2 -1
- package/pathways/summary.js +3 -3
- package/server/graphql.js +4 -4
- package/server/{pathwayPrompter.js → modelExecutor.js} +24 -21
- package/server/pathwayResolver.js +25 -20
- package/server/plugins/azureCognitivePlugin.js +25 -20
- package/server/plugins/azureTranslatePlugin.js +6 -10
- package/server/plugins/cohereGeneratePlugin.js +5 -12
- package/server/plugins/cohereSummarizePlugin.js +5 -12
- package/server/plugins/localModelPlugin.js +3 -3
- package/server/plugins/modelPlugin.js +18 -12
- package/server/plugins/openAiChatExtensionPlugin.js +5 -5
- package/server/plugins/openAiChatPlugin.js +8 -10
- package/server/plugins/openAiCompletionPlugin.js +9 -12
- package/server/plugins/openAiDallE3Plugin.js +14 -31
- package/server/plugins/openAiEmbeddingsPlugin.js +6 -9
- package/server/plugins/openAiImagePlugin.js +19 -15
- package/server/plugins/openAiWhisperPlugin.js +167 -99
- package/server/plugins/palmChatPlugin.js +9 -10
- package/server/plugins/palmCodeCompletionPlugin.js +2 -2
- package/server/plugins/palmCompletionPlugin.js +11 -12
- package/server/resolver.js +2 -2
- package/server/rest.js +4 -5
- package/server/subscriptions.js +2 -0
- package/tests/config.test.js +1 -1
- package/tests/mocks.js +5 -0
- package/tests/modelPlugin.test.js +3 -10
- package/tests/openAiChatPlugin.test.js +9 -8
- package/tests/openai_api.test.js +3 -3
- package/tests/palmChatPlugin.test.js +1 -1
- package/tests/palmCompletionPlugin.test.js +1 -1
- package/tests/pathwayResolver.test.js +2 -1
- package/tests/requestMonitor.test.js +94 -0
- package/tests/{requestDurationEstimator.test.js → requestMonitorDurationEstimator.test.js} +21 -17
- package/tests/truncateMessages.test.js +1 -1
- package/lib/request.js +0 -260
- package/lib/requestDurationEstimator.js +0 -90
- /package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/blobHandler.js +0 -0
- /package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/docHelper.js +0 -0
- /package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/function.json +0 -0
- /package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/helper.js +0 -0
- /package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/index.js +0 -0
- /package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/localFileHandler.js +0 -0
- /package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/redis.js +0 -0
- /package/{helper_apps/CortexFileHandler → helper-apps/cortex-file-handler}/start.js +0 -0
package/server/rest.js
CHANGED
|
@@ -167,11 +167,10 @@ const processIncomingStream = (requestId, res, jsonResponse) => {
|
|
|
167
167
|
// Fire the resolver for the async requestProgress
|
|
168
168
|
logger.info(`Rest Endpoint starting async requestProgress, requestId: ${requestId}`);
|
|
169
169
|
const { resolver, args } = requestState[requestId];
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
resolver(args, false);
|
|
170
|
+
requestState[requestId].useRedis = false;
|
|
171
|
+
requestState[requestId].started = true;
|
|
172
|
+
|
|
173
|
+
resolver && resolver(args);
|
|
175
174
|
|
|
176
175
|
return subscription;
|
|
177
176
|
|
package/server/subscriptions.js
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import pubsub from './pubsub.js';
|
|
2
2
|
import { withFilter } from 'graphql-subscriptions';
|
|
3
3
|
import { publishRequestProgressSubscription } from '../lib/redisSubscription.js';
|
|
4
|
+
import logger from '../lib/logger.js';
|
|
4
5
|
|
|
5
6
|
const subscriptions = {
|
|
6
7
|
requestProgress: {
|
|
7
8
|
subscribe: withFilter(
|
|
8
9
|
(_, args, __, _info) => {
|
|
10
|
+
logger.debug(`Client requested subscription for request ids: ${args.requestIds}`);
|
|
9
11
|
publishRequestProgressSubscription(args.requestIds);
|
|
10
12
|
return pubsub.asyncIterator(['REQUEST_PROGRESS'])
|
|
11
13
|
},
|
package/tests/config.test.js
CHANGED
package/tests/mocks.js
CHANGED
|
@@ -6,6 +6,7 @@ export const mockConfig = {
|
|
|
6
6
|
defaultModelName: 'testModel',
|
|
7
7
|
models: {
|
|
8
8
|
testModel: {
|
|
9
|
+
name: 'testModel',
|
|
9
10
|
url: 'https://api.example.com/testModel',
|
|
10
11
|
type: 'OPENAI-COMPLETION',
|
|
11
12
|
},
|
|
@@ -40,6 +41,7 @@ export const mockConfig = {
|
|
|
40
41
|
|
|
41
42
|
export const mockPathwayResolverString = {
|
|
42
43
|
model: {
|
|
44
|
+
name: 'testModel',
|
|
43
45
|
url: 'https://api.example.com/testModel',
|
|
44
46
|
type: 'OPENAI-COMPLETION',
|
|
45
47
|
},
|
|
@@ -51,6 +53,7 @@ export const mockConfig = {
|
|
|
51
53
|
|
|
52
54
|
export const mockPathwayResolverFunction = {
|
|
53
55
|
model: {
|
|
56
|
+
name: 'testModel',
|
|
54
57
|
url: 'https://api.example.com/testModel',
|
|
55
58
|
type: 'OPENAI-COMPLETION',
|
|
56
59
|
},
|
|
@@ -64,6 +67,7 @@ export const mockConfig = {
|
|
|
64
67
|
|
|
65
68
|
export const mockPathwayResolverMessages = {
|
|
66
69
|
model: {
|
|
70
|
+
name: 'testModel',
|
|
67
71
|
url: 'https://api.example.com/testModel',
|
|
68
72
|
type: 'OPENAI-COMPLETION',
|
|
69
73
|
},
|
|
@@ -78,3 +82,4 @@ export const mockConfig = {
|
|
|
78
82
|
}),
|
|
79
83
|
};
|
|
80
84
|
|
|
85
|
+
export const mockModelEndpoints = { testModel: { name: 'testModel', url: 'https://api.example.com/testModel', type: 'OPENAI-COMPLETION' }};
|
|
@@ -8,10 +8,10 @@ const DEFAULT_MAX_TOKENS = 4096;
|
|
|
8
8
|
const DEFAULT_PROMPT_TOKEN_RATIO = 0.5;
|
|
9
9
|
|
|
10
10
|
// Mock configuration and pathway objects
|
|
11
|
-
const { config, pathway,
|
|
11
|
+
const { config, pathway, model } = mockPathwayResolverString;
|
|
12
12
|
|
|
13
13
|
test('ModelPlugin constructor', (t) => {
|
|
14
|
-
const modelPlugin = new ModelPlugin(
|
|
14
|
+
const modelPlugin = new ModelPlugin(pathway, model);
|
|
15
15
|
|
|
16
16
|
t.is(modelPlugin.modelName, pathway.model, 'modelName should be set from pathway');
|
|
17
17
|
t.deepEqual(modelPlugin.model, config.get('models')[pathway.model], 'model should be set from config');
|
|
@@ -20,7 +20,7 @@ test('ModelPlugin constructor', (t) => {
|
|
|
20
20
|
});
|
|
21
21
|
|
|
22
22
|
test.beforeEach((t) => {
|
|
23
|
-
t.context.modelPlugin = new ModelPlugin(
|
|
23
|
+
t.context.modelPlugin = new ModelPlugin(pathway, model);
|
|
24
24
|
});
|
|
25
25
|
|
|
26
26
|
test('getCompiledPrompt - text and parameters', (t) => {
|
|
@@ -71,13 +71,6 @@ test('getPromptTokenRatio', (t) => {
|
|
|
71
71
|
t.is(modelPlugin.getPromptTokenRatio(), DEFAULT_PROMPT_TOKEN_RATIO, 'getPromptTokenRatio should return default prompt token ratio');
|
|
72
72
|
});
|
|
73
73
|
|
|
74
|
-
test('requestUrl', (t) => {
|
|
75
|
-
const { modelPlugin } = t.context;
|
|
76
|
-
|
|
77
|
-
const expectedUrl = HandleBars.compile(modelPlugin.model.url)({ ...modelPlugin.model, ...config.getEnv(), ...config });
|
|
78
|
-
t.is(modelPlugin.requestUrl(), expectedUrl, 'requestUrl should return the correct URL');
|
|
79
|
-
});
|
|
80
|
-
|
|
81
74
|
test('default parseResponse', (t) => {
|
|
82
75
|
const { modelPlugin } = t.context;
|
|
83
76
|
const multipleChoicesResponse = {
|
|
@@ -1,19 +1,20 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
2
|
import OpenAIChatPlugin from '../server/plugins/openAiChatPlugin.js';
|
|
3
3
|
import { mockPathwayResolverMessages } from './mocks.js';
|
|
4
|
+
import { config } from '../config.js';
|
|
4
5
|
|
|
5
|
-
const {
|
|
6
|
+
const { pathway, modelName, model } = mockPathwayResolverMessages;
|
|
6
7
|
|
|
7
8
|
// Test the constructor
|
|
8
9
|
test('constructor', (t) => {
|
|
9
|
-
const plugin = new OpenAIChatPlugin(
|
|
10
|
-
t.is(plugin.config,
|
|
10
|
+
const plugin = new OpenAIChatPlugin(pathway, model);
|
|
11
|
+
t.is(plugin.config, config);
|
|
11
12
|
t.is(plugin.pathwayPrompt, mockPathwayResolverMessages.pathway.prompt);
|
|
12
13
|
});
|
|
13
14
|
|
|
14
15
|
// Test the convertPalmToOpenAIMessages function
|
|
15
16
|
test('convertPalmToOpenAIMessages', (t) => {
|
|
16
|
-
const plugin = new OpenAIChatPlugin(
|
|
17
|
+
const plugin = new OpenAIChatPlugin(pathway, model);
|
|
17
18
|
const context = 'This is a test context.';
|
|
18
19
|
const examples = [
|
|
19
20
|
{
|
|
@@ -37,7 +38,7 @@ test('convertPalmToOpenAIMessages', (t) => {
|
|
|
37
38
|
|
|
38
39
|
// Test the getRequestParameters function
|
|
39
40
|
test('getRequestParameters', async (t) => {
|
|
40
|
-
const plugin = new OpenAIChatPlugin(
|
|
41
|
+
const plugin = new OpenAIChatPlugin(pathway, model);
|
|
41
42
|
const text = 'Help me';
|
|
42
43
|
const parameters = { name: 'John', age: 30 };
|
|
43
44
|
const prompt = mockPathwayResolverMessages.pathway.prompt;
|
|
@@ -59,7 +60,7 @@ test('getRequestParameters', async (t) => {
|
|
|
59
60
|
|
|
60
61
|
// Test the execute function
|
|
61
62
|
test('execute', async (t) => {
|
|
62
|
-
const plugin = new OpenAIChatPlugin(
|
|
63
|
+
const plugin = new OpenAIChatPlugin(pathway, model);
|
|
63
64
|
const text = 'Help me';
|
|
64
65
|
const parameters = { name: 'John', age: 30 };
|
|
65
66
|
const prompt = mockPathwayResolverMessages.pathway.prompt;
|
|
@@ -91,7 +92,7 @@ test('execute', async (t) => {
|
|
|
91
92
|
|
|
92
93
|
// Test the parseResponse function
|
|
93
94
|
test('parseResponse', (t) => {
|
|
94
|
-
const plugin = new OpenAIChatPlugin(
|
|
95
|
+
const plugin = new OpenAIChatPlugin(pathway, model);
|
|
95
96
|
const data = {
|
|
96
97
|
choices: [
|
|
97
98
|
{
|
|
@@ -107,7 +108,7 @@ test('parseResponse', (t) => {
|
|
|
107
108
|
|
|
108
109
|
// Test the logRequestData function
|
|
109
110
|
test('logRequestData', (t) => {
|
|
110
|
-
const plugin = new OpenAIChatPlugin(
|
|
111
|
+
const plugin = new OpenAIChatPlugin(pathway, model);
|
|
111
112
|
const data = {
|
|
112
113
|
messages: [
|
|
113
114
|
{ role: 'user', content: 'User: Help me\nAssistant: Please help John who is 30 years old.' },
|
package/tests/openai_api.test.js
CHANGED
|
@@ -5,7 +5,7 @@ import got from 'got';
|
|
|
5
5
|
import axios from 'axios';
|
|
6
6
|
import serverFactory from '../index.js';
|
|
7
7
|
|
|
8
|
-
const API_BASE =
|
|
8
|
+
const API_BASE = `http://localhost:${process.env.CORTEX_PORT}/v1`;
|
|
9
9
|
|
|
10
10
|
let testServer;
|
|
11
11
|
|
|
@@ -110,7 +110,7 @@ test('POST SSE: /v1/completions should send a series of events and a [DONE] even
|
|
|
110
110
|
stream: true,
|
|
111
111
|
};
|
|
112
112
|
|
|
113
|
-
const url =
|
|
113
|
+
const url = `http://localhost:${process.env.CORTEX_PORT}/v1`;
|
|
114
114
|
|
|
115
115
|
const completionsAssertions = (t, messageJson) => {
|
|
116
116
|
t.truthy(messageJson.id);
|
|
@@ -133,7 +133,7 @@ test('POST SSE: /v1/chat/completions should send a series of events and a [DONE]
|
|
|
133
133
|
stream: true,
|
|
134
134
|
};
|
|
135
135
|
|
|
136
|
-
const url =
|
|
136
|
+
const url = `http://localhost:${process.env.CORTEX_PORT}/v1`;
|
|
137
137
|
|
|
138
138
|
const chatCompletionsAssertions = (t, messageJson) => {
|
|
139
139
|
t.truthy(messageJson.id);
|
|
@@ -6,7 +6,7 @@ import { mockPathwayResolverMessages } from './mocks.js';
|
|
|
6
6
|
const { config, pathway, modelName, model } = mockPathwayResolverMessages;
|
|
7
7
|
|
|
8
8
|
test.beforeEach((t) => {
|
|
9
|
-
const palmChatPlugin = new PalmChatPlugin(
|
|
9
|
+
const palmChatPlugin = new PalmChatPlugin(pathway, model);
|
|
10
10
|
t.context = { palmChatPlugin };
|
|
11
11
|
});
|
|
12
12
|
|
|
@@ -7,7 +7,7 @@ import { mockPathwayResolverString } from './mocks.js';
|
|
|
7
7
|
const { config, pathway, modelName, model } = mockPathwayResolverString;
|
|
8
8
|
|
|
9
9
|
test.beforeEach((t) => {
|
|
10
|
-
const palmCompletionPlugin = new PalmCompletionPlugin(
|
|
10
|
+
const palmCompletionPlugin = new PalmCompletionPlugin(pathway, model);
|
|
11
11
|
t.context = { palmCompletionPlugin };
|
|
12
12
|
});
|
|
13
13
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
2
|
import { PathwayResolver } from '../server/pathwayResolver.js';
|
|
3
3
|
import sinon from 'sinon';
|
|
4
|
-
import { mockConfig, mockPathwayString } from './mocks.js';
|
|
4
|
+
import { mockConfig, mockPathwayString, mockModelEndpoints } from './mocks.js';
|
|
5
5
|
|
|
6
6
|
const mockPathway = mockPathwayString;
|
|
7
7
|
mockPathway.useInputChunking = false;
|
|
@@ -16,6 +16,7 @@ test.beforeEach((t) => {
|
|
|
16
16
|
config: mockConfig,
|
|
17
17
|
pathway: mockPathway,
|
|
18
18
|
args: mockArgs,
|
|
19
|
+
endpoints: mockModelEndpoints,
|
|
19
20
|
});
|
|
20
21
|
});
|
|
21
22
|
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import RequestMonitor from '../lib/requestMonitor.js'; // replace with actual path
|
|
3
|
+
|
|
4
|
+
test('RequestMonitor: startCall', t => {
|
|
5
|
+
const rm = new RequestMonitor();
|
|
6
|
+
|
|
7
|
+
const callId = rm.startCall();
|
|
8
|
+
|
|
9
|
+
t.is(rm.callStartTimes.has(callId), true);
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
test('RequestMonitor: endCall', t => {
|
|
13
|
+
const rm = new RequestMonitor();
|
|
14
|
+
|
|
15
|
+
const callId = rm.startCall();
|
|
16
|
+
rm.endCall(callId);
|
|
17
|
+
|
|
18
|
+
t.is(rm.callStartTimes.has(callId), false);
|
|
19
|
+
t.is(rm.callCount.size(), 1);
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
test('RequestMonitor: getAverageCallDuration', async t => {
|
|
23
|
+
const rm = new RequestMonitor();
|
|
24
|
+
|
|
25
|
+
const callId1 = rm.startCall();
|
|
26
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
27
|
+
rm.endCall(callId1);
|
|
28
|
+
|
|
29
|
+
const callId2 = rm.startCall();
|
|
30
|
+
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
31
|
+
rm.endCall(callId2);
|
|
32
|
+
|
|
33
|
+
const average = rm.getAverageCallDuration();
|
|
34
|
+
t.truthy(average > 1400 && average < 1600);
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('RequestMonitor: incrementError429Count', t => {
|
|
38
|
+
const rm = new RequestMonitor();
|
|
39
|
+
|
|
40
|
+
rm.incrementError429Count();
|
|
41
|
+
|
|
42
|
+
t.is(rm.error429Count.size(), 1);
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('RequestMonitor: getCallRate', async t => {
|
|
46
|
+
const rm = new RequestMonitor();
|
|
47
|
+
|
|
48
|
+
rm.startCall();
|
|
49
|
+
rm.endCall();
|
|
50
|
+
|
|
51
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
52
|
+
|
|
53
|
+
const callRate = rm.getCallRate();
|
|
54
|
+
t.truthy(callRate > 0.9 && callRate < 1.1);
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
test('RequestMonitor: getPeakCallRate', async t => {
|
|
58
|
+
const rm = new RequestMonitor();
|
|
59
|
+
|
|
60
|
+
rm.startCall();
|
|
61
|
+
rm.endCall();
|
|
62
|
+
|
|
63
|
+
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
64
|
+
|
|
65
|
+
rm.startCall();
|
|
66
|
+
rm.endCall();
|
|
67
|
+
|
|
68
|
+
const peakCallRate = rm.getPeakCallRate();
|
|
69
|
+
t.truthy(peakCallRate > 1.9 && peakCallRate < 2.1);
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('RequestMonitor: getError429Rate', t => {
|
|
73
|
+
const rm = new RequestMonitor();
|
|
74
|
+
|
|
75
|
+
rm.startCall();
|
|
76
|
+
rm.endCall();
|
|
77
|
+
rm.incrementError429Count();
|
|
78
|
+
|
|
79
|
+
t.is(rm.getError429Rate(), 1);
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
test('RequestMonitor: reset', t => {
|
|
83
|
+
const rm = new RequestMonitor();
|
|
84
|
+
|
|
85
|
+
rm.startCall();
|
|
86
|
+
rm.endCall();
|
|
87
|
+
rm.incrementError429Count();
|
|
88
|
+
|
|
89
|
+
rm.reset();
|
|
90
|
+
|
|
91
|
+
t.is(rm.callCount.size(), 0);
|
|
92
|
+
t.is(rm.error429Count.size(), 0);
|
|
93
|
+
t.is(rm.peakCallRate, 0);
|
|
94
|
+
});
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import test from 'ava';
|
|
2
|
-
import
|
|
2
|
+
import RequestMonitor from '../lib/requestMonitor.js';
|
|
3
3
|
|
|
4
4
|
test('add and get average request duration', async (t) => {
|
|
5
|
-
const estimator = new
|
|
5
|
+
const estimator = new RequestMonitor(5);
|
|
6
6
|
|
|
7
|
-
estimator.
|
|
7
|
+
const callid = estimator.startCall();
|
|
8
8
|
await new Promise(resolve => setTimeout(() => {
|
|
9
|
-
estimator.
|
|
9
|
+
estimator.endCall(callid);
|
|
10
10
|
|
|
11
|
-
const average = estimator.calculatePercentComplete();
|
|
11
|
+
const average = estimator.calculatePercentComplete(callid);
|
|
12
12
|
|
|
13
13
|
// An average should be calculated after the first completed request
|
|
14
14
|
t.not(average, 0);
|
|
@@ -17,31 +17,31 @@ test('add and get average request duration', async (t) => {
|
|
|
17
17
|
});
|
|
18
18
|
|
|
19
19
|
test('add more requests than size of durations array', (t) => {
|
|
20
|
-
const estimator = new
|
|
20
|
+
const estimator = new RequestMonitor(5);
|
|
21
21
|
|
|
22
22
|
for (let i = 0; i < 10; i++) {
|
|
23
|
-
estimator.
|
|
24
|
-
estimator.
|
|
23
|
+
const callid = estimator.startCall();
|
|
24
|
+
estimator.endCall(callid);
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
// Array size should not exceed maximum length (5 in this case)
|
|
28
|
-
t.is(estimator.
|
|
28
|
+
t.is(estimator.callDurations.size(), 5);
|
|
29
29
|
});
|
|
30
30
|
|
|
31
31
|
test('calculate percent complete of current request based on average of past durations', async (t) => {
|
|
32
|
-
const estimator = new
|
|
32
|
+
const estimator = new RequestMonitor(5);
|
|
33
33
|
|
|
34
34
|
for (let i = 0; i < 4; i++) {
|
|
35
|
-
estimator.
|
|
35
|
+
const callid = estimator.startCall();
|
|
36
36
|
// wait 1 second
|
|
37
37
|
await new Promise(resolve => setTimeout(resolve, 1000));
|
|
38
|
-
estimator.
|
|
38
|
+
estimator.endCall(callid);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
-
estimator.
|
|
41
|
+
const callid = estimator.startCall();
|
|
42
42
|
|
|
43
43
|
await new Promise(resolve => setTimeout(() => {
|
|
44
|
-
const percentComplete = estimator.calculatePercentComplete();
|
|
44
|
+
const percentComplete = estimator.calculatePercentComplete(callid);
|
|
45
45
|
|
|
46
46
|
// Depending on how fast the operations are,
|
|
47
47
|
// the percentage may not be exactly 50%, but
|
|
@@ -52,8 +52,12 @@ test('calculate percent complete of current request based on average of past dur
|
|
|
52
52
|
});
|
|
53
53
|
|
|
54
54
|
test('calculate percent complete based on average of past durations', async (t) => {
|
|
55
|
-
const estimator = new
|
|
56
|
-
estimator.
|
|
57
|
-
|
|
55
|
+
const estimator = new RequestMonitor(5);
|
|
56
|
+
estimator.callDurations.clear;
|
|
57
|
+
estimator.callDurations.pushBack({endTime: new Date(), callDuration: 1000});
|
|
58
|
+
estimator.callDurations.pushBack({endTime: new Date(), callDuration: 2000});
|
|
59
|
+
estimator.callDurations.pushBack({endTime: new Date(), callDuration: 3000});
|
|
60
|
+
|
|
61
|
+
const average = estimator.getAverageCallDuration();
|
|
58
62
|
t.is(average, 2000);
|
|
59
63
|
});
|
|
@@ -6,7 +6,7 @@ import { mockPathwayResolverString } from './mocks.js';
|
|
|
6
6
|
|
|
7
7
|
const { config, pathway, modelName, model } = mockPathwayResolverString;
|
|
8
8
|
|
|
9
|
-
const modelPlugin = new ModelPlugin(
|
|
9
|
+
const modelPlugin = new ModelPlugin(pathway, model);
|
|
10
10
|
|
|
11
11
|
const generateMessage = (role, content) => ({ role, content });
|
|
12
12
|
|