@aj-archipelago/cortex 1.3.4 → 1.3.6
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/helper-apps/cortex-autogen/agents.py +90 -20
- package/helper-apps/cortex-realtime-voice-server/.env.sample +6 -0
- package/helper-apps/cortex-realtime-voice-server/README.md +22 -0
- package/helper-apps/cortex-realtime-voice-server/bun.lockb +0 -0
- package/helper-apps/cortex-realtime-voice-server/client/bun.lockb +0 -0
- package/helper-apps/cortex-realtime-voice-server/client/index.html +12 -0
- package/helper-apps/cortex-realtime-voice-server/client/package.json +65 -0
- package/helper-apps/cortex-realtime-voice-server/client/postcss.config.js +6 -0
- package/helper-apps/cortex-realtime-voice-server/client/public/favicon.ico +0 -0
- package/helper-apps/cortex-realtime-voice-server/client/public/index.html +43 -0
- package/helper-apps/cortex-realtime-voice-server/client/public/logo192.png +0 -0
- package/helper-apps/cortex-realtime-voice-server/client/public/logo512.png +0 -0
- package/helper-apps/cortex-realtime-voice-server/client/public/manifest.json +25 -0
- package/helper-apps/cortex-realtime-voice-server/client/public/robots.txt +3 -0
- package/helper-apps/cortex-realtime-voice-server/client/public/sounds/connect.mp3 +0 -0
- package/helper-apps/cortex-realtime-voice-server/client/public/sounds/disconnect.mp3 +0 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/App.test.tsx +9 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/App.tsx +126 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/SettingsModal.tsx +207 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/Chat.tsx +553 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/ChatBubble.tsx +22 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/ChatBubbleLeft.tsx +22 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/ChatBubbleRight.tsx +21 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/ChatMessage.tsx +27 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/ChatMessageInput.tsx +74 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/ChatTile.tsx +211 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/audio/SoundEffects.ts +56 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/audio/WavPacker.ts +112 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/audio/WavRecorder.ts +571 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/audio/WavStreamPlayer.ts +290 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/audio/analysis/AudioAnalysis.ts +186 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/audio/analysis/constants.ts +59 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/audio/worklets/AudioProcessor.ts +214 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/audio/worklets/StreamProcessor.ts +183 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/components/AudioVisualizer.tsx +151 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/components/CopyButton.tsx +32 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/components/ImageOverlay.tsx +166 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/components/MicrophoneVisualizer.tsx +95 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/components/ScreenshotCapture.tsx +116 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/hooks/useWindowResize.ts +27 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/chat/utils/audio.ts +33 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/index.css +20 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/index.tsx +19 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/logo.svg +1 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/react-app-env.d.ts +1 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/reportWebVitals.ts +15 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/setupTests.ts +5 -0
- package/helper-apps/cortex-realtime-voice-server/client/src/utils/logger.ts +45 -0
- package/helper-apps/cortex-realtime-voice-server/client/tailwind.config.js +14 -0
- package/helper-apps/cortex-realtime-voice-server/client/tsconfig.json +30 -0
- package/helper-apps/cortex-realtime-voice-server/client/vite.config.ts +22 -0
- package/helper-apps/cortex-realtime-voice-server/index.ts +19 -0
- package/helper-apps/cortex-realtime-voice-server/package.json +28 -0
- package/helper-apps/cortex-realtime-voice-server/src/ApiServer.ts +35 -0
- package/helper-apps/cortex-realtime-voice-server/src/SocketServer.ts +769 -0
- package/helper-apps/cortex-realtime-voice-server/src/Tools.ts +546 -0
- package/helper-apps/cortex-realtime-voice-server/src/cortex/expert.ts +29 -0
- package/helper-apps/cortex-realtime-voice-server/src/cortex/image.ts +29 -0
- package/helper-apps/cortex-realtime-voice-server/src/cortex/memory.ts +89 -0
- package/helper-apps/cortex-realtime-voice-server/src/cortex/reason.ts +29 -0
- package/helper-apps/cortex-realtime-voice-server/src/cortex/search.ts +30 -0
- package/helper-apps/cortex-realtime-voice-server/src/cortex/style.ts +31 -0
- package/helper-apps/cortex-realtime-voice-server/src/cortex/utils.ts +94 -0
- package/helper-apps/cortex-realtime-voice-server/src/cortex/vision.ts +34 -0
- package/helper-apps/cortex-realtime-voice-server/src/realtime/client.ts +484 -0
- package/helper-apps/cortex-realtime-voice-server/src/realtime/realtimeTypes.ts +279 -0
- package/helper-apps/cortex-realtime-voice-server/src/realtime/socket.ts +27 -0
- package/helper-apps/cortex-realtime-voice-server/src/realtime/transcription.ts +75 -0
- package/helper-apps/cortex-realtime-voice-server/src/realtime/utils.ts +33 -0
- package/helper-apps/cortex-realtime-voice-server/src/utils/logger.ts +45 -0
- package/helper-apps/cortex-realtime-voice-server/src/utils/prompt.ts +81 -0
- package/helper-apps/cortex-realtime-voice-server/tsconfig.json +28 -0
- package/package.json +1 -1
- package/pathways/basePathway.js +3 -1
- package/pathways/system/entity/memory/sys_memory_manager.js +3 -0
- package/pathways/system/entity/memory/sys_memory_update.js +43 -45
- package/pathways/system/entity/memory/sys_read_memory.js +86 -6
- package/pathways/system/entity/memory/sys_search_memory.js +66 -0
- package/pathways/system/entity/shared/sys_entity_constants.js +1 -1
- package/pathways/system/entity/sys_entity_continue.js +2 -1
- package/pathways/system/entity/sys_entity_start.js +13 -2
- package/pathways/system/entity/sys_generator_ack.js +2 -2
- package/pathways/system/entity/sys_generator_expert.js +0 -2
- package/pathways/system/entity/sys_generator_memory.js +31 -0
- package/pathways/system/entity/sys_generator_quick.js +22 -7
- package/pathways/system/entity/sys_generator_reasoning.js +1 -1
- package/pathways/system/entity/sys_generator_results.js +20 -16
- package/pathways/system/entity/sys_generator_voice_filler.js +1 -1
- package/pathways/system/entity/sys_generator_voice_sample.js +36 -0
- package/pathways/system/entity/sys_router_tool.js +13 -10
- package/pathways/system/sys_parse_numbered_object_list.js +1 -1
- package/server/pathwayResolver.js +41 -31
- package/server/plugins/azureVideoTranslatePlugin.js +28 -16
- package/server/plugins/claude3VertexPlugin.js +0 -9
- package/server/plugins/gemini15ChatPlugin.js +18 -5
- package/server/plugins/modelPlugin.js +27 -6
- package/server/plugins/openAiChatPlugin.js +10 -8
- package/server/plugins/openAiVisionPlugin.js +56 -0
- package/tests/memoryfunction.test.js +73 -1
|
@@ -19,6 +19,8 @@ import threading
|
|
|
19
19
|
import shutil
|
|
20
20
|
|
|
21
21
|
human_input_queues = {}
|
|
22
|
+
human_input_text_queues = {}
|
|
23
|
+
request_stored_message_queues = {}
|
|
22
24
|
def background_human_input_check(request_id):
|
|
23
25
|
while True:
|
|
24
26
|
human_input = check_for_human_input(request_id)
|
|
@@ -26,8 +28,20 @@ def background_human_input_check(request_id):
|
|
|
26
28
|
human_input_queues[request_id].put(human_input)
|
|
27
29
|
if human_input in ["TERMINATE", "PAUSE"]:
|
|
28
30
|
break
|
|
31
|
+
else:
|
|
32
|
+
if not human_input_text_queues.get(request_id):
|
|
33
|
+
human_input_text_queues[request_id] = queue.Queue()
|
|
34
|
+
human_input_text_queues[request_id].put(human_input)
|
|
29
35
|
time.sleep(1)
|
|
30
36
|
|
|
37
|
+
|
|
38
|
+
def get_message_with_user_input(message, request_id):
|
|
39
|
+
human_input_text = ""
|
|
40
|
+
if human_input_text_queues.get(request_id):
|
|
41
|
+
while not human_input_text_queues[request_id].empty():
|
|
42
|
+
human_input_text += " " + human_input_text_queues[request_id].get()
|
|
43
|
+
return message + human_input_text
|
|
44
|
+
|
|
31
45
|
def get_request_temp_dir(request_id):
|
|
32
46
|
if not request_id:
|
|
33
47
|
logging.warning("No request_id provided!")
|
|
@@ -100,6 +114,7 @@ def chat_with_agents(**kwargs):
|
|
|
100
114
|
original_request_message = kwargs.pop("original_request_message", None)
|
|
101
115
|
original_request_message_data = kwargs.pop("original_request_message_data", None)
|
|
102
116
|
|
|
117
|
+
|
|
103
118
|
llm_config = kwargs.pop("llm_config", None)
|
|
104
119
|
request_id = kwargs.pop("request_id", None)
|
|
105
120
|
chat_publish_progress = kwargs.pop("chat_publish_progress", None)
|
|
@@ -137,13 +152,14 @@ def chat_with_agents(**kwargs):
|
|
|
137
152
|
assistant.send = create_send_function(assistant)
|
|
138
153
|
user_proxy.send = create_send_function(user_proxy)
|
|
139
154
|
|
|
155
|
+
message_with_possible_human_input = get_message_with_user_input(message, request_id)
|
|
156
|
+
|
|
140
157
|
chat_result = user_proxy.initiate_chat(
|
|
141
158
|
assistant,
|
|
142
|
-
message=
|
|
159
|
+
message=message_with_possible_human_input,
|
|
143
160
|
)
|
|
144
161
|
|
|
145
162
|
|
|
146
|
-
|
|
147
163
|
code_msg = find_code_message(all_messages)
|
|
148
164
|
if code_msg:
|
|
149
165
|
try:
|
|
@@ -155,12 +171,20 @@ def chat_with_agents(**kwargs):
|
|
|
155
171
|
index_message({
|
|
156
172
|
"requestId": request_id,
|
|
157
173
|
"content":corrector_result, #code_msg,
|
|
158
|
-
"task": original_request_message,
|
|
174
|
+
"task": get_message_with_user_input(original_request_message,request_id),
|
|
159
175
|
"contextId": original_request_message_data.get("contextId"),
|
|
160
176
|
})
|
|
161
177
|
except Exception as e:
|
|
162
178
|
logging.error(f"Error extracting code corrector result: {e}")
|
|
163
179
|
|
|
180
|
+
try:
|
|
181
|
+
request_stored_message_queues[request_id].put(all_messages[-2]["message"] or all_messages[-2]["content"])
|
|
182
|
+
request_stored_message_queues[request_id].put(all_messages[-1]["message"] or all_messages[-1]["content"])
|
|
183
|
+
except Exception as e:
|
|
184
|
+
logging.error(f"Error storing messages in queue: {e}")
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
|
|
164
188
|
if return_type == "chat_history":
|
|
165
189
|
return chat_result.chat_history
|
|
166
190
|
if return_type == "chat_result":
|
|
@@ -175,7 +199,6 @@ def chat_with_agents(**kwargs):
|
|
|
175
199
|
return chat_result
|
|
176
200
|
|
|
177
201
|
|
|
178
|
-
|
|
179
202
|
def logged_send(sender, original_send, message, recipient, request_reply=None, silent=True, request_id=None, chat_publish_progress=None, all_messages=None):
|
|
180
203
|
if not message:
|
|
181
204
|
logging.info("Empty message, skipping!")
|
|
@@ -214,15 +237,19 @@ def logged_send(sender, original_send, message, recipient, request_reply=None, s
|
|
|
214
237
|
return logged_send(sender, original_send, new_input, recipient, request_reply, silent)
|
|
215
238
|
logging.info("Pause timeout, ending conversation")
|
|
216
239
|
raise Exception("Conversation ended due to pause timeout")
|
|
240
|
+
|
|
241
|
+
#if not terminate or pause, then it's text input from human
|
|
217
242
|
logging.info(f"Human input to {recipient.name}: {human_input}")
|
|
218
|
-
|
|
243
|
+
#need to update original message with human input
|
|
244
|
+
new_input = message + human_input
|
|
245
|
+
return original_send(new_input, recipient, request_reply, silent)
|
|
219
246
|
|
|
220
247
|
logging.info(f"Message from {sender.name} to {recipient.name}: {message}")
|
|
221
248
|
|
|
222
249
|
return original_send(message, recipient, request_reply, silent)
|
|
223
250
|
|
|
224
251
|
|
|
225
|
-
def process_message(original_request_message_data, original_request_message_data_obj):
|
|
252
|
+
def process_message(original_request_message_data, original_request_message_data_obj, first_run=True):
|
|
226
253
|
try:
|
|
227
254
|
all_messages = []
|
|
228
255
|
started_at = datetime.now()
|
|
@@ -230,9 +257,15 @@ def process_message(original_request_message_data, original_request_message_data
|
|
|
230
257
|
original_request_message = original_request_message_data['message']
|
|
231
258
|
|
|
232
259
|
human_input_queues[request_id] = queue.Queue()
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
260
|
+
human_input_text_queues[request_id] = queue.Queue()
|
|
261
|
+
if not request_stored_message_queues.get(request_id):
|
|
262
|
+
request_stored_message_queues[request_id] = queue.Queue()
|
|
263
|
+
request_stored_message_queues[request_id].put(original_request_message)
|
|
264
|
+
|
|
265
|
+
if first_run:
|
|
266
|
+
thread = threading.Thread(target=background_human_input_check, args=(request_id,))
|
|
267
|
+
thread.daemon = True
|
|
268
|
+
thread.start()
|
|
236
269
|
|
|
237
270
|
final_msg = process_message_safe(original_request_message_data, original_request_message_data_obj, original_request_message, all_messages, request_id, started_at)
|
|
238
271
|
|
|
@@ -252,6 +285,44 @@ def process_message(original_request_message_data, original_request_message_data
|
|
|
252
285
|
publish_request_progress(finalData)
|
|
253
286
|
store_in_mongo(finalData)
|
|
254
287
|
|
|
288
|
+
#wait for any human input before terminating
|
|
289
|
+
#if you receive human input start the conversation again
|
|
290
|
+
for i in range(31*6): # 30+1 minutes
|
|
291
|
+
if human_input_queues[request_id].empty():
|
|
292
|
+
time.sleep(1)
|
|
293
|
+
else:
|
|
294
|
+
human_input = human_input_queues[request_id].get()
|
|
295
|
+
if human_input:
|
|
296
|
+
logging.info(f"Human input to assistant: {human_input}")
|
|
297
|
+
#update request with human input
|
|
298
|
+
new_message_data = original_request_message_data.copy()
|
|
299
|
+
|
|
300
|
+
old_task = original_request_message_data.get("message")
|
|
301
|
+
|
|
302
|
+
#get request_stored_message_queues
|
|
303
|
+
old_messages = []
|
|
304
|
+
if request_stored_message_queues.get(request_id):
|
|
305
|
+
while not request_stored_message_queues[request_id].empty():
|
|
306
|
+
old_messages.append(request_stored_message_queues[request_id].get())
|
|
307
|
+
|
|
308
|
+
|
|
309
|
+
#convert to text, limit to max 2000 characters, keep most recent
|
|
310
|
+
old_messages_text = "\n".join(old_messages)
|
|
311
|
+
old_messages_text = old_messages_text[-2000:]
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
new_message_data['message'] = f"NEW TASK: {human_input}\n\nPREV TASK: {old_task} STUFF DONE IN PREV TASK: {old_messages_text}\n\n{final_msg}\n\n"
|
|
315
|
+
new_message_data['keywords'] = ''
|
|
316
|
+
# new_message_data_obj = original_request_message_data_obj.copy()
|
|
317
|
+
# new_message_data_obj['message'] = new_message_data['message']
|
|
318
|
+
|
|
319
|
+
|
|
320
|
+
|
|
321
|
+
process_message(new_message_data, original_request_message_data_obj, first_run=False)
|
|
322
|
+
return
|
|
323
|
+
|
|
324
|
+
logging.info(f"Task completed, task:\n{get_message_with_user_input(original_request_message,request_id)},\nresult: {final_msg}")
|
|
325
|
+
|
|
255
326
|
|
|
256
327
|
except Exception as e:
|
|
257
328
|
logging.error(f"Error processing message: {str(e)}")
|
|
@@ -292,7 +363,6 @@ def process_message(original_request_message_data, original_request_message_data
|
|
|
292
363
|
logging.error(f"Error cleaning up: {str(e)}")
|
|
293
364
|
|
|
294
365
|
|
|
295
|
-
|
|
296
366
|
def process_message_safe(original_request_message_data, original_request_message_data_obj, original_request_message, all_messages, request_id, started_at):
|
|
297
367
|
config_list = config_list_from_json(env_or_file="OAI_CONFIG_LIST")
|
|
298
368
|
llm_config = {
|
|
@@ -342,10 +412,10 @@ def process_message_safe(original_request_message_data, original_request_message
|
|
|
342
412
|
|
|
343
413
|
|
|
344
414
|
preparer = AssistantAgent("preparer", llm_config=llm_config, system_message=prompts.get("PLANNER_SYSTEM_MESSAGE"))
|
|
345
|
-
prepared_plan = preparer.generate_reply(messages=[{"content": original_request_message, "role":"user"}])
|
|
415
|
+
prepared_plan = preparer.generate_reply(messages=[{"content": get_message_with_user_input(original_request_message,request_id), "role":"user"}])
|
|
346
416
|
|
|
347
417
|
helper_decider = AssistantAgent("helper_decider", llm_config=llm_config, system_message=prompts.get("HELPER_DECIDER_SYSTEM_MESSAGE"))
|
|
348
|
-
helper_decider_result = helper_decider.generate_reply(messages=[{"content": original_request_message, "role":"user"}])
|
|
418
|
+
helper_decider_result = helper_decider.generate_reply(messages=[{"content": get_message_with_user_input(original_request_message,request_id), "role":"user"}])
|
|
349
419
|
|
|
350
420
|
try:
|
|
351
421
|
helper_decider_result = json.loads(helper_decider_result)
|
|
@@ -361,17 +431,17 @@ def process_message_safe(original_request_message_data, original_request_message
|
|
|
361
431
|
context += f"\n#SECTION_OF_OLD_TASK_CODE_INFO_START:\nHere's code/info from old-tasks that might help:\n{search_index(code_keywords)}\n#SECTION_OF_OLD_TASK_CODE_INFO_END\n"
|
|
362
432
|
|
|
363
433
|
if helper_decider_result.get("bing_search"):
|
|
364
|
-
bing_search_message = f"Search Bing for more information on the task: {original_request_message}, prepared draft plan to solve task: {prepared_plan}"
|
|
434
|
+
bing_search_message = f"Search Bing for more information on the task: {get_message_with_user_input(original_request_message,request_id)}, prepared draft plan to solve task: {prepared_plan}"
|
|
365
435
|
result = chat(prompts.get("BING_SEARCH_PROMPT"), bing_search_message)
|
|
366
436
|
context += f"\n\nBing search results: {result}"
|
|
367
437
|
|
|
368
438
|
if helper_decider_result.get("cognitive_search"):
|
|
369
|
-
cognitive_search_message = f"Search cognitive index for more information on the task: {original_request_message}."
|
|
439
|
+
cognitive_search_message = f"Search cognitive index for more information on the task: {get_message_with_user_input(original_request_message,request_id)}."
|
|
370
440
|
result = chat(prompts.get("COGNITIVE_SEARCH_PROMPT"), cognitive_search_message)
|
|
371
441
|
context += f"\n\nCognitive search results: {result}"
|
|
372
442
|
|
|
373
443
|
|
|
374
|
-
context = process_helper_results(helper_decider_result, original_request_message, context, chat)
|
|
444
|
+
context = process_helper_results(helper_decider_result, get_message_with_user_input(original_request_message,request_id), context, chat)
|
|
375
445
|
|
|
376
446
|
context_message = ""
|
|
377
447
|
if context:
|
|
@@ -379,7 +449,7 @@ def process_message_safe(original_request_message_data, original_request_message
|
|
|
379
449
|
|
|
380
450
|
|
|
381
451
|
check_message = f"""
|
|
382
|
-
Task: \n{original_request_message}\n\n
|
|
452
|
+
Task: \n{get_message_with_user_input(original_request_message,request_id)}\n\n
|
|
383
453
|
Context to check if task can be considered completed: {context_message}\n\n
|
|
384
454
|
"""
|
|
385
455
|
|
|
@@ -389,7 +459,7 @@ Context to check if task can be considered completed: {context_message}\n\n
|
|
|
389
459
|
chat_result = None
|
|
390
460
|
if check_result != "DONE":
|
|
391
461
|
message = f"""
|
|
392
|
-
Your task is to complete the following: \n{original_request_message}\n\n"
|
|
462
|
+
Your task is to complete the following: \n{get_message_with_user_input(original_request_message,request_id)}\n\n"
|
|
393
463
|
Here is a draft plan to solve the task: \n{prepared_plan}\n\n
|
|
394
464
|
{context_message}
|
|
395
465
|
You don't have to follow the plan, it's just a suggestion.
|
|
@@ -404,7 +474,7 @@ Do your best to complete the task, user expects you to continue original task re
|
|
|
404
474
|
presenter_messages_context = context_message
|
|
405
475
|
presenter_message = f"""
|
|
406
476
|
Here is everything done in order to complete the task: {presenter_messages_context}\n\n
|
|
407
|
-
Original task was: {original_request_message}\n\n
|
|
477
|
+
Original task was: {get_message_with_user_input(original_request_message,request_id)}\n\n
|
|
408
478
|
Reply to it with task result, do not forget that user expects you continue original task request conversation:\n\n
|
|
409
479
|
"""
|
|
410
480
|
|
|
@@ -418,6 +488,6 @@ Reply to it with task result, do not forget that user expects you continue origi
|
|
|
418
488
|
final_msg += f"\n\n[Download all files of this task]({zip_url})"
|
|
419
489
|
|
|
420
490
|
|
|
421
|
-
print(f"Task completed, task:\n{original_request_message},\nresult: {final_msg}")
|
|
422
|
-
logging.info(f"Task completed, task:\n{original_request_message},\nresult: {final_msg}")
|
|
491
|
+
print(f"Task completed, task:\n{get_message_with_user_input(original_request_message,request_id)},\nresult: {final_msg}")
|
|
492
|
+
logging.info(f"Task completed, task:\n{get_message_with_user_input(original_request_message,request_id)},\nresult: {final_msg}")
|
|
423
493
|
return final_msg
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
# cortex-realtime-voice
|
|
2
|
+
|
|
3
|
+
To install dependencies:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
bun install
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
To run:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
cd client
|
|
13
|
+
bun run build
|
|
14
|
+
cd ..
|
|
15
|
+
bun run start
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
To run in production:
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
bun run start:prod
|
|
22
|
+
```
|
|
Binary file
|
|
Binary file
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
|
6
|
+
<title>Cortex Realtime Voice</title>
|
|
7
|
+
</head>
|
|
8
|
+
<body>
|
|
9
|
+
<div id="root"></div>
|
|
10
|
+
<script type="module" src="/src/index.tsx"></script>
|
|
11
|
+
</body>
|
|
12
|
+
</html>
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "client",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"dependencies": {
|
|
6
|
+
"@emotion/react": "^11.14.0",
|
|
7
|
+
"@emotion/styled": "^11.14.0",
|
|
8
|
+
"@mui/icons-material": "^6.2.0",
|
|
9
|
+
"@mui/material": "^6.2.0",
|
|
10
|
+
"@tailwindcss/typography": "^0.5.15",
|
|
11
|
+
"katex": "^0.16.15",
|
|
12
|
+
"react": "^19.0.0",
|
|
13
|
+
"react-dom": "^19.0.0",
|
|
14
|
+
"react-markdown": "^9.0.1",
|
|
15
|
+
"react-spinners": "0.15.0",
|
|
16
|
+
"react-syntax-highlighter": "^15.6.1",
|
|
17
|
+
"rehype-katex": "^7.0.1",
|
|
18
|
+
"rehype-raw": "^7.0.0",
|
|
19
|
+
"remark-gfm": "^4.0.0",
|
|
20
|
+
"remark-math": "^6.0.0",
|
|
21
|
+
"socket.io-client": "4.8.1",
|
|
22
|
+
"typescript": "^4.4.2",
|
|
23
|
+
"web-vitals": "^2.1.0"
|
|
24
|
+
},
|
|
25
|
+
"devDependencies": {
|
|
26
|
+
"@babel/plugin-proposal-private-property-in-object": "7.21.11",
|
|
27
|
+
"@testing-library/jest-dom": "^5.14.1",
|
|
28
|
+
"@testing-library/react": "^13.0.0",
|
|
29
|
+
"@testing-library/user-event": "^13.2.1",
|
|
30
|
+
"@types/jest": "^27.0.1",
|
|
31
|
+
"@types/node": "^16.7.13",
|
|
32
|
+
"@types/react": "^18.0.0",
|
|
33
|
+
"@types/react-dom": "^18.0.0",
|
|
34
|
+
"@types/react-syntax-highlighter": "^15.5.13",
|
|
35
|
+
"@vitejs/plugin-react": "^4.3.4",
|
|
36
|
+
"autoprefixer": "^10.4.20",
|
|
37
|
+
"postcss": "^8.4.49",
|
|
38
|
+
"tailwindcss": "^3.4.17",
|
|
39
|
+
"vite": "^6.0.5"
|
|
40
|
+
},
|
|
41
|
+
"scripts": {
|
|
42
|
+
"start": "vite",
|
|
43
|
+
"dev": "vite",
|
|
44
|
+
"build": "vite build",
|
|
45
|
+
"preview": "vite preview"
|
|
46
|
+
},
|
|
47
|
+
"eslintConfig": {
|
|
48
|
+
"extends": [
|
|
49
|
+
"react-app",
|
|
50
|
+
"react-app/jest"
|
|
51
|
+
]
|
|
52
|
+
},
|
|
53
|
+
"browserslist": {
|
|
54
|
+
"production": [
|
|
55
|
+
">0.2%",
|
|
56
|
+
"not dead",
|
|
57
|
+
"not op_mini all"
|
|
58
|
+
],
|
|
59
|
+
"development": [
|
|
60
|
+
"last 1 chrome version",
|
|
61
|
+
"last 1 firefox version",
|
|
62
|
+
"last 1 safari version"
|
|
63
|
+
]
|
|
64
|
+
}
|
|
65
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8" />
|
|
5
|
+
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
|
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1" />
|
|
7
|
+
<meta name="theme-color" content="#000000" />
|
|
8
|
+
<meta
|
|
9
|
+
name="description"
|
|
10
|
+
content="Chat with the Cortex Realtime Voice Server"
|
|
11
|
+
/>
|
|
12
|
+
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
|
|
13
|
+
<!--
|
|
14
|
+
manifest.json provides metadata used when your web app is installed on a
|
|
15
|
+
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
|
|
16
|
+
-->
|
|
17
|
+
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
|
|
18
|
+
<!--
|
|
19
|
+
Notice the use of %PUBLIC_URL% in the tags above.
|
|
20
|
+
It will be replaced with the URL of the `public` folder during the build.
|
|
21
|
+
Only files inside the `public` folder can be referenced from the HTML.
|
|
22
|
+
|
|
23
|
+
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
|
24
|
+
work correctly both with client-side routing and a non-root public URL.
|
|
25
|
+
Learn how to configure a non-root public URL by running `npm run build`.
|
|
26
|
+
-->
|
|
27
|
+
<title>Cortex Realtime Voice</title>
|
|
28
|
+
</head>
|
|
29
|
+
<body>
|
|
30
|
+
<noscript>You need to enable JavaScript to run this app.</noscript>
|
|
31
|
+
<div id="root"></div>
|
|
32
|
+
<!--
|
|
33
|
+
This HTML file is a template.
|
|
34
|
+
If you open it directly in the browser, you will see an empty page.
|
|
35
|
+
|
|
36
|
+
You can add webfonts, meta tags, or analytics to this file.
|
|
37
|
+
The build step will place the bundled scripts into the <body> tag.
|
|
38
|
+
|
|
39
|
+
To begin the development, run `npm start` or `yarn start`.
|
|
40
|
+
To create a production bundle, use `npm run build` or `yarn build`.
|
|
41
|
+
-->
|
|
42
|
+
</body>
|
|
43
|
+
</html>
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"short_name": "React App",
|
|
3
|
+
"name": "Create React App Sample",
|
|
4
|
+
"icons": [
|
|
5
|
+
{
|
|
6
|
+
"src": "favicon.ico",
|
|
7
|
+
"sizes": "64x64 32x32 24x24 16x16",
|
|
8
|
+
"type": "image/x-icon"
|
|
9
|
+
},
|
|
10
|
+
{
|
|
11
|
+
"src": "logo192.png",
|
|
12
|
+
"type": "image/png",
|
|
13
|
+
"sizes": "192x192"
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
"src": "logo512.png",
|
|
17
|
+
"type": "image/png",
|
|
18
|
+
"sizes": "512x512"
|
|
19
|
+
}
|
|
20
|
+
],
|
|
21
|
+
"start_url": ".",
|
|
22
|
+
"display": "standalone",
|
|
23
|
+
"theme_color": "#000000",
|
|
24
|
+
"background_color": "#ffffff"
|
|
25
|
+
}
|
|
Binary file
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { render, screen } from '@testing-library/react';
|
|
3
|
+
import App from './App';
|
|
4
|
+
|
|
5
|
+
test('renders learn react link', () => {
|
|
6
|
+
render(<App />);
|
|
7
|
+
const linkElement = screen.getByText(/learn react/i);
|
|
8
|
+
expect(linkElement).toBeInTheDocument();
|
|
9
|
+
});
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import {useEffect, useState} from 'react';
|
|
2
|
+
import ClipLoader from "react-spinners/ClipLoader";
|
|
3
|
+
import Chat from "./chat/Chat";
|
|
4
|
+
import {SettingsModal} from "./SettingsModal";
|
|
5
|
+
import { SettingsData } from "./SettingsModal";
|
|
6
|
+
import type { Voice } from '../../src/realtime/realtimeTypes';
|
|
7
|
+
|
|
8
|
+
function App() {
|
|
9
|
+
const [loading, setLoading] = useState(true);
|
|
10
|
+
const [userName, setUserName] = useState('');
|
|
11
|
+
const [userId, setUserId] = useState('');
|
|
12
|
+
const [aiName, setAiName] = useState('Jarvis');
|
|
13
|
+
const [settingsOpen, setSettingsOpen] = useState(false);
|
|
14
|
+
const [language, setLanguage] = useState('en');
|
|
15
|
+
const [aiMemorySelfModify, setAiMemorySelfModify] = useState(false);
|
|
16
|
+
const [aiStyle, setAiStyle] = useState('Anthropic');
|
|
17
|
+
const [voice, setVoice] = useState('alloy' as Voice);
|
|
18
|
+
|
|
19
|
+
const onCloseSettings = () => setSettingsOpen(false);
|
|
20
|
+
const onSaveSettings = (settings: SettingsData) => {
|
|
21
|
+
console.log('Saving settings', settings);
|
|
22
|
+
setUserName(settings.userName);
|
|
23
|
+
localStorage.setItem('userName', settings.userName);
|
|
24
|
+
|
|
25
|
+
let newUserId = settings.userId;
|
|
26
|
+
if (!newUserId || newUserId.length === 0) {
|
|
27
|
+
newUserId = Math.random().toString(36).substring(7);
|
|
28
|
+
}
|
|
29
|
+
setUserId(newUserId);
|
|
30
|
+
localStorage.setItem('userId', newUserId);
|
|
31
|
+
|
|
32
|
+
setAiName(settings.aiName);
|
|
33
|
+
localStorage.setItem('aiName', settings.aiName);
|
|
34
|
+
|
|
35
|
+
setLanguage(settings.language);
|
|
36
|
+
localStorage.setItem('language', settings.language);
|
|
37
|
+
|
|
38
|
+
setAiMemorySelfModify(settings.aiMemorySelfModify);
|
|
39
|
+
localStorage.setItem('aiMemorySelfModify', String(settings.aiMemorySelfModify));
|
|
40
|
+
|
|
41
|
+
setAiStyle(settings.aiStyle);
|
|
42
|
+
localStorage.setItem('aiStyle', settings.aiStyle);
|
|
43
|
+
|
|
44
|
+
setVoice(settings.voice as Voice);
|
|
45
|
+
localStorage.setItem('voice', settings.voice);
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
const name = localStorage.getItem('userName');
|
|
50
|
+
if (name) {
|
|
51
|
+
setUserName(localStorage.getItem('userName') as string);
|
|
52
|
+
} else {
|
|
53
|
+
setSettingsOpen(true);
|
|
54
|
+
}
|
|
55
|
+
const id = localStorage.getItem('userId');
|
|
56
|
+
if (id) {
|
|
57
|
+
setUserId(localStorage.getItem('userId') as string);
|
|
58
|
+
} else {
|
|
59
|
+
setSettingsOpen(true);
|
|
60
|
+
}
|
|
61
|
+
const ai = localStorage.getItem('aiName');
|
|
62
|
+
if (ai) {
|
|
63
|
+
setAiName(localStorage.getItem('aiName') as string);
|
|
64
|
+
} else {
|
|
65
|
+
setSettingsOpen(true);
|
|
66
|
+
}
|
|
67
|
+
const savedLanguage = localStorage.getItem('language');
|
|
68
|
+
if (savedLanguage) setLanguage(savedLanguage);
|
|
69
|
+
|
|
70
|
+
const savedAiMemorySelfModify = localStorage.getItem('aiMemorySelfModify');
|
|
71
|
+
if (savedAiMemorySelfModify) setAiMemorySelfModify(savedAiMemorySelfModify === 'true');
|
|
72
|
+
|
|
73
|
+
const savedAiStyle = localStorage.getItem('aiStyle');
|
|
74
|
+
if (savedAiStyle) setAiStyle(savedAiStyle);
|
|
75
|
+
|
|
76
|
+
const savedVoice = localStorage.getItem('voice');
|
|
77
|
+
if (savedVoice) setVoice(savedVoice as Voice);
|
|
78
|
+
|
|
79
|
+
setLoading(false);
|
|
80
|
+
}, []);
|
|
81
|
+
|
|
82
|
+
if (loading) {
|
|
83
|
+
return (
|
|
84
|
+
<div className="min-h-screen bg-gradient-to-b from-gray-900 via-gray-800 to-gray-900 flex justify-center items-center">
|
|
85
|
+
<ClipLoader color={'#0EA5E9'} loading={true} size={150}/>
|
|
86
|
+
</div>
|
|
87
|
+
);
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
return (
|
|
91
|
+
<div className="h-screen overflow-hidden bg-gradient-to-b from-gray-900 via-gray-800 to-gray-900">
|
|
92
|
+
<button
|
|
93
|
+
className="fixed top-4 right-4 z-10 p-2 text-gray-400 hover:text-cyan-400 transition-colors duration-200"
|
|
94
|
+
onClick={() => setSettingsOpen(true)}
|
|
95
|
+
aria-label="Settings"
|
|
96
|
+
>
|
|
97
|
+
⚙️
|
|
98
|
+
</button>
|
|
99
|
+
|
|
100
|
+
{userName && userName.length > 0 && (
|
|
101
|
+
<Chat
|
|
102
|
+
userId={userId}
|
|
103
|
+
userName={userName}
|
|
104
|
+
aiName={aiName}
|
|
105
|
+
language={language}
|
|
106
|
+
aiMemorySelfModify={aiMemorySelfModify}
|
|
107
|
+
aiStyle={aiStyle}
|
|
108
|
+
voice={voice}
|
|
109
|
+
/>
|
|
110
|
+
)}
|
|
111
|
+
<SettingsModal
|
|
112
|
+
aiName={aiName}
|
|
113
|
+
userName={userName}
|
|
114
|
+
userId={userId}
|
|
115
|
+
voice={voice}
|
|
116
|
+
aiStyle={aiStyle}
|
|
117
|
+
language={language}
|
|
118
|
+
isOpen={settingsOpen}
|
|
119
|
+
onClose={onCloseSettings}
|
|
120
|
+
onSave={onSaveSettings}
|
|
121
|
+
/>
|
|
122
|
+
</div>
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export default App;
|