@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.
- package/config.js +25 -4
- package/helper-apps/cortex-autogen2/agents.py +19 -6
- package/helper-apps/cortex-autogen2/services/azure_ai_search.py +115 -0
- package/helper-apps/cortex-autogen2/services/run_analyzer.py +594 -0
- package/helper-apps/cortex-autogen2/task_processor.py +98 -2
- package/lib/crypto.js +1 -0
- package/lib/entityConstants.js +12 -35
- package/lib/keyValueStorageClient.js +53 -1
- package/lib/util.js +33 -6
- package/package.json +2 -1
- package/pathways/system/entity/memory/sys_memory_manager.js +1 -0
- package/pathways/system/entity/memory/sys_memory_process.js +4 -3
- package/pathways/system/entity/memory/sys_memory_update.js +4 -3
- package/pathways/system/entity/memory/sys_read_memory.js +12 -4
- package/pathways/system/entity/memory/sys_save_memory.js +16 -9
- package/pathways/system/entity/memory/sys_search_memory.js +5 -4
- package/pathways/system/entity/sys_entity_agent.js +2 -1
- package/pathways/system/entity/tools/sys_tool_bing_search.js +2 -2
- package/pathways/system/entity/tools/sys_tool_bing_search_afagent.js +1 -2
- package/pathways/system/entity/tools/sys_tool_callmodel.js +2 -1
- package/pathways/system/entity/tools/sys_tool_coding.js +1 -2
- package/pathways/system/entity/tools/sys_tool_grok_x_search.js +1 -1
- package/pathways/system/entity/tools/sys_tool_image.js +2 -1
- package/pathways/system/entity/tools/sys_tool_image_gemini.js +3 -3
- package/pathways/system/entity/tools/sys_tool_mermaid.js +187 -38
- package/pathways/system/entity/tools/sys_tool_reasoning.js +2 -0
- package/pathways/system/entity/tools/sys_tool_verify.js +1 -1
- package/pathways/transcribe_gemini.js +3 -2
- package/server/graphql.js +1 -1
- package/server/pathwayResolver.js +8 -7
- package/server/plugins/veoVideoPlugin.js +29 -1
- package/testrun.log +35371 -0
- package/tests/integration/graphql/async/stream/vendors/openai_streaming.test.js +1 -3
- package/tests/unit/core/crypto.test.js +65 -0
- 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":
|
|
205
|
-
"maxReturnTokens":
|
|
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":
|
|
220
|
-
"maxReturnTokens":
|
|
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
|
-
#
|
|
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
|
+
|