@aj-archipelago/cortex 1.4.0 โ†’ 1.4.2

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 (35) hide show
  1. package/config.js +25 -4
  2. package/helper-apps/cortex-autogen2/agents.py +19 -6
  3. package/helper-apps/cortex-autogen2/services/azure_ai_search.py +115 -0
  4. package/helper-apps/cortex-autogen2/services/run_analyzer.py +594 -0
  5. package/helper-apps/cortex-autogen2/task_processor.py +98 -2
  6. package/lib/crypto.js +1 -0
  7. package/lib/entityConstants.js +12 -35
  8. package/lib/keyValueStorageClient.js +53 -1
  9. package/lib/util.js +33 -6
  10. package/package.json +2 -1
  11. package/pathways/system/entity/memory/sys_memory_manager.js +1 -0
  12. package/pathways/system/entity/memory/sys_memory_process.js +4 -3
  13. package/pathways/system/entity/memory/sys_memory_update.js +4 -3
  14. package/pathways/system/entity/memory/sys_read_memory.js +12 -4
  15. package/pathways/system/entity/memory/sys_save_memory.js +16 -9
  16. package/pathways/system/entity/memory/sys_search_memory.js +5 -4
  17. package/pathways/system/entity/sys_entity_agent.js +2 -1
  18. package/pathways/system/entity/tools/sys_tool_bing_search.js +2 -2
  19. package/pathways/system/entity/tools/sys_tool_bing_search_afagent.js +1 -2
  20. package/pathways/system/entity/tools/sys_tool_callmodel.js +2 -1
  21. package/pathways/system/entity/tools/sys_tool_coding.js +1 -2
  22. package/pathways/system/entity/tools/sys_tool_grok_x_search.js +1 -1
  23. package/pathways/system/entity/tools/sys_tool_image.js +2 -1
  24. package/pathways/system/entity/tools/sys_tool_image_gemini.js +3 -3
  25. package/pathways/system/entity/tools/sys_tool_mermaid.js +187 -38
  26. package/pathways/system/entity/tools/sys_tool_reasoning.js +2 -0
  27. package/pathways/system/entity/tools/sys_tool_verify.js +1 -1
  28. package/pathways/transcribe_gemini.js +3 -2
  29. package/server/graphql.js +1 -1
  30. package/server/pathwayResolver.js +8 -7
  31. package/server/plugins/veoVideoPlugin.js +29 -1
  32. package/testrun.log +35371 -0
  33. package/tests/integration/graphql/async/stream/vendors/openai_streaming.test.js +1 -3
  34. package/tests/unit/core/crypto.test.js +65 -0
  35. package/tests/unit/core/doubleEncryptionStorageClient.test.js +262 -0
@@ -52,7 +52,6 @@ test('OpenAI vendor streaming over subscriptions emits OAI-style deltas', async
52
52
 
53
53
  t.true(events.length > 0);
54
54
 
55
- // Ensure streamed chunks (when they include model) use gpt-4.1 (not mini)
56
55
  const models = events
57
56
  .map(e => {
58
57
  try {
@@ -64,8 +63,7 @@ test('OpenAI vendor streaming over subscriptions emits OAI-style deltas', async
64
63
  .filter(Boolean);
65
64
 
66
65
  if (models.length > 0) {
67
- t.truthy(models.find(m => /gpt-4\.1(?!-mini)/.test(m)));
68
- t.falsy(models.find(m => /gpt-4\.1-mini/.test(m)));
66
+ t.truthy(models.find(m => /gpt-5-chat/.test(m)));
69
67
  }
70
68
  });
71
69
 
@@ -0,0 +1,65 @@
1
+ // crypto.test.js
2
+ // Tests for encryption and decryption functions in cortex/lib/crypto.js
3
+
4
+ import test from 'ava';
5
+ import { encrypt, decrypt } from '../../../lib/crypto.js';
6
+
7
+ // Test data
8
+ const testData = 'Hello, this is test data!';
9
+ const systemKey = '1234567890123456789012345678901234567890123456789012345678901234'; // 64 hex chars
10
+ const userKey = 'abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890'; // 64 hex chars
11
+ const wrongUserKey = '0000000000000000000000000000000000000000000000000000000000000000'; // 64 hex chars
12
+ const wrongSystemKey = 'ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff'; // 64 hex chars
13
+
14
+ // Basic encryption/decryption tests
15
+ test('encrypt should encrypt data with valid key', t => {
16
+ const encrypted = encrypt(testData, systemKey);
17
+ t.truthy(encrypted);
18
+ t.not(encrypted, testData);
19
+ t.true(encrypted.includes(':'));
20
+ });
21
+
22
+ test('decrypt should decrypt data with correct key', t => {
23
+ const encrypted = encrypt(testData, systemKey);
24
+ const decrypted = decrypt(encrypted, systemKey);
25
+ t.is(decrypted, testData);
26
+ });
27
+
28
+ test('encrypt should return original data when no key provided', t => {
29
+ const result = encrypt(testData, null);
30
+ t.is(result, testData);
31
+ });
32
+
33
+ test('decrypt should return original data when no key provided', t => {
34
+ const result = decrypt(testData, null);
35
+ t.is(result, testData);
36
+ });
37
+
38
+ // Edge cases and error handling
39
+ test('encrypt should handle empty string', t => {
40
+ const encrypted = encrypt('', systemKey);
41
+ t.truthy(encrypted);
42
+ const decrypted = decrypt(encrypted, systemKey);
43
+ t.is(decrypted, '');
44
+ });
45
+
46
+ test('encrypt should handle special characters', t => {
47
+ const specialData = 'Special chars: !@#$%^&*()_+-=[]{}|;:,.<>?';
48
+ const encrypted = encrypt(specialData, systemKey);
49
+ const decrypted = decrypt(encrypted, systemKey);
50
+ t.is(decrypted, specialData);
51
+ });
52
+
53
+ test('encrypt should handle unicode characters', t => {
54
+ const unicodeData = 'Unicode: ๐Ÿš€ ๐ŸŒŸ รฑรกรฉรญรณรบ ไธญๆ–‡ ุงู„ุนุฑุจูŠุฉ';
55
+ const encrypted = encrypt(unicodeData, systemKey);
56
+ const decrypted = decrypt(encrypted, systemKey);
57
+ t.is(decrypted, unicodeData);
58
+ });
59
+
60
+ test('encrypt should handle JSON data', t => {
61
+ const jsonData = JSON.stringify({ message: 'test', number: 42, array: [1, 2, 3] });
62
+ const encrypted = encrypt(jsonData, systemKey);
63
+ const decrypted = decrypt(encrypted, systemKey);
64
+ t.is(decrypted, jsonData);
65
+ });
@@ -0,0 +1,262 @@
1
+ // doubleEncryptionStorageClient.test.js
2
+ // Tests for context key encryption integration in keyValueStorageClient
3
+
4
+ import test from 'ava';
5
+ import { setvWithDoubleEncryption, getvWithDoubleDecryption, setv, getv } from '../../../lib/keyValueStorageClient.js';
6
+ import { encrypt, decrypt } from '../../../lib/crypto.js';
7
+
8
+ // Test data
9
+ const testData = { message: 'Hello, this is test data!', number: 42, array: [1, 2, 3] };
10
+ const systemKey = '1234567890123456789012345678901234567890123456789012345678901234'; // 64 hex chars
11
+ const userKey = 'abcdef1234567890abcdef1234567890abcdef1234567890abcdef1234567890'; // 64 hex chars
12
+
13
+ // Mock the config to provide test keys
14
+ import { config } from '../../../config.js';
15
+ const originalGet = config.get;
16
+ const mockGet = (key) => {
17
+ switch (key) {
18
+ case 'storageConnectionString':
19
+ return 'redis://localhost:6379'; // Use in-memory Redis for tests
20
+ case 'cortexId':
21
+ return 'test-cortex';
22
+ case 'redisEncryptionKey':
23
+ return systemKey;
24
+ default:
25
+ return originalGet(key);
26
+ }
27
+ };
28
+ config.get = mockGet;
29
+
30
+ // Helper function to clear storage between tests
31
+ async function clearStorage() {
32
+ // Clear any existing test data
33
+ try {
34
+ await setvWithDoubleEncryption('test-key', null, userKey);
35
+ await setv('test-key', null);
36
+ } catch (error) {
37
+ // Ignore errors when clearing
38
+ }
39
+ }
40
+
41
+ test.beforeEach(async t => {
42
+ await clearStorage();
43
+ });
44
+
45
+ // Test 1: Double encryption/decryption with both contextKey and redisEncryptionKey
46
+ test('should store and retrieve data with double encryption when both keys provided', async t => {
47
+ const key = 'test-double-encryption';
48
+
49
+ // Store with double encryption
50
+ await setvWithDoubleEncryption(key, testData, userKey);
51
+
52
+ // Retrieve with double decryption
53
+ const retrieved = await getvWithDoubleDecryption(key, userKey);
54
+
55
+ t.deepEqual(retrieved, testData);
56
+ });
57
+
58
+ // Test 2: Double encryption/decryption with only redisEncryptionKey (no contextKey)
59
+ test('should store and retrieve data with single encryption when no contextKey provided', async t => {
60
+ const key = 'test-single-encryption';
61
+
62
+ // Store with single encryption (no contextKey)
63
+ await setvWithDoubleEncryption(key, testData, null);
64
+
65
+ // Retrieve with single decryption
66
+ const retrieved = await getvWithDoubleDecryption(key, null);
67
+
68
+ t.deepEqual(retrieved, testData);
69
+ });
70
+
71
+ // Test 3: Reading single-encrypted data (from keyValueStorageClient) with doubleDecryption
72
+ test('should read single-encrypted data from keyValueStorageClient with doubleDecryption', async t => {
73
+ const key = 'test-single-to-double';
74
+
75
+ // Store using keyValueStorageClient (single encryption)
76
+ await setv(key, testData);
77
+
78
+ // Read using doubleEncryptionStorageClient (should handle single-encrypted data)
79
+ const retrieved = await getvWithDoubleDecryption(key, userKey);
80
+
81
+ t.deepEqual(retrieved, testData);
82
+ });
83
+
84
+ // Test 4: Reading single-encrypted data without contextKey
85
+ test('should read single-encrypted data from keyValueStorageClient without contextKey', async t => {
86
+ const key = 'test-single-to-double-no-context';
87
+
88
+ // Store using keyValueStorageClient (single encryption)
89
+ await setv(key, testData);
90
+
91
+ // Read using doubleEncryptionStorageClient without contextKey
92
+ const retrieved = await getvWithDoubleDecryption(key, null);
93
+
94
+ t.deepEqual(retrieved, testData);
95
+ });
96
+
97
+ // Test 5: Reading unencrypted data with doubleDecryption
98
+ test('should read unencrypted data with doubleDecryption', async t => {
99
+ const key = 'test-unencrypted';
100
+
101
+ // Store unencrypted data using keyValueStorageClient with no encryption key
102
+ const originalRedisKey = config.get('redisEncryptionKey');
103
+ config.get = (key) => {
104
+ switch (key) {
105
+ case 'storageConnectionString':
106
+ return 'redis://localhost:6379';
107
+ case 'cortexId':
108
+ return 'test-cortex';
109
+ case 'redisEncryptionKey':
110
+ return null; // No encryption
111
+ default:
112
+ return originalGet(key);
113
+ }
114
+ };
115
+
116
+ // Store unencrypted data
117
+ await setv(key, testData);
118
+
119
+ // Restore mock config
120
+ config.get = mockGet;
121
+
122
+ // Read using doubleEncryptionStorageClient (should handle unencrypted data)
123
+ const retrieved = await getvWithDoubleDecryption(key, userKey);
124
+
125
+ t.deepEqual(retrieved, testData);
126
+ });
127
+
128
+ // Test 6: Reading unencrypted data without contextKey
129
+ test('should read unencrypted data without contextKey', async t => {
130
+ const key = 'test-unencrypted-no-context';
131
+
132
+ // Store unencrypted data using keyValueStorageClient with no encryption key
133
+ const originalRedisKey = config.get('redisEncryptionKey');
134
+ config.get = (key) => {
135
+ switch (key) {
136
+ case 'storageConnectionString':
137
+ return 'redis://localhost:6379';
138
+ case 'cortexId':
139
+ return 'test-cortex';
140
+ case 'redisEncryptionKey':
141
+ return null; // No encryption
142
+ default:
143
+ return originalGet(key);
144
+ }
145
+ };
146
+
147
+ // Store unencrypted data
148
+ await setv(key, testData);
149
+
150
+ // Restore mock config
151
+ config.get = mockGet;
152
+
153
+ // Read using doubleEncryptionStorageClient without contextKey
154
+ const retrieved = await getvWithDoubleDecryption(key, null);
155
+
156
+ t.deepEqual(retrieved, testData);
157
+ });
158
+
159
+ // Test 7: Mixed data types - some double-encrypted, some single-encrypted
160
+ test('should handle mixed encryption states in storage', async t => {
161
+ const doubleKey = 'test-mixed-double';
162
+ const singleKey = 'test-mixed-single';
163
+
164
+ // Store with different encryption methods
165
+ await setvWithDoubleEncryption(doubleKey, testData, userKey); // Double encrypted
166
+ await setv(singleKey, testData); // Single encrypted
167
+
168
+ // Both should be readable with doubleDecryption
169
+ const doubleRetrieved = await getvWithDoubleDecryption(doubleKey, userKey);
170
+ const singleRetrieved = await getvWithDoubleDecryption(singleKey, userKey);
171
+
172
+ t.deepEqual(doubleRetrieved, testData, 'Double-encrypted data should be readable');
173
+ t.deepEqual(singleRetrieved, testData, 'Single-encrypted data should be readable');
174
+ });
175
+
176
+ // Test 8: Edge case - null/undefined data handling
177
+ test('should handle null and undefined data gracefully', async t => {
178
+ const key1 = 'test-null-data';
179
+ const key2 = 'test-undefined-data';
180
+
181
+ // Store null data
182
+ await setvWithDoubleEncryption(key1, null, userKey);
183
+ const retrieved1 = await getvWithDoubleDecryption(key1, userKey);
184
+ t.is(retrieved1, null);
185
+
186
+ // Store undefined data
187
+ await setvWithDoubleEncryption(key2, undefined, userKey);
188
+ const retrieved2 = await getvWithDoubleDecryption(key2, userKey);
189
+ t.is(retrieved2, undefined);
190
+ });
191
+
192
+ // Test 9: Edge case - empty object handling
193
+ test('should handle empty objects', async t => {
194
+ const key = 'test-empty-object';
195
+ const emptyData = {};
196
+
197
+ await setvWithDoubleEncryption(key, emptyData, userKey);
198
+ const retrieved = await getvWithDoubleDecryption(key, userKey);
199
+
200
+ t.deepEqual(retrieved, emptyData);
201
+ });
202
+
203
+ // Test 10: Context key changes between operations
204
+ test('should handle context key changes between operations', async t => {
205
+ const key1 = 'test-context-change-1';
206
+ const key2 = 'test-context-change-2';
207
+ const newUserKey = '1111111111111111111111111111111111111111111111111111111111111111';
208
+
209
+ // Store with first context key
210
+ await setvWithDoubleEncryption(key1, testData, userKey);
211
+
212
+ // Retrieve with same context key
213
+ const retrieved1 = await getvWithDoubleDecryption(key1, userKey);
214
+ t.deepEqual(retrieved1, testData);
215
+
216
+ // Store with different context key (different key to avoid conflicts)
217
+ await setvWithDoubleEncryption(key2, testData, newUserKey);
218
+
219
+ // Retrieve with new context key
220
+ const retrieved2 = await getvWithDoubleDecryption(key2, newUserKey);
221
+ t.deepEqual(retrieved2, testData);
222
+
223
+ // Verify that data encrypted with one key cannot be decrypted with another
224
+ const wrongKeyRetrieved = await getvWithDoubleDecryption(key1, newUserKey);
225
+ t.notDeepEqual(wrongKeyRetrieved, testData, 'Data encrypted with one key should not be readable with different key');
226
+ });
227
+
228
+ // Test 11: Large data handling
229
+ test('should handle large data objects', async t => {
230
+ const key = 'test-large-data';
231
+ const largeData = {
232
+ message: 'Large data test',
233
+ array: Array(1000).fill(0).map((_, i) => i),
234
+ nested: {
235
+ level1: {
236
+ level2: {
237
+ level3: Array(100).fill('test')
238
+ }
239
+ }
240
+ }
241
+ };
242
+
243
+ await setvWithDoubleEncryption(key, largeData, userKey);
244
+ const retrieved = await getvWithDoubleDecryption(key, userKey);
245
+
246
+ t.deepEqual(retrieved, largeData);
247
+ });
248
+
249
+ // Test 12: Special characters and unicode
250
+ test('should handle special characters and unicode', async t => {
251
+ const key = 'test-special-chars';
252
+ const specialData = {
253
+ message: 'Special chars: !@#$%^&*()_+-=[]{}|;:,.<>?',
254
+ unicode: 'Unicode: ๐Ÿš€ ๐ŸŒŸ รฑรกรฉรญรณรบ ไธญๆ–‡ ุงู„ุนุฑุจูŠุฉ',
255
+ emoji: '๐Ÿ˜€๐Ÿ˜๐Ÿ˜‚๐Ÿคฃ๐Ÿ˜ƒ๐Ÿ˜„๐Ÿ˜…๐Ÿ˜†๐Ÿ˜‰๐Ÿ˜Š'
256
+ };
257
+
258
+ await setvWithDoubleEncryption(key, specialData, userKey);
259
+ const retrieved = await getvWithDoubleDecryption(key, userKey);
260
+
261
+ t.deepEqual(retrieved, specialData);
262
+ });