@aj-archipelago/cortex 1.3.62 → 1.3.63
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/.github/workflows/cortex-file-handler-test.yml +61 -0
- package/README.md +31 -7
- package/config/default.example.json +15 -0
- package/config.js +133 -12
- package/helper-apps/cortex-autogen2/DigiCertGlobalRootCA.crt.pem +22 -0
- package/helper-apps/cortex-autogen2/Dockerfile +31 -0
- package/helper-apps/cortex-autogen2/Dockerfile.worker +41 -0
- package/helper-apps/cortex-autogen2/README.md +183 -0
- package/helper-apps/cortex-autogen2/__init__.py +1 -0
- package/helper-apps/cortex-autogen2/agents.py +131 -0
- package/helper-apps/cortex-autogen2/docker-compose.yml +20 -0
- package/helper-apps/cortex-autogen2/function_app.py +55 -0
- package/helper-apps/cortex-autogen2/host.json +15 -0
- package/helper-apps/cortex-autogen2/main.py +126 -0
- package/helper-apps/cortex-autogen2/poetry.lock +3652 -0
- package/helper-apps/cortex-autogen2/pyproject.toml +36 -0
- package/helper-apps/cortex-autogen2/requirements.txt +20 -0
- package/helper-apps/cortex-autogen2/send_task.py +105 -0
- package/helper-apps/cortex-autogen2/services/__init__.py +1 -0
- package/helper-apps/cortex-autogen2/services/azure_queue.py +85 -0
- package/helper-apps/cortex-autogen2/services/redis_publisher.py +153 -0
- package/helper-apps/cortex-autogen2/task_processor.py +488 -0
- package/helper-apps/cortex-autogen2/tools/__init__.py +24 -0
- package/helper-apps/cortex-autogen2/tools/azure_blob_tools.py +175 -0
- package/helper-apps/cortex-autogen2/tools/azure_foundry_agents.py +601 -0
- package/helper-apps/cortex-autogen2/tools/coding_tools.py +72 -0
- package/helper-apps/cortex-autogen2/tools/download_tools.py +48 -0
- package/helper-apps/cortex-autogen2/tools/file_tools.py +545 -0
- package/helper-apps/cortex-autogen2/tools/search_tools.py +646 -0
- package/helper-apps/cortex-azure-cleaner/README.md +36 -0
- package/helper-apps/cortex-file-converter/README.md +93 -0
- package/helper-apps/cortex-file-converter/key_to_pdf.py +104 -0
- package/helper-apps/cortex-file-converter/list_blob_extensions.py +89 -0
- package/helper-apps/cortex-file-converter/process_azure_keynotes.py +181 -0
- package/helper-apps/cortex-file-converter/requirements.txt +1 -0
- package/helper-apps/cortex-file-handler/.env.test.azure.ci +7 -0
- package/helper-apps/cortex-file-handler/.env.test.azure.sample +1 -1
- package/helper-apps/cortex-file-handler/.env.test.gcs.ci +10 -0
- package/helper-apps/cortex-file-handler/.env.test.gcs.sample +2 -2
- package/helper-apps/cortex-file-handler/INTERFACE.md +41 -0
- package/helper-apps/cortex-file-handler/package.json +1 -1
- package/helper-apps/cortex-file-handler/scripts/setup-azure-container.js +41 -17
- package/helper-apps/cortex-file-handler/scripts/setup-test-containers.js +30 -15
- package/helper-apps/cortex-file-handler/scripts/test-azure.sh +32 -6
- package/helper-apps/cortex-file-handler/scripts/test-gcs.sh +24 -2
- package/helper-apps/cortex-file-handler/scripts/validate-env.js +128 -0
- package/helper-apps/cortex-file-handler/src/blobHandler.js +161 -51
- package/helper-apps/cortex-file-handler/src/constants.js +3 -0
- package/helper-apps/cortex-file-handler/src/fileChunker.js +10 -8
- package/helper-apps/cortex-file-handler/src/index.js +116 -9
- package/helper-apps/cortex-file-handler/src/redis.js +61 -1
- package/helper-apps/cortex-file-handler/src/services/ConversionService.js +11 -8
- package/helper-apps/cortex-file-handler/src/services/FileConversionService.js +2 -2
- package/helper-apps/cortex-file-handler/src/services/storage/AzureStorageProvider.js +88 -6
- package/helper-apps/cortex-file-handler/src/services/storage/GCSStorageProvider.js +58 -0
- package/helper-apps/cortex-file-handler/src/services/storage/StorageFactory.js +25 -5
- package/helper-apps/cortex-file-handler/src/services/storage/StorageProvider.js +9 -0
- package/helper-apps/cortex-file-handler/src/services/storage/StorageService.js +120 -16
- package/helper-apps/cortex-file-handler/src/start.js +27 -17
- package/helper-apps/cortex-file-handler/tests/FileConversionService.test.js +52 -1
- package/helper-apps/cortex-file-handler/tests/blobHandler.test.js +40 -0
- package/helper-apps/cortex-file-handler/tests/checkHashShortLived.test.js +553 -0
- package/helper-apps/cortex-file-handler/tests/cleanup.test.js +46 -52
- package/helper-apps/cortex-file-handler/tests/containerConversionFlow.test.js +451 -0
- package/helper-apps/cortex-file-handler/tests/containerNameParsing.test.js +229 -0
- package/helper-apps/cortex-file-handler/tests/containerParameterFlow.test.js +392 -0
- package/helper-apps/cortex-file-handler/tests/conversionResilience.test.js +7 -2
- package/helper-apps/cortex-file-handler/tests/deleteOperations.test.js +348 -0
- package/helper-apps/cortex-file-handler/tests/fileChunker.test.js +23 -2
- package/helper-apps/cortex-file-handler/tests/fileUpload.test.js +11 -5
- package/helper-apps/cortex-file-handler/tests/getOperations.test.js +58 -24
- package/helper-apps/cortex-file-handler/tests/postOperations.test.js +11 -4
- package/helper-apps/cortex-file-handler/tests/shortLivedUrlConversion.test.js +225 -0
- package/helper-apps/cortex-file-handler/tests/start.test.js +8 -12
- package/helper-apps/cortex-file-handler/tests/storage/StorageFactory.test.js +80 -0
- package/helper-apps/cortex-file-handler/tests/storage/StorageService.test.js +388 -22
- package/helper-apps/cortex-file-handler/tests/testUtils.helper.js +74 -0
- package/lib/cortexResponse.js +153 -0
- package/lib/entityConstants.js +21 -3
- package/lib/logger.js +21 -4
- package/lib/pathwayTools.js +28 -9
- package/lib/util.js +49 -0
- package/package.json +1 -1
- package/pathways/basePathway.js +1 -0
- package/pathways/bing_afagent.js +54 -1
- package/pathways/call_tools.js +2 -3
- package/pathways/chat_jarvis.js +1 -1
- package/pathways/google_cse.js +27 -0
- package/pathways/grok_live_search.js +18 -0
- package/pathways/system/entity/memory/sys_memory_lookup_required.js +1 -0
- package/pathways/system/entity/memory/sys_memory_required.js +1 -0
- package/pathways/system/entity/memory/sys_search_memory.js +1 -0
- package/pathways/system/entity/sys_entity_agent.js +56 -4
- package/pathways/system/entity/sys_generator_quick.js +1 -0
- package/pathways/system/entity/tools/sys_tool_bing_search_afagent.js +26 -0
- package/pathways/system/entity/tools/sys_tool_google_search.js +141 -0
- package/pathways/system/entity/tools/sys_tool_grok_x_search.js +237 -0
- package/pathways/system/entity/tools/sys_tool_image.js +1 -1
- package/pathways/system/rest_streaming/sys_claude_37_sonnet.js +21 -0
- package/pathways/system/rest_streaming/sys_claude_41_opus.js +21 -0
- package/pathways/system/rest_streaming/sys_claude_4_sonnet.js +21 -0
- package/pathways/system/rest_streaming/sys_google_gemini_25_flash.js +25 -0
- package/pathways/system/rest_streaming/{sys_google_gemini_chat.js → sys_google_gemini_25_pro.js} +6 -4
- package/pathways/system/rest_streaming/sys_grok_4.js +23 -0
- package/pathways/system/rest_streaming/sys_grok_4_fast_non_reasoning.js +23 -0
- package/pathways/system/rest_streaming/sys_grok_4_fast_reasoning.js +23 -0
- package/pathways/system/rest_streaming/sys_openai_chat.js +3 -0
- package/pathways/system/rest_streaming/sys_openai_chat_gpt41.js +22 -0
- package/pathways/system/rest_streaming/sys_openai_chat_gpt41_mini.js +21 -0
- package/pathways/system/rest_streaming/sys_openai_chat_gpt41_nano.js +21 -0
- package/pathways/system/rest_streaming/{sys_claude_35_sonnet.js → sys_openai_chat_gpt4_omni.js} +6 -4
- package/pathways/system/rest_streaming/sys_openai_chat_gpt4_omni_mini.js +21 -0
- package/pathways/system/rest_streaming/{sys_claude_3_haiku.js → sys_openai_chat_gpt5.js} +7 -5
- package/pathways/system/rest_streaming/sys_openai_chat_gpt5_chat.js +21 -0
- package/pathways/system/rest_streaming/sys_openai_chat_gpt5_mini.js +21 -0
- package/pathways/system/rest_streaming/sys_openai_chat_gpt5_nano.js +21 -0
- package/pathways/system/rest_streaming/{sys_openai_chat_o1.js → sys_openai_chat_o3.js} +6 -3
- package/pathways/system/rest_streaming/sys_openai_chat_o3_mini.js +3 -0
- package/pathways/system/workspaces/run_workspace_prompt.js +99 -0
- package/pathways/vision.js +1 -1
- package/server/graphql.js +1 -1
- package/server/modelExecutor.js +8 -0
- package/server/pathwayResolver.js +166 -16
- package/server/pathwayResponseParser.js +16 -8
- package/server/plugins/azureFoundryAgentsPlugin.js +1 -1
- package/server/plugins/claude3VertexPlugin.js +193 -45
- package/server/plugins/gemini15ChatPlugin.js +21 -0
- package/server/plugins/gemini15VisionPlugin.js +360 -0
- package/server/plugins/googleCsePlugin.js +94 -0
- package/server/plugins/grokVisionPlugin.js +365 -0
- package/server/plugins/modelPlugin.js +3 -1
- package/server/plugins/openAiChatPlugin.js +106 -13
- package/server/plugins/openAiVisionPlugin.js +42 -30
- package/server/resolver.js +28 -4
- package/server/rest.js +270 -53
- package/server/typeDef.js +1 -0
- package/tests/{mocks.js → helpers/mocks.js} +5 -2
- package/tests/{server.js → helpers/server.js} +2 -2
- package/tests/helpers/sseAssert.js +23 -0
- package/tests/helpers/sseClient.js +73 -0
- package/tests/helpers/subscriptionAssert.js +11 -0
- package/tests/helpers/subscriptions.js +113 -0
- package/tests/{sublong.srt → integration/features/translate/sublong.srt} +4543 -4543
- package/tests/integration/features/translate/translate_chunking_stream.test.js +100 -0
- package/tests/{translate_srt.test.js → integration/features/translate/translate_srt.test.js} +2 -2
- package/tests/integration/graphql/async/stream/agentic.test.js +477 -0
- package/tests/integration/graphql/async/stream/subscription_streaming.test.js +62 -0
- package/tests/integration/graphql/async/stream/sys_entity_start_streaming.test.js +71 -0
- package/tests/integration/graphql/async/stream/vendors/claude_streaming.test.js +56 -0
- package/tests/integration/graphql/async/stream/vendors/gemini_streaming.test.js +66 -0
- package/tests/integration/graphql/async/stream/vendors/grok_streaming.test.js +56 -0
- package/tests/integration/graphql/async/stream/vendors/openai_streaming.test.js +72 -0
- package/tests/integration/graphql/features/google/sysToolGoogleSearch.test.js +96 -0
- package/tests/integration/graphql/features/grok/grok.test.js +688 -0
- package/tests/integration/graphql/features/grok/grok_x_search_tool.test.js +354 -0
- package/tests/{main.test.js → integration/graphql/features/main.test.js} +1 -1
- package/tests/{call_tools.test.js → integration/graphql/features/tools/call_tools.test.js} +2 -2
- package/tests/{vision.test.js → integration/graphql/features/vision/vision.test.js} +1 -1
- package/tests/integration/graphql/subscriptions/connection.test.js +26 -0
- package/tests/{openai_api.test.js → integration/rest/oai/openai_api.test.js} +63 -238
- package/tests/integration/rest/oai/tool_calling_api.test.js +343 -0
- package/tests/integration/rest/oai/tool_calling_streaming.test.js +85 -0
- package/tests/integration/rest/vendors/claude_streaming.test.js +47 -0
- package/tests/integration/rest/vendors/claude_tool_calling_streaming.test.js +75 -0
- package/tests/integration/rest/vendors/gemini_streaming.test.js +47 -0
- package/tests/integration/rest/vendors/gemini_tool_calling_streaming.test.js +75 -0
- package/tests/integration/rest/vendors/grok_streaming.test.js +55 -0
- package/tests/integration/rest/vendors/grok_tool_calling_streaming.test.js +75 -0
- package/tests/{azureAuthTokenHelper.test.js → unit/core/azureAuthTokenHelper.test.js} +1 -1
- package/tests/{chunkfunction.test.js → unit/core/chunkfunction.test.js} +2 -2
- package/tests/{config.test.js → unit/core/config.test.js} +3 -3
- package/tests/{encodeCache.test.js → unit/core/encodeCache.test.js} +1 -1
- package/tests/{fastLruCache.test.js → unit/core/fastLruCache.test.js} +1 -1
- package/tests/{handleBars.test.js → unit/core/handleBars.test.js} +1 -1
- package/tests/{memoryfunction.test.js → unit/core/memoryfunction.test.js} +2 -2
- package/tests/unit/core/mergeResolver.test.js +952 -0
- package/tests/{parser.test.js → unit/core/parser.test.js} +3 -3
- package/tests/unit/core/pathwayResolver.test.js +187 -0
- package/tests/{requestMonitor.test.js → unit/core/requestMonitor.test.js} +1 -1
- package/tests/{requestMonitorDurationEstimator.test.js → unit/core/requestMonitorDurationEstimator.test.js} +1 -1
- package/tests/{truncateMessages.test.js → unit/core/truncateMessages.test.js} +3 -3
- package/tests/{util.test.js → unit/core/util.test.js} +1 -1
- package/tests/{apptekTranslatePlugin.test.js → unit/plugins/apptekTranslatePlugin.test.js} +3 -3
- package/tests/{azureFoundryAgents.test.js → unit/plugins/azureFoundryAgents.test.js} +136 -1
- package/tests/{claude3VertexPlugin.test.js → unit/plugins/claude3VertexPlugin.test.js} +32 -10
- package/tests/{claude3VertexToolConversion.test.js → unit/plugins/claude3VertexToolConversion.test.js} +3 -3
- package/tests/unit/plugins/googleCsePlugin.test.js +111 -0
- package/tests/unit/plugins/grokVisionPlugin.test.js +1392 -0
- package/tests/{modelPlugin.test.js → unit/plugins/modelPlugin.test.js} +3 -3
- package/tests/{multimodal_conversion.test.js → unit/plugins/multimodal_conversion.test.js} +4 -4
- package/tests/{openAiChatPlugin.test.js → unit/plugins/openAiChatPlugin.test.js} +13 -4
- package/tests/{openAiToolPlugin.test.js → unit/plugins/openAiToolPlugin.test.js} +35 -27
- package/tests/{tokenHandlingTests.test.js → unit/plugins/tokenHandlingTests.test.js} +5 -5
- package/tests/{translate_apptek.test.js → unit/plugins/translate_apptek.test.js} +3 -3
- package/tests/{streaming.test.js → unit/plugins.streaming/plugin_stream_events.test.js} +19 -58
- package/helper-apps/mogrt-handler/tests/test-files/test.gif +0 -1
- package/helper-apps/mogrt-handler/tests/test-files/test.mogrt +0 -1
- package/helper-apps/mogrt-handler/tests/test-files/test.mp4 +0 -1
- package/pathways/system/rest_streaming/sys_openai_chat_gpt4.js +0 -19
- package/pathways/system/rest_streaming/sys_openai_chat_gpt4_32.js +0 -19
- package/pathways/system/rest_streaming/sys_openai_chat_gpt4_turbo.js +0 -19
- package/pathways/system/workspaces/run_claude35_sonnet.js +0 -21
- package/pathways/system/workspaces/run_claude3_haiku.js +0 -20
- package/pathways/system/workspaces/run_gpt35turbo.js +0 -20
- package/pathways/system/workspaces/run_gpt4.js +0 -20
- package/pathways/system/workspaces/run_gpt4_32.js +0 -20
- package/tests/agentic.test.js +0 -256
- package/tests/pathwayResolver.test.js +0 -78
- package/tests/subscription.test.js +0 -387
- /package/tests/{subchunk.srt → integration/features/translate/subchunk.srt} +0 -0
- /package/tests/{subhorizontal.srt → integration/features/translate/subhorizontal.srt} +0 -0
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
from autogen_agentchat.agents import AssistantAgent, CodeExecutorAgent
|
|
2
|
+
from autogen_ext.code_executors.local import LocalCommandLineCodeExecutor
|
|
3
|
+
import os
|
|
4
|
+
from autogen_core.tools import FunctionTool
|
|
5
|
+
from tools.azure_blob_tools import upload_file_to_azure_blob
|
|
6
|
+
|
|
7
|
+
#AGENTS
|
|
8
|
+
MAGENTIC_ONE_CODER_DESCRIPTION = "A helpful and general-purpose AI assistant that has strong language skills, Python skills, and Linux command line skills."
|
|
9
|
+
|
|
10
|
+
MAGENTIC_ONE_CODER_SYSTEM_MESSAGE = """You are a helpful AI assistant.
|
|
11
|
+
Solve tasks using your coding and language skills.
|
|
12
|
+
In the following cases, suggest python code (in a python coding block) or shell script (in a sh coding block) for the user to execute.
|
|
13
|
+
1. When you need to collect info, use the code to output the info you need, for example, browse or search the web, download/read a file, print the content of a webpage or a file, get the current date/time, check the operating system. After sufficient info is printed and the task is ready to be solved based on your language skill, you can solve the task by yourself.
|
|
14
|
+
2. When you need to perform some task with code, use the code to perform the task and output the result. Finish the task smartly.
|
|
15
|
+
Solve the task step by step if you need to. If a plan is not provided, explain your plan first. Be clear which step uses code, and which step uses your language skill.
|
|
16
|
+
When using code, you must indicate the script type in the code block. The user cannot provide any other feedback or perform any other action beyond executing the code you suggest. The user can't modify your code. So do not suggest incomplete code which requires users to modify. Don't use a code block if it's not intended to be executed by the user.
|
|
17
|
+
Don't include multiple code blocks in one response. Do not ask users to copy and paste the result. Instead, use the 'print' function for the output when relevant. Check the execution result returned by the user.
|
|
18
|
+
If the result indicates there is an error, fix the error and output the code again. Suggest the full code instead of partial code or code changes. If the error can't be fixed or if the task is not solved even after the code is executed successfully, analyze the problem, revisit your assumption, collect additional info you need, and think of a different approach to try.
|
|
19
|
+
When you find an answer, verify the answer carefully. Include verifiable evidence in your response if possible."""
|
|
20
|
+
|
|
21
|
+
|
|
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")
|
|
26
|
+
code_executor = LocalCommandLineCodeExecutor(work_dir=work_dir, timeout=300)
|
|
27
|
+
|
|
28
|
+
#TOOLS
|
|
29
|
+
upload_file_to_cloud_tool = FunctionTool(upload_file_to_azure_blob, description="Upload files to the cloud. You must use absolute path to reference local files.")
|
|
30
|
+
|
|
31
|
+
coder_agent = AssistantAgent(
|
|
32
|
+
"coder_agent",
|
|
33
|
+
model_client=default_model_client,
|
|
34
|
+
description=MAGENTIC_ONE_CODER_DESCRIPTION,
|
|
35
|
+
system_message=MAGENTIC_ONE_CODER_SYSTEM_MESSAGE + f"""
|
|
36
|
+
Save remote files images, videos, etc. in order to work with them locally.
|
|
37
|
+
Make sure to log/print everything in code otherwise you will lose the context and cannot debug it.
|
|
38
|
+
Make sure your code is perfect.
|
|
39
|
+
Never ask for user input or user to do anything.
|
|
40
|
+
Never ask questions.
|
|
41
|
+
Your are expert in coding, do wonders.
|
|
42
|
+
If you need to do advanced stuff you can do a project and run it.
|
|
43
|
+
You can split codes, build projects, run anything, coding is your strength in this task.
|
|
44
|
+
Take actionable verifiable small steps if needed.
|
|
45
|
+
Understand that pitfalls and find ways to overcome them.
|
|
46
|
+
Progress is important, do not get stuck in a loop, keep trying but do not repeat the same steps.
|
|
47
|
+
Current directory might be different from the one you think it is, use absolute path to reference files.
|
|
48
|
+
Code executor working directory is: {work_dir}
|
|
49
|
+
So you can only access files in this directory.
|
|
50
|
+
Always use absolute path to reference files as current directory might be different from the one you think it is.
|
|
51
|
+
""",
|
|
52
|
+
)
|
|
53
|
+
|
|
54
|
+
code_executor_agent = CodeExecutorAgent("code_executor", code_executor=code_executor)
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
terminator_agent = AssistantAgent(
|
|
58
|
+
"terminator_agent",
|
|
59
|
+
model_client=default_model_client,
|
|
60
|
+
description="A helpful assistant that can terminate.",
|
|
61
|
+
system_message="""You are a helpful assistant that can terminate.
|
|
62
|
+
Original task must be completed in order to terminate.
|
|
63
|
+
Only output: TERMINATE, if completed.
|
|
64
|
+
If not completed, give the reason instead of TERMINATE.
|
|
65
|
+
Do not ask questions you are the terminator.
|
|
66
|
+
Always output in single line without any other text.
|
|
67
|
+
Do not give empty response.
|
|
68
|
+
In order to terminate:
|
|
69
|
+
- Task must be completed.
|
|
70
|
+
- All referenced local files must have been uploaded to the cloud and their public URLs retrieved and included in the final output.
|
|
71
|
+
- Presenter must have provided the final output.
|
|
72
|
+
All code must have been executed in order to terminate.
|
|
73
|
+
Deliverables must have been provided in order to terminate.
|
|
74
|
+
If you cannot terminate because of same reason after 3 attempts, terminate.
|
|
75
|
+
Example outputs:
|
|
76
|
+
|
|
77
|
+
TERMINATE
|
|
78
|
+
|
|
79
|
+
TASK NOT COMPLETED: missing missing missing
|
|
80
|
+
""",
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
presenter_agent = AssistantAgent(
|
|
85
|
+
"presenter_agent",
|
|
86
|
+
model_client=default_model_client,
|
|
87
|
+
description="A highly skilled and creative presentation specialist, responsible for crafting visually stunning and exceptionally informative final deliverables.",
|
|
88
|
+
system_message="""You are a highly skilled and creative presentation specialist, responsible for crafting visually stunning and exceptionally informative final deliverables.
|
|
89
|
+
Your goal is to transform raw task results into engaging, professional, and visually appealing presentations, primarily using Markdown.
|
|
90
|
+
|
|
91
|
+
Here's what makes a great presentation:
|
|
92
|
+
- **Captivating Structure**: Start with a compelling summary, followed by well-organized sections with clear headings and subheadings.
|
|
93
|
+
- **Stunning Visuals**: Integrate relevant images, videos, and even diagrams (if applicable and possible via markdown) seamlessly to enhance understanding and engagement. Ensure visuals are high-quality and directly support the content.
|
|
94
|
+
**IMPORTANT: Actively look for `UPLOADED_FILES_SAS_URLS` provided in the input. If images or other visual assets are available via these URLs, you MUST incorporate them into your Markdown presentation. Describe and explain these visuals to the user, providing context and insights.**
|
|
95
|
+
- **Professional Aesthetics**: Utilize Markdown's full capabilities for formatting, including bolding, italics, lists, and tables, to create a clean, readable, and visually pleasing layout. Think about white space and information hierarchy.
|
|
96
|
+
- **Concise & Impactful Language**: Use persuasive and professional language. Avoid jargon where possible, or explain it clearly. Every word should contribute to clarity and impact.
|
|
97
|
+
- **User-Centric Design**: Remember that your output will be directly displayed in a React application. Focus on great UI/UX, ensuring the presentation is intuitive and easy for the end-user to consume.
|
|
98
|
+
- **Complete & Actionable**: Ensure all necessary information from the task is included, and if appropriate, guide the user towards next steps or key takeaways.
|
|
99
|
+
|
|
100
|
+
Report must be a direct reply to the user's task. You are the final voice to the user, so make it perfect.
|
|
101
|
+
User does not have local access to the files, so you must provide direct URLs for any external resources (e.g., images uploaded to cloud storage).
|
|
102
|
+
When including downloadable assets, always look for and use the `download_url` provided in JSON outputs from the `file_cloud_uploader_agent`. These URLs are public and include necessary SAS tokens for access.
|
|
103
|
+
Crucially, your output should be a final, polished presentation of the task result, suitable for direct display in a user interface.
|
|
104
|
+
**Your report MUST only contain the direct result of the user's task. Absolutely NO explanations of how the task was accomplished, internal agent thought processes, or any operational details should be included. Do not mention which tools or agents were used, or how they were used to achieve the result.**
|
|
105
|
+
**Focus exclusively on delivering the requested information (e.g., image galleries, reports) and only include minimal, essential explanations directly related to the visuals or content.** For example, for an image gallery, provide brief descriptions for each image or a short overview of the gallery structure, but do not explain the steps taken by the agents or the internal workflow.
|
|
106
|
+
**Do not include extensive executive summaries, detailed operational breakdowns, or generic quick-start guides unless explicitly asked for.**
|
|
107
|
+
Do not include raw code snippets, internal thought processes, intermediate data, or any technical logs that are not part of the final, user-friendly deliverable.
|
|
108
|
+
**Absolutely DO NOT include instructions on how to run, save, or modify any code (e.g., "save as .py", "pip install", "python script.py").**
|
|
109
|
+
**DO NOT provide information about packaging, dependencies, or development workflows.**
|
|
110
|
+
Your output is for a non-technical end-user viewing it in a React app.
|
|
111
|
+
**CRITICAL: ONLY use URLs for any files (images, videos, documents, etc.) that are explicitly provided in the `UPLOADED_FILES_SAS_URLS` or directly within the `RESULT` content from other agents, specifically from the `file_cloud_uploader_agent`. If a valid, real URL is not provided, you MUST NOT include any placeholder, fake, or fabricated URLs. NEVER hallucinate or fabricate any links or content.**
|
|
112
|
+
"""
|
|
113
|
+
)
|
|
114
|
+
|
|
115
|
+
file_cloud_uploader_agent = AssistantAgent(
|
|
116
|
+
"file_cloud_uploader_agent",
|
|
117
|
+
model_client=default_model_client,
|
|
118
|
+
tools=[upload_file_to_cloud_tool],
|
|
119
|
+
description="A helpful assistant that can upload files to the cloud.",
|
|
120
|
+
system_message=f"""You are a helpful assistant that can upload files to the cloud.
|
|
121
|
+
Upload referenced files to the cloud.
|
|
122
|
+
Use your tool to upload the files.
|
|
123
|
+
User does not have local access to the files so you must upload them to the cloud and provide the url.
|
|
124
|
+
Your current working directory for file operations is: {work_dir}.
|
|
125
|
+
When referencing local files for upload, **always prepend the '{work_dir}/' to the filename** to form the correct absolute path. For example, if a file is named 'test.text' in the working directory, the absolute path should be '{work_dir}/test.txt'.
|
|
126
|
+
""",
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
agents = [coder_agent, code_executor_agent, file_cloud_uploader_agent, presenter_agent, terminator_agent]
|
|
130
|
+
|
|
131
|
+
return agents, presenter_agent
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
services:
|
|
2
|
+
cortex-autogen-function:
|
|
3
|
+
build:
|
|
4
|
+
context: .
|
|
5
|
+
dockerfile: Dockerfile
|
|
6
|
+
platforms:
|
|
7
|
+
- linux/amd64
|
|
8
|
+
ports:
|
|
9
|
+
- "7071:80"
|
|
10
|
+
environment:
|
|
11
|
+
- CORTEX_API_BASE_URL=http://host.docker.internal:4000/v1
|
|
12
|
+
- REDIS_CONNECTION_STRING=redis://host.docker.internal:6379
|
|
13
|
+
healthcheck:
|
|
14
|
+
test: ["CMD", "curl", "-f", "http://localhost:80/api/health"]
|
|
15
|
+
interval: 30s
|
|
16
|
+
timeout: 10s
|
|
17
|
+
retries: 3
|
|
18
|
+
start_period: 60s
|
|
19
|
+
restart: unless-stopped
|
|
20
|
+
network_mode: host
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import azure.functions as func
|
|
2
|
+
import logging
|
|
3
|
+
import json
|
|
4
|
+
from azure.storage.queue import QueueClient
|
|
5
|
+
import os
|
|
6
|
+
import redis
|
|
7
|
+
from task_processor import process_queue_message
|
|
8
|
+
# from agents import process_message
|
|
9
|
+
|
|
10
|
+
# logging.getLogger().setLevel(logging.WARNING)
|
|
11
|
+
logging.getLogger().setLevel(logging.INFO)
|
|
12
|
+
|
|
13
|
+
app = func.FunctionApp()
|
|
14
|
+
|
|
15
|
+
connection_string = os.environ["AZURE_STORAGE_CONNECTION_STRING"]
|
|
16
|
+
queue_name = os.environ.get("AZURE_QUEUE_NAME") or os.environ.get("QUEUE_NAME", "autogen-message-queue")
|
|
17
|
+
logging.info(f"📦 Using Azure Storage Queue name: {queue_name}")
|
|
18
|
+
queue_client = QueueClient.from_connection_string(connection_string, queue_name)
|
|
19
|
+
|
|
20
|
+
redis_client = redis.from_url(os.environ['REDIS_CONNECTION_STRING'])
|
|
21
|
+
channel = 'requestProgress'
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
@app.queue_trigger(arg_name="msg", queue_name=queue_name, connection="AZURE_STORAGE_CONNECTION_STRING")
|
|
25
|
+
def queue_trigger(msg: func.QueueMessage):
|
|
26
|
+
"""Queue trigger function to process Cortex AutoGen tasks."""
|
|
27
|
+
logging.info(f"🔍 QUEUE_TRIGGER: Processing message {msg.id}")
|
|
28
|
+
|
|
29
|
+
try:
|
|
30
|
+
message_body = msg.get_body().decode('utf-8')
|
|
31
|
+
message_data = {
|
|
32
|
+
"id": msg.id,
|
|
33
|
+
"content": message_body,
|
|
34
|
+
"pop_receipt": None,
|
|
35
|
+
"dequeue_count": msg.dequeue_count
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
logging.info(f"🔍 QUEUE_TRIGGER: Content: {message_data['content'][:100]}...")
|
|
39
|
+
|
|
40
|
+
# Process the message synchronously
|
|
41
|
+
import asyncio
|
|
42
|
+
loop = asyncio.new_event_loop()
|
|
43
|
+
asyncio.set_event_loop(loop)
|
|
44
|
+
try:
|
|
45
|
+
result = loop.run_until_complete(process_queue_message(message_data))
|
|
46
|
+
if result:
|
|
47
|
+
logging.info(f"✅ QUEUE_TRIGGER: Message {msg.id} processed successfully")
|
|
48
|
+
else:
|
|
49
|
+
logging.warning(f"⚠️ QUEUE_TRIGGER: Message {msg.id} returned no result")
|
|
50
|
+
finally:
|
|
51
|
+
loop.close()
|
|
52
|
+
|
|
53
|
+
except Exception as e:
|
|
54
|
+
logging.error(f"❌ QUEUE_TRIGGER: Error processing message {msg.id}: {e}", exc_info=True)
|
|
55
|
+
raise
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": "2.0",
|
|
3
|
+
"logging": {
|
|
4
|
+
"applicationInsights": {
|
|
5
|
+
"samplingSettings": {
|
|
6
|
+
"isEnabled": true,
|
|
7
|
+
"excludedTypes": "Request"
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"extensionBundle": {
|
|
12
|
+
"id": "Microsoft.Azure.Functions.ExtensionBundle",
|
|
13
|
+
"version": "[4.*, 5.0.0)"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
import json
|
|
5
|
+
import base64
|
|
6
|
+
import logging
|
|
7
|
+
from services.azure_queue import get_queue_service
|
|
8
|
+
from task_processor import TaskProcessor
|
|
9
|
+
|
|
10
|
+
# Add the parent directory of 'src' to sys.path to allow imports like 'from cortex_autogen2.tools import ...'
|
|
11
|
+
# This is crucial when running main.py directly from outside the 'src' directory.
|
|
12
|
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
13
|
+
project_root = os.path.abspath(os.path.join(current_dir, '..', '..'))
|
|
14
|
+
if project_root not in sys.path:
|
|
15
|
+
sys.path.insert(0, project_root)
|
|
16
|
+
|
|
17
|
+
# Load environment variables
|
|
18
|
+
from dotenv import load_dotenv
|
|
19
|
+
load_dotenv()
|
|
20
|
+
|
|
21
|
+
# Configure logging
|
|
22
|
+
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')
|
|
23
|
+
logging.getLogger("azure.core.pipeline.policies.http_logging_policy").setLevel(logging.WARNING)
|
|
24
|
+
logger = logging.getLogger(__name__)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
async def process_task(task_id: str, task_content: str, processor: TaskProcessor) -> None:
|
|
28
|
+
"""Process a single task using the TaskProcessor."""
|
|
29
|
+
await processor.process_task(task_id, task_content)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
async def main():
|
|
34
|
+
"""
|
|
35
|
+
Main function to continuously process tasks from the Azure queue.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
continuous_mode = os.getenv("CONTINUOUS_MODE", "true").lower() == "true"
|
|
39
|
+
logger.info(f"🚀 Starting AutoGen Worker, continuous_mode: {continuous_mode}")
|
|
40
|
+
|
|
41
|
+
# Add a small initial delay in non-continuous mode to allow tasks to be enqueued
|
|
42
|
+
if not continuous_mode:
|
|
43
|
+
await asyncio.sleep(1)
|
|
44
|
+
|
|
45
|
+
try:
|
|
46
|
+
azure_queue = await get_queue_service()
|
|
47
|
+
processor = TaskProcessor()
|
|
48
|
+
await processor.initialize()
|
|
49
|
+
|
|
50
|
+
try:
|
|
51
|
+
while True: # Continuous loop
|
|
52
|
+
try:
|
|
53
|
+
message = await azure_queue.get_task()
|
|
54
|
+
if message:
|
|
55
|
+
task_id = message.get("id")
|
|
56
|
+
pop_receipt = message.get("pop_receipt")
|
|
57
|
+
|
|
58
|
+
if not task_id or not pop_receipt:
|
|
59
|
+
logger.error(f"❌ Invalid message format: {message}")
|
|
60
|
+
# Delete the invalid message to prevent infinite retry
|
|
61
|
+
if task_id and pop_receipt:
|
|
62
|
+
await azure_queue.delete_task(task_id, pop_receipt)
|
|
63
|
+
continue
|
|
64
|
+
|
|
65
|
+
raw_content = message.get("content") or message.get("message")
|
|
66
|
+
if not raw_content:
|
|
67
|
+
logger.error(f"❌ Message has no content: {message}")
|
|
68
|
+
await azure_queue.delete_task(task_id, pop_receipt)
|
|
69
|
+
continue
|
|
70
|
+
|
|
71
|
+
try:
|
|
72
|
+
decoded_content = base64.b64decode(raw_content).decode('utf-8')
|
|
73
|
+
task_data = json.loads(decoded_content)
|
|
74
|
+
except (json.JSONDecodeError, TypeError, ValueError) as e:
|
|
75
|
+
logger.warning(f"⚠️ Failed to decode as base64, trying as raw JSON: {e}")
|
|
76
|
+
try:
|
|
77
|
+
task_data = json.loads(raw_content)
|
|
78
|
+
except json.JSONDecodeError as e2:
|
|
79
|
+
logger.error(f"❌ Failed to parse message content: {e2}")
|
|
80
|
+
await azure_queue.delete_task(task_id, pop_receipt)
|
|
81
|
+
continue
|
|
82
|
+
|
|
83
|
+
# Fix: Check message field first, then content field
|
|
84
|
+
task_content = task_data.get("message") or task_data.get("content")
|
|
85
|
+
if not task_content:
|
|
86
|
+
logger.error(f"❌ No task content found in: {task_data}")
|
|
87
|
+
await azure_queue.delete_task(task_id, pop_receipt)
|
|
88
|
+
continue
|
|
89
|
+
|
|
90
|
+
logger.info(f"📩 Received task: {task_content}...")
|
|
91
|
+
|
|
92
|
+
await process_task(task_id, task_content, processor)
|
|
93
|
+
|
|
94
|
+
await azure_queue.delete_task(task_id, pop_receipt)
|
|
95
|
+
logger.info(f"✅ Task {task_id} processed successfully.")
|
|
96
|
+
else:
|
|
97
|
+
if continuous_mode:
|
|
98
|
+
logger.info("⏳ No tasks in queue. Waiting 3 seconds...")
|
|
99
|
+
await asyncio.sleep(3) # Wait before checking again
|
|
100
|
+
else:
|
|
101
|
+
logger.info("📭 No tasks in queue. Exiting (non-continuous mode).")
|
|
102
|
+
break
|
|
103
|
+
|
|
104
|
+
except Exception as e:
|
|
105
|
+
logger.error(f"❌ Error processing task: {e}")
|
|
106
|
+
if continuous_mode:
|
|
107
|
+
logger.info("📝 Continuing to next task...")
|
|
108
|
+
await asyncio.sleep(5) # Brief pause before retrying
|
|
109
|
+
else:
|
|
110
|
+
raise # Re-raise in non-continuous mode
|
|
111
|
+
|
|
112
|
+
finally:
|
|
113
|
+
await processor.close()
|
|
114
|
+
logger.info("🔌 Connections closed. Worker shutting down.")
|
|
115
|
+
|
|
116
|
+
except Exception as e:
|
|
117
|
+
logger.error(f"❌ Error in main loop: {e}")
|
|
118
|
+
raise
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
if __name__ == "__main__":
|
|
122
|
+
asyncio.run(main())
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
|
|
126
|
+
|