@aj-archipelago/cortex 1.2.0 → 1.3.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/config.js +47 -11
- package/helper-apps/cortex-autogen/OAI_CONFIG_LIST +2 -1
- package/helper-apps/cortex-autogen/agents.py +387 -0
- package/helper-apps/cortex-autogen/agents_extra.py +14 -0
- package/helper-apps/cortex-autogen/config.py +18 -0
- package/helper-apps/cortex-autogen/data_operations.py +29 -0
- package/helper-apps/cortex-autogen/function_app.py +6 -3
- package/helper-apps/cortex-autogen/main.py +4 -4
- package/helper-apps/cortex-autogen/prompts.py +196 -0
- package/helper-apps/cortex-autogen/prompts_extra.py +5 -0
- package/helper-apps/cortex-autogen/requirements.txt +2 -1
- package/helper-apps/cortex-autogen/search.py +83 -0
- package/helper-apps/cortex-autogen/test.sh +40 -0
- package/helper-apps/cortex-autogen/utils.py +78 -0
- package/lib/handleBars.js +25 -0
- package/lib/logger.js +2 -0
- package/lib/util.js +3 -1
- package/package.json +1 -1
- package/pathways/chat_code.js +1 -1
- package/pathways/chat_context.js +1 -1
- package/pathways/chat_jarvis.js +1 -1
- package/pathways/chat_persist.js +1 -1
- package/pathways/chat_title.js +25 -0
- package/pathways/{flux_image.js → image_flux.js} +6 -2
- package/pathways/image_recraft.js +10 -0
- package/pathways/rag.js +1 -1
- package/pathways/rag_jarvis.js +1 -1
- package/pathways/rag_search_helper.js +1 -1
- package/pathways/system/entity/memory/sys_memory_manager.js +71 -0
- package/pathways/system/entity/memory/sys_memory_required.js +21 -0
- package/pathways/system/entity/memory/sys_memory_update.js +190 -0
- package/pathways/system/entity/memory/sys_read_memory.js +37 -0
- package/pathways/system/entity/memory/sys_save_memory.js +60 -0
- package/pathways/system/entity/shared/sys_entity_constants.js +24 -0
- package/pathways/system/entity/sys_entity_continue.js +57 -0
- package/pathways/system/entity/sys_entity_start.js +218 -0
- package/pathways/system/entity/sys_generator_error.js +20 -0
- package/pathways/system/entity/sys_generator_expert.js +26 -0
- package/pathways/system/entity/sys_generator_image.js +127 -0
- package/pathways/system/entity/sys_generator_quick.js +19 -0
- package/pathways/system/entity/sys_generator_reasoning.js +27 -0
- package/pathways/system/entity/sys_generator_results.js +304 -0
- package/pathways/system/entity/sys_generator_video_vision.js +27 -0
- package/pathways/system/entity/sys_image_prompt_builder.js +35 -0
- package/pathways/system/entity/sys_query_builder.js +101 -0
- package/pathways/system/entity/sys_router_code.js +37 -0
- package/pathways/system/entity/sys_router_tool.js +64 -0
- package/pathways/{sys_claude_35_sonnet.js → system/rest_streaming/sys_claude_35_sonnet.js} +1 -1
- package/pathways/{sys_claude_3_haiku.js → system/rest_streaming/sys_claude_3_haiku.js} +1 -1
- package/pathways/{sys_google_chat.js → system/rest_streaming/sys_google_chat.js} +1 -1
- package/pathways/{sys_google_code_chat.js → system/rest_streaming/sys_google_code_chat.js} +1 -1
- package/pathways/{sys_google_gemini_chat.js → system/rest_streaming/sys_google_gemini_chat.js} +1 -1
- package/pathways/{sys_openai_chat.js → system/rest_streaming/sys_openai_chat.js} +1 -1
- package/pathways/{sys_openai_chat_16.js → system/rest_streaming/sys_openai_chat_16.js} +1 -1
- package/pathways/{sys_openai_chat_gpt4.js → system/rest_streaming/sys_openai_chat_gpt4.js} +1 -1
- package/pathways/{sys_openai_chat_gpt4_32.js → system/rest_streaming/sys_openai_chat_gpt4_32.js} +1 -1
- package/pathways/{sys_openai_chat_gpt4_turbo.js → system/rest_streaming/sys_openai_chat_gpt4_turbo.js} +1 -1
- package/pathways/{sys_parse_numbered_object_list.js → system/sys_parse_numbered_object_list.js} +2 -2
- package/pathways/{sys_repair_json.js → system/sys_repair_json.js} +1 -1
- package/pathways/{run_claude35_sonnet.js → system/workspaces/run_claude35_sonnet.js} +1 -1
- package/pathways/{run_claude3_haiku.js → system/workspaces/run_claude3_haiku.js} +1 -1
- package/pathways/{run_gpt35turbo.js → system/workspaces/run_gpt35turbo.js} +1 -1
- package/pathways/{run_gpt4.js → system/workspaces/run_gpt4.js} +1 -1
- package/pathways/{run_gpt4_32.js → system/workspaces/run_gpt4_32.js} +1 -1
- package/server/parser.js +6 -1
- package/server/pathwayResolver.js +62 -10
- package/server/plugins/azureCognitivePlugin.js +14 -1
- package/server/plugins/claude3VertexPlugin.js +25 -15
- package/server/plugins/gemini15ChatPlugin.js +1 -1
- package/server/plugins/geminiChatPlugin.js +1 -1
- package/server/plugins/modelPlugin.js +10 -1
- package/server/plugins/openAiChatPlugin.js +4 -3
- package/server/plugins/openAiDallE3Plugin.js +12 -4
- package/server/plugins/openAiVisionPlugin.js +1 -2
- package/server/plugins/replicateApiPlugin.js +46 -12
- package/tests/multimodal_conversion.test.js +6 -8
- package/helper-apps/cortex-autogen/myautogen.py +0 -317
- package/helper-apps/cortex-autogen/prompt.txt +0 -0
- package/helper-apps/cortex-autogen/prompt_summary.txt +0 -37
- package/pathways/index.js +0 -152
- /package/pathways/{sys_openai_completion.js → system/rest_streaming/sys_openai_completion.js} +0 -0
package/pathways/{sys_parse_numbered_object_list.js → system/sys_parse_numbered_object_list.js}
RENAMED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Prompt } from '
|
|
1
|
+
import { Prompt } from '../../server/prompt.js';
|
|
2
2
|
|
|
3
3
|
export default {
|
|
4
4
|
prompt: [
|
|
5
5
|
new Prompt({
|
|
6
6
|
messages: [
|
|
7
|
-
{ "role": "system", "content": "Assistant is a list parsing AI. When user posts text including a numbered list and a desired set of fields, assistant will carefully read the list and attempt to convert the list into a JSON object with the given fields. If there are extra fields, assistant will ignore them. If there are some missing fields, assistant will just skip the missing fields and return the rest. If the conversion is not at all possible, assistant will return an empty JSON array. Assistant will generate only the repaired JSON object in a directly parseable format with no markdown surrounding it and no other response or commentary." },
|
|
7
|
+
{ "role": "system", "content": "Assistant is a list parsing AI. When user posts text including a numbered list and a desired set of fields, assistant will carefully read the list and attempt to convert the list into a JSON object with the given fields. If a field value is numeric, it should be returned as a number in the JSON object. If there are extra fields, assistant will ignore them. If there are some missing fields, assistant will just skip the missing fields and return the rest. If the conversion is not at all possible, assistant will return an empty JSON array. Assistant will generate only the repaired JSON object in a directly parseable format with no markdown surrounding it and no other response or commentary." },
|
|
8
8
|
{ "role": "user", "content": `Fields: {{{format}}}\nList: {{{text}}}`},
|
|
9
9
|
]
|
|
10
10
|
})
|
package/server/parser.js
CHANGED
|
@@ -40,7 +40,12 @@ const isNumberedList = (data) => {
|
|
|
40
40
|
|
|
41
41
|
async function parseJson(str) {
|
|
42
42
|
try {
|
|
43
|
-
JSON
|
|
43
|
+
// check for the common error case that the JSON is surrounded by markdown
|
|
44
|
+
const match = str.match(/```\s*(?:json)?(.*?)```/s);
|
|
45
|
+
if (match) {
|
|
46
|
+
str = match[1].trim();
|
|
47
|
+
}
|
|
48
|
+
JSON.parse(str);
|
|
44
49
|
return str;
|
|
45
50
|
} catch (error) {
|
|
46
51
|
try {
|
|
@@ -221,15 +221,59 @@ class PathwayResolver {
|
|
|
221
221
|
// Get saved context from contextId or change contextId if needed
|
|
222
222
|
const { contextId } = args;
|
|
223
223
|
this.savedContextId = contextId ? contextId : uuidv4();
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
224
|
+
|
|
225
|
+
const loadMemory = async () => {
|
|
226
|
+
// Load initial values
|
|
227
|
+
this.savedContext = (getv && await getv(contextId)) || {};
|
|
228
|
+
this.memorySelf = (getv && await getv(`${contextId}-memorySelf`)) || "";
|
|
229
|
+
this.memoryDirectives = (getv && await getv(`${contextId}-memoryDirectives`)) || "";
|
|
230
|
+
this.memoryTopics = (getv && await getv(`${contextId}-memoryTopics`)) || "";
|
|
231
|
+
this.memoryUser = (getv && await getv(`${contextId}-memoryUser`)) || "";
|
|
232
|
+
|
|
233
|
+
// Store initial state for comparison
|
|
234
|
+
this.initialState = {
|
|
235
|
+
savedContext: this.savedContext,
|
|
236
|
+
memorySelf: this.memorySelf,
|
|
237
|
+
memoryDirectives: this.memoryDirectives,
|
|
238
|
+
memoryTopics: this.memoryTopics,
|
|
239
|
+
memoryUser: this.memoryUser
|
|
240
|
+
};
|
|
241
|
+
};
|
|
242
|
+
|
|
243
|
+
const saveChangedMemory = async () => {
|
|
244
|
+
this.savedContextId = this.savedContextId || uuidv4();
|
|
245
|
+
|
|
246
|
+
const currentState = {
|
|
247
|
+
savedContext: this.savedContext,
|
|
248
|
+
memorySelf: this.memorySelf,
|
|
249
|
+
memoryDirectives: this.memoryDirectives,
|
|
250
|
+
memoryTopics: this.memoryTopics,
|
|
251
|
+
memoryUser: this.memoryUser
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
if (currentState.savedContext !== this.initialState.savedContext) {
|
|
255
|
+
setv && await setv(this.savedContextId, this.savedContext);
|
|
256
|
+
}
|
|
257
|
+
if (currentState.memorySelf !== this.initialState.memorySelf) {
|
|
258
|
+
setv && await setv(`${this.savedContextId}-memorySelf`, this.memorySelf);
|
|
259
|
+
}
|
|
260
|
+
if (currentState.memoryDirectives !== this.initialState.memoryDirectives) {
|
|
261
|
+
setv && await setv(`${this.savedContextId}-memoryDirectives`, this.memoryDirectives);
|
|
262
|
+
}
|
|
263
|
+
if (currentState.memoryTopics !== this.initialState.memoryTopics) {
|
|
264
|
+
setv && await setv(`${this.savedContextId}-memoryTopics`, this.memoryTopics);
|
|
265
|
+
}
|
|
266
|
+
if (currentState.memoryUser !== this.initialState.memoryUser) {
|
|
267
|
+
setv && await setv(`${this.savedContextId}-memoryUser`, this.memoryUser);
|
|
268
|
+
}
|
|
269
|
+
};
|
|
228
270
|
|
|
229
271
|
const MAX_RETRIES = 3;
|
|
230
272
|
let data = null;
|
|
231
273
|
|
|
232
274
|
for (let retries = 0; retries < MAX_RETRIES; retries++) {
|
|
275
|
+
await loadMemory(); // Reset memory state on each retry
|
|
276
|
+
|
|
233
277
|
data = await this.processRequest(args);
|
|
234
278
|
if (!data) {
|
|
235
279
|
break;
|
|
@@ -241,13 +285,10 @@ class PathwayResolver {
|
|
|
241
285
|
}
|
|
242
286
|
|
|
243
287
|
logger.warn(`Bad pathway result - retrying pathway. Attempt ${retries + 1} of ${MAX_RETRIES}`);
|
|
244
|
-
this.savedContext = JSON.parse(savedContextStr);
|
|
245
288
|
}
|
|
246
289
|
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
this.savedContextId = this.savedContextId || uuidv4();
|
|
250
|
-
setv && setv(this.savedContextId, this.savedContext);
|
|
290
|
+
if (data !== null) {
|
|
291
|
+
await saveChangedMemory();
|
|
251
292
|
}
|
|
252
293
|
|
|
253
294
|
return data;
|
|
@@ -419,7 +460,14 @@ class PathwayResolver {
|
|
|
419
460
|
|
|
420
461
|
// If this text is empty, skip applying the prompt as it will likely be a nonsensical result
|
|
421
462
|
if (!/^\s*$/.test(text) || parameters?.file || parameters?.inputVector || this?.modelName.includes('cognitive')) {
|
|
422
|
-
result = await this.modelExecutor.execute(text, {
|
|
463
|
+
result = await this.modelExecutor.execute(text, {
|
|
464
|
+
...parameters,
|
|
465
|
+
...this.savedContext,
|
|
466
|
+
memorySelf: this.memorySelf,
|
|
467
|
+
memoryDirectives: this.memoryDirectives,
|
|
468
|
+
memoryTopics: this.memoryTopics,
|
|
469
|
+
memoryUser: this.memoryUser
|
|
470
|
+
}, prompt, this);
|
|
423
471
|
} else {
|
|
424
472
|
result = text;
|
|
425
473
|
}
|
|
@@ -439,6 +487,10 @@ class PathwayResolver {
|
|
|
439
487
|
|
|
440
488
|
// save the result to the context if requested and no errors
|
|
441
489
|
if (prompt.saveResultTo && this.errors.length === 0) {
|
|
490
|
+
// Update memory property if it matches a known type
|
|
491
|
+
if (["memorySelf", "memoryUser", "memoryDirectives", "memoryTopics"].includes(prompt.saveResultTo)) {
|
|
492
|
+
this[prompt.saveResultTo] = result;
|
|
493
|
+
}
|
|
442
494
|
this.savedContext[prompt.saveResultTo] = result;
|
|
443
495
|
}
|
|
444
496
|
return result;
|
|
@@ -55,7 +55,7 @@ class AzureCognitivePlugin extends ModelPlugin {
|
|
|
55
55
|
{ search: searchQuery,
|
|
56
56
|
"searchMode": "all",
|
|
57
57
|
"queryType": "full",
|
|
58
|
-
select: 'id', top: TOP
|
|
58
|
+
select: 'id', top: TOP, skip: 0
|
|
59
59
|
};
|
|
60
60
|
|
|
61
61
|
const docsToDelete = JSON.parse(await this.executeRequest(cortexRequest));
|
|
@@ -115,6 +115,19 @@ class AzureCognitivePlugin extends ModelPlugin {
|
|
|
115
115
|
];
|
|
116
116
|
} else {
|
|
117
117
|
data.search = modelPromptText;
|
|
118
|
+
data.top = parameters.top || 50;
|
|
119
|
+
data.skip = 0;
|
|
120
|
+
if (parameters.titleOnly) {
|
|
121
|
+
switch(indexName){
|
|
122
|
+
case 'indexcortex':
|
|
123
|
+
case 'indexwires':
|
|
124
|
+
data.select = 'title,id';
|
|
125
|
+
break;
|
|
126
|
+
default:
|
|
127
|
+
data.select = 'title,id,url';
|
|
128
|
+
break;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
118
131
|
}
|
|
119
132
|
|
|
120
133
|
filter && (data.filter = filter);
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import OpenAIVisionPlugin from "./openAiVisionPlugin.js";
|
|
2
2
|
import logger from "../../lib/logger.js";
|
|
3
|
+
import axios from 'axios';
|
|
3
4
|
|
|
4
5
|
const allowedMIMETypes = ['image/jpeg', 'image/png', 'image/gif', 'image/webp'];
|
|
5
|
-
async function convertContentItem(item) {
|
|
6
6
|
|
|
7
|
+
async function convertContentItem(item, maxImageSize) {
|
|
7
8
|
let imageUrl = "";
|
|
8
9
|
|
|
9
10
|
try {
|
|
@@ -27,6 +28,14 @@ async function convertContentItem(item) {
|
|
|
27
28
|
try {
|
|
28
29
|
const urlData = imageUrl.startsWith("data:") ? imageUrl : await fetchImageAsDataURL(imageUrl);
|
|
29
30
|
if (!urlData) { return null; }
|
|
31
|
+
|
|
32
|
+
// Check base64 size
|
|
33
|
+
const base64Size = (urlData.length * 3) / 4;
|
|
34
|
+
if (base64Size > maxImageSize) {
|
|
35
|
+
logger.warn(`Image size ${base64Size} bytes exceeds maximum allowed size ${maxImageSize} - skipping image content.`);
|
|
36
|
+
return null;
|
|
37
|
+
}
|
|
38
|
+
|
|
30
39
|
const [, mimeType = "image/jpeg"] = urlData.match(/data:([a-zA-Z0-9]+\/[a-zA-Z0-9-.+]+).*,.*/) || [];
|
|
31
40
|
const base64Image = urlData.split(",")[1];
|
|
32
41
|
|
|
@@ -60,25 +69,26 @@ async function convertContentItem(item) {
|
|
|
60
69
|
// Fetch image and convert to base 64 data URL
|
|
61
70
|
async function fetchImageAsDataURL(imageUrl) {
|
|
62
71
|
try {
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
}
|
|
72
|
+
// First check headers
|
|
73
|
+
const headResponse = await axios.head(imageUrl, {
|
|
74
|
+
timeout: 30000, // 30 second timeout
|
|
75
|
+
maxRedirects: 5
|
|
76
|
+
});
|
|
68
77
|
|
|
69
|
-
const contentType =
|
|
78
|
+
const contentType = headResponse.headers['content-type'];
|
|
70
79
|
if (!contentType || !allowedMIMETypes.includes(contentType)) {
|
|
71
80
|
logger.warn(`Unsupported image type: ${contentType} - skipping image content.`);
|
|
72
81
|
return null;
|
|
73
82
|
}
|
|
74
83
|
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
84
|
+
// Then get the actual image data
|
|
85
|
+
const dataResponse = await axios.get(imageUrl, {
|
|
86
|
+
timeout: 30000,
|
|
87
|
+
responseType: 'arraybuffer',
|
|
88
|
+
maxRedirects: 5
|
|
89
|
+
});
|
|
79
90
|
|
|
80
|
-
const
|
|
81
|
-
const base64Image = Buffer.from(buffer).toString("base64");
|
|
91
|
+
const base64Image = Buffer.from(dataResponse.data).toString('base64');
|
|
82
92
|
return `data:${contentType};base64,${base64Image}`;
|
|
83
93
|
}
|
|
84
94
|
catch (e) {
|
|
@@ -151,7 +161,7 @@ class Claude3VertexPlugin extends OpenAIVisionPlugin {
|
|
|
151
161
|
const claude3Messages = await Promise.all(
|
|
152
162
|
finalMessages.map(async (message) => {
|
|
153
163
|
const contentArray = Array.isArray(message.content) ? message.content : [message.content];
|
|
154
|
-
const claude3Content = await Promise.all(contentArray.map(convertContentItem));
|
|
164
|
+
const claude3Content = await Promise.all(contentArray.map(item => convertContentItem(item, this.getModelMaxImageSize())));
|
|
155
165
|
return {
|
|
156
166
|
role: message.role,
|
|
157
167
|
content: claude3Content.filter(Boolean),
|
|
@@ -301,7 +311,7 @@ class Claude3VertexPlugin extends OpenAIVisionPlugin {
|
|
|
301
311
|
|
|
302
312
|
shortenContent(content, maxWords = 40) {
|
|
303
313
|
const words = content.split(" ");
|
|
304
|
-
if (words.length <= maxWords) {
|
|
314
|
+
if (words.length <= maxWords || logger.level === 'debug') {
|
|
305
315
|
return content;
|
|
306
316
|
}
|
|
307
317
|
return words.slice(0, maxWords / 2).join(" ") +
|
|
@@ -200,7 +200,7 @@ class Gemini15ChatPlugin extends ModelPlugin {
|
|
|
200
200
|
} else if (Array.isArray(responseData)) {
|
|
201
201
|
const { mergedResult, safetyRatings } = mergeResults(responseData);
|
|
202
202
|
if (safetyRatings?.length) {
|
|
203
|
-
logger.warn(
|
|
203
|
+
logger.warn(`response was blocked because the input or response potentially violates policies`);
|
|
204
204
|
logger.verbose(`Safety Ratings: ${JSON.stringify(safetyRatings, null, 2)}`);
|
|
205
205
|
}
|
|
206
206
|
const { length, units } = this.getLength(mergedResult);
|
|
@@ -195,7 +195,7 @@ class GeminiChatPlugin extends ModelPlugin {
|
|
|
195
195
|
} else if (Array.isArray(responseData)) {
|
|
196
196
|
const { mergedResult, safetyRatings } = mergeResults(responseData);
|
|
197
197
|
if (safetyRatings?.length) {
|
|
198
|
-
logger.warn(
|
|
198
|
+
logger.warn(`response was blocked because the input or response potentially violates policies`);
|
|
199
199
|
logger.verbose(`Safety Ratings: ${JSON.stringify(safetyRatings, null, 2)}`);
|
|
200
200
|
}
|
|
201
201
|
const { length, units } = this.getLength(mergedResult);
|
|
@@ -9,6 +9,7 @@ import { config } from '../../config.js';
|
|
|
9
9
|
const DEFAULT_MAX_TOKENS = 4096;
|
|
10
10
|
const DEFAULT_MAX_RETURN_TOKENS = 256;
|
|
11
11
|
const DEFAULT_PROMPT_TOKEN_RATIO = 0.5;
|
|
12
|
+
const DEFAULT_MAX_IMAGE_SIZE = 20 * 1024 * 1024; // 20MB default
|
|
12
13
|
|
|
13
14
|
class ModelPlugin {
|
|
14
15
|
constructor(pathway, model) {
|
|
@@ -249,7 +250,12 @@ class ModelPlugin {
|
|
|
249
250
|
let length = 0;
|
|
250
251
|
let units = isProd ? 'characters' : 'tokens';
|
|
251
252
|
if (data) {
|
|
252
|
-
|
|
253
|
+
if (isProd || data.length > 5000) {
|
|
254
|
+
length = data.length;
|
|
255
|
+
units = 'characters';
|
|
256
|
+
} else {
|
|
257
|
+
length = encode(data).length;
|
|
258
|
+
}
|
|
253
259
|
}
|
|
254
260
|
return {length, units};
|
|
255
261
|
}
|
|
@@ -341,6 +347,9 @@ class ModelPlugin {
|
|
|
341
347
|
return requestProgress;
|
|
342
348
|
}
|
|
343
349
|
|
|
350
|
+
getModelMaxImageSize() {
|
|
351
|
+
return (this.promptParameters.maxImageSize ?? this.model.maxImageSize ?? DEFAULT_MAX_IMAGE_SIZE);
|
|
352
|
+
}
|
|
344
353
|
|
|
345
354
|
}
|
|
346
355
|
|
|
@@ -115,9 +115,10 @@ class OpenAIChatPlugin extends ModelPlugin {
|
|
|
115
115
|
const content = message.content === undefined ? JSON.stringify(message) : (Array.isArray(message.content) ? message.content.map(item => JSON.stringify(item)).join(', ') : message.content);
|
|
116
116
|
const words = content.split(" ");
|
|
117
117
|
const { length, units } = this.getLength(content);
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
|
|
119
|
+
const displayContent = logger.level === 'debug' ? content : (words.length < 41 ? content : words.slice(0, 20).join(" ") + " ... " + words.slice(-20).join(" "));
|
|
120
|
+
|
|
121
|
+
logger.verbose(`message ${index + 1}: role: ${message.role}, ${units}: ${length}, content: "${displayContent}"`);
|
|
121
122
|
totalLength += length;
|
|
122
123
|
totalUnits = units;
|
|
123
124
|
});
|
|
@@ -52,14 +52,20 @@ class OpenAIDallE3Plugin extends ModelPlugin {
|
|
|
52
52
|
|
|
53
53
|
requestPromise
|
|
54
54
|
.then((response) => handleResponse(response))
|
|
55
|
-
.catch((error) => handleResponse(error));
|
|
55
|
+
.catch((error) => handleResponse(error, true));
|
|
56
56
|
|
|
57
|
-
function handleResponse(response) {
|
|
57
|
+
function handleResponse(response, isError = false) {
|
|
58
58
|
let status = "succeeded";
|
|
59
|
-
let data
|
|
60
|
-
|
|
59
|
+
let data;
|
|
60
|
+
|
|
61
|
+
if (isError) {
|
|
62
|
+
status = "failed";
|
|
63
|
+
data = JSON.stringify({ error: response.message || response });
|
|
64
|
+
} else if (response.data?.error) {
|
|
61
65
|
status = "failed";
|
|
62
66
|
data = JSON.stringify(response.data);
|
|
67
|
+
} else {
|
|
68
|
+
data = JSON.stringify(response);
|
|
63
69
|
}
|
|
64
70
|
|
|
65
71
|
const requestProgress = {
|
|
@@ -80,12 +86,14 @@ class OpenAIDallE3Plugin extends ModelPlugin {
|
|
|
80
86
|
let progress =
|
|
81
87
|
requestDurationEstimator.calculatePercentComplete(callid);
|
|
82
88
|
|
|
89
|
+
if (typeof progress === 'number' && !isNaN(progress) && progress >= 0 && progress <= 1) {
|
|
83
90
|
await publishRequestProgress({
|
|
84
91
|
requestId,
|
|
85
92
|
status: "pending",
|
|
86
93
|
progress,
|
|
87
94
|
data,
|
|
88
95
|
});
|
|
96
|
+
}
|
|
89
97
|
|
|
90
98
|
if (state.status !== "pending") {
|
|
91
99
|
break;
|
|
@@ -31,8 +31,7 @@ class OpenAIVisionPlugin extends OpenAIChatPlugin {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
if (typeof parsedItem === 'object' && parsedItem !== null && parsedItem.type === 'image_url') {
|
|
34
|
-
parsedItem.image_url
|
|
35
|
-
return parsedItem;
|
|
34
|
+
return {type: parsedItem.type, image_url: {url: parsedItem.url || parsedItem.image_url.url}};
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
return parsedItem;
|
|
@@ -16,19 +16,53 @@ class ReplicateApiPlugin extends ModelPlugin {
|
|
|
16
16
|
prompt,
|
|
17
17
|
);
|
|
18
18
|
|
|
19
|
-
const
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
//safety_tolerance: 5,
|
|
27
|
-
go_fast: true,
|
|
28
|
-
megapixels: "1",
|
|
29
|
-
num_outputs: combinedParameters.numberResults,
|
|
30
|
-
},
|
|
19
|
+
const isValidSchnellAspectRatio = (ratio) => {
|
|
20
|
+
const validRatios = [
|
|
21
|
+
'1:1', '16:9', '21:9', '3:2', '2:3', '4:5',
|
|
22
|
+
'5:4', '3:4', '4:3', '9:16', '9:21'
|
|
23
|
+
];
|
|
24
|
+
|
|
25
|
+
return validRatios.includes(ratio);
|
|
31
26
|
};
|
|
27
|
+
|
|
28
|
+
let requestParameters = {};
|
|
29
|
+
|
|
30
|
+
switch (combinedParameters.model) {
|
|
31
|
+
case "replicate-flux-11-pro":
|
|
32
|
+
requestParameters = {
|
|
33
|
+
input: {
|
|
34
|
+
aspect_ratio: combinedParameters.aspectRatio || "1:1",
|
|
35
|
+
output_format: combinedParameters.outputFormat || "webp",
|
|
36
|
+
output_quality: combinedParameters.outputQuality || 80,
|
|
37
|
+
prompt: modelPromptText,
|
|
38
|
+
prompt_upsampling: combinedParameters.promptUpsampling || false,
|
|
39
|
+
safety_tolerance: combinedParameters.safety_tolerance || 3,
|
|
40
|
+
go_fast: true,
|
|
41
|
+
megapixels: "1",
|
|
42
|
+
width: combinedParameters.width,
|
|
43
|
+
height: combinedParameters.height,
|
|
44
|
+
size: combinedParameters.size || "1024x1024",
|
|
45
|
+
style: combinedParameters.style || "realistic_image",
|
|
46
|
+
},
|
|
47
|
+
};
|
|
48
|
+
break;
|
|
49
|
+
case "replicate-flux-1-schnell":
|
|
50
|
+
requestParameters = {
|
|
51
|
+
input: {
|
|
52
|
+
aspect_ratio: isValidSchnellAspectRatio(combinedParameters.aspectRatio) ? combinedParameters.aspectRatio : "1:1",
|
|
53
|
+
output_format: combinedParameters.outputFormat || "webp",
|
|
54
|
+
output_quality: combinedParameters.outputQuality || 80,
|
|
55
|
+
prompt: modelPromptText,
|
|
56
|
+
go_fast: true,
|
|
57
|
+
megapixels: "1",
|
|
58
|
+
num_outputs: combinedParameters.numberResults,
|
|
59
|
+
num_inference_steps: combinedParameters.steps || 4,
|
|
60
|
+
disable_safety_checker: true,
|
|
61
|
+
},
|
|
62
|
+
};
|
|
63
|
+
break;
|
|
64
|
+
|
|
65
|
+
}
|
|
32
66
|
|
|
33
67
|
return requestParameters;
|
|
34
68
|
}
|
|
@@ -112,11 +112,10 @@ test('Cortex special properties conversion', async (t) => {
|
|
|
112
112
|
]}
|
|
113
113
|
];
|
|
114
114
|
|
|
115
|
-
const
|
|
116
|
-
const { system: claudeSystem, modifiedMessages: claudeMessages } = await claude.convertMessagesToClaudeVertex(parsedOpenAI);
|
|
115
|
+
const { system: claudeSystem, modifiedMessages: claudeMessages } = await claude.convertMessagesToClaudeVertex(cortexMessages);
|
|
117
116
|
|
|
118
|
-
const { modifiedMessages: geminiMessages } = gemini.convertMessagesToGemini(
|
|
119
|
-
const { modifiedMessages: geminiMessages15, system: geminiSystem15 } = gemini15.convertMessagesToGemini(
|
|
117
|
+
const { modifiedMessages: geminiMessages } = gemini.convertMessagesToGemini(cortexMessages);
|
|
118
|
+
const { modifiedMessages: geminiMessages15, system: geminiSystem15 } = gemini15.convertMessagesToGemini(cortexMessages);
|
|
120
119
|
|
|
121
120
|
// Check Claude conversion
|
|
122
121
|
t.true(claudeMessages[0].content[1].source.data.startsWith('/9j/4AAQ'));
|
|
@@ -142,10 +141,9 @@ test('Mixed content types conversion', async (t) => {
|
|
|
142
141
|
]}
|
|
143
142
|
];
|
|
144
143
|
|
|
145
|
-
const
|
|
146
|
-
const {
|
|
147
|
-
const { modifiedMessages } =
|
|
148
|
-
const { modifiedMessages: modifiedMessages15, system: system15 } = gemini15.convertMessagesToGemini(parsedOpenAI);
|
|
144
|
+
const { system: claudeSystem, modifiedMessages: claudeMessages } = await claude.convertMessagesToClaudeVertex(mixedMessages);
|
|
145
|
+
const { modifiedMessages } = gemini.convertMessagesToGemini(mixedMessages);
|
|
146
|
+
const { modifiedMessages: modifiedMessages15, system: system15 } = gemini15.convertMessagesToGemini(mixedMessages);
|
|
149
147
|
|
|
150
148
|
// Check Claude conversion
|
|
151
149
|
t.is(claudeMessages.length, 3);
|