meshagent-agents 0.5.2__tar.gz → 0.5.4__tar.gz
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.
Potentially problematic release.
This version of meshagent-agents might be problematic. Click here for more details.
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/CHANGELOG.md +6 -0
- {meshagent_agents-0.5.2/meshagent_agents.egg-info → meshagent_agents-0.5.4}/PKG-INFO +6 -6
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/adapter.py +1 -1
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/agent.py +1 -1
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/chat.py +207 -132
- meshagent_agents-0.5.4/meshagent/agents/version.py +1 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4/meshagent_agents.egg-info}/PKG-INFO +6 -6
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent_agents.egg-info/requires.txt +5 -5
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/pyproject.toml +5 -5
- meshagent_agents-0.5.2/meshagent/agents/version.py +0 -1
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/LICENSE +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/MANIFEST.in +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/README.md +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/__init__.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/context.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/development.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/hosting.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/indexer.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/listener.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/mail.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/planning.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/prompt.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/pydantic.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/schemas/__init__.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/schemas/document.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/schemas/gallery.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/schemas/presentation.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/schemas/schema.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/schemas/super_editor_document.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/single_shot_writer.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/thread_schema.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/utils.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/worker.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/writer.py +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent_agents.egg-info/SOURCES.txt +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent_agents.egg-info/dependency_links.txt +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent_agents.egg-info/top_level.txt +0 -0
- {meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meshagent-agents
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.4
|
|
4
4
|
Summary: Agent Building Blocks for Meshagent
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Documentation, https://docs.meshagent.com
|
|
@@ -12,19 +12,19 @@ License-File: LICENSE
|
|
|
12
12
|
Requires-Dist: pyjwt~=2.10
|
|
13
13
|
Requires-Dist: pytest~=8.4
|
|
14
14
|
Requires-Dist: pytest-asyncio~=0.26
|
|
15
|
-
Requires-Dist: meshagent-api~=0.5.
|
|
16
|
-
Requires-Dist: meshagent-tools~=0.5.
|
|
17
|
-
Requires-Dist: meshagent-openai~=0.5.
|
|
15
|
+
Requires-Dist: meshagent-api~=0.5.4
|
|
16
|
+
Requires-Dist: meshagent-tools~=0.5.4
|
|
17
|
+
Requires-Dist: meshagent-openai~=0.5.4
|
|
18
18
|
Requires-Dist: pydantic~=2.11
|
|
19
19
|
Requires-Dist: opentelemetry-distro~=0.54b1
|
|
20
20
|
Provides-Extra: all
|
|
21
|
-
Requires-Dist: meshagent-api[all]~=0.5.
|
|
21
|
+
Requires-Dist: meshagent-api[all]~=0.5.4; extra == "all"
|
|
22
22
|
Requires-Dist: chonkie~=0.5.1; extra == "all"
|
|
23
23
|
Requires-Dist: chonkie[semantic]~=0.5.1; extra == "all"
|
|
24
24
|
Requires-Dist: chonkie[openai]~=0.5.1; extra == "all"
|
|
25
25
|
Requires-Dist: aiosmtplib~=4.0.1; extra == "all"
|
|
26
26
|
Provides-Extra: sync
|
|
27
|
-
Requires-Dist: meshagent-api[sync]~=0.5.
|
|
27
|
+
Requires-Dist: meshagent-api[sync]~=0.5.4; extra == "sync"
|
|
28
28
|
Provides-Extra: mail
|
|
29
29
|
Requires-Dist: aiosmtplib~=4.0.1; extra == "mail"
|
|
30
30
|
Provides-Extra: rag
|
|
@@ -44,7 +44,7 @@ class LLMAdapter(Generic[T]):
|
|
|
44
44
|
*,
|
|
45
45
|
context: AgentChatContext,
|
|
46
46
|
room: RoomClient,
|
|
47
|
-
toolkits: Toolkit,
|
|
47
|
+
toolkits: list[Toolkit],
|
|
48
48
|
tool_adapter: Optional[ToolResponseAdapter] = None,
|
|
49
49
|
output_schema: Optional[dict] = None,
|
|
50
50
|
event_handler: Optional[Callable[[T], None]] = None,
|
|
@@ -335,7 +335,7 @@ class TaskRunner(SingleRoomAgent):
|
|
|
335
335
|
requires=None,
|
|
336
336
|
supports_tools: Optional[bool] = None,
|
|
337
337
|
input_schema: dict,
|
|
338
|
-
output_schema: dict,
|
|
338
|
+
output_schema: Optional[dict] = None,
|
|
339
339
|
labels: Optional[list[str]] = None,
|
|
340
340
|
toolkits: Optional[list[Toolkit]] = None,
|
|
341
341
|
):
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
from .agent import SingleRoomAgent, AgentChatContext
|
|
1
|
+
from meshagent.agents.agent import SingleRoomAgent, AgentChatContext
|
|
2
2
|
from meshagent.api.chan import Chan
|
|
3
3
|
from meshagent.api import (
|
|
4
4
|
RoomMessage,
|
|
@@ -10,7 +10,7 @@ from meshagent.api import (
|
|
|
10
10
|
MeshDocument,
|
|
11
11
|
)
|
|
12
12
|
from meshagent.tools import Toolkit, ToolContext
|
|
13
|
-
from .adapter import LLMAdapter, ToolResponseAdapter
|
|
13
|
+
from meshagent.agents.adapter import LLMAdapter, ToolResponseAdapter
|
|
14
14
|
from meshagent.openai.tools.responses_adapter import ImageGenerationTool, LocalShellTool
|
|
15
15
|
import asyncio
|
|
16
16
|
from typing import Optional
|
|
@@ -22,6 +22,7 @@ from typing import Literal
|
|
|
22
22
|
import base64
|
|
23
23
|
from openai.types.responses import ResponseStreamEvent
|
|
24
24
|
from asyncio import CancelledError
|
|
25
|
+
from meshagent.api import RoomException
|
|
25
26
|
|
|
26
27
|
from opentelemetry import trace
|
|
27
28
|
import shlex
|
|
@@ -307,13 +308,22 @@ class ChatBot(SingleRoomAgent):
|
|
|
307
308
|
|
|
308
309
|
async def _send_and_save_chat(
|
|
309
310
|
self,
|
|
310
|
-
|
|
311
|
+
thread: MeshDocument,
|
|
311
312
|
path: str,
|
|
312
313
|
to: RemoteParticipant,
|
|
313
314
|
id: str,
|
|
314
315
|
text: str,
|
|
315
316
|
thread_attributes: dict,
|
|
316
317
|
):
|
|
318
|
+
messages = None
|
|
319
|
+
|
|
320
|
+
for prop in thread.root.get_children():
|
|
321
|
+
if prop.tag_name == "messages":
|
|
322
|
+
messages = prop
|
|
323
|
+
|
|
324
|
+
if messages is None:
|
|
325
|
+
raise RoomException("messages element was not found in thread document")
|
|
326
|
+
|
|
317
327
|
with tracer.start_as_current_span("chatbot.thread.message") as span:
|
|
318
328
|
span.set_attributes(thread_attributes)
|
|
319
329
|
span.set_attribute("role", "assistant")
|
|
@@ -339,10 +349,10 @@ class ChatBot(SingleRoomAgent):
|
|
|
339
349
|
},
|
|
340
350
|
)
|
|
341
351
|
|
|
342
|
-
async def
|
|
352
|
+
async def _greet(
|
|
343
353
|
self,
|
|
344
354
|
*,
|
|
345
|
-
|
|
355
|
+
thread: MeshDocument,
|
|
346
356
|
path: str,
|
|
347
357
|
chat_context: AgentChatContext,
|
|
348
358
|
participant: RemoteParticipant,
|
|
@@ -353,7 +363,7 @@ class ChatBot(SingleRoomAgent):
|
|
|
353
363
|
await self._send_and_save_chat(
|
|
354
364
|
id=str(uuid.uuid4()),
|
|
355
365
|
to=RemoteParticipant(id=participant.id),
|
|
356
|
-
|
|
366
|
+
thread=thread,
|
|
357
367
|
path=path,
|
|
358
368
|
text=self._auto_greet_message,
|
|
359
369
|
thread_attributes=thread_attributes,
|
|
@@ -403,34 +413,92 @@ class ChatBot(SingleRoomAgent):
|
|
|
403
413
|
async def close_thread(self, *, path: str):
|
|
404
414
|
return await self.room.sync.close(path=path)
|
|
405
415
|
|
|
406
|
-
async def
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
416
|
+
async def load_thread_context(self, *, thread_context: ChatThreadContext):
|
|
417
|
+
"""
|
|
418
|
+
load the thread from the thread document by inserting the current messages in the thread into the chat context
|
|
419
|
+
"""
|
|
420
|
+
thread = thread_context.thread
|
|
421
|
+
chat_context = thread_context.chat
|
|
422
|
+
for prop in thread.root.get_children():
|
|
423
|
+
if prop.tag_name == "messages":
|
|
424
|
+
doc_messages = prop
|
|
425
|
+
|
|
426
|
+
for element in doc_messages.get_children():
|
|
427
|
+
if isinstance(element, Element) and element.tag_name == "message":
|
|
428
|
+
msg = element["text"]
|
|
429
|
+
if element[
|
|
430
|
+
"author_name"
|
|
431
|
+
] == self.room.local_participant.get_attribute("name"):
|
|
432
|
+
chat_context.append_assistant_message(msg)
|
|
433
|
+
else:
|
|
434
|
+
chat_context.append_user_message(msg)
|
|
435
|
+
|
|
436
|
+
for child in element.get_children():
|
|
437
|
+
if child.tag_name == "file":
|
|
438
|
+
chat_context.append_assistant_message(
|
|
439
|
+
f"the user attached a file with the path '{child.get_attribute('path')}'"
|
|
440
|
+
)
|
|
441
|
+
|
|
442
|
+
if doc_messages is None:
|
|
443
|
+
raise Exception("thread was not properly initialized")
|
|
412
444
|
|
|
445
|
+
async def prepare_llm_context(self, *, context: ChatThreadContext):
|
|
446
|
+
"""
|
|
447
|
+
called prior to sending the request to the LLM in case the agent needs to modify the context prior to sending
|
|
448
|
+
"""
|
|
449
|
+
pass
|
|
450
|
+
|
|
451
|
+
async def _process_llm_events(
|
|
452
|
+
self,
|
|
453
|
+
*,
|
|
454
|
+
thread_context: ChatThreadContext,
|
|
455
|
+
llm_messages: asyncio.Queue,
|
|
456
|
+
thread_attributes: dict,
|
|
457
|
+
):
|
|
458
|
+
thread = thread_context.thread
|
|
413
459
|
doc_messages = None
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
460
|
+
for prop in thread.root.get_children():
|
|
461
|
+
if prop.tag_name == "messages":
|
|
462
|
+
doc_messages = prop
|
|
417
463
|
|
|
418
|
-
|
|
464
|
+
if doc_messages is None:
|
|
465
|
+
raise RoomException("messages element is missing from thread document")
|
|
419
466
|
|
|
420
|
-
|
|
467
|
+
context_message = None
|
|
468
|
+
updates = asyncio.Queue()
|
|
469
|
+
|
|
470
|
+
# throttle updates so we don't send too many syncs over the wire at once
|
|
471
|
+
async def update_thread():
|
|
421
472
|
try:
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
473
|
+
changes = {}
|
|
474
|
+
while True:
|
|
475
|
+
try:
|
|
476
|
+
element, partial = updates.get_nowait()
|
|
477
|
+
changes[element] = partial
|
|
478
|
+
|
|
479
|
+
except asyncio.QueueEmpty:
|
|
480
|
+
for e, p in changes.items():
|
|
481
|
+
e["text"] = p
|
|
482
|
+
|
|
483
|
+
changes.clear()
|
|
484
|
+
|
|
485
|
+
e, p = await updates.get()
|
|
486
|
+
changes[e] = p
|
|
427
487
|
|
|
428
|
-
|
|
429
|
-
partial = ""
|
|
430
|
-
content_element = None
|
|
431
|
-
context_message = None
|
|
488
|
+
await asyncio.sleep(0.1)
|
|
432
489
|
|
|
433
|
-
|
|
490
|
+
except asyncio.QueueShutDown:
|
|
491
|
+
# flush any pending changes
|
|
492
|
+
for e, p in changes.items():
|
|
493
|
+
e["text"] = p
|
|
494
|
+
|
|
495
|
+
changes.clear()
|
|
496
|
+
pass
|
|
497
|
+
|
|
498
|
+
update_thread_task = asyncio.create_task(update_thread())
|
|
499
|
+
try:
|
|
500
|
+
while True:
|
|
501
|
+
evt = await llm_messages.get()
|
|
434
502
|
for participant in self._room.messaging.get_participants():
|
|
435
503
|
logger.debug(
|
|
436
504
|
f"sending event {evt.type} to {participant.get_attribute('name')}"
|
|
@@ -440,6 +508,7 @@ class ChatBot(SingleRoomAgent):
|
|
|
440
508
|
|
|
441
509
|
if evt.type == "response.content_part.added":
|
|
442
510
|
partial = ""
|
|
511
|
+
|
|
443
512
|
content_element = doc_messages.append_child(
|
|
444
513
|
tag_name="message",
|
|
445
514
|
attributes={
|
|
@@ -454,11 +523,11 @@ class ChatBot(SingleRoomAgent):
|
|
|
454
523
|
)
|
|
455
524
|
|
|
456
525
|
context_message = {"role": "assistant", "content": ""}
|
|
457
|
-
|
|
526
|
+
thread_context.chat.messages.append(context_message)
|
|
458
527
|
|
|
459
528
|
elif evt.type == "response.output_text.delta":
|
|
460
529
|
partial += evt.delta
|
|
461
|
-
content_element
|
|
530
|
+
updates.put_nowait((content_element, partial))
|
|
462
531
|
context_message["content"] = partial
|
|
463
532
|
|
|
464
533
|
elif evt.type == "response.output_text.done":
|
|
@@ -472,9 +541,21 @@ class ChatBot(SingleRoomAgent):
|
|
|
472
541
|
span.set_attribute("role", "assistant")
|
|
473
542
|
span.set_attributes(thread_attributes)
|
|
474
543
|
span.set_attributes({"text": evt.text})
|
|
544
|
+
except asyncio.QueueShutDown:
|
|
545
|
+
pass
|
|
546
|
+
finally:
|
|
547
|
+
updates.shutdown()
|
|
548
|
+
await update_thread_task
|
|
549
|
+
|
|
550
|
+
async def _spawn_thread(self, path: str, messages: Chan[RoomMessage]):
|
|
551
|
+
logger.debug("chatbot is starting a thread", extra={"path": path})
|
|
552
|
+
chat_context = await self.init_chat_context()
|
|
553
|
+
opened = False
|
|
554
|
+
|
|
555
|
+
current_file = None
|
|
556
|
+
thread_context = None
|
|
475
557
|
|
|
476
|
-
|
|
477
|
-
llm_task.add_done_callback(done_processing_llm_events)
|
|
558
|
+
thread_attributes = None
|
|
478
559
|
|
|
479
560
|
thread = None
|
|
480
561
|
|
|
@@ -483,9 +564,9 @@ class ChatBot(SingleRoomAgent):
|
|
|
483
564
|
|
|
484
565
|
while True:
|
|
485
566
|
while True:
|
|
486
|
-
logger.
|
|
567
|
+
logger.debug(f"waiting for message on thread {path}")
|
|
487
568
|
received = await messages.recv()
|
|
488
|
-
logger.
|
|
569
|
+
logger.debug(f"received message on thread {path}: {received.type}")
|
|
489
570
|
|
|
490
571
|
chat_with_participant = None
|
|
491
572
|
for participant in self._room.messaging.get_participants():
|
|
@@ -540,100 +621,57 @@ class ChatBot(SingleRoomAgent):
|
|
|
540
621
|
|
|
541
622
|
thread = await self.open_thread(path=path)
|
|
542
623
|
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
== self.room.local_participant.get_attribute(
|
|
556
|
-
"name"
|
|
557
|
-
)
|
|
558
|
-
):
|
|
559
|
-
chat_context.append_assistant_message(
|
|
560
|
-
msg
|
|
561
|
-
)
|
|
562
|
-
else:
|
|
563
|
-
chat_context.append_user_message(msg)
|
|
564
|
-
|
|
565
|
-
for child in element.get_children():
|
|
566
|
-
if child.tag_name == "file":
|
|
567
|
-
chat_context.append_assistant_message(
|
|
568
|
-
f"the user attached a file with the path '{child.get_attribute('path')}'"
|
|
569
|
-
)
|
|
570
|
-
|
|
571
|
-
if doc_messages is None:
|
|
572
|
-
raise Exception("thread was not properly initialized")
|
|
624
|
+
thread_context = ChatThreadContext(
|
|
625
|
+
path=path,
|
|
626
|
+
chat=chat_context,
|
|
627
|
+
thread=thread,
|
|
628
|
+
participants=get_thread_participants(
|
|
629
|
+
room=self.room, thread=thread
|
|
630
|
+
),
|
|
631
|
+
)
|
|
632
|
+
|
|
633
|
+
await self.load_thread_context(
|
|
634
|
+
thread_context=thread_context
|
|
635
|
+
)
|
|
573
636
|
|
|
574
637
|
if received.type == "opened":
|
|
575
638
|
if not opened:
|
|
576
639
|
opened = True
|
|
577
640
|
|
|
578
|
-
await self.
|
|
641
|
+
await self._greet(
|
|
579
642
|
path=path,
|
|
580
643
|
chat_context=chat_context,
|
|
581
644
|
participant=chat_with_participant,
|
|
582
|
-
|
|
645
|
+
thread=thread,
|
|
583
646
|
thread_attributes=thread_attributes,
|
|
584
647
|
)
|
|
585
648
|
|
|
586
649
|
if received.type == "chat":
|
|
587
650
|
if thread is None:
|
|
588
|
-
|
|
589
|
-
type="thread is not open", data={}
|
|
590
|
-
)
|
|
651
|
+
logger.info("thread is not open", extra={"path": path})
|
|
591
652
|
break
|
|
592
653
|
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
self.room.developer.log_nowait(
|
|
605
|
-
type="llm.message",
|
|
606
|
-
data={
|
|
607
|
-
"context": chat_context.id,
|
|
608
|
-
"participant_id": self.room.local_participant.id,
|
|
609
|
-
"participant_name": self.room.local_participant.get_attribute(
|
|
610
|
-
"name"
|
|
611
|
-
),
|
|
612
|
-
"message": {
|
|
613
|
-
"content": {
|
|
614
|
-
"role": "user",
|
|
615
|
-
"text": received.message["text"],
|
|
616
|
-
}
|
|
617
|
-
},
|
|
618
|
-
},
|
|
619
|
-
)
|
|
620
|
-
|
|
621
|
-
attachments = received.message.get("attachments", [])
|
|
622
|
-
text = received.message["text"]
|
|
623
|
-
|
|
624
|
-
for attachment in attachments:
|
|
625
|
-
chat_context.append_assistant_message(
|
|
626
|
-
message=f"the user attached a file at the path '{attachment['path']}'"
|
|
627
|
-
)
|
|
654
|
+
logger.debug(
|
|
655
|
+
"chatbot received a chat",
|
|
656
|
+
extra={
|
|
657
|
+
"context": chat_context.id,
|
|
658
|
+
"participant_id": self.room.local_participant.id,
|
|
659
|
+
"participant_name": self.room.local_participant.get_attribute(
|
|
660
|
+
"name"
|
|
661
|
+
),
|
|
662
|
+
"text": received.message["text"],
|
|
663
|
+
},
|
|
664
|
+
)
|
|
628
665
|
|
|
629
|
-
|
|
666
|
+
attachments = received.message.get("attachments", [])
|
|
667
|
+
text = received.message["text"]
|
|
630
668
|
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
669
|
+
for attachment in attachments:
|
|
670
|
+
chat_context.append_assistant_message(
|
|
671
|
+
message=f"the user attached a file at the path '{attachment['path']}'"
|
|
672
|
+
)
|
|
635
673
|
|
|
636
|
-
|
|
674
|
+
chat_context.append_user_message(message=text)
|
|
637
675
|
|
|
638
676
|
if messages.empty():
|
|
639
677
|
break
|
|
@@ -654,6 +692,16 @@ class ChatBot(SingleRoomAgent):
|
|
|
654
692
|
span.set_attributes({"text": text})
|
|
655
693
|
|
|
656
694
|
try:
|
|
695
|
+
for participant in get_thread_participants(
|
|
696
|
+
room=self._room, thread=thread
|
|
697
|
+
):
|
|
698
|
+
# TODO: async gather
|
|
699
|
+
self._room.messaging.send_message_nowait(
|
|
700
|
+
to=participant,
|
|
701
|
+
type="thinking",
|
|
702
|
+
message={"thinking": True, "path": path},
|
|
703
|
+
)
|
|
704
|
+
|
|
657
705
|
if thread_context is None:
|
|
658
706
|
thread_context = ChatThreadContext(
|
|
659
707
|
path=path,
|
|
@@ -668,9 +716,6 @@ class ChatBot(SingleRoomAgent):
|
|
|
668
716
|
room=self.room, thread=thread
|
|
669
717
|
)
|
|
670
718
|
|
|
671
|
-
def handle_event(evt):
|
|
672
|
-
llm_messages.send_nowait(evt)
|
|
673
|
-
|
|
674
719
|
with tracer.start_as_current_span("chatbot.llm") as span:
|
|
675
720
|
try:
|
|
676
721
|
with tracer.start_as_current_span(
|
|
@@ -683,6 +728,23 @@ class ChatBot(SingleRoomAgent):
|
|
|
683
728
|
)
|
|
684
729
|
)
|
|
685
730
|
|
|
731
|
+
await self.prepare_llm_context(
|
|
732
|
+
context=thread_context
|
|
733
|
+
)
|
|
734
|
+
|
|
735
|
+
llm_messages = asyncio.Queue[ResponseStreamEvent]()
|
|
736
|
+
|
|
737
|
+
def handle_event(evt):
|
|
738
|
+
llm_messages.put_nowait(evt)
|
|
739
|
+
|
|
740
|
+
llm_task = asyncio.create_task(
|
|
741
|
+
self._process_llm_events(
|
|
742
|
+
thread_context=thread_context,
|
|
743
|
+
llm_messages=llm_messages,
|
|
744
|
+
thread_attributes=thread_attributes,
|
|
745
|
+
)
|
|
746
|
+
)
|
|
747
|
+
|
|
686
748
|
await self._llm_adapter.next(
|
|
687
749
|
context=chat_context,
|
|
688
750
|
room=self._room,
|
|
@@ -690,10 +752,14 @@ class ChatBot(SingleRoomAgent):
|
|
|
690
752
|
tool_adapter=self._tool_adapter,
|
|
691
753
|
event_handler=handle_event,
|
|
692
754
|
)
|
|
755
|
+
|
|
756
|
+
llm_messages.shutdown()
|
|
757
|
+
await llm_task
|
|
758
|
+
|
|
693
759
|
except Exception as e:
|
|
694
760
|
logger.error("An error was encountered", exc_info=e)
|
|
695
761
|
await self._send_and_save_chat(
|
|
696
|
-
|
|
762
|
+
thread=thread,
|
|
697
763
|
to=chat_with_participant,
|
|
698
764
|
path=path,
|
|
699
765
|
id=str(uuid.uuid4()),
|
|
@@ -702,27 +768,30 @@ class ChatBot(SingleRoomAgent):
|
|
|
702
768
|
)
|
|
703
769
|
|
|
704
770
|
finally:
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
771
|
+
|
|
772
|
+
async def cleanup():
|
|
773
|
+
for participant in get_thread_participants(
|
|
774
|
+
room=self._room, thread=thread
|
|
775
|
+
):
|
|
776
|
+
self._room.messaging.send_message_nowait(
|
|
777
|
+
to=participant,
|
|
778
|
+
type="thinking",
|
|
779
|
+
message={"thinking": False, "path": path},
|
|
780
|
+
)
|
|
781
|
+
|
|
782
|
+
asyncio.shield(cleanup())
|
|
714
783
|
|
|
715
784
|
finally:
|
|
716
|
-
llm_messages.close()
|
|
717
785
|
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
)
|
|
786
|
+
async def cleanup():
|
|
787
|
+
if self.room is not None:
|
|
788
|
+
logger.info(f"thread was ended {path}")
|
|
789
|
+
logger.info("chatbot thread ended", extra={"path": path})
|
|
723
790
|
|
|
724
|
-
|
|
725
|
-
|
|
791
|
+
if thread is not None:
|
|
792
|
+
await self.close_thread(path=path)
|
|
793
|
+
|
|
794
|
+
asyncio.shield(cleanup())
|
|
726
795
|
|
|
727
796
|
def _get_message_channel(self, key: str) -> Chan[RoomMessage]:
|
|
728
797
|
if key not in self._message_channels:
|
|
@@ -756,7 +825,7 @@ class ChatBot(SingleRoomAgent):
|
|
|
756
825
|
|
|
757
826
|
messages = self._get_message_channel(path)
|
|
758
827
|
|
|
759
|
-
logger.
|
|
828
|
+
logger.debug(
|
|
760
829
|
f"queued incoming message for thread {path}: {message.type}"
|
|
761
830
|
)
|
|
762
831
|
|
|
@@ -765,6 +834,7 @@ class ChatBot(SingleRoomAgent):
|
|
|
765
834
|
if path not in self._thread_tasks or self._thread_tasks[path].done():
|
|
766
835
|
|
|
767
836
|
def thread_done(task: asyncio.Task):
|
|
837
|
+
self._thread_tasks.pop(path)
|
|
768
838
|
self._message_channels.pop(path)
|
|
769
839
|
try:
|
|
770
840
|
task.result()
|
|
@@ -775,7 +845,7 @@ class ChatBot(SingleRoomAgent):
|
|
|
775
845
|
f"The chat thread ended with an error {e}", exc_info=e
|
|
776
846
|
)
|
|
777
847
|
|
|
778
|
-
logger.
|
|
848
|
+
logger.debug(f"spawning chat thread for {path}")
|
|
779
849
|
task = asyncio.create_task(
|
|
780
850
|
self._spawn_thread(messages=messages, path=path)
|
|
781
851
|
)
|
|
@@ -783,6 +853,11 @@ class ChatBot(SingleRoomAgent):
|
|
|
783
853
|
|
|
784
854
|
self._thread_tasks[path] = task
|
|
785
855
|
|
|
856
|
+
elif message.type == "cancel":
|
|
857
|
+
path = message.message["path"]
|
|
858
|
+
if path in self._thread_tasks:
|
|
859
|
+
self._thread_tasks[path].cancel()
|
|
860
|
+
|
|
786
861
|
elif message.type == "typing":
|
|
787
862
|
|
|
788
863
|
def callback(task: asyncio.Task):
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.5.4"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: meshagent-agents
|
|
3
|
-
Version: 0.5.
|
|
3
|
+
Version: 0.5.4
|
|
4
4
|
Summary: Agent Building Blocks for Meshagent
|
|
5
5
|
License-Expression: Apache-2.0
|
|
6
6
|
Project-URL: Documentation, https://docs.meshagent.com
|
|
@@ -12,19 +12,19 @@ License-File: LICENSE
|
|
|
12
12
|
Requires-Dist: pyjwt~=2.10
|
|
13
13
|
Requires-Dist: pytest~=8.4
|
|
14
14
|
Requires-Dist: pytest-asyncio~=0.26
|
|
15
|
-
Requires-Dist: meshagent-api~=0.5.
|
|
16
|
-
Requires-Dist: meshagent-tools~=0.5.
|
|
17
|
-
Requires-Dist: meshagent-openai~=0.5.
|
|
15
|
+
Requires-Dist: meshagent-api~=0.5.4
|
|
16
|
+
Requires-Dist: meshagent-tools~=0.5.4
|
|
17
|
+
Requires-Dist: meshagent-openai~=0.5.4
|
|
18
18
|
Requires-Dist: pydantic~=2.11
|
|
19
19
|
Requires-Dist: opentelemetry-distro~=0.54b1
|
|
20
20
|
Provides-Extra: all
|
|
21
|
-
Requires-Dist: meshagent-api[all]~=0.5.
|
|
21
|
+
Requires-Dist: meshagent-api[all]~=0.5.4; extra == "all"
|
|
22
22
|
Requires-Dist: chonkie~=0.5.1; extra == "all"
|
|
23
23
|
Requires-Dist: chonkie[semantic]~=0.5.1; extra == "all"
|
|
24
24
|
Requires-Dist: chonkie[openai]~=0.5.1; extra == "all"
|
|
25
25
|
Requires-Dist: aiosmtplib~=4.0.1; extra == "all"
|
|
26
26
|
Provides-Extra: sync
|
|
27
|
-
Requires-Dist: meshagent-api[sync]~=0.5.
|
|
27
|
+
Requires-Dist: meshagent-api[sync]~=0.5.4; extra == "sync"
|
|
28
28
|
Provides-Extra: mail
|
|
29
29
|
Requires-Dist: aiosmtplib~=4.0.1; extra == "mail"
|
|
30
30
|
Provides-Extra: rag
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
pyjwt~=2.10
|
|
2
2
|
pytest~=8.4
|
|
3
3
|
pytest-asyncio~=0.26
|
|
4
|
-
meshagent-api~=0.5.
|
|
5
|
-
meshagent-tools~=0.5.
|
|
6
|
-
meshagent-openai~=0.5.
|
|
4
|
+
meshagent-api~=0.5.4
|
|
5
|
+
meshagent-tools~=0.5.4
|
|
6
|
+
meshagent-openai~=0.5.4
|
|
7
7
|
pydantic~=2.11
|
|
8
8
|
opentelemetry-distro~=0.54b1
|
|
9
9
|
|
|
10
10
|
[all]
|
|
11
|
-
meshagent-api[all]~=0.5.
|
|
11
|
+
meshagent-api[all]~=0.5.4
|
|
12
12
|
chonkie~=0.5.1
|
|
13
13
|
chonkie[semantic]~=0.5.1
|
|
14
14
|
chonkie[openai]~=0.5.1
|
|
@@ -23,4 +23,4 @@ chonkie[semantic]~=0.5.1
|
|
|
23
23
|
chonkie[openai]~=0.5.1
|
|
24
24
|
|
|
25
25
|
[sync]
|
|
26
|
-
meshagent-api[sync]~=0.5.
|
|
26
|
+
meshagent-api[sync]~=0.5.4
|
|
@@ -17,16 +17,16 @@ dependencies = [
|
|
|
17
17
|
"pyjwt~=2.10",
|
|
18
18
|
"pytest~=8.4",
|
|
19
19
|
"pytest-asyncio~=0.26",
|
|
20
|
-
"meshagent-api~=0.5.
|
|
21
|
-
"meshagent-tools~=0.5.
|
|
22
|
-
"meshagent-openai~=0.5.
|
|
20
|
+
"meshagent-api~=0.5.4",
|
|
21
|
+
"meshagent-tools~=0.5.4",
|
|
22
|
+
"meshagent-openai~=0.5.4",
|
|
23
23
|
"pydantic~=2.11",
|
|
24
24
|
"opentelemetry-distro~=0.54b1"
|
|
25
25
|
]
|
|
26
26
|
|
|
27
27
|
[project.optional-dependencies]
|
|
28
28
|
all = [
|
|
29
|
-
"meshagent-api[all]~=0.5.
|
|
29
|
+
"meshagent-api[all]~=0.5.4",
|
|
30
30
|
"chonkie~=0.5.1",
|
|
31
31
|
"chonkie[semantic]~=0.5.1",
|
|
32
32
|
"chonkie[openai]~=0.5.1",
|
|
@@ -34,7 +34,7 @@ all = [
|
|
|
34
34
|
]
|
|
35
35
|
|
|
36
36
|
sync = [
|
|
37
|
-
"meshagent-api[sync]~=0.5.
|
|
37
|
+
"meshagent-api[sync]~=0.5.4",
|
|
38
38
|
]
|
|
39
39
|
|
|
40
40
|
mail = [
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "0.5.2"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent/agents/schemas/super_editor_document.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{meshagent_agents-0.5.2 → meshagent_agents-0.5.4}/meshagent_agents.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|