@aj-archipelago/cortex 1.1.19 → 1.1.21
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/config/default.example.json +1 -14
- package/config.js +12 -0
- package/helper-apps/cortex-file-handler/blobHandler.js +54 -13
- package/helper-apps/cortex-file-handler/index.js +8 -7
- package/helper-apps/cortex-file-handler/package.json +1 -0
- package/lib/pathwayTools.js +11 -1
- package/lib/requestExecutor.js +4 -4
- package/lib/util.js +163 -1
- package/package.json +1 -1
- package/pathways/index.js +2 -0
- package/pathways/transcribe_neuralspace.js +18 -0
- package/server/modelExecutor.js +4 -0
- package/server/pathwayResolver.js +19 -1
- package/server/plugins/claude3VertexPlugin.js +274 -140
- package/server/plugins/gemini15ChatPlugin.js +8 -3
- package/server/plugins/gemini15VisionPlugin.js +23 -6
- package/server/plugins/geminiChatPlugin.js +1 -1
- package/server/plugins/geminiVisionPlugin.js +2 -3
- package/server/plugins/neuralSpacePlugin.js +252 -0
- package/server/plugins/openAiVisionPlugin.js +24 -7
- package/server/plugins/openAiWhisperPlugin.js +5 -152
- package/server/plugins/palmChatPlugin.js +1 -1
- package/server/resolver.js +11 -3
- package/server/typeDef.js +1 -0
- package/tests/claude3VertexPlugin.test.js +214 -0
- package/tests/mocks.js +2 -0
- package/tests/openAiChatPlugin.test.js +4 -0
- package/tests/vision.test.js +1 -1
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import test from 'ava';
|
|
2
|
+
import Claude3VertexPlugin from '../server/plugins/claude3VertexPlugin.js';
|
|
3
|
+
import { mockPathwayResolverMessages } from './mocks.js';
|
|
4
|
+
import { config } from '../config.js';
|
|
5
|
+
|
|
6
|
+
const { pathway, modelName, model } = mockPathwayResolverMessages;
|
|
7
|
+
|
|
8
|
+
test('constructor', (t) => {
|
|
9
|
+
const plugin = new Claude3VertexPlugin(pathway, model);
|
|
10
|
+
t.is(plugin.config, config);
|
|
11
|
+
t.is(plugin.pathwayPrompt, mockPathwayResolverMessages.pathway.prompt);
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
test('getRequestParameters', async (t) => {
|
|
15
|
+
const plugin = new Claude3VertexPlugin(pathway, model);
|
|
16
|
+
const text = 'Help me';
|
|
17
|
+
const parameters = { name: 'John', age: 30, stream: false };
|
|
18
|
+
const prompt = mockPathwayResolverMessages.pathway.prompt;
|
|
19
|
+
|
|
20
|
+
const result = await plugin.getRequestParameters(text, parameters, prompt, { messages: [] });
|
|
21
|
+
t.deepEqual(result, {
|
|
22
|
+
system: '',
|
|
23
|
+
messages: [
|
|
24
|
+
{
|
|
25
|
+
role: "user",
|
|
26
|
+
content: [
|
|
27
|
+
{
|
|
28
|
+
type: "text",
|
|
29
|
+
text: "Translate this: Help me",
|
|
30
|
+
},
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
role: "assistant",
|
|
35
|
+
content: [
|
|
36
|
+
{
|
|
37
|
+
type: "text",
|
|
38
|
+
text: "Translating: Help me",
|
|
39
|
+
},
|
|
40
|
+
],
|
|
41
|
+
},
|
|
42
|
+
{
|
|
43
|
+
role: "user",
|
|
44
|
+
content: [
|
|
45
|
+
{
|
|
46
|
+
type: "text",
|
|
47
|
+
text: "Nice work!",
|
|
48
|
+
},
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
],
|
|
52
|
+
max_tokens: plugin.getModelMaxReturnTokens(),
|
|
53
|
+
anthropic_version: 'vertex-2023-10-16',
|
|
54
|
+
stream: false,
|
|
55
|
+
temperature: 0.7,
|
|
56
|
+
});
|
|
57
|
+
});
|
|
58
|
+
|
|
59
|
+
test('parseResponse', (t) => {
|
|
60
|
+
const plugin = new Claude3VertexPlugin(pathway, model);
|
|
61
|
+
|
|
62
|
+
const dataWithTextContent = {
|
|
63
|
+
content: [
|
|
64
|
+
{ type: 'text', text: 'Hello, World!' }
|
|
65
|
+
]
|
|
66
|
+
};
|
|
67
|
+
const resultWithTextContent = plugin.parseResponse(dataWithTextContent);
|
|
68
|
+
t.is(resultWithTextContent, 'Hello, World!');
|
|
69
|
+
|
|
70
|
+
const dataWithoutTextContent = {
|
|
71
|
+
content: [
|
|
72
|
+
{ type: 'image', url: 'http://example.com/image.jpg' }
|
|
73
|
+
]
|
|
74
|
+
};
|
|
75
|
+
const resultWithoutTextContent = plugin.parseResponse(dataWithoutTextContent);
|
|
76
|
+
t.deepEqual(resultWithoutTextContent, dataWithoutTextContent);
|
|
77
|
+
|
|
78
|
+
const dataWithoutContent = {};
|
|
79
|
+
const resultWithoutContent = plugin.parseResponse(dataWithoutContent);
|
|
80
|
+
t.deepEqual(resultWithoutContent, dataWithoutContent);
|
|
81
|
+
|
|
82
|
+
const dataNull = null;
|
|
83
|
+
const resultNull = plugin.parseResponse(dataNull);
|
|
84
|
+
t.is(resultNull, dataNull);
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
test('convertMessagesToClaudeVertex text message', async (t) => {
|
|
88
|
+
const plugin = new Claude3VertexPlugin(pathway, model);
|
|
89
|
+
// Test with text message
|
|
90
|
+
let messages = [
|
|
91
|
+
{ role: 'system', content: 'System message' },
|
|
92
|
+
{ role: 'user', content: 'User message' },
|
|
93
|
+
{ role: 'assistant', content: 'Assistant message' },
|
|
94
|
+
{ role: 'user', content: 'User message 2' },
|
|
95
|
+
];
|
|
96
|
+
let output = await plugin.convertMessagesToClaudeVertex(messages);
|
|
97
|
+
t.deepEqual(output, {
|
|
98
|
+
system: 'System message',
|
|
99
|
+
modifiedMessages: [
|
|
100
|
+
{
|
|
101
|
+
role: "user",
|
|
102
|
+
content: [
|
|
103
|
+
{
|
|
104
|
+
type: "text",
|
|
105
|
+
text: "User message",
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
role: "assistant",
|
|
111
|
+
content: [
|
|
112
|
+
{
|
|
113
|
+
type: "text",
|
|
114
|
+
text: "Assistant message",
|
|
115
|
+
},
|
|
116
|
+
],
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
role: "user",
|
|
120
|
+
content: [
|
|
121
|
+
{
|
|
122
|
+
type: "text",
|
|
123
|
+
text: "User message 2",
|
|
124
|
+
},
|
|
125
|
+
],
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
});
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
test('convertMessagesToClaudeVertex image_url message', async (t) => {
|
|
132
|
+
const plugin = new Claude3VertexPlugin(pathway, model);
|
|
133
|
+
// Test with image_url message
|
|
134
|
+
const messages = [
|
|
135
|
+
{
|
|
136
|
+
role: 'assistant',
|
|
137
|
+
content: {
|
|
138
|
+
type: 'image_url',
|
|
139
|
+
// Define image_url, make sure it's accessible and supported MIME type
|
|
140
|
+
image_url: 'https://static.toiimg.com/thumb/msid-102827471,width-1280,height-720,resizemode-4/102827471.jpg'
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
];
|
|
144
|
+
const output = await plugin.convertMessagesToClaudeVertex(messages);
|
|
145
|
+
|
|
146
|
+
// Define a regex for base64 validation
|
|
147
|
+
const base64Regex = /^[A-Za-z0-9+/]+={0,2}$/;
|
|
148
|
+
const base64Data = output.modifiedMessages[0].content[0].source.data;
|
|
149
|
+
|
|
150
|
+
t.is(output.system, '');
|
|
151
|
+
t.is(output.modifiedMessages[0].role, 'assistant');
|
|
152
|
+
t.is(output.modifiedMessages[0].content[0].type, 'image');
|
|
153
|
+
t.is(output.modifiedMessages[0].content[0].source.type, 'base64');
|
|
154
|
+
t.is(output.modifiedMessages[0].content[0].source.media_type, 'image/jpeg');
|
|
155
|
+
|
|
156
|
+
// Check if the base64 data looks reasonable
|
|
157
|
+
t.true(base64Data.length > 100); // Check if the data is sufficiently long
|
|
158
|
+
t.true(base64Regex.test(base64Data)); // Check if the data matches the base64 regex
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
test('convertMessagesToClaudeVertex unsupported type', async (t) => {
|
|
162
|
+
const plugin = new Claude3VertexPlugin(pathway, model);
|
|
163
|
+
// Test with unsupported type
|
|
164
|
+
const messages = [{ role: 'user', content: { type: 'unsupported_type' } }];
|
|
165
|
+
const output = await plugin.convertMessagesToClaudeVertex(messages);
|
|
166
|
+
t.deepEqual(output, { system: '', modifiedMessages: [{role: 'user', content: [] }] });
|
|
167
|
+
});
|
|
168
|
+
|
|
169
|
+
test('convertMessagesToClaudeVertex empty messages', async (t) => {
|
|
170
|
+
const plugin = new Claude3VertexPlugin(pathway, model);
|
|
171
|
+
// Test with empty messages
|
|
172
|
+
const messages = [];
|
|
173
|
+
const output = await plugin.convertMessagesToClaudeVertex(messages);
|
|
174
|
+
t.deepEqual(output, { system: '', modifiedMessages: [] });
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
test('convertMessagesToClaudeVertex system message', async (t) => {
|
|
178
|
+
const plugin = new Claude3VertexPlugin(pathway, model);
|
|
179
|
+
// Test with system message
|
|
180
|
+
const messages = [{ role: 'system', content: 'System message' }];
|
|
181
|
+
const output = await plugin.convertMessagesToClaudeVertex(messages);
|
|
182
|
+
t.deepEqual(output, { system: 'System message', modifiedMessages: [] });
|
|
183
|
+
});
|
|
184
|
+
|
|
185
|
+
test('convertMessagesToClaudeVertex system message with user message', async (t) => {
|
|
186
|
+
const plugin = new Claude3VertexPlugin(pathway, model);
|
|
187
|
+
// Test with system message followed by user message
|
|
188
|
+
const messages = [
|
|
189
|
+
{ role: 'system', content: 'System message' },
|
|
190
|
+
{ role: 'user', content: 'User message' }
|
|
191
|
+
];
|
|
192
|
+
const output = await plugin.convertMessagesToClaudeVertex(messages);
|
|
193
|
+
t.deepEqual(output, {
|
|
194
|
+
system: 'System message',
|
|
195
|
+
modifiedMessages: [{ role: 'user', content: [{ type: 'text', text: 'User message' }] }]
|
|
196
|
+
});
|
|
197
|
+
});
|
|
198
|
+
|
|
199
|
+
test('convertMessagesToClaudeVertex user message with unsupported image type', async (t) => {
|
|
200
|
+
const plugin = new Claude3VertexPlugin(pathway, model);
|
|
201
|
+
// Test with unsupported image type
|
|
202
|
+
const messages = [{ role: 'user', content: { type: 'image_url', image_url: 'http://example.com/image.svg' } }];
|
|
203
|
+
const output = await plugin.convertMessagesToClaudeVertex(messages);
|
|
204
|
+
t.deepEqual(output, { system: '', modifiedMessages: [{role: 'user', content: [] }] });
|
|
205
|
+
});
|
|
206
|
+
|
|
207
|
+
test('convertMessagesToClaudeVertex user message with no content', async (t) => {
|
|
208
|
+
const plugin = new Claude3VertexPlugin(pathway, model);
|
|
209
|
+
// Test with no content
|
|
210
|
+
const messages = [{ role: 'user', content: null }];
|
|
211
|
+
const output = await plugin.convertMessagesToClaudeVertex(messages);
|
|
212
|
+
t.deepEqual(output, { system: '', modifiedMessages: [] });
|
|
213
|
+
});
|
|
214
|
+
|
package/tests/mocks.js
CHANGED
|
@@ -35,6 +35,7 @@ export const mockConfig = {
|
|
|
35
35
|
messages: [
|
|
36
36
|
{ role: 'user', content: 'Translate this: {{{text}}}' },
|
|
37
37
|
{ role: 'assistant', content: 'Translating: {{{text}}}' },
|
|
38
|
+
{ role: 'user', content: 'Nice work!' },
|
|
38
39
|
],
|
|
39
40
|
}),
|
|
40
41
|
};
|
|
@@ -78,6 +79,7 @@ export const mockConfig = {
|
|
|
78
79
|
messages: [
|
|
79
80
|
{ role: 'user', content: 'Translate this: {{{text}}}' },
|
|
80
81
|
{ role: 'assistant', content: 'Translating: {{{text}}}' },
|
|
82
|
+
{ role: 'user', content: 'Nice work!' },
|
|
81
83
|
],
|
|
82
84
|
}),
|
|
83
85
|
};
|
package/tests/vision.test.js
CHANGED
|
@@ -131,7 +131,7 @@ test('vision multi single long text', async t => {
|
|
|
131
131
|
},
|
|
132
132
|
});
|
|
133
133
|
|
|
134
|
-
t.is(response.body?.singleResult?.errors?.[0]?.message, 'Unable to process your request as your single message content is too long. Please try again with a shorter message.');
|
|
134
|
+
t.is(response.body?.singleResult?.errors?.[0]?.message || response.body?.singleResult?.data?.vision?.result, 'Unable to process your request as your single message content is too long. Please try again with a shorter message.');
|
|
135
135
|
});
|
|
136
136
|
|
|
137
137
|
|