@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
package/config.js CHANGED
@@ -190,6 +190,21 @@ var config = convict({
190
190
  },
191
191
  "maxTokenLength": 8192,
192
192
  },
193
+ "oai-gpt5-chat": {
194
+ "type": "OPENAI-VISION",
195
+ "url": "https://api.openai.com/v1/chat/completions",
196
+ "headers": {
197
+ "Authorization": "Bearer {{OPENAI_API_KEY}}",
198
+ "Content-Type": "application/json"
199
+ },
200
+ "params": {
201
+ "model": "gpt-5-chat-latest"
202
+ },
203
+ "requestsPerSecond": 50,
204
+ "maxTokenLength": 128000,
205
+ "maxReturnTokens": 16384,
206
+ "supportsStreaming": true
207
+ },
193
208
  "oai-gpt5": {
194
209
  "type": "OPENAI-REASONING-VISION",
195
210
  "url": "https://api.openai.com/v1/chat/completions",
@@ -201,8 +216,8 @@ var config = convict({
201
216
  "model": "gpt-5"
202
217
  },
203
218
  "requestsPerSecond": 50,
204
- "maxTokenLength": 1000000,
205
- "maxReturnTokens": 16384,
219
+ "maxTokenLength": 400000,
220
+ "maxReturnTokens": 128000,
206
221
  "supportsStreaming": true
207
222
  },
208
223
  "oai-gpt5-mini": {
@@ -216,8 +231,8 @@ var config = convict({
216
231
  "model": "gpt-5-mini"
217
232
  },
218
233
  "requestsPerSecond": 50,
219
- "maxTokenLength": 1000000,
220
- "maxReturnTokens": 16384,
234
+ "maxTokenLength": 400000,
235
+ "maxReturnTokens": 128000,
221
236
  "supportsStreaming": true
222
237
  },
223
238
  "oai-gpt4o": {
@@ -965,6 +980,12 @@ const buildPathways = async (config) => {
965
980
  continue;
966
981
  }
967
982
 
983
+ // Skip tool if explicitly disabled
984
+ if (toolDef.enabled === false) {
985
+ logger.info(`Skipping disabled tool in pathway ${key}`);
986
+ continue;
987
+ }
988
+
968
989
  const { description, parameters } = toolDef.function;
969
990
  const name = toolDef.function.name.toLowerCase();
970
991
 
@@ -1,6 +1,7 @@
1
1
  from autogen_agentchat.agents import AssistantAgent, CodeExecutorAgent
2
2
  from autogen_ext.code_executors.local import LocalCommandLineCodeExecutor
3
- import os
3
+ import os
4
+ from typing import Optional
4
5
  from autogen_core.tools import FunctionTool
5
6
  from tools.azure_blob_tools import upload_file_to_azure_blob
6
7
 
@@ -19,10 +20,22 @@ If the result indicates there is an error, fix the error and output the code aga
19
20
  When you find an answer, verify the answer carefully. Include verifiable evidence in your response if possible."""
20
21
 
21
22
 
22
- async def get_agents(default_model_client, big_model_client, small_model_client):
23
-
24
- #code executor
25
- work_dir = os.getenv("CORTEX_WORK_DIR", "/home/site/wwwroot/coding")
23
+ async def get_agents(default_model_client, big_model_client, small_model_client, request_work_dir: Optional[str] = None):
24
+
25
+ # Resolve work dir (prefer per-request dir if provided or from env)
26
+ work_dir = request_work_dir or os.getenv("CORTEX_WORK_DIR", "/home/site/wwwroot/coding")
27
+ try:
28
+ # In Azure Functions, ensure /tmp is used for write access if an /app path was set
29
+ if os.getenv("WEBSITE_INSTANCE_ID") and work_dir.startswith("/app/"):
30
+ work_dir = "/tmp/coding"
31
+ os.makedirs(work_dir, exist_ok=True)
32
+ except Exception:
33
+ try:
34
+ work_dir = "/tmp/coding"
35
+ os.makedirs(work_dir, exist_ok=True)
36
+ except Exception:
37
+ pass
38
+
26
39
  code_executor = LocalCommandLineCodeExecutor(work_dir=work_dir, timeout=300)
27
40
 
28
41
  #TOOLS
@@ -128,4 +141,4 @@ async def get_agents(default_model_client, big_model_client, small_model_client)
128
141
 
129
142
  agents = [coder_agent, code_executor_agent, file_cloud_uploader_agent, presenter_agent, terminator_agent]
130
143
 
131
- return agents, presenter_agent
144
+ return agents, presenter_agent, terminator_agent
@@ -0,0 +1,115 @@
1
+ import os
2
+ import logging
3
+ from typing import Any, Dict, List, Optional
4
+
5
+ import requests
6
+
7
+
8
+ logger = logging.getLogger(__name__)
9
+
10
+
11
+ API_VERSION = os.getenv("AZURE_COGNITIVE_API_VERSION", "2023-11-01")
12
+
13
+
14
+ def _get_base_url() -> Optional[str]:
15
+ url = os.getenv("AZURE_COGNITIVE_API_URL")
16
+ if not url:
17
+ return None
18
+ # normalize: strip trailing slashes
19
+ return url.rstrip("/")
20
+
21
+
22
+ def _get_index_name() -> str:
23
+ return os.getenv("AZURE_COGNITIVE_INDEX_WRITE", "index-autogen2")
24
+
25
+
26
+ def _get_headers() -> Optional[Dict[str, str]]:
27
+ api_key = os.getenv("AZURE_COGNITIVE_API_KEY_WRITE")
28
+ if not api_key:
29
+ return None
30
+ return {
31
+ "Content-Type": "application/json",
32
+ "api-key": api_key,
33
+ }
34
+
35
+
36
+ def upsert_run_rest(doc: Dict[str, Any]) -> bool:
37
+ """
38
+ Best-effort upsert of a single run document into Azure Cognitive Search via REST.
39
+
40
+ Expects index with fields: id (key), date (DateTimeOffset), task (String), content (String), owner (String), requestId (String)
41
+ """
42
+ try:
43
+ base = _get_base_url()
44
+ headers = _get_headers()
45
+ index_name = _get_index_name()
46
+ if not base or not headers:
47
+ logger.debug("[Search] Missing base URL or API key; skipping upsert.")
48
+ return False
49
+
50
+ url = f"{base}/indexes/{index_name}/docs/index"
51
+ params = {"api-version": API_VERSION}
52
+ # Ensure @search.action on the document
53
+ payload = {
54
+ "value": [
55
+ {"@search.action": "mergeOrUpload", **doc}
56
+ ]
57
+ }
58
+ resp = requests.post(url, headers=headers, params=params, json=payload, timeout=20)
59
+ try:
60
+ resp.raise_for_status()
61
+ return True
62
+ except Exception as e:
63
+ logger.warning(f"[Search] Upsert failed: {e} - status={resp.status_code} text={resp.text[:500]}")
64
+ return False
65
+ except Exception as e:
66
+ logger.warning(f"[Search] Upsert error: {e}")
67
+ return False
68
+
69
+
70
+ def search_similar_rest(query_text: str, top: int = 3) -> List[Dict[str, Any]]:
71
+ """
72
+ Full-text search for similar tasks using task/content fields.
73
+ Returns a list of raw result documents (selected fields only).
74
+ """
75
+ try:
76
+ base = _get_base_url()
77
+ headers = _get_headers()
78
+ index_name = _get_index_name()
79
+ if not base or not headers:
80
+ logger.debug("[Search] Missing base URL or API key; skipping search.")
81
+ return []
82
+
83
+ url = f"{base}/indexes/{index_name}/docs/search"
84
+ params = {"api-version": API_VERSION}
85
+ body = {
86
+ "search": query_text or "",
87
+ "top": int(top or 3),
88
+ "searchFields": "task,content",
89
+ "select": "id,task,content,date,requestId,owner",
90
+ }
91
+ resp = requests.post(url, headers=headers, params=params, json=body, timeout=20)
92
+ try:
93
+ resp.raise_for_status()
94
+ data = resp.json() or {}
95
+ # Azure returns { "value": [ {"@search.score": ..., ...fields } ] }
96
+ vals = data.get("value") or []
97
+ # Extract documents only
98
+ docs: List[Dict[str, Any]] = []
99
+ for v in vals:
100
+ try:
101
+ # Remove score and return selected fields
102
+ v = dict(v)
103
+ v.pop("@search.score", None)
104
+ docs.append(v)
105
+ except Exception:
106
+ continue
107
+ return docs
108
+ except Exception as e:
109
+ logger.debug(f"[Search] Search failed: {e} - status={resp.status_code} text={resp.text[:500]}")
110
+ return []
111
+ except Exception as e:
112
+ logger.debug(f"[Search] Search error: {e}")
113
+ return []
114
+
115
+