@aj-archipelago/cortex 1.3.67 → 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/config.js +27 -0
- package/helper-apps/cortex-doc-to-pdf/DocToPdfFunction/__init__.py +3 -0
- package/helper-apps/cortex-doc-to-pdf/DocToPdfFunction/function.json +20 -0
- package/helper-apps/cortex-doc-to-pdf/Dockerfile +46 -0
- package/helper-apps/cortex-doc-to-pdf/README.md +408 -0
- package/helper-apps/cortex-doc-to-pdf/converter.py +157 -0
- package/helper-apps/cortex-doc-to-pdf/docker-compose.yml +23 -0
- package/helper-apps/cortex-doc-to-pdf/document_converter.py +181 -0
- package/helper-apps/cortex-doc-to-pdf/examples/README.md +252 -0
- package/helper-apps/cortex-doc-to-pdf/examples/nodejs-client.js +266 -0
- package/helper-apps/cortex-doc-to-pdf/examples/package-lock.json +297 -0
- package/helper-apps/cortex-doc-to-pdf/examples/package.json +23 -0
- package/helper-apps/cortex-doc-to-pdf/function_app.py +85 -0
- package/helper-apps/cortex-doc-to-pdf/host.json +16 -0
- package/helper-apps/cortex-doc-to-pdf/request_handlers.py +193 -0
- package/helper-apps/cortex-doc-to-pdf/requirements.txt +3 -0
- package/helper-apps/cortex-doc-to-pdf/tests/run_tests.sh +26 -0
- package/helper-apps/cortex-doc-to-pdf/tests/test_conversion.py +320 -0
- package/helper-apps/cortex-doc-to-pdf/tests/test_streaming.py +419 -0
- package/helper-apps/cortex-file-handler/package-lock.json +1 -0
- package/helper-apps/cortex-file-handler/package.json +1 -0
- package/helper-apps/cortex-file-handler/src/services/ConversionService.js +81 -8
- package/helper-apps/cortex-file-handler/tests/FileConversionService.test.js +54 -7
- package/helper-apps/cortex-file-handler/tests/getOperations.test.js +19 -7
- package/lib/encodeCache.js +5 -0
- package/lib/keyValueStorageClient.js +5 -0
- package/lib/logger.js +1 -1
- package/lib/pathwayTools.js +8 -1
- package/lib/redisSubscription.js +6 -0
- package/lib/requestExecutor.js +4 -0
- package/lib/util.js +88 -0
- package/package.json +1 -1
- package/pathways/basePathway.js +3 -3
- package/pathways/bing_afagent.js +1 -0
- package/pathways/gemini_15_vision.js +1 -1
- package/pathways/google_cse.js +2 -2
- package/pathways/image_gemini_25.js +85 -0
- package/pathways/image_prompt_optimizer_gemini_25.js +149 -0
- package/pathways/image_qwen.js +28 -0
- package/pathways/image_seedream4.js +26 -0
- package/pathways/rag.js +1 -1
- package/pathways/rag_jarvis.js +1 -1
- package/pathways/system/entity/sys_entity_continue.js +1 -1
- package/pathways/system/entity/sys_generator_results.js +1 -1
- package/pathways/system/entity/tools/sys_tool_google_search.js +15 -2
- package/pathways/system/entity/tools/sys_tool_grok_x_search.js +3 -3
- package/pathways/system/entity/tools/sys_tool_image.js +28 -23
- package/pathways/system/entity/tools/sys_tool_image_gemini.js +135 -0
- package/server/graphql.js +9 -2
- package/server/modelExecutor.js +4 -0
- package/server/pathwayResolver.js +19 -18
- package/server/plugins/claude3VertexPlugin.js +13 -8
- package/server/plugins/gemini15ChatPlugin.js +15 -10
- package/server/plugins/gemini15VisionPlugin.js +2 -23
- package/server/plugins/gemini25ImagePlugin.js +155 -0
- package/server/plugins/modelPlugin.js +3 -2
- package/server/plugins/openAiChatPlugin.js +6 -6
- package/server/plugins/replicateApiPlugin.js +268 -12
- package/server/plugins/veoVideoPlugin.js +15 -1
- package/server/rest.js +2 -0
- package/server/typeDef.js +96 -10
- package/tests/integration/apptekTranslatePlugin.integration.test.js +1 -1
- package/tests/unit/core/pathwayManager.test.js +2 -4
- package/tests/unit/plugins/gemini25ImagePlugin.test.js +294 -0
|
@@ -107,7 +107,8 @@ export default {
|
|
|
107
107
|
try {
|
|
108
108
|
// Pass-through: call Google CSE with provided args
|
|
109
109
|
const response = await callPathway('google_cse', {
|
|
110
|
-
...args
|
|
110
|
+
...args,
|
|
111
|
+
text: args.q
|
|
111
112
|
}, resolver);
|
|
112
113
|
|
|
113
114
|
if (resolver.errors && resolver.errors.length > 0) {
|
|
@@ -117,7 +118,19 @@ export default {
|
|
|
117
118
|
return JSON.stringify({ _type: "SearchError", value: errorMessages, recoveryMessage: "This tool failed. You should try the backup tool for this function." });
|
|
118
119
|
}
|
|
119
120
|
|
|
120
|
-
|
|
121
|
+
// Check if response is null or empty
|
|
122
|
+
if (!response) {
|
|
123
|
+
logger.error('Google CSE search returned null response');
|
|
124
|
+
return JSON.stringify({ _type: "SearchError", value: ["No response received from Google CSE"], recoveryMessage: "This tool failed. You should try the backup tool for this function." });
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
let parsedResponse;
|
|
128
|
+
try {
|
|
129
|
+
parsedResponse = JSON.parse(response);
|
|
130
|
+
} catch (parseError) {
|
|
131
|
+
logger.error(`Failed to parse Google CSE response: ${parseError.message}`);
|
|
132
|
+
return JSON.stringify({ _type: "SearchError", value: ["Invalid response format from Google CSE"], recoveryMessage: "This tool failed. You should try the backup tool for this function." });
|
|
133
|
+
}
|
|
121
134
|
|
|
122
135
|
const results = [];
|
|
123
136
|
const items = parsedResponse.items || [];
|
|
@@ -10,8 +10,8 @@ export default {
|
|
|
10
10
|
inputParameters: {
|
|
11
11
|
text: '',
|
|
12
12
|
userMessage: '',
|
|
13
|
-
includedHandles:
|
|
14
|
-
excludedHandles:
|
|
13
|
+
includedHandles: { type: 'array', items: { type: 'string' }, default: [] },
|
|
14
|
+
excludedHandles: { type: 'array', items: { type: 'string' }, default: [] },
|
|
15
15
|
minFavorites: 0,
|
|
16
16
|
minViews: 0,
|
|
17
17
|
maxResults: 10
|
|
@@ -244,4 +244,4 @@ export default {
|
|
|
244
244
|
throw e;
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
|
-
};
|
|
247
|
+
};
|
|
@@ -15,7 +15,7 @@ export default {
|
|
|
15
15
|
icon: "🎨",
|
|
16
16
|
function: {
|
|
17
17
|
name: "GenerateImage",
|
|
18
|
-
description: "Use when asked to create, generate, or generate revisions of visual content. Any time the user asks you for a picture, a selfie, artwork, a drawing or if you want to illustrate something for the user, you can use this tool to generate any sort of image from cartoon to photo realistic.
|
|
18
|
+
description: "Use when asked to create, generate, or generate revisions of visual content. Any time the user asks you for a picture, a selfie, artwork, a drawing or if you want to illustrate something for the user, you can use this tool to generate any sort of image from cartoon to photo realistic. This tool does not display the image to the user - you need to do that with markdown in your response.",
|
|
19
19
|
parameters: {
|
|
20
20
|
type: "object",
|
|
21
21
|
properties: {
|
|
@@ -23,16 +23,12 @@ export default {
|
|
|
23
23
|
type: "string",
|
|
24
24
|
description: "A very detailed prompt describing the image you want to create. You should be very specific - explaining subject matter, style, and details about the image including things like camera angle, lens types, lighting, photographic techniques, etc. Any details you can provide to the image creation engine will help it create the most accurate and useful images. The more detailed and descriptive the prompt, the better the result."
|
|
25
25
|
},
|
|
26
|
-
renderText: {
|
|
27
|
-
type: "boolean",
|
|
28
|
-
description: "Set to true if the image should be optimized to show correct text. This is useful when the user asks for a picture of something that includes specific text as it invokes a different image generation model that is optimized for including text."
|
|
29
|
-
},
|
|
30
26
|
userMessage: {
|
|
31
27
|
type: "string",
|
|
32
28
|
description: "A user-friendly message that describes what you're doing with this tool"
|
|
33
29
|
}
|
|
34
30
|
},
|
|
35
|
-
required: ["detailedInstructions", "
|
|
31
|
+
required: ["detailedInstructions", "userMessage"]
|
|
36
32
|
}
|
|
37
33
|
}
|
|
38
34
|
},
|
|
@@ -41,7 +37,7 @@ export default {
|
|
|
41
37
|
icon: "🔄",
|
|
42
38
|
function: {
|
|
43
39
|
name: "ModifyImage",
|
|
44
|
-
description: "Use when asked to modify, transform, or edit an existing image. This tool can apply various transformations like style changes, artistic effects, or specific modifications to an image that has been previously uploaded or generated. It takes up to two input images as a reference and outputs a new image based on the instructions.",
|
|
40
|
+
description: "Use when asked to modify, transform, or edit an existing image. This tool can apply various transformations like style changes, artistic effects, or specific modifications to an image that has been previously uploaded or generated. It takes up to two input images as a reference and outputs a new image based on the instructions. This tool does not display the image to the user - you need to do that with markdown in your response.",
|
|
45
41
|
parameters: {
|
|
46
42
|
type: "object",
|
|
47
43
|
properties: {
|
|
@@ -53,6 +49,10 @@ export default {
|
|
|
53
49
|
type: "string",
|
|
54
50
|
description: "The second input image URL copied exactly from an image_url field in your chat context if there is one."
|
|
55
51
|
},
|
|
52
|
+
inputImage3: {
|
|
53
|
+
type: "string",
|
|
54
|
+
description: "The third input image URL copied exactly from an image_url field in your chat context if there is one."
|
|
55
|
+
},
|
|
56
56
|
detailedInstructions: {
|
|
57
57
|
type: "string",
|
|
58
58
|
description: "A very detailed prompt describing how you want to modify the image. Be specific about the changes you want to make, including style changes, artistic effects, or specific modifications. The more detailed and descriptive the prompt, the better the result."
|
|
@@ -71,32 +71,37 @@ export default {
|
|
|
71
71
|
const pathwayResolver = resolver;
|
|
72
72
|
|
|
73
73
|
try {
|
|
74
|
-
let model = "replicate-
|
|
74
|
+
let model = "replicate-seedream-4";
|
|
75
75
|
let prompt = args.detailedInstructions || "";
|
|
76
|
-
let numberResults = args.numberResults || 1;
|
|
77
|
-
let negativePrompt = args.negativePrompt || "";
|
|
78
76
|
|
|
79
77
|
// If we have an input image, use the flux-kontext-max model
|
|
80
|
-
if (args.inputImage) {
|
|
81
|
-
model = "replicate-
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// If we have two input images, use the multi-image-kontext-max model
|
|
85
|
-
if (args.inputImage2) {
|
|
86
|
-
model = "replicate-multi-image-kontext-max";
|
|
78
|
+
if (args.inputImage || args.inputImage2 || args.inputImage3) {
|
|
79
|
+
model = "replicate-qwen-image-edit-plus";
|
|
87
80
|
}
|
|
88
81
|
|
|
89
82
|
pathwayResolver.tool = JSON.stringify({ toolUsed: "image" });
|
|
90
|
-
|
|
83
|
+
|
|
84
|
+
// Build parameters object, only including image parameters if they have non-empty values
|
|
85
|
+
const params = {
|
|
91
86
|
...args,
|
|
92
87
|
text: prompt,
|
|
93
|
-
negativePrompt,
|
|
94
|
-
numberResults,
|
|
95
88
|
model,
|
|
96
89
|
stream: false,
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
90
|
+
};
|
|
91
|
+
|
|
92
|
+
if (args.inputImage && args.inputImage.trim()) {
|
|
93
|
+
params.input_image = args.inputImage;
|
|
94
|
+
}
|
|
95
|
+
if (args.inputImage2 && args.inputImage2.trim()) {
|
|
96
|
+
params.input_image_2 = args.inputImage2;
|
|
97
|
+
}
|
|
98
|
+
if (args.inputImage3 && args.inputImage3.trim()) {
|
|
99
|
+
params.input_image_3 = args.inputImage3;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
// Call appropriate pathway based on model
|
|
103
|
+
const pathwayName = model.includes('seedream') ? 'image_seedream4' : 'image_qwen';
|
|
104
|
+
return await callPathway(pathwayName, params);
|
|
100
105
|
|
|
101
106
|
} catch (e) {
|
|
102
107
|
pathwayResolver.logError(e.message ?? e);
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
// sys_tool_image_gemini.js
|
|
2
|
+
// Entity tool that creates and modifies images for the entity to show to the user
|
|
3
|
+
import { callPathway } from '../../../../lib/pathwayTools.js';
|
|
4
|
+
import { uploadImageToCloud } from '../../../../lib/util.js';
|
|
5
|
+
|
|
6
|
+
export default {
|
|
7
|
+
prompt: [],
|
|
8
|
+
useInputChunking: false,
|
|
9
|
+
enableDuplicateRequests: false,
|
|
10
|
+
inputParameters: {
|
|
11
|
+
model: 'oai-gpt4o',
|
|
12
|
+
},
|
|
13
|
+
timeout: 300,
|
|
14
|
+
/*
|
|
15
|
+
toolDefinition: [{
|
|
16
|
+
type: "function",
|
|
17
|
+
icon: "🎨",
|
|
18
|
+
function: {
|
|
19
|
+
name: "GenerateImage",
|
|
20
|
+
description: "Use when asked to create, generate, or generate revisions of visual content. Any time the user asks you for a picture, a selfie, artwork, a drawing or if you want to illustrate something for the user, you can use this tool to generate any sort of image from cartoon to photo realistic. After you have generated the image, you must include the image in your response to show it to the user.",
|
|
21
|
+
parameters: {
|
|
22
|
+
type: "object",
|
|
23
|
+
properties: {
|
|
24
|
+
detailedInstructions: {
|
|
25
|
+
type: "string",
|
|
26
|
+
description: "A very detailed prompt describing the image you want to create. You should be very specific - explaining subject matter, style, and details about the image including things like camera angle, lens types, lighting, photographic techniques, etc. Any details you can provide to the image creation engine will help it create the most accurate and useful images. The more detailed and descriptive the prompt, the better the result."
|
|
27
|
+
},
|
|
28
|
+
userMessage: {
|
|
29
|
+
type: "string",
|
|
30
|
+
description: "A user-friendly message that describes what you're doing with this tool"
|
|
31
|
+
}
|
|
32
|
+
},
|
|
33
|
+
required: ["detailedInstructions", "renderText", "userMessage"]
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
type: "function",
|
|
39
|
+
icon: "🔄",
|
|
40
|
+
function: {
|
|
41
|
+
name: "ModifyImage",
|
|
42
|
+
description: "Use when asked to modify, transform, or edit an existing image. This tool can apply various transformations like style changes, artistic effects, or specific modifications to an image that has been previously uploaded or generated. It takes up to two input images as a reference and outputs a new image based on the instructions.",
|
|
43
|
+
parameters: {
|
|
44
|
+
type: "object",
|
|
45
|
+
properties: {
|
|
46
|
+
inputImage: {
|
|
47
|
+
type: "string",
|
|
48
|
+
description: "The first image URL copied exactly from an image_url field in your chat context."
|
|
49
|
+
},
|
|
50
|
+
inputImage2: {
|
|
51
|
+
type: "string",
|
|
52
|
+
description: "The second input image URL copied exactly from an image_url field in your chat context if there is one."
|
|
53
|
+
},
|
|
54
|
+
inputImage3: {
|
|
55
|
+
type: "string",
|
|
56
|
+
description: "The third input image URL copied exactly from an image_url field in your chat context if there is one."
|
|
57
|
+
},
|
|
58
|
+
detailedInstructions: {
|
|
59
|
+
type: "string",
|
|
60
|
+
description: "A very detailed prompt describing how you want to modify the image. Be specific about the changes you want to make, including style changes, artistic effects, or specific modifications. The more detailed and descriptive the prompt, the better the result."
|
|
61
|
+
},
|
|
62
|
+
userMessage: {
|
|
63
|
+
type: "string",
|
|
64
|
+
description: "A user-friendly message that describes what you're doing with this tool"
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
required: ["inputImage", "detailedInstructions", "userMessage"]
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}],
|
|
71
|
+
*/
|
|
72
|
+
executePathway: async ({args, runAllPrompts, resolver}) => {
|
|
73
|
+
const pathwayResolver = resolver;
|
|
74
|
+
|
|
75
|
+
try {
|
|
76
|
+
let model = "gemini-25-flash-image";
|
|
77
|
+
let prompt = args.detailedInstructions || "";
|
|
78
|
+
|
|
79
|
+
// Call the image generation pathway
|
|
80
|
+
let result = await callPathway('image_gemini_25', {
|
|
81
|
+
...args,
|
|
82
|
+
text: prompt,
|
|
83
|
+
model,
|
|
84
|
+
stream: false,
|
|
85
|
+
input_image: args.inputImage,
|
|
86
|
+
input_image_2: args.inputImage2,
|
|
87
|
+
input_image_3: args.inputImage3,
|
|
88
|
+
optimizePrompt: true,
|
|
89
|
+
}, pathwayResolver);
|
|
90
|
+
|
|
91
|
+
pathwayResolver.tool = JSON.stringify({ toolUsed: "image" });
|
|
92
|
+
|
|
93
|
+
if (pathwayResolver.pathwayResultData) {
|
|
94
|
+
if (pathwayResolver.pathwayResultData.artifacts && Array.isArray(pathwayResolver.pathwayResultData.artifacts)) {
|
|
95
|
+
const uploadedImages = [];
|
|
96
|
+
|
|
97
|
+
// Process each image artifact
|
|
98
|
+
for (const artifact of pathwayResolver.pathwayResultData.artifacts) {
|
|
99
|
+
if (artifact.type === 'image' && artifact.data && artifact.mimeType) {
|
|
100
|
+
try {
|
|
101
|
+
// Upload image to cloud storage
|
|
102
|
+
const imageUrl = await uploadImageToCloud(artifact.data, artifact.mimeType, pathwayResolver);
|
|
103
|
+
uploadedImages.push({
|
|
104
|
+
type: 'image',
|
|
105
|
+
url: imageUrl,
|
|
106
|
+
mimeType: artifact.mimeType
|
|
107
|
+
});
|
|
108
|
+
} catch (uploadError) {
|
|
109
|
+
pathwayResolver.logError(`Failed to upload artifact: ${uploadError.message}`);
|
|
110
|
+
// Keep original artifact as fallback
|
|
111
|
+
uploadedImages.push(artifact);
|
|
112
|
+
}
|
|
113
|
+
} else {
|
|
114
|
+
// Keep non-image artifacts as-is
|
|
115
|
+
uploadedImages.push(artifact);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Return the urls of the uploaded images as text in the result
|
|
120
|
+
result = result + '\n' + uploadedImages.map(image => image.url).join('\n');
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
// If result is not a CortexResponse, log a warning but return as-is
|
|
124
|
+
pathwayResolver.logWarning('No artifacts to upload');
|
|
125
|
+
result = result + '\n' + 'No images generated';
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
return result;
|
|
129
|
+
|
|
130
|
+
} catch (e) {
|
|
131
|
+
pathwayResolver.logError(e.message ?? e);
|
|
132
|
+
return await callPathway('sys_generator_error', { ...args, text: e.message }, pathwayResolver);
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
};
|
package/server/graphql.js
CHANGED
|
@@ -36,10 +36,17 @@ const getPlugins = (config) => {
|
|
|
36
36
|
//if cache is enabled and Redis is available, use it
|
|
37
37
|
let cache;
|
|
38
38
|
if (config.get('enableGraphqlCache') && config.get('storageConnectionString')) {
|
|
39
|
-
|
|
39
|
+
const keyvCache = new Keyv(config.get('storageConnectionString'), {
|
|
40
40
|
ssl: true,
|
|
41
41
|
abortConnect: false,
|
|
42
|
-
})
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
// Handle Redis connection errors to prevent crashes
|
|
45
|
+
keyvCache.on('error', (error) => {
|
|
46
|
+
logger.error(`GraphQL Keyv Redis connection error: ${error}`);
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
cache = new KeyvAdapter(keyvCache);
|
|
43
50
|
//caching similar strings, embedding hashing, ... #delta similarity
|
|
44
51
|
// TODO: custom cache key:
|
|
45
52
|
// https://www.apollographql.com/docs/apollo-server/performance/cache-backends#implementing-your-own-cache-backend
|
package/server/modelExecutor.js
CHANGED
|
@@ -21,6 +21,7 @@ import GeminiChatPlugin from './plugins/geminiChatPlugin.js';
|
|
|
21
21
|
import GeminiVisionPlugin from './plugins/geminiVisionPlugin.js';
|
|
22
22
|
import Gemini15ChatPlugin from './plugins/gemini15ChatPlugin.js';
|
|
23
23
|
import Gemini15VisionPlugin from './plugins/gemini15VisionPlugin.js';
|
|
24
|
+
import Gemini25ImagePlugin from './plugins/gemini25ImagePlugin.js';
|
|
24
25
|
import AzureBingPlugin from './plugins/azureBingPlugin.js';
|
|
25
26
|
import Claude3VertexPlugin from './plugins/claude3VertexPlugin.js';
|
|
26
27
|
import NeuralSpacePlugin from './plugins/neuralSpacePlugin.js';
|
|
@@ -103,6 +104,9 @@ class ModelExecutor {
|
|
|
103
104
|
case 'GEMINI-1.5-VISION':
|
|
104
105
|
plugin = new Gemini15VisionPlugin(pathway, model);
|
|
105
106
|
break;
|
|
107
|
+
case 'GEMINI-2.5-IMAGE':
|
|
108
|
+
plugin = new Gemini25ImagePlugin(pathway, model);
|
|
109
|
+
break;
|
|
106
110
|
case 'AZURE-BING':
|
|
107
111
|
plugin = new AzureBingPlugin(pathway, model);
|
|
108
112
|
break;
|
|
@@ -8,8 +8,8 @@ import { Prompt } from './prompt.js';
|
|
|
8
8
|
import { getv, setv } from '../lib/keyValueStorageClient.js';
|
|
9
9
|
import { requestState } from './requestState.js';
|
|
10
10
|
import { callPathway, addCitationsToResolver } from '../lib/pathwayTools.js';
|
|
11
|
-
import { publishRequestProgress } from '../lib/redisSubscription.js';
|
|
12
11
|
import logger from '../lib/logger.js';
|
|
12
|
+
import { publishRequestProgress } from '../lib/redisSubscription.js';
|
|
13
13
|
// eslint-disable-next-line import/no-extraneous-dependencies
|
|
14
14
|
import { createParser } from 'eventsource-parser';
|
|
15
15
|
import CortexResponse from '../lib/cortexResponse.js';
|
|
@@ -158,6 +158,11 @@ class PathwayResolver {
|
|
|
158
158
|
return;
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
+
// Handle CortexResponse objects - merge them into pathwayResultData
|
|
162
|
+
if (responseData && typeof responseData === 'object' && responseData.constructor && responseData.constructor.name === 'CortexResponse') {
|
|
163
|
+
this.pathwayResultData = this.mergeResultData(responseData);
|
|
164
|
+
}
|
|
165
|
+
|
|
161
166
|
// If the response is a stream, handle it as streaming response
|
|
162
167
|
if (responseData && typeof responseData.on === 'function') {
|
|
163
168
|
await this.handleStream(responseData);
|
|
@@ -205,7 +210,8 @@ class PathwayResolver {
|
|
|
205
210
|
toolCalls: cortexResponse.toolCalls,
|
|
206
211
|
functionCall: cortexResponse.functionCall,
|
|
207
212
|
usage: cortexResponse.usage,
|
|
208
|
-
finishReason: cortexResponse.finishReason
|
|
213
|
+
finishReason: cortexResponse.finishReason,
|
|
214
|
+
artifacts: cortexResponse.artifacts
|
|
209
215
|
};
|
|
210
216
|
newData = cortexData;
|
|
211
217
|
}
|
|
@@ -214,7 +220,7 @@ class PathwayResolver {
|
|
|
214
220
|
const merged = { ...currentData, ...newData };
|
|
215
221
|
|
|
216
222
|
// Handle array fields that should be concatenated
|
|
217
|
-
const arrayFields = ['citations', 'toolCalls'];
|
|
223
|
+
const arrayFields = ['citations', 'toolCalls', 'artifacts'];
|
|
218
224
|
for (const field of arrayFields) {
|
|
219
225
|
const currentArray = currentData[field] || [];
|
|
220
226
|
const newArray = newData[field] || [];
|
|
@@ -593,7 +599,7 @@ class PathwayResolver {
|
|
|
593
599
|
if (previousResult) {
|
|
594
600
|
previousResult = this.truncate(previousResult, 2 * this.chunkMaxTokenLength);
|
|
595
601
|
}
|
|
596
|
-
result = await this.applyPrompt(this.prompts[i],
|
|
602
|
+
result = await this.applyPrompt(this.prompts[i], text, currentParameters);
|
|
597
603
|
} else {
|
|
598
604
|
// Limit context to N characters
|
|
599
605
|
if (previousResult) {
|
|
@@ -664,20 +670,15 @@ class PathwayResolver {
|
|
|
664
670
|
}
|
|
665
671
|
let result = '';
|
|
666
672
|
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
676
|
-
memoryContext: this.memoryContext
|
|
677
|
-
}, prompt, this);
|
|
678
|
-
} else {
|
|
679
|
-
result = text;
|
|
680
|
-
}
|
|
673
|
+
result = await this.modelExecutor.execute(text, {
|
|
674
|
+
...parameters,
|
|
675
|
+
...this.savedContext,
|
|
676
|
+
memorySelf: this.memorySelf,
|
|
677
|
+
memoryDirectives: this.memoryDirectives,
|
|
678
|
+
memoryTopics: this.memoryTopics,
|
|
679
|
+
memoryUser: this.memoryUser,
|
|
680
|
+
memoryContext: this.memoryContext
|
|
681
|
+
}, prompt, this);
|
|
681
682
|
|
|
682
683
|
requestState[this.requestId].completedCount++;
|
|
683
684
|
|
|
@@ -304,12 +304,17 @@ class Claude3VertexPlugin extends OpenAIVisionPlugin {
|
|
|
304
304
|
requestParameters.messages = modifiedMessages;
|
|
305
305
|
|
|
306
306
|
// Convert OpenAI tools format to Claude format if present
|
|
307
|
-
|
|
308
|
-
|
|
307
|
+
let toolsArray = parameters.tools;
|
|
308
|
+
if (typeof toolsArray === 'string') {
|
|
309
|
+
try {
|
|
310
|
+
toolsArray = JSON.parse(toolsArray);
|
|
311
|
+
} catch (e) {
|
|
312
|
+
toolsArray = [];
|
|
313
|
+
}
|
|
309
314
|
}
|
|
310
315
|
|
|
311
|
-
if (
|
|
312
|
-
requestParameters.tools =
|
|
316
|
+
if (toolsArray && Array.isArray(toolsArray) && toolsArray.length > 0) {
|
|
317
|
+
requestParameters.tools = toolsArray.map(tool => {
|
|
313
318
|
if (tool.type === 'function') {
|
|
314
319
|
return {
|
|
315
320
|
name: tool.function.name,
|
|
@@ -325,14 +330,13 @@ class Claude3VertexPlugin extends OpenAIVisionPlugin {
|
|
|
325
330
|
});
|
|
326
331
|
}
|
|
327
332
|
|
|
333
|
+
// Handle tool_choice parameter conversion from OpenAI format to Claude format
|
|
328
334
|
if (parameters.tool_choice) {
|
|
329
|
-
// Convert OpenAI tool_choice format to Claude format
|
|
330
335
|
let toolChoice = parameters.tool_choice;
|
|
331
336
|
|
|
332
|
-
//
|
|
337
|
+
// Parse JSON string if needed
|
|
333
338
|
if (typeof toolChoice === 'string') {
|
|
334
339
|
try {
|
|
335
|
-
// Try to parse as JSON first
|
|
336
340
|
toolChoice = JSON.parse(toolChoice);
|
|
337
341
|
} catch (e) {
|
|
338
342
|
// If not JSON, handle as simple string values: auto, required, none
|
|
@@ -343,11 +347,12 @@ class Claude3VertexPlugin extends OpenAIVisionPlugin {
|
|
|
343
347
|
} else if (toolChoice === 'none') {
|
|
344
348
|
requestParameters.tool_choice = { type: 'none' };
|
|
345
349
|
}
|
|
350
|
+
toolChoice = null; // Prevent further processing
|
|
346
351
|
}
|
|
347
352
|
}
|
|
348
353
|
|
|
349
354
|
// Handle parsed object
|
|
350
|
-
if (toolChoice.type === "function") {
|
|
355
|
+
if (toolChoice && toolChoice.type === "function") {
|
|
351
356
|
// Handle function-specific tool choice
|
|
352
357
|
requestParameters.tool_choice = {
|
|
353
358
|
type: "tool",
|
|
@@ -138,16 +138,16 @@ class Gemini15ChatPlugin extends ModelPlugin {
|
|
|
138
138
|
}
|
|
139
139
|
|
|
140
140
|
const requestParameters = {
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
141
|
+
contents: requestMessages,
|
|
142
|
+
generationConfig: {
|
|
143
|
+
temperature: this.temperature || 0.7,
|
|
144
|
+
maxOutputTokens: max_tokens || this.getModelMaxReturnTokens(),
|
|
145
|
+
topP: parameters.topP || 0.95,
|
|
146
|
+
topK: parameters.topK || 40,
|
|
147
|
+
},
|
|
148
|
+
...(geminiSafetySettings ? {safety_settings: geminiSafetySettings} : {}),
|
|
149
|
+
...(system ? {systemInstruction: system} : {}),
|
|
150
|
+
...(geminiTools ? {tools: geminiTools} : {})
|
|
151
151
|
};
|
|
152
152
|
|
|
153
153
|
return requestParameters;
|
|
@@ -155,6 +155,11 @@ class Gemini15ChatPlugin extends ModelPlugin {
|
|
|
155
155
|
|
|
156
156
|
// Parse the response from the new Chat API
|
|
157
157
|
parseResponse(data) {
|
|
158
|
+
// Handle CortexResponse objects by returning them as-is
|
|
159
|
+
if (data && typeof data === 'object' && data.constructor && data.constructor.name === 'CortexResponse') {
|
|
160
|
+
return data;
|
|
161
|
+
}
|
|
162
|
+
|
|
158
163
|
// If data is not an array, return it directly
|
|
159
164
|
let dataToMerge = [];
|
|
160
165
|
if (data && data.contents && Array.isArray(data.contents)) {
|
|
@@ -204,34 +204,13 @@ class Gemini15VisionPlugin extends Gemini15ChatPlugin {
|
|
|
204
204
|
}
|
|
205
205
|
}
|
|
206
206
|
|
|
207
|
-
if (toolsArray && Array.isArray(toolsArray)) {
|
|
207
|
+
if (toolsArray && Array.isArray(toolsArray) && toolsArray.length > 0) {
|
|
208
208
|
convertedTools = this.convertOpenAIToolsToGemini(toolsArray);
|
|
209
209
|
}
|
|
210
210
|
|
|
211
|
-
if (cortexRequest?.tools && Array.isArray(cortexRequest.tools)) {
|
|
212
|
-
const requestTools = this.convertOpenAIToolsToGemini(cortexRequest.tools);
|
|
213
|
-
convertedTools = [...convertedTools, ...requestTools];
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
if (cortexRequest?.pathway?.tools && Array.isArray(cortexRequest.pathway.tools)) {
|
|
217
|
-
const pathwayTools = this.convertOpenAIToolsToGemini(cortexRequest.pathway.tools);
|
|
218
|
-
convertedTools = [...convertedTools, ...pathwayTools];
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
// Temporarily remove geminiTools from pathway to prevent override
|
|
222
|
-
const originalGeminiTools = cortexRequest?.pathway?.geminiTools;
|
|
223
|
-
if (cortexRequest?.pathway) {
|
|
224
|
-
delete cortexRequest.pathway.geminiTools;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
211
|
const baseParameters = super.getRequestParameters(text, parameters, prompt, cortexRequest);
|
|
228
212
|
|
|
229
|
-
|
|
230
|
-
if (cortexRequest?.pathway && originalGeminiTools !== undefined) {
|
|
231
|
-
cortexRequest.pathway.geminiTools = originalGeminiTools;
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
if (convertedTools.length > 0) {
|
|
213
|
+
if (convertedTools[0]?.functionDeclarations?.length > 0) {
|
|
235
214
|
baseParameters.tools = convertedTools;
|
|
236
215
|
|
|
237
216
|
// Handle tool_choice parameter - convert OpenAI format to Gemini toolConfig
|