@aj-archipelago/cortex 1.4.1 → 1.4.3

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.
Files changed (97) hide show
  1. package/README.md +1 -0
  2. package/config.js +1 -1
  3. package/helper-apps/cortex-autogen2/.dockerignore +1 -0
  4. package/helper-apps/cortex-autogen2/Dockerfile +6 -10
  5. package/helper-apps/cortex-autogen2/Dockerfile.worker +2 -0
  6. package/helper-apps/cortex-autogen2/agents.py +203 -2
  7. package/helper-apps/cortex-autogen2/main.py +1 -1
  8. package/helper-apps/cortex-autogen2/pyproject.toml +12 -0
  9. package/helper-apps/cortex-autogen2/requirements.txt +14 -0
  10. package/helper-apps/cortex-autogen2/services/redis_publisher.py +1 -1
  11. package/helper-apps/cortex-autogen2/services/run_analyzer.py +1 -1
  12. package/helper-apps/cortex-autogen2/task_processor.py +431 -229
  13. package/helper-apps/cortex-autogen2/test_entity_fetcher.py +305 -0
  14. package/helper-apps/cortex-autogen2/tests/README.md +240 -0
  15. package/helper-apps/cortex-autogen2/tests/TEST_REPORT.md +342 -0
  16. package/helper-apps/cortex-autogen2/tests/__init__.py +8 -0
  17. package/helper-apps/cortex-autogen2/tests/analysis/__init__.py +1 -0
  18. package/helper-apps/cortex-autogen2/tests/analysis/improvement_suggester.py +224 -0
  19. package/helper-apps/cortex-autogen2/tests/analysis/trend_analyzer.py +211 -0
  20. package/helper-apps/cortex-autogen2/tests/cli/__init__.py +1 -0
  21. package/helper-apps/cortex-autogen2/tests/cli/run_tests.py +296 -0
  22. package/helper-apps/cortex-autogen2/tests/collectors/__init__.py +1 -0
  23. package/helper-apps/cortex-autogen2/tests/collectors/log_collector.py +252 -0
  24. package/helper-apps/cortex-autogen2/tests/collectors/progress_collector.py +182 -0
  25. package/helper-apps/cortex-autogen2/tests/conftest.py +15 -0
  26. package/helper-apps/cortex-autogen2/tests/database/__init__.py +1 -0
  27. package/helper-apps/cortex-autogen2/tests/database/repository.py +501 -0
  28. package/helper-apps/cortex-autogen2/tests/database/schema.sql +108 -0
  29. package/helper-apps/cortex-autogen2/tests/evaluators/__init__.py +1 -0
  30. package/helper-apps/cortex-autogen2/tests/evaluators/llm_scorer.py +294 -0
  31. package/helper-apps/cortex-autogen2/tests/evaluators/prompts.py +250 -0
  32. package/helper-apps/cortex-autogen2/tests/evaluators/wordcloud_validator.py +168 -0
  33. package/helper-apps/cortex-autogen2/tests/metrics/__init__.py +1 -0
  34. package/helper-apps/cortex-autogen2/tests/metrics/collector.py +155 -0
  35. package/helper-apps/cortex-autogen2/tests/orchestrator.py +576 -0
  36. package/helper-apps/cortex-autogen2/tests/test_cases.yaml +279 -0
  37. package/helper-apps/cortex-autogen2/tests/test_data.db +0 -0
  38. package/helper-apps/cortex-autogen2/tests/utils/__init__.py +3 -0
  39. package/helper-apps/cortex-autogen2/tests/utils/connectivity.py +112 -0
  40. package/helper-apps/cortex-autogen2/tools/azure_blob_tools.py +74 -24
  41. package/helper-apps/cortex-autogen2/tools/entity_api_registry.json +38 -0
  42. package/helper-apps/cortex-autogen2/tools/file_tools.py +1 -1
  43. package/helper-apps/cortex-autogen2/tools/search_tools.py +436 -238
  44. package/helper-apps/cortex-file-handler/package-lock.json +2 -2
  45. package/helper-apps/cortex-file-handler/package.json +1 -1
  46. package/helper-apps/cortex-file-handler/scripts/setup-test-containers.js +4 -5
  47. package/helper-apps/cortex-file-handler/src/blobHandler.js +36 -144
  48. package/helper-apps/cortex-file-handler/src/services/FileConversionService.js +5 -3
  49. package/helper-apps/cortex-file-handler/src/services/storage/AzureStorageProvider.js +34 -1
  50. package/helper-apps/cortex-file-handler/src/services/storage/GCSStorageProvider.js +22 -0
  51. package/helper-apps/cortex-file-handler/src/services/storage/LocalStorageProvider.js +28 -1
  52. package/helper-apps/cortex-file-handler/src/services/storage/StorageFactory.js +29 -4
  53. package/helper-apps/cortex-file-handler/src/services/storage/StorageProvider.js +11 -0
  54. package/helper-apps/cortex-file-handler/src/services/storage/StorageService.js +1 -1
  55. package/helper-apps/cortex-file-handler/tests/blobHandler.test.js +3 -2
  56. package/helper-apps/cortex-file-handler/tests/checkHashShortLived.test.js +8 -1
  57. package/helper-apps/cortex-file-handler/tests/containerConversionFlow.test.js +5 -2
  58. package/helper-apps/cortex-file-handler/tests/containerNameParsing.test.js +14 -7
  59. package/helper-apps/cortex-file-handler/tests/containerParameterFlow.test.js +5 -2
  60. package/helper-apps/cortex-file-handler/tests/storage/StorageFactory.test.js +31 -19
  61. package/lib/crypto.js +1 -65
  62. package/lib/keyValueStorageClient.js +53 -1
  63. package/package.json +1 -1
  64. package/pathways/system/entity/memory/sys_read_memory.js +1 -1
  65. package/pathways/system/entity/memory/sys_save_memory.js +1 -1
  66. package/pathways/system/entity/memory/sys_search_memory.js +1 -1
  67. package/server/modelExecutor.js +4 -0
  68. package/server/pathwayResolver.js +1 -1
  69. package/server/plugins/claude4VertexPlugin.js +540 -0
  70. package/server/plugins/openAiWhisperPlugin.js +43 -2
  71. package/testrun.log +35371 -0
  72. package/tests/integration/graphql/async/stream/vendors/openai_streaming.test.js +1 -3
  73. package/tests/integration/rest/vendors/claude_streaming.test.js +121 -0
  74. package/tests/unit/core/crypto.test.js +4 -102
  75. package/tests/unit/core/doubleEncryptionStorageClient.test.js +262 -0
  76. package/tests/unit/plugins/claude4VertexPlugin.test.js +462 -0
  77. package/tests/unit/plugins/claude4VertexToolConversion.test.js +413 -0
  78. package/helper-apps/cortex-autogen/.funcignore +0 -8
  79. package/helper-apps/cortex-autogen/Dockerfile +0 -10
  80. package/helper-apps/cortex-autogen/OAI_CONFIG_LIST +0 -6
  81. package/helper-apps/cortex-autogen/agents.py +0 -493
  82. package/helper-apps/cortex-autogen/agents_extra.py +0 -14
  83. package/helper-apps/cortex-autogen/config.py +0 -18
  84. package/helper-apps/cortex-autogen/data_operations.py +0 -29
  85. package/helper-apps/cortex-autogen/function_app.py +0 -44
  86. package/helper-apps/cortex-autogen/host.json +0 -15
  87. package/helper-apps/cortex-autogen/main.py +0 -38
  88. package/helper-apps/cortex-autogen/prompts.py +0 -196
  89. package/helper-apps/cortex-autogen/prompts_extra.py +0 -5
  90. package/helper-apps/cortex-autogen/requirements.txt +0 -9
  91. package/helper-apps/cortex-autogen/search.py +0 -85
  92. package/helper-apps/cortex-autogen/test.sh +0 -40
  93. package/helper-apps/cortex-autogen/tools/sasfileuploader.py +0 -66
  94. package/helper-apps/cortex-autogen/utils.py +0 -88
  95. package/helper-apps/cortex-autogen2/DigiCertGlobalRootCA.crt.pem +0 -22
  96. package/helper-apps/cortex-autogen2/poetry.lock +0 -3652
  97. package/lib/doubleEncryptionStorageClient.js +0 -97
@@ -71,11 +71,14 @@ test.after.always(async (t) => {
71
71
 
72
72
  // Test container parameter validation
73
73
  test("should validate container names correctly", (t) => {
74
+ // Get current container names
75
+ const currentContainers = AZURE_STORAGE_CONTAINER_NAMES;
76
+
74
77
  // Test with valid container names from configuration
75
- AZURE_STORAGE_CONTAINER_NAMES.forEach(containerName => {
78
+ currentContainers.forEach(containerName => {
76
79
  t.true(isValidContainerName(containerName), `${containerName} should be valid`);
77
80
  });
78
-
81
+
79
82
  // Test with invalid container names
80
83
  const invalidNames = ["invalid-container", "", null, undefined, "nonexistent"];
81
84
  invalidNames.forEach(name => {
@@ -123,19 +123,27 @@ test("should get azure provider with specific container name", async (t) => {
123
123
  return;
124
124
  }
125
125
 
126
- const factory = new StorageFactory();
127
-
128
- // Mock the blobHandler constants for this test
129
- const mockConstants = {
130
- AZURE_STORAGE_CONTAINER_NAMES: ["container1", "container2", "container3"],
131
- DEFAULT_AZURE_STORAGE_CONTAINER_NAME: "container1",
132
- isValidContainerName: (name) => ["container1", "container2", "container3"].includes(name)
133
- };
126
+ // Save original env value
127
+ const originalEnv = process.env.AZURE_STORAGE_CONTAINER_NAME;
134
128
 
135
- // Test with valid container name
136
- const provider = await factory.getAzureProvider("container2");
137
- t.truthy(provider);
138
- t.is(provider.containerName, "container2");
129
+ try {
130
+ // Set test container names in environment
131
+ process.env.AZURE_STORAGE_CONTAINER_NAME = "container1,container2,container3";
132
+
133
+ const factory = new StorageFactory();
134
+
135
+ // Test with valid container name
136
+ const provider = await factory.getAzureProvider("container2");
137
+ t.truthy(provider);
138
+ t.is(provider.containerName, "container2");
139
+ } finally {
140
+ // Restore original env
141
+ if (originalEnv) {
142
+ process.env.AZURE_STORAGE_CONTAINER_NAME = originalEnv;
143
+ } else {
144
+ delete process.env.AZURE_STORAGE_CONTAINER_NAME;
145
+ }
146
+ }
139
147
  });
140
148
 
141
149
  test("should throw error for invalid container name", async (t) => {
@@ -159,21 +167,25 @@ test("should cache providers by container name", async (t) => {
159
167
  return;
160
168
  }
161
169
 
162
- const factory = new StorageFactory();
163
-
164
- // Mock valid container names for testing
170
+ // Save original env value
165
171
  const originalEnv = process.env.AZURE_STORAGE_CONTAINER_NAME;
166
- process.env.AZURE_STORAGE_CONTAINER_NAME = "test1,test2,test3";
167
172
 
168
173
  try {
169
- const provider1 = await factory.getAzureProvider("test1");
170
- const provider2 = await factory.getAzureProvider("test1");
171
- const provider3 = await factory.getAzureProvider("test2");
174
+ // Set test container names in environment
175
+ process.env.AZURE_STORAGE_CONTAINER_NAME = "container1,container2,container3";
176
+
177
+ const factory = new StorageFactory();
178
+
179
+ const provider1 = await factory.getAzureProvider("container1");
180
+ const provider2 = await factory.getAzureProvider("container1");
181
+ const provider3 = await factory.getAzureProvider("container2");
172
182
 
173
183
  // Same container should return same instance
174
184
  t.is(provider1, provider2);
175
185
  // Different container should return different instance
176
186
  t.not(provider1, provider3);
187
+ t.is(provider1.containerName, "container1");
188
+ t.is(provider3.containerName, "container2");
177
189
  } finally {
178
190
  // Restore original env
179
191
  if (originalEnv) {
package/lib/crypto.js CHANGED
@@ -36,70 +36,6 @@ function decrypt(message, key) {
36
36
  }
37
37
  }
38
38
 
39
- // Double encryption: encrypt with user key first, then system key
40
- function doubleEncrypt(data, userContextKey, systemKey) {
41
- if (!systemKey) {
42
- logger.error('System key is required for encryption');
43
- return null;
44
- }
45
-
46
- if (!userContextKey) {
47
- // If no user key provided, use single-layer encryption with system key
48
- return encrypt(data, systemKey);
49
- }
50
-
51
- try {
52
- // First encrypt with user's contextKey
53
- const userEncrypted = encrypt(data, userContextKey);
54
- if (!userEncrypted) {
55
- logger.error('User encryption failed, falling back to system encryption only');
56
- return encrypt(data, systemKey);
57
- }
58
-
59
- // Then encrypt with system key
60
- return encrypt(userEncrypted, systemKey);
61
- } catch (error) {
62
- logger.error(`Double encryption failed: ${error.message}`);
63
- // Fallback to single-layer system encryption
64
- return encrypt(data, systemKey);
65
- }
66
- }
67
-
68
- // Double decryption: decrypt with system key first, then user key
69
- function doubleDecrypt(encryptedData, userContextKey, systemKey) {
70
- if (!systemKey) {
71
- logger.error('System key is required for decryption');
72
- return null;
73
- }
74
-
75
- if (!userContextKey) {
76
- // If no user key provided, use single-layer decryption with system key
77
- return decrypt(encryptedData, systemKey);
78
- }
79
-
80
- try {
81
- // First decrypt with system key
82
- const systemDecrypted = decrypt(encryptedData, systemKey);
83
- if (!systemDecrypted) {
84
- logger.error('System decryption failed');
85
- return null;
86
- }
87
-
88
- // Try to decrypt with user's contextKey
89
- const userDecrypted = decrypt(systemDecrypted, userContextKey);
90
- if (userDecrypted) {
91
- // Successfully double-decrypted
92
- return userDecrypted;
93
- }
94
-
95
- // User decryption failed, but system decryption succeeded
96
- // This means the data was single-encrypted with system key only
97
- return systemDecrypted;
98
- } catch (error) {
99
- logger.error(`Double decryption failed: ${error.message}`);
100
- return null;
101
- }
102
- }
103
39
 
104
40
  function tryBufferKey(key) {
105
41
  if (key.length === 64) {
@@ -108,4 +44,4 @@ function tryBufferKey(key) {
108
44
  return key;
109
45
  }
110
46
 
111
- export { encrypt, decrypt, doubleEncrypt, doubleDecrypt };
47
+ export { encrypt, decrypt };
@@ -45,8 +45,60 @@ async function getv(key) {
45
45
  return keyValueStorageClient && (await keyValueStorageClient.get(key));
46
46
  }
47
47
 
48
+ // Set values to keyv with additional context key encryption
49
+ async function setvWithDoubleEncryption(key, value, contextKey) {
50
+ let processedValue = value;
51
+
52
+ // If contextKey exists and is not empty, encrypt the value with it
53
+ if (contextKey && contextKey.trim() !== '' && value !== null && value !== undefined) {
54
+ try {
55
+ // Convert value to string for encryption
56
+ const stringValue = typeof value === 'string' ? value : JSON.stringify(value);
57
+ processedValue = encrypt(stringValue, contextKey);
58
+ } catch (error) {
59
+ logger.error(`Context key encryption failed: ${error.message}`);
60
+ // Continue with unencrypted value if context encryption fails
61
+ }
62
+ }
63
+
64
+ return keyValueStorageClient && (await keyValueStorageClient.set(key, processedValue));
65
+ }
66
+
67
+ // Get values from keyv with additional context key decryption
68
+ async function getvWithDoubleDecryption(key, contextKey) {
69
+ const result = keyValueStorageClient && (await keyValueStorageClient.get(key));
70
+
71
+ if (result === null || result === undefined) {
72
+ return result;
73
+ }
74
+
75
+ // If contextKey exists and is not empty, try to decrypt the result with it
76
+ if (contextKey && contextKey.trim() !== '') {
77
+ try {
78
+ // Try to decrypt with context key
79
+ const decrypted = decrypt(result, contextKey);
80
+ if (decrypted) {
81
+ // Try to parse as JSON, if it fails return the string as-is
82
+ try {
83
+ return JSON.parse(decrypted);
84
+ } catch (parseError) {
85
+ return decrypted;
86
+ }
87
+ }
88
+ } catch (error) {
89
+ // If context decryption fails, the data might not be context-encrypted
90
+ // or the context key might be wrong, so return the result as-is
91
+ logger.debug(`Context key decryption failed, returning original data: ${error.message}`);
92
+ }
93
+ }
94
+
95
+ return result;
96
+ }
97
+
48
98
  export {
49
99
  keyValueStorageClient,
50
100
  setv,
51
- getv
101
+ getv,
102
+ setvWithDoubleEncryption,
103
+ getvWithDoubleDecryption
52
104
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aj-archipelago/cortex",
3
- "version": "1.4.1",
3
+ "version": "1.4.3",
4
4
  "description": "Cortex is a GraphQL API for AI. It provides a simple, extensible interface for using AI services from OpenAI, Azure and others.",
5
5
  "private": false,
6
6
  "repository": {
@@ -2,7 +2,7 @@
2
2
  // it should never try to call other pathways
3
3
 
4
4
  import { getv } from '../../../../lib/keyValueStorageClient.js';
5
- import { getvWithDoubleDecryption } from '../../../../lib/doubleEncryptionStorageClient.js';
5
+ import { getvWithDoubleDecryption } from '../../../../lib/keyValueStorageClient.js';
6
6
 
7
7
  const isValidISOTimestamp = (timestamp) => {
8
8
  if (!timestamp) return false;
@@ -1,5 +1,5 @@
1
1
  import { getv } from '../../../../lib/keyValueStorageClient.js';
2
- import { setvWithDoubleEncryption } from '../../../../lib/doubleEncryptionStorageClient.js';
2
+ import { setvWithDoubleEncryption } from '../../../../lib/keyValueStorageClient.js';
3
3
 
4
4
  export default {
5
5
  inputParameters: {
@@ -1,6 +1,6 @@
1
1
  import { Prompt } from '../../../../server/prompt.js';
2
2
  import { callPathway } from '../../../../lib/pathwayTools.js';
3
- import { setvWithDoubleEncryption } from '../../../../lib/doubleEncryptionStorageClient.js';
3
+ import { setvWithDoubleEncryption } from '../../../../lib/keyValueStorageClient.js';
4
4
 
5
5
  export default {
6
6
  prompt:
@@ -24,6 +24,7 @@ import Gemini15VisionPlugin from './plugins/gemini15VisionPlugin.js';
24
24
  import Gemini25ImagePlugin from './plugins/gemini25ImagePlugin.js';
25
25
  import AzureBingPlugin from './plugins/azureBingPlugin.js';
26
26
  import Claude3VertexPlugin from './plugins/claude3VertexPlugin.js';
27
+ import Claude4VertexPlugin from './plugins/claude4VertexPlugin.js';
27
28
  import NeuralSpacePlugin from './plugins/neuralSpacePlugin.js';
28
29
  import RunwareAiPlugin from './plugins/runwareAiPlugin.js';
29
30
  import ReplicateApiPlugin from './plugins/replicateApiPlugin.js';
@@ -113,6 +114,9 @@ class ModelExecutor {
113
114
  case 'CLAUDE-3-VERTEX':
114
115
  plugin = new Claude3VertexPlugin(pathway, model);
115
116
  break;
117
+ case 'CLAUDE-4-VERTEX':
118
+ plugin = new Claude4VertexPlugin(pathway, model);
119
+ break;
116
120
  case 'RUNWARE-AI':
117
121
  plugin = new RunwareAiPlugin(pathway, model);
118
122
  break;
@@ -6,7 +6,7 @@ import { getFirstNToken, getLastNToken, getSemanticChunks } from './chunker.js';
6
6
  import { PathwayResponseParser } from './pathwayResponseParser.js';
7
7
  import { Prompt } from './prompt.js';
8
8
  import { getv, setv } from '../lib/keyValueStorageClient.js';
9
- import { getvWithDoubleDecryption, setvWithDoubleEncryption } from '../lib/doubleEncryptionStorageClient.js';
9
+ import { getvWithDoubleDecryption, setvWithDoubleEncryption } from '../lib/keyValueStorageClient.js';
10
10
  import { requestState } from './requestState.js';
11
11
  import { callPathway, addCitationsToResolver } from '../lib/pathwayTools.js';
12
12
  import logger from '../lib/logger.js';