@aj-archipelago/cortex 1.2.1 → 1.3.1
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 +38 -11
- package/helper-apps/cortex-autogen/OAI_CONFIG_LIST +2 -1
- package/helper-apps/cortex-autogen/agents.py +392 -0
- package/helper-apps/cortex-autogen/agents_extra.py +14 -0
- package/helper-apps/cortex-autogen/config.py +18 -0
- package/helper-apps/cortex-autogen/data_operations.py +29 -0
- package/helper-apps/cortex-autogen/function_app.py +6 -3
- package/helper-apps/cortex-autogen/main.py +4 -4
- package/helper-apps/cortex-autogen/prompts.py +196 -0
- package/helper-apps/cortex-autogen/prompts_extra.py +5 -0
- package/helper-apps/cortex-autogen/requirements.txt +2 -1
- package/helper-apps/cortex-autogen/search.py +83 -0
- package/helper-apps/cortex-autogen/test.sh +40 -0
- package/helper-apps/cortex-autogen/utils.py +78 -0
- package/lib/handleBars.js +25 -0
- package/lib/logger.js +2 -0
- package/lib/util.js +3 -1
- package/package.json +1 -1
- package/pathways/chat_code.js +1 -1
- package/pathways/chat_context.js +1 -1
- package/pathways/chat_jarvis.js +1 -1
- package/pathways/chat_persist.js +1 -1
- package/pathways/chat_title.js +25 -0
- package/pathways/image_recraft.js +1 -1
- package/pathways/rag.js +1 -1
- package/pathways/rag_jarvis.js +1 -1
- package/pathways/rag_search_helper.js +1 -1
- package/pathways/system/entity/memory/sys_memory_manager.js +71 -0
- package/pathways/system/entity/memory/sys_memory_required.js +21 -0
- package/pathways/system/entity/memory/sys_memory_update.js +196 -0
- package/pathways/system/entity/memory/sys_read_memory.js +37 -0
- package/pathways/system/entity/memory/sys_save_memory.js +60 -0
- package/pathways/system/entity/shared/sys_entity_constants.js +27 -0
- package/pathways/system/entity/sys_entity_continue.js +55 -0
- package/pathways/system/entity/sys_entity_start.js +239 -0
- package/pathways/system/entity/sys_generator_error.js +20 -0
- package/pathways/system/entity/sys_generator_expert.js +26 -0
- package/pathways/system/entity/sys_generator_image.js +127 -0
- package/pathways/system/entity/sys_generator_quick.js +19 -0
- package/pathways/system/entity/sys_generator_reasoning.js +27 -0
- package/pathways/system/entity/sys_generator_results.js +310 -0
- package/pathways/system/entity/sys_generator_video_vision.js +27 -0
- package/pathways/system/entity/sys_image_prompt_builder.js +35 -0
- package/pathways/system/entity/sys_query_builder.js +110 -0
- package/pathways/system/entity/sys_router_code.js +37 -0
- package/pathways/system/entity/sys_router_tool.js +67 -0
- package/pathways/{sys_claude_35_sonnet.js → system/rest_streaming/sys_claude_35_sonnet.js} +1 -1
- package/pathways/{sys_claude_3_haiku.js → system/rest_streaming/sys_claude_3_haiku.js} +1 -1
- package/pathways/{sys_google_chat.js → system/rest_streaming/sys_google_chat.js} +1 -1
- package/pathways/{sys_google_code_chat.js → system/rest_streaming/sys_google_code_chat.js} +1 -1
- package/pathways/{sys_google_gemini_chat.js → system/rest_streaming/sys_google_gemini_chat.js} +1 -1
- package/pathways/{sys_openai_chat.js → system/rest_streaming/sys_openai_chat.js} +1 -1
- package/pathways/{sys_openai_chat_16.js → system/rest_streaming/sys_openai_chat_16.js} +1 -1
- package/pathways/{sys_openai_chat_gpt4.js → system/rest_streaming/sys_openai_chat_gpt4.js} +1 -1
- package/pathways/{sys_openai_chat_gpt4_32.js → system/rest_streaming/sys_openai_chat_gpt4_32.js} +1 -1
- package/pathways/{sys_openai_chat_gpt4_turbo.js → system/rest_streaming/sys_openai_chat_gpt4_turbo.js} +1 -1
- package/pathways/{sys_parse_numbered_object_list.js → system/sys_parse_numbered_object_list.js} +2 -2
- package/pathways/{sys_repair_json.js → system/sys_repair_json.js} +1 -1
- package/pathways/{run_claude35_sonnet.js → system/workspaces/run_claude35_sonnet.js} +1 -1
- package/pathways/{run_claude3_haiku.js → system/workspaces/run_claude3_haiku.js} +1 -1
- package/pathways/{run_gpt35turbo.js → system/workspaces/run_gpt35turbo.js} +1 -1
- package/pathways/{run_gpt4.js → system/workspaces/run_gpt4.js} +1 -1
- package/pathways/{run_gpt4_32.js → system/workspaces/run_gpt4_32.js} +1 -1
- package/server/pathwayResolver.js +62 -10
- package/server/plugins/azureCognitivePlugin.js +14 -1
- package/server/plugins/azureVideoTranslatePlugin.js +1 -1
- package/server/plugins/claude3VertexPlugin.js +25 -15
- package/server/plugins/gemini15ChatPlugin.js +1 -1
- package/server/plugins/geminiChatPlugin.js +1 -1
- package/server/plugins/modelPlugin.js +10 -1
- package/server/plugins/openAiChatPlugin.js +4 -3
- package/server/plugins/openAiDallE3Plugin.js +12 -4
- package/server/plugins/openAiVisionPlugin.js +1 -2
- package/server/plugins/replicateApiPlugin.js +75 -17
- package/tests/multimodal_conversion.test.js +6 -8
- package/helper-apps/cortex-autogen/myautogen.py +0 -317
- package/helper-apps/cortex-autogen/prompt.txt +0 -0
- package/helper-apps/cortex-autogen/prompt_summary.txt +0 -37
- package/pathways/index.js +0 -154
- /package/pathways/{sys_openai_completion.js → system/rest_streaming/sys_openai_completion.js} +0 -0
|
@@ -9,6 +9,7 @@ import { config } from '../../config.js';
|
|
|
9
9
|
const DEFAULT_MAX_TOKENS = 4096;
|
|
10
10
|
const DEFAULT_MAX_RETURN_TOKENS = 256;
|
|
11
11
|
const DEFAULT_PROMPT_TOKEN_RATIO = 0.5;
|
|
12
|
+
const DEFAULT_MAX_IMAGE_SIZE = 20 * 1024 * 1024; // 20MB default
|
|
12
13
|
|
|
13
14
|
class ModelPlugin {
|
|
14
15
|
constructor(pathway, model) {
|
|
@@ -249,7 +250,12 @@ class ModelPlugin {
|
|
|
249
250
|
let length = 0;
|
|
250
251
|
let units = isProd ? 'characters' : 'tokens';
|
|
251
252
|
if (data) {
|
|
252
|
-
|
|
253
|
+
if (isProd || data.length > 5000) {
|
|
254
|
+
length = data.length;
|
|
255
|
+
units = 'characters';
|
|
256
|
+
} else {
|
|
257
|
+
length = encode(data).length;
|
|
258
|
+
}
|
|
253
259
|
}
|
|
254
260
|
return {length, units};
|
|
255
261
|
}
|
|
@@ -341,6 +347,9 @@ class ModelPlugin {
|
|
|
341
347
|
return requestProgress;
|
|
342
348
|
}
|
|
343
349
|
|
|
350
|
+
getModelMaxImageSize() {
|
|
351
|
+
return (this.promptParameters.maxImageSize ?? this.model.maxImageSize ?? DEFAULT_MAX_IMAGE_SIZE);
|
|
352
|
+
}
|
|
344
353
|
|
|
345
354
|
}
|
|
346
355
|
|
|
@@ -115,9 +115,10 @@ class OpenAIChatPlugin extends ModelPlugin {
|
|
|
115
115
|
const content = message.content === undefined ? JSON.stringify(message) : (Array.isArray(message.content) ? message.content.map(item => JSON.stringify(item)).join(', ') : message.content);
|
|
116
116
|
const words = content.split(" ");
|
|
117
117
|
const { length, units } = this.getLength(content);
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
|
|
119
|
+
const displayContent = logger.level === 'debug' ? content : (words.length < 41 ? content : words.slice(0, 20).join(" ") + " ... " + words.slice(-20).join(" "));
|
|
120
|
+
|
|
121
|
+
logger.verbose(`message ${index + 1}: role: ${message.role}, ${units}: ${length}, content: "${displayContent}"`);
|
|
121
122
|
totalLength += length;
|
|
122
123
|
totalUnits = units;
|
|
123
124
|
});
|
|
@@ -52,14 +52,20 @@ class OpenAIDallE3Plugin extends ModelPlugin {
|
|
|
52
52
|
|
|
53
53
|
requestPromise
|
|
54
54
|
.then((response) => handleResponse(response))
|
|
55
|
-
.catch((error) => handleResponse(error));
|
|
55
|
+
.catch((error) => handleResponse(error, true));
|
|
56
56
|
|
|
57
|
-
function handleResponse(response) {
|
|
57
|
+
function handleResponse(response, isError = false) {
|
|
58
58
|
let status = "succeeded";
|
|
59
|
-
let data
|
|
60
|
-
|
|
59
|
+
let data;
|
|
60
|
+
|
|
61
|
+
if (isError) {
|
|
62
|
+
status = "failed";
|
|
63
|
+
data = JSON.stringify({ error: response.message || response });
|
|
64
|
+
} else if (response.data?.error) {
|
|
61
65
|
status = "failed";
|
|
62
66
|
data = JSON.stringify(response.data);
|
|
67
|
+
} else {
|
|
68
|
+
data = JSON.stringify(response);
|
|
63
69
|
}
|
|
64
70
|
|
|
65
71
|
const requestProgress = {
|
|
@@ -80,12 +86,14 @@ class OpenAIDallE3Plugin extends ModelPlugin {
|
|
|
80
86
|
let progress =
|
|
81
87
|
requestDurationEstimator.calculatePercentComplete(callid);
|
|
82
88
|
|
|
89
|
+
if (typeof progress === 'number' && !isNaN(progress) && progress >= 0 && progress <= 1) {
|
|
83
90
|
await publishRequestProgress({
|
|
84
91
|
requestId,
|
|
85
92
|
status: "pending",
|
|
86
93
|
progress,
|
|
87
94
|
data,
|
|
88
95
|
});
|
|
96
|
+
}
|
|
89
97
|
|
|
90
98
|
if (state.status !== "pending") {
|
|
91
99
|
break;
|
|
@@ -31,8 +31,7 @@ class OpenAIVisionPlugin extends OpenAIChatPlugin {
|
|
|
31
31
|
}
|
|
32
32
|
|
|
33
33
|
if (typeof parsedItem === 'object' && parsedItem !== null && parsedItem.type === 'image_url') {
|
|
34
|
-
parsedItem.image_url
|
|
35
|
-
return parsedItem;
|
|
34
|
+
return {type: parsedItem.type, image_url: {url: parsedItem.url || parsedItem.image_url.url}};
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
return parsedItem;
|
|
@@ -16,23 +16,81 @@ class ReplicateApiPlugin extends ModelPlugin {
|
|
|
16
16
|
prompt,
|
|
17
17
|
);
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
19
|
+
let requestParameters = {};
|
|
20
|
+
|
|
21
|
+
switch (combinedParameters.model) {
|
|
22
|
+
case "replicate-flux-11-pro":
|
|
23
|
+
requestParameters = {
|
|
24
|
+
input: {
|
|
25
|
+
aspect_ratio: combinedParameters.aspectRatio || "1:1",
|
|
26
|
+
output_format: combinedParameters.outputFormat || "webp",
|
|
27
|
+
output_quality: combinedParameters.outputQuality || 80,
|
|
28
|
+
prompt: modelPromptText,
|
|
29
|
+
prompt_upsampling: combinedParameters.promptUpsampling || false,
|
|
30
|
+
safety_tolerance: combinedParameters.safety_tolerance || 3,
|
|
31
|
+
go_fast: true,
|
|
32
|
+
megapixels: "1",
|
|
33
|
+
width: combinedParameters.width,
|
|
34
|
+
height: combinedParameters.height,
|
|
35
|
+
size: combinedParameters.size || "1024x1024",
|
|
36
|
+
style: combinedParameters.style || "realistic_image",
|
|
37
|
+
},
|
|
38
|
+
};
|
|
39
|
+
break;
|
|
40
|
+
case "replicate-recraft-v3": {
|
|
41
|
+
const validStyles = [
|
|
42
|
+
'any',
|
|
43
|
+
'realistic_image',
|
|
44
|
+
'digital_illustration',
|
|
45
|
+
'digital_illustration/pixel_art',
|
|
46
|
+
'digital_illustration/hand_drawn',
|
|
47
|
+
'digital_illustration/grain',
|
|
48
|
+
'digital_illustration/infantile_sketch',
|
|
49
|
+
'digital_illustration/2d_art_poster',
|
|
50
|
+
'digital_illustration/handmade_3d',
|
|
51
|
+
'digital_illustration/hand_drawn_outline',
|
|
52
|
+
'digital_illustration/engraving_color',
|
|
53
|
+
'digital_illustration/2d_art_poster_2',
|
|
54
|
+
'realistic_image/b_and_w',
|
|
55
|
+
'realistic_image/hard_flash',
|
|
56
|
+
'realistic_image/hdr',
|
|
57
|
+
'realistic_image/natural_light',
|
|
58
|
+
'realistic_image/studio_portrait',
|
|
59
|
+
'realistic_image/enterprise',
|
|
60
|
+
'realistic_image/motion_blur'
|
|
61
|
+
];
|
|
62
|
+
|
|
63
|
+
requestParameters = {
|
|
64
|
+
input: {
|
|
65
|
+
prompt: modelPromptText,
|
|
66
|
+
size: combinedParameters.size || "1024x1024",
|
|
67
|
+
style: validStyles.includes(combinedParameters.style) ? combinedParameters.style : "realistic_image",
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
case "replicate-flux-1-schnell": {
|
|
73
|
+
const validRatios = [
|
|
74
|
+
'1:1', '16:9', '21:9', '3:2', '2:3', '4:5',
|
|
75
|
+
'5:4', '3:4', '4:3', '9:16', '9:21'
|
|
76
|
+
];
|
|
77
|
+
|
|
78
|
+
requestParameters = {
|
|
79
|
+
input: {
|
|
80
|
+
aspect_ratio: validRatios.includes(combinedParameters.aspectRatio) ? combinedParameters.aspectRatio : "1:1",
|
|
81
|
+
output_format: combinedParameters.outputFormat || "webp",
|
|
82
|
+
output_quality: combinedParameters.outputQuality || 80,
|
|
83
|
+
prompt: modelPromptText,
|
|
84
|
+
go_fast: true,
|
|
85
|
+
megapixels: "1",
|
|
86
|
+
num_outputs: combinedParameters.numberResults,
|
|
87
|
+
num_inference_steps: combinedParameters.steps || 4,
|
|
88
|
+
disable_safety_checker: true,
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
break;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
36
94
|
|
|
37
95
|
return requestParameters;
|
|
38
96
|
}
|
|
@@ -112,11 +112,10 @@ test('Cortex special properties conversion', async (t) => {
|
|
|
112
112
|
]}
|
|
113
113
|
];
|
|
114
114
|
|
|
115
|
-
const
|
|
116
|
-
const { system: claudeSystem, modifiedMessages: claudeMessages } = await claude.convertMessagesToClaudeVertex(parsedOpenAI);
|
|
115
|
+
const { system: claudeSystem, modifiedMessages: claudeMessages } = await claude.convertMessagesToClaudeVertex(cortexMessages);
|
|
117
116
|
|
|
118
|
-
const { modifiedMessages: geminiMessages } = gemini.convertMessagesToGemini(
|
|
119
|
-
const { modifiedMessages: geminiMessages15, system: geminiSystem15 } = gemini15.convertMessagesToGemini(
|
|
117
|
+
const { modifiedMessages: geminiMessages } = gemini.convertMessagesToGemini(cortexMessages);
|
|
118
|
+
const { modifiedMessages: geminiMessages15, system: geminiSystem15 } = gemini15.convertMessagesToGemini(cortexMessages);
|
|
120
119
|
|
|
121
120
|
// Check Claude conversion
|
|
122
121
|
t.true(claudeMessages[0].content[1].source.data.startsWith('/9j/4AAQ'));
|
|
@@ -142,10 +141,9 @@ test('Mixed content types conversion', async (t) => {
|
|
|
142
141
|
]}
|
|
143
142
|
];
|
|
144
143
|
|
|
145
|
-
const
|
|
146
|
-
const {
|
|
147
|
-
const { modifiedMessages } =
|
|
148
|
-
const { modifiedMessages: modifiedMessages15, system: system15 } = gemini15.convertMessagesToGemini(parsedOpenAI);
|
|
144
|
+
const { system: claudeSystem, modifiedMessages: claudeMessages } = await claude.convertMessagesToClaudeVertex(mixedMessages);
|
|
145
|
+
const { modifiedMessages } = gemini.convertMessagesToGemini(mixedMessages);
|
|
146
|
+
const { modifiedMessages: modifiedMessages15, system: system15 } = gemini15.convertMessagesToGemini(mixedMessages);
|
|
149
147
|
|
|
150
148
|
// Check Claude conversion
|
|
151
149
|
t.is(claudeMessages.length, 3);
|
|
@@ -1,317 +0,0 @@
|
|
|
1
|
-
import azure.functions as func
|
|
2
|
-
import logging
|
|
3
|
-
import json
|
|
4
|
-
import autogen
|
|
5
|
-
from autogen import AssistantAgent, UserProxyAgent, config_list_from_json, register_function
|
|
6
|
-
from azure.storage.queue import QueueClient
|
|
7
|
-
import os
|
|
8
|
-
import tempfile
|
|
9
|
-
import redis
|
|
10
|
-
from dotenv import load_dotenv
|
|
11
|
-
import requests
|
|
12
|
-
import pathlib
|
|
13
|
-
import pymongo
|
|
14
|
-
import logging
|
|
15
|
-
from datetime import datetime, timezone, timedelta
|
|
16
|
-
import shutil
|
|
17
|
-
import time
|
|
18
|
-
import base64
|
|
19
|
-
import zipfile
|
|
20
|
-
from azure.storage.blob import BlobServiceClient, generate_blob_sas, BlobSasPermissions
|
|
21
|
-
|
|
22
|
-
load_dotenv()
|
|
23
|
-
|
|
24
|
-
connection_string = os.environ["AZURE_STORAGE_CONNECTION_STRING"]
|
|
25
|
-
human_input_queue_name = os.environ.get("HUMAN_INPUT_QUEUE_NAME", "autogen-human-input-queue")
|
|
26
|
-
human_input_queue_client = QueueClient.from_connection_string(connection_string, human_input_queue_name)
|
|
27
|
-
|
|
28
|
-
def check_for_human_input(request_id):
|
|
29
|
-
messages = human_input_queue_client.receive_messages()
|
|
30
|
-
for message in messages:
|
|
31
|
-
content = json.loads(base64.b64decode(message.content).decode('utf-8'))
|
|
32
|
-
if content['codeRequestId'] == request_id:
|
|
33
|
-
human_input_queue_client.delete_message(message)
|
|
34
|
-
return content['text']
|
|
35
|
-
return None
|
|
36
|
-
|
|
37
|
-
DEFAULT_SUMMARY_PROMPT = "Summarize the takeaway from the conversation. Do not add any introductory phrases."
|
|
38
|
-
try:
|
|
39
|
-
with open("prompt_summary.txt", "r") as file:
|
|
40
|
-
summary_prompt = file.read() or DEFAULT_SUMMARY_PROMPT
|
|
41
|
-
except FileNotFoundError:
|
|
42
|
-
summary_prompt = DEFAULT_SUMMARY_PROMPT
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
def store_in_mongo(data):
|
|
46
|
-
try:
|
|
47
|
-
if 'MONGO_URI' in os.environ:
|
|
48
|
-
client = pymongo.MongoClient(os.environ['MONGO_URI'])
|
|
49
|
-
collection = client.get_default_database()[os.environ.get('MONGO_COLLECTION_NAME', 'autogenruns')]
|
|
50
|
-
collection.insert_one(data)
|
|
51
|
-
else:
|
|
52
|
-
logging.warning("MONGO_URI not found in environment variables")
|
|
53
|
-
except Exception as e:
|
|
54
|
-
logging.error(f"An error occurred while storing data in MongoDB: {str(e)}")
|
|
55
|
-
|
|
56
|
-
redis_client = redis.from_url(os.environ['REDIS_CONNECTION_STRING'])
|
|
57
|
-
channel = 'requestProgress'
|
|
58
|
-
|
|
59
|
-
def connect_redis():
|
|
60
|
-
if not redis_client.ping():
|
|
61
|
-
try:
|
|
62
|
-
redis_client.ping()
|
|
63
|
-
except redis.ConnectionError as e:
|
|
64
|
-
logging.error(f"Error reconnecting to Redis: {e}")
|
|
65
|
-
return False
|
|
66
|
-
return True
|
|
67
|
-
|
|
68
|
-
def publish_request_progress(data):
|
|
69
|
-
if connect_redis():
|
|
70
|
-
try:
|
|
71
|
-
message = json.dumps(data)
|
|
72
|
-
#logging.info(f"Publishing message {message} to channel {channel}")
|
|
73
|
-
redis_client.publish(channel, message)
|
|
74
|
-
except Exception as e:
|
|
75
|
-
logging.error(f"Error publishing message: {e}")
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def get_given_system_message():
|
|
79
|
-
env_context = os.environ.get("ENV_SYSTEM_MESSAGE_CONTEXT")
|
|
80
|
-
|
|
81
|
-
if not env_context:
|
|
82
|
-
return read_local_file("prompt.txt")
|
|
83
|
-
|
|
84
|
-
if env_context.startswith(("http://", "https://")):
|
|
85
|
-
return fetch_from_url(env_context)
|
|
86
|
-
|
|
87
|
-
if pathlib.Path(env_context).suffix:
|
|
88
|
-
return read_local_file(env_context)
|
|
89
|
-
|
|
90
|
-
return env_context
|
|
91
|
-
|
|
92
|
-
def read_local_file(filename):
|
|
93
|
-
try:
|
|
94
|
-
with open(filename, "r") as file:
|
|
95
|
-
return file.read()
|
|
96
|
-
except FileNotFoundError:
|
|
97
|
-
logging.error(f"{filename} not found")
|
|
98
|
-
return ""
|
|
99
|
-
|
|
100
|
-
def fetch_from_url(url):
|
|
101
|
-
try:
|
|
102
|
-
response = requests.get(url)
|
|
103
|
-
response.raise_for_status()
|
|
104
|
-
return response.text
|
|
105
|
-
except requests.RequestException as e:
|
|
106
|
-
logging.error(f"Error fetching from URL: {e}")
|
|
107
|
-
return ""
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
def zip_and_upload_tmp_folder(temp_dir):
|
|
111
|
-
zip_path = os.path.join(temp_dir, "tmp_contents.zip")
|
|
112
|
-
with zipfile.ZipFile(zip_path, 'w', zipfile.ZIP_DEFLATED) as zipf:
|
|
113
|
-
for root, _, files in os.walk(temp_dir):
|
|
114
|
-
for file in files:
|
|
115
|
-
file_path = os.path.join(root, file)
|
|
116
|
-
arcname = os.path.relpath(file_path, temp_dir)
|
|
117
|
-
zipf.write(file_path, arcname)
|
|
118
|
-
|
|
119
|
-
blob_service_client = BlobServiceClient.from_connection_string(os.environ["AZURE_STORAGE_CONNECTION_STRING"])
|
|
120
|
-
container_name = os.environ.get("AZURE_BLOB_CONTAINER", "autogen-uploads")
|
|
121
|
-
blob_name = f"tmp_contents_{datetime.now(timezone.utc).strftime('%Y%m%d%H%M%S')}.zip"
|
|
122
|
-
blob_client = blob_service_client.get_blob_client(container=container_name, blob=blob_name)
|
|
123
|
-
|
|
124
|
-
with open(zip_path, "rb") as data:
|
|
125
|
-
blob_client.upload_blob(data)
|
|
126
|
-
|
|
127
|
-
account_key = blob_service_client.credential.account_key
|
|
128
|
-
account_name = blob_service_client.account_name
|
|
129
|
-
expiry = datetime.now(timezone.utc) + timedelta(hours=1)
|
|
130
|
-
|
|
131
|
-
sas_token = generate_blob_sas(
|
|
132
|
-
account_name,
|
|
133
|
-
container_name,
|
|
134
|
-
blob_name,
|
|
135
|
-
account_key=account_key,
|
|
136
|
-
permission=BlobSasPermissions(read=True),
|
|
137
|
-
expiry=expiry
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
return f"{blob_client.url}?{sas_token}"
|
|
141
|
-
|
|
142
|
-
def process_message(message_data, original_request_message):
|
|
143
|
-
# logging.info(f"Processing Message: {message_data}")
|
|
144
|
-
try:
|
|
145
|
-
started_at = datetime.now()
|
|
146
|
-
message = message_data['message']
|
|
147
|
-
request_id = message_data.get('requestId') or msg.id
|
|
148
|
-
|
|
149
|
-
config_list = config_list_from_json(env_or_file="OAI_CONFIG_LIST")
|
|
150
|
-
base_url = os.environ.get("CORTEX_API_BASE_URL")
|
|
151
|
-
api_key = os.environ.get("CORTEX_API_KEY")
|
|
152
|
-
llm_config = {"config_list": config_list, "base_url": base_url, "api_key": api_key, "cache_seed": None, "timeout": 600}
|
|
153
|
-
|
|
154
|
-
with tempfile.TemporaryDirectory() as temp_dir:
|
|
155
|
-
#copy /tools directory to temp_dir
|
|
156
|
-
shutil.copytree(os.path.join(os.getcwd(), "tools"), temp_dir, dirs_exist_ok=True)
|
|
157
|
-
|
|
158
|
-
code_executor = autogen.coding.LocalCommandLineCodeExecutor(work_dir=temp_dir)
|
|
159
|
-
|
|
160
|
-
message_count = 0
|
|
161
|
-
total_messages = 20 * 2
|
|
162
|
-
all_messages = []
|
|
163
|
-
|
|
164
|
-
terminate_count = 0
|
|
165
|
-
def is_termination_msg(m):
|
|
166
|
-
nonlocal terminate_count
|
|
167
|
-
content = m.get("content", "").strip()
|
|
168
|
-
if not content:
|
|
169
|
-
return False
|
|
170
|
-
if content.rstrip().endswith("TERMINATE"):
|
|
171
|
-
terminate_count += 1
|
|
172
|
-
return terminate_count >= 3 or "first message must use the" in content.lower()
|
|
173
|
-
|
|
174
|
-
system_message_given = get_given_system_message()
|
|
175
|
-
system_message_assistant = AssistantAgent.DEFAULT_SYSTEM_MESSAGE
|
|
176
|
-
|
|
177
|
-
if system_message_given:
|
|
178
|
-
system_message_assistant = system_message_given
|
|
179
|
-
else:
|
|
180
|
-
print("No extra system message given for assistant")
|
|
181
|
-
|
|
182
|
-
assistant = AssistantAgent("assistant",
|
|
183
|
-
llm_config=llm_config,
|
|
184
|
-
system_message=system_message_assistant,
|
|
185
|
-
# code_execution_config={"executor": code_executor},
|
|
186
|
-
is_termination_msg=is_termination_msg,
|
|
187
|
-
)
|
|
188
|
-
|
|
189
|
-
user_proxy = UserProxyAgent(
|
|
190
|
-
"user_proxy",
|
|
191
|
-
# llm_config=llm_config,
|
|
192
|
-
system_message=system_message_given,
|
|
193
|
-
code_execution_config={"executor": code_executor},
|
|
194
|
-
human_input_mode="NEVER",
|
|
195
|
-
max_consecutive_auto_reply=20,
|
|
196
|
-
is_termination_msg=is_termination_msg,
|
|
197
|
-
)
|
|
198
|
-
|
|
199
|
-
# description = "Upload a file to Azure Blob Storage and get URL back with a SAS token. Requires AZURE_STORAGE_CONNECTION_STRING and AZURE_BLOB_CONTAINER environment variables. Input: file_path (str). Output: SAS URL (str) or error message."
|
|
200
|
-
|
|
201
|
-
# register_function(
|
|
202
|
-
# autogen_sas_uploader,
|
|
203
|
-
# caller=assistant,
|
|
204
|
-
# executor=user_proxy,
|
|
205
|
-
# name="autogen_sas_uploader",
|
|
206
|
-
# description=description,
|
|
207
|
-
# )
|
|
208
|
-
|
|
209
|
-
# register_function(
|
|
210
|
-
# autogen_sas_uploader,
|
|
211
|
-
# caller=user_proxy,
|
|
212
|
-
# executor=assistant,
|
|
213
|
-
# name="autogen_sas_uploader",
|
|
214
|
-
# description=description,
|
|
215
|
-
# )
|
|
216
|
-
|
|
217
|
-
original_assistant_send = assistant.send
|
|
218
|
-
original_user_proxy_send = user_proxy.send
|
|
219
|
-
|
|
220
|
-
def logged_send(sender, original_send, message, recipient, request_reply=None, silent=True):
|
|
221
|
-
nonlocal message_count, all_messages
|
|
222
|
-
if not message:
|
|
223
|
-
return
|
|
224
|
-
|
|
225
|
-
if True or sender.name == "user_proxy":
|
|
226
|
-
human_input = check_for_human_input(request_id)
|
|
227
|
-
if human_input:
|
|
228
|
-
if human_input == "TERMINATE":
|
|
229
|
-
logging.info("Terminating conversation")
|
|
230
|
-
raise Exception("Conversation terminated by user")
|
|
231
|
-
elif human_input == "PAUSE":
|
|
232
|
-
logging.info("Pausing conversation")
|
|
233
|
-
pause_start = time.time()
|
|
234
|
-
while time.time() - pause_start < 60*15: # 15 minutes pause timeout
|
|
235
|
-
time.sleep(10)
|
|
236
|
-
new_input = check_for_human_input(request_id)
|
|
237
|
-
if new_input:
|
|
238
|
-
logging.info(f"Resuming conversation with human input: {new_input}")
|
|
239
|
-
return logged_send(sender, original_send, new_input, recipient, request_reply, silent)
|
|
240
|
-
logging.info("Pause timeout, ending conversation")
|
|
241
|
-
raise Exception("Conversation ended due to pause timeout")
|
|
242
|
-
logging.info(f"Human input to {recipient.name}: {human_input}")
|
|
243
|
-
return original_send(human_input, recipient, request_reply, silent)
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
logging.info(f"Message from {sender.name} to {recipient.name}: {message}")
|
|
247
|
-
|
|
248
|
-
message_count += 1
|
|
249
|
-
progress = min(message_count / total_messages, 1)
|
|
250
|
-
all_messages.append({"sender": sender.name, "message": message})
|
|
251
|
-
|
|
252
|
-
# if sender.name == "assistant":
|
|
253
|
-
publish_request_progress({
|
|
254
|
-
"requestId": request_id,
|
|
255
|
-
"progress": progress,
|
|
256
|
-
"info": message
|
|
257
|
-
})
|
|
258
|
-
return original_send(message, recipient, request_reply, silent)
|
|
259
|
-
|
|
260
|
-
assistant.send = lambda message, recipient, request_reply=None, silent=False: logged_send(assistant, original_assistant_send, message, recipient, request_reply, silent)
|
|
261
|
-
user_proxy.send = lambda message, recipient, request_reply=None, silent=False: logged_send(user_proxy, original_user_proxy_send, message, recipient, request_reply, silent)
|
|
262
|
-
|
|
263
|
-
#summary_method="reflection_with_llm", "last_msg"
|
|
264
|
-
chat_result = user_proxy.initiate_chat(assistant, message=message, summary_method="reflection_with_llm", summary_args={"summary_role": "user", "summary_prompt": summary_prompt})
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
zip_url = zip_and_upload_tmp_folder(temp_dir)
|
|
268
|
-
|
|
269
|
-
msg = ""
|
|
270
|
-
try:
|
|
271
|
-
msg = all_messages[-1 if all_messages[-2]["message"] else -3]["message"]
|
|
272
|
-
logging.info(f"####Final message: {msg}")
|
|
273
|
-
except Exception as e:
|
|
274
|
-
logging.error(f"Error getting final message: {e}")
|
|
275
|
-
msg = f"Finished, with errors 🤖 ... {e}"
|
|
276
|
-
|
|
277
|
-
msg = chat_result.summary if chat_result.summary else msg
|
|
278
|
-
msg += f"\n\n[Download all files of this task]({zip_url})"
|
|
279
|
-
|
|
280
|
-
finalData = {
|
|
281
|
-
"requestId": request_id,
|
|
282
|
-
"requestMessage": message_data.get("message"),
|
|
283
|
-
"progress": 1,
|
|
284
|
-
"data": msg,
|
|
285
|
-
"contextId": message_data.get("contextId"),
|
|
286
|
-
"conversation": all_messages,
|
|
287
|
-
"createdAt": datetime.now(timezone.utc).isoformat(),
|
|
288
|
-
"insertionTime": original_request_message.insertion_time.astimezone(timezone.utc).isoformat() if original_request_message else None,
|
|
289
|
-
"startedAt": started_at.astimezone(timezone.utc).isoformat(),
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
# Final message to indicate completion
|
|
293
|
-
publish_request_progress(finalData)
|
|
294
|
-
store_in_mongo(finalData)
|
|
295
|
-
|
|
296
|
-
except Exception as e:
|
|
297
|
-
logging.error(f"Error processing message: {str(e)}")
|
|
298
|
-
if request_id:
|
|
299
|
-
publish_request_progress({
|
|
300
|
-
"requestId": request_id,
|
|
301
|
-
"progress": 1,
|
|
302
|
-
"error": str(e),
|
|
303
|
-
"data": str(e),
|
|
304
|
-
})
|
|
305
|
-
store_in_mongo({
|
|
306
|
-
"requestId": request_id,
|
|
307
|
-
"requestMessage": message_data.get("message"),
|
|
308
|
-
"progress": 1,
|
|
309
|
-
"error": str(e),
|
|
310
|
-
"data": str(e),
|
|
311
|
-
"contextId": message_data.get("contextId"),
|
|
312
|
-
"conversation": all_messages,
|
|
313
|
-
"createdAt": datetime.now(timezone.utc).isoformat(),
|
|
314
|
-
"insertionTime": original_request_message.insertion_time.astimezone(timezone.utc).isoformat() if original_request_message else None,
|
|
315
|
-
"startedAt": started_at.astimezone(timezone.utc).isoformat(),
|
|
316
|
-
})
|
|
317
|
-
|
|
File without changes
|
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
Provide a detailed summary of the conversation, including key points, decisions, and action items, and so on.
|
|
2
|
-
Do not add any introductory phrases.
|
|
3
|
-
Avoid expressing gratitude or using pleasantries.
|
|
4
|
-
Maintain a professional and direct tone throughout responses.
|
|
5
|
-
Include most recent meaningful messages from the conversation in the summary.
|
|
6
|
-
You must include all your uploaded URLs, and url of your uploaded final code URL.
|
|
7
|
-
Your reply will be only thing that finally gets to surface so make sure it is complete.
|
|
8
|
-
Do not mention words like "Summary of the conversation", "Response", "Task", "The conversation" or so as it doesn't makes sense.
|
|
9
|
-
Also no need for "Request", user already know its request and task.
|
|
10
|
-
Be as detailed as possible without being annoying.
|
|
11
|
-
Start with the result as that is the most important part, do not mention "Result" as user already know its result.
|
|
12
|
-
No need to say information about generated SAS urls just include them, only include the latest versions of same file.
|
|
13
|
-
No need to say none of this as user already 'll be aware as has got the result:
|
|
14
|
-
- Code executed successfully, producing correct result ...
|
|
15
|
-
- File uploaded to Azure Blob Storage with unique timestamp ...
|
|
16
|
-
- SAS URL generated for file access, valid for ...
|
|
17
|
-
- File accessibility verified ...
|
|
18
|
-
- Code execution details ...
|
|
19
|
-
- Current date and time ...
|
|
20
|
-
- Script executed twice due to debugging environment ...
|
|
21
|
-
- Verification code ...
|
|
22
|
-
- Issues encountered and resolved: ...
|
|
23
|
-
- The original plan ...
|
|
24
|
-
- Performed at ...
|
|
25
|
-
|
|
26
|
-
No need to mention about code files uploaded to Azure Blob or point URLs as SAS-URLS as its a task that you already do and is known.
|
|
27
|
-
No need to mention SAS URL, just give the url itself.
|
|
28
|
-
Never include TERMINATE in your response.
|
|
29
|
-
|
|
30
|
-
When formulating your responses, it's crucial to leverage the full capabilities of markdown formatting to create rich, visually appealing content. This approach not only enhances the user experience but also allows for more effective communication of complex ideas. Follow these guidelines to ensure your responses are both informative and visually engaging, create responses that are not only informative but also visually appealing and easy to comprehend:
|
|
31
|
-
- For images:  and <img src="IMAGE_URL" alt="Alt Text">
|
|
32
|
-
- For videos: <video src="VIDEO_URL" controls></video>
|
|
33
|
-
- For urls: [Link Text](URL)
|
|
34
|
-
If there an image url, you must always include it as url and markdown e.g.:  and [Alt Text](IMAGE_URL)
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
Make sure to present it nicely so human finds it appealing.
|