meshagent-agents 0.0.5__py3-none-any.whl → 0.0.7__py3-none-any.whl

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/agent.py CHANGED
@@ -256,9 +256,14 @@ class SingleRoomAgent(Agent):
256
256
 
257
257
  class TaskRunner(SingleRoomAgent):
258
258
 
259
- def __init__(self, *, name, title = None, description = None, requires = None, supports_tools : Optional[bool] = None, input_schema: dict, output_schema: dict, labels: Optional[list[str]] = None):
259
+ def __init__(self, *, name, title = None, description = None, requires = None, supports_tools : Optional[bool] = None, input_schema: dict, output_schema: dict, labels: Optional[list[str]] = None, toolkits: Optional[list[Toolkit]] = None):
260
260
  super().__init__(name=name, title=title, description=description, requires=requires, labels=labels)
261
261
 
262
+ if toolkits == None:
263
+ toolkits = []
264
+
265
+ self._toolkits = toolkits
266
+
262
267
  self._registration_id = None
263
268
 
264
269
  if input_schema == None:
@@ -353,25 +358,30 @@ class TaskRunner(SingleRoomAgent):
353
358
  async def worker():
354
359
  # Decode and parse the message
355
360
  message = json.loads(data.decode('utf-8'))
356
- logger.info("got message %s", message)
361
+ logger.info("agent got message %s", message)
357
362
  args = message["arguments"]
358
363
  task_id = message["task_id"]
359
364
  context_json = message["context"]
360
365
  toolkits_json = message["toolkits"]
361
366
 
362
-
363
367
  #context_json = message["context"]
364
368
 
365
369
  try:
366
370
  chat_context = await self.init_chat_context()
367
371
 
368
372
  caller : Participant | None = None
369
-
373
+ on_behalf_of : Participant | None = None
374
+ on_behalf_of_id = message.get("on_behalf_of_id", None)
375
+
370
376
  for participant in self._room.messaging.get_participants():
371
377
  if message["caller_id"] == participant.id:
372
378
  caller = participant
373
379
  break
374
380
 
381
+ if on_behalf_of_id == participant.id:
382
+ on_behalf_of = participant
383
+ break
384
+
375
385
  if caller == None:
376
386
  caller = RemoteParticipant(
377
387
  id=message["caller_id"],
@@ -379,15 +389,30 @@ class TaskRunner(SingleRoomAgent):
379
389
  attributes={}
380
390
  )
381
391
 
382
-
383
- context = AgentCallContext(chat=chat_context, room=self.room, caller=caller)
384
-
392
+ if on_behalf_of_id != None and on_behalf_of == None:
393
+ on_behalf_of = RemoteParticipant(
394
+ id=message["on_behalf_of_id"],
395
+ role="user",
396
+ attributes={}
397
+ )
398
+
399
+ tool_target = caller
400
+ if on_behalf_of != None:
401
+ tool_target = on_behalf_of
402
+
403
+ toolkits = [
404
+ *self._toolkits,
405
+ *await self.get_required_tools(participant_id=tool_target.id)
406
+ ]
407
+
408
+ context = AgentCallContext(chat=chat_context, room=self.room, caller=caller, on_behalf_of=on_behalf_of, toolkits=toolkits)
409
+
385
410
  for toolkit_json in toolkits_json:
386
411
  tools = []
387
412
  for tool_json in toolkit_json["tools"]:
388
413
  tools.append(RoomTool(
389
- on_behalf_of_id=message["caller_id"],
390
- participant_id=message["caller_id"],
414
+ on_behalf_of_id=on_behalf_of_id,
415
+ participant_id=tool_target.id,
391
416
  toolkit_name=toolkit_json["name"],
392
417
  name=tool_json["name"],
393
418
  title=tool_json["title"],
@@ -405,6 +430,8 @@ class TaskRunner(SingleRoomAgent):
405
430
  tools=tools,
406
431
  ))
407
432
 
433
+
434
+
408
435
  response = await self.ask(context=context, arguments=args)
409
436
 
410
437
  await protocol.send(type="agent.ask_response", data=json.dumps({
meshagent/agents/chat.py CHANGED
@@ -10,7 +10,7 @@ from meshagent.tools import MultiToolkit
10
10
  import urllib
11
11
  import uuid
12
12
  import datetime
13
-
13
+ import json
14
14
  from openai.types.responses import ResponseStreamEvent
15
15
 
16
16
  logging.basicConfig()
@@ -176,7 +176,9 @@ class ChatBot(SingleRoomAgent):
176
176
  doc_messages = None
177
177
  current_file = None
178
178
  llm_messages = Chan[ResponseStreamEvent]()
179
-
179
+ thread_context = None
180
+
181
+
180
182
  def done_processing_llm_events(task: asyncio.Task):
181
183
  try:
182
184
  task.result()
@@ -191,7 +193,10 @@ class ChatBot(SingleRoomAgent):
191
193
 
192
194
  async for evt in llm_messages:
193
195
 
194
- #await self.room.messaging.send_message(to=chat_with_participant, type="llm.event", message=evt)
196
+ for participant in self._room.messaging.get_participants():
197
+ logger.info(f"sending event {evt.type} to {participant.get_attribute("name")}")
198
+
199
+ self.room.messaging.send_message_nowait(to=participant, type="llm.event", message=json.loads(evt.to_json()))
195
200
 
196
201
  if evt.type == "response.content_part.added":
197
202
  partial = ""
@@ -291,7 +296,7 @@ class ChatBot(SingleRoomAgent):
291
296
 
292
297
  for participant in get_thread_participants(room=self._room, thread=thread):
293
298
  # TODO: async gather
294
- await self._room.messaging.send_message(to=participant, type="thinking", message={"thinking":True, "path": path})
299
+ self._room.messaging.send_message_nowait(to=participant, type="thinking", message={"thinking":True, "path": path})
295
300
 
296
301
  if chat_with_participant.id == received.from_participant_id:
297
302
  self.room.developer.log_nowait(type="llm.message", data={ "context" : chat_context.id, "participant_id" : self.room.local_participant.id, "participant_name" : self.room.local_participant.get_attribute("name"), "message" : { "content" : { "role" : "user", "text" : received.message["text"] } } })
@@ -320,19 +325,21 @@ class ChatBot(SingleRoomAgent):
320
325
 
321
326
 
322
327
  try:
323
-
324
- toolkits = [
325
- *self._toolkits,
326
- *await self.get_required_tools(participant_id=chat_with_participant.id)
327
- ]
328
-
329
- thread_context = ChatThreadContext(
330
- chat=chat_context,
331
- thread=thread,
332
- toolkits=toolkits,
333
- )
328
+
329
+ if thread_context == None:
330
+ toolkits = [
331
+ *self._toolkits,
332
+ *await self.get_required_tools(participant_id=chat_with_participant.id)
333
+ ]
334
+
335
+ thread_context = ChatThreadContext(
336
+ chat=chat_context,
337
+ thread=thread,
338
+ toolkits=toolkits,
339
+ participants=get_thread_participants(room=self.room, thread=thread)
340
+ )
334
341
 
335
- await self.init_thread_context(thread_context=thread_context)
342
+ await self.init_thread_context(thread_context=thread_context)
336
343
 
337
344
  def handle_event(evt):
338
345
  llm_messages.send_nowait(evt)
@@ -341,7 +348,7 @@ class ChatBot(SingleRoomAgent):
341
348
  response = await self._llm_adapter.next(
342
349
  context=chat_context,
343
350
  room=self._room,
344
- toolkits=toolkits,
351
+ toolkits=thread_context.toolkits,
345
352
  tool_adapter=self._tool_adapter,
346
353
  event_handler=handle_event
347
354
  )
@@ -353,7 +360,7 @@ class ChatBot(SingleRoomAgent):
353
360
  finally:
354
361
  for participant in get_thread_participants(room=self._room, thread=thread):
355
362
  # TODO: async gather
356
- await self._room.messaging.send_message(to=participant, type="thinking", message={"thinking":False, "path" : path})
363
+ self._room.messaging.send_message_nowait(to=participant, type="thinking", message={"thinking":False, "path" : path})
357
364
 
358
365
 
359
366
  finally:
@@ -386,11 +393,16 @@ class ChatBot(SingleRoomAgent):
386
393
  async def start(self, *, room):
387
394
 
388
395
  await super().start(room=room)
396
+
397
+ logger.info("Starting chatbot")
389
398
 
390
399
  await self.room.local_participant.set_attribute("empty_state_title", self._empty_state_title)
391
400
 
392
401
  def on_message(message: RoomMessage):
393
402
 
403
+ logger.info(f"received message {message.type}")
404
+
405
+
394
406
  messages = self._get_message_channel(participant_id=message.from_participant_id)
395
407
  if message.type == "chat" or message.type == "opened":
396
408
  messages.send_nowait(message)
@@ -444,5 +456,7 @@ class ChatBot(SingleRoomAgent):
444
456
 
445
457
  room.messaging.on("participant_added", on_participant_added)
446
458
 
459
+
460
+ logger.info("Enabling chatbot messaging")
447
461
  await room.messaging.enable()
448
462
 
@@ -81,13 +81,14 @@ class AgentChatContext:
81
81
  return AgentChatContext(messages=json["messages"], system_role=json.get("system_role", None))
82
82
 
83
83
  class AgentCallContext:
84
- def __init__(self, *, chat: AgentChatContext, room: RoomClient, toolkits: Optional[list[Toolkit]] = None, caller: Optional[Participant] = None):
84
+ def __init__(self, *, chat: AgentChatContext, room: RoomClient, toolkits: Optional[list[Toolkit]] = None, caller: Optional[Participant] = None, on_behalf_of: Optional[Participant] = None):
85
85
  self._room = room
86
86
  if toolkits == None:
87
87
  toolkits = list[Toolkit]()
88
88
  self._toolkits = toolkits
89
89
  self._chat = chat
90
90
  self._caller = caller
91
+ self._on_behalf_of = on_behalf_of
91
92
 
92
93
  @property
93
94
  def toolkits(self):
@@ -101,6 +102,10 @@ class AgentCallContext:
101
102
  def caller(self):
102
103
  return self._caller
103
104
 
105
+ @property
106
+ def on_behalf_of(self):
107
+ return self._on_behalf_of
108
+
104
109
  @property
105
110
  def room(self):
106
111
  return self._room
@@ -370,10 +370,10 @@ class StorageIndexer(SingleRoomAgent):
370
370
  logger.error("error while indexing", exc_info=e)
371
371
 
372
372
 
373
- def _on_file_deleted(self, path: str):
373
+ def _on_file_deleted(self, path: str, participant_id: str):
374
374
  self._chan.send_nowait(FileIndexEvent(path=path, deleted=True))
375
375
 
376
- def _on_file_updated(self, path: str):
376
+ def _on_file_updated(self, path: str, participant_id: str):
377
377
  self._chan.send_nowait(FileIndexEvent(path=path, deleted=False))
378
378
 
379
379
 
@@ -279,7 +279,8 @@ class PlanningResponder(TaskRunner):
279
279
  output_schema=output_schema,
280
280
  requires=requires,
281
281
  supports_tools=supports_tools,
282
- labels=labels
282
+ labels=labels,
283
+ toolkits=toolkits
283
284
  )
284
285
 
285
286
  self._max_iterations = max_iterations
@@ -294,11 +295,6 @@ class PlanningResponder(TaskRunner):
294
295
  self._llm_adapter = llm_adapter
295
296
  self._tool_adapter = tool_adapter
296
297
 
297
- if toolkits == None:
298
- toolkits = []
299
-
300
- self.toolkits = toolkits
301
-
302
298
  self._use_terminate_tool = use_terminate_tool
303
299
 
304
300
  async def init_chat_context(self):
@@ -389,14 +385,8 @@ class PlanningResponder(TaskRunner):
389
385
 
390
386
  try:
391
387
  logger.info("COMPLETION STARTING: Step %s", i)
392
-
393
- toolkits = [
394
- *self.toolkits,
395
- *context.toolkits
396
- ]
397
-
398
- responses = await self._llm_adapter.next(context=context.chat, room=room, toolkits=toolkits, tool_adapter=self._tool_adapter, output_schema=rs)
399
-
388
+
389
+ responses = await self._llm_adapter.next(context=context.chat, room=room, toolkits=context.toolkits, tool_adapter=self._tool_adapter, output_schema=rs)
400
390
 
401
391
  logger.info("COMPLETION RESPONSE %s", responses)
402
392
 
@@ -0,0 +1,39 @@
1
+ from meshagent.api import RoomClient, Requirement, RoomException, Participant
2
+ from meshagent.tools import validate_openai_schema, Toolkit
3
+ import json
4
+ from typing import Optional
5
+ import asyncio
6
+
7
+ async def generate_json(*, on_behalf_of: Optional[Participant] = None, room: RoomClient, prompt: Optional[str] = None, output_schema: dict, requires: Optional[list[Requirement]] = None) -> dict:
8
+
9
+ # make sure agent is in the room before proceeding
10
+ agent = None
11
+ for i in range(10):
12
+ agents = await room.agents.list_agents()
13
+ for a in agents:
14
+ if a.name == "meshagent.planning_responder":
15
+ agent = a
16
+ break
17
+
18
+ if agent != None:
19
+ break
20
+
21
+ await asyncio.sleep(1)
22
+
23
+ if agent == None:
24
+ raise RoomException("unable to locate required agent (meshagent.planning_responder)")
25
+
26
+
27
+ if prompt == None:
28
+ prompt = f"ask me a series of questions to completely fill out the data structure described by this JSON schema ${json.dumps(output_schema)}. If you need to ask multiple questions, try to include all of them in a single form."
29
+
30
+ validate_openai_schema(output_schema)
31
+ return await room.agents.ask(
32
+ on_behalf_of=on_behalf_of,
33
+ agent="meshagent.planning_responder",
34
+ requires = requires,
35
+ arguments = {
36
+ "prompt": prompt,
37
+ "output_schema": output_schema,
38
+ },
39
+ )
@@ -1 +1 @@
1
- __version__ = "0.0.5"
1
+ __version__ = "0.0.7"
@@ -103,20 +103,19 @@ class Worker(TaskRunner):
103
103
  try:
104
104
  while True:
105
105
 
106
- toolkits = [
107
- *self._toolkits,
108
- *context.toolkits,
109
- *await self.get_required_tools(participant_id=self.room.local_participant.id)
110
- ]
106
+ tool_target = context.caller
107
+ if context.on_behalf_of != None:
108
+ tool_target = context.on_behalf_of
109
+
111
110
  response = await self._llm_adapter.next(
112
111
  context=chat_context,
113
112
  room=self._room,
114
- toolkits=toolkits,
113
+ toolkits=context.toolkits,
115
114
  tool_adapter=self._tool_adapter,
116
115
  output_schema=step_schema,
117
116
  )
118
117
 
119
- if response["finished"] or len(toolkits) == 0:
118
+ if response["finished"] or len(context.toolkits) == 0:
120
119
  break
121
120
  else:
122
121
  chat_context.append_user_message(message="proceed to the next step if you are ready")
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.2
1
+ Metadata-Version: 2.4
2
2
  Name: meshagent-agents
3
- Version: 0.0.5
3
+ Version: 0.0.7
4
4
  Summary: Agent Building Blocks for Meshagent
5
5
  Home-page:
6
6
  License: Apache License 2.0
@@ -13,9 +13,9 @@ License-File: LICENSE
13
13
  Requires-Dist: pyjwt>=2.0.0
14
14
  Requires-Dist: pytest>=8.3.4
15
15
  Requires-Dist: pytest-asyncio>=0.24.0
16
- Requires-Dist: meshagent-api>=0.0.5
17
- Requires-Dist: meshagent-tools>=0.0.5
18
- Requires-Dist: meshagent-openai>=0.0.5
16
+ Requires-Dist: meshagent-api>=0.0.7
17
+ Requires-Dist: meshagent-tools>=0.0.7
18
+ Requires-Dist: meshagent-openai>=0.0.7
19
19
  Requires-Dist: pydantic>=2.10.4
20
20
  Requires-Dist: pydantic-ai>=0.0.23
21
21
  Requires-Dist: chonkie>=0.5.1
@@ -23,6 +23,7 @@ Requires-Dist: chonkie[semantic]>=0.5.1
23
23
  Requires-Dist: chonkie[openai]>=0.5.1
24
24
  Dynamic: description-content-type
25
25
  Dynamic: license
26
+ Dynamic: license-file
26
27
  Dynamic: project-url
27
28
  Dynamic: requires-dist
28
29
  Dynamic: requires-python
@@ -0,0 +1,23 @@
1
+ meshagent/agents/__init__.py,sha256=uLDRp7W4wG0M2JHmyWBA4oYwYUsqGPD3VVHmcAddGAs,343
2
+ meshagent/agents/adapter.py,sha256=i2ck7a6B8ByXRZgtOH7chc7VT2cpk3uBAdEd93Ts7jI,1278
3
+ meshagent/agents/agent.py,sha256=3TO8buY5yGFmtZPlf1aUiVxa-O8sLoKwpREpSUVNlso,16788
4
+ meshagent/agents/chat.py,sha256=f21i_Qna0fYv0GXmyaWqpzy43hwtIeEjxo22Id5UFL0,18016
5
+ meshagent/agents/context.py,sha256=4aKEWoQHg60uuzMJ-9T3RFxVncXZ5lrOPRYKvtuuShA,3358
6
+ meshagent/agents/development.py,sha256=04VYL1Q_BWUTQeVuiVOpyjcs8bzUIX1eQ4VyTtjc5s0,926
7
+ meshagent/agents/hosting.py,sha256=e2wMGbWFt0WO3CJaTQehwbucftgUNVTgRsrBWiYDgcU,4973
8
+ meshagent/agents/indexer.py,sha256=RnnRhxPs8QkpChTp4qQNQs9qzP1gkmlo-7mmL4Cqs64,19441
9
+ meshagent/agents/listener.py,sha256=kKFaWPmvmk1aCAlI55AAU3-QnOWCSZbf621xZz10rbs,5388
10
+ meshagent/agents/planning.py,sha256=GLP97e_u7NmG1HjsucPpZndqiFPYVTEAYDdu1dQu5Go,22958
11
+ meshagent/agents/prompt.py,sha256=sidiyLLC6Lr9KO3cUTKttd2oROlcizle_4iKoaNrfhA,1864
12
+ meshagent/agents/pydantic.py,sha256=BXALTyj8O9vV-eY5ejiJoYIY4zVl9AKetsqGUxixbiY,6091
13
+ meshagent/agents/single_shot_writer.py,sha256=CJ7KgekR6JUSbYZ8OdYmhBPPjEWDYNtbIjR4g1wkWAA,3405
14
+ meshagent/agents/thread_schema.py,sha256=mmm1p7A6Eux98xsNXwGSNq_DjkMn3hsyaWsplc6akCM,2575
15
+ meshagent/agents/utils.py,sha256=Vjl1CR_K7VbTl0RRBnswfxxndhl8oJMDdOxPlOsC9Fk,1443
16
+ meshagent/agents/version.py,sha256=D0UVD6fSKhTEm2bcEShuydq4MtAQfmIq3CLzUVZH53I,21
17
+ meshagent/agents/worker.py,sha256=tKN-s0bqRCsF8DowtN5Y3TdDkayzwwGYGQcDwBxAiKM,4303
18
+ meshagent/agents/writer.py,sha256=Ff8RVxdpFNKmo6zxaGkuFMz8MIKumdM0FIXX_6lbZ6Q,2738
19
+ meshagent_agents-0.0.7.dist-info/licenses/LICENSE,sha256=eTt0SPW-sVNdkZe9PS_S8WfCIyLjRXRl7sUBWdlteFg,10254
20
+ meshagent_agents-0.0.7.dist-info/METADATA,sha256=UGqoAtFA2KYioi1Uo55VWGqhD4_xDZubGEOgzAfByrQ,918
21
+ meshagent_agents-0.0.7.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
22
+ meshagent_agents-0.0.7.dist-info/top_level.txt,sha256=GlcXnHtRP6m7zlG3Df04M35OsHtNXy_DY09oFwWrH74,10
23
+ meshagent_agents-0.0.7.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (76.1.0)
2
+ Generator: setuptools (77.0.3)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,22 +0,0 @@
1
- meshagent/agents/__init__.py,sha256=uLDRp7W4wG0M2JHmyWBA4oYwYUsqGPD3VVHmcAddGAs,343
2
- meshagent/agents/adapter.py,sha256=i2ck7a6B8ByXRZgtOH7chc7VT2cpk3uBAdEd93Ts7jI,1278
3
- meshagent/agents/agent.py,sha256=t9AwoKjF_bgPrJdN9dr73J-CkQy_oAQWyHKB1Q4RPOU,15734
4
- meshagent/agents/chat.py,sha256=5Uhy8rxsGDssLGbLkNvNPWTH4T2R8Irc9qAC3w2YP_I,17413
5
- meshagent/agents/context.py,sha256=1j38JGb0Nc0CZ0UMC_VkKjMraHZdsqBStTGNrP2nanM,3191
6
- meshagent/agents/development.py,sha256=04VYL1Q_BWUTQeVuiVOpyjcs8bzUIX1eQ4VyTtjc5s0,926
7
- meshagent/agents/hosting.py,sha256=e2wMGbWFt0WO3CJaTQehwbucftgUNVTgRsrBWiYDgcU,4973
8
- meshagent/agents/indexer.py,sha256=t7FbUxTSHSS-2pLrYSiCuv7P28y00XA8iJtEsuQjTZA,19399
9
- meshagent/agents/listener.py,sha256=kKFaWPmvmk1aCAlI55AAU3-QnOWCSZbf621xZz10rbs,5388
10
- meshagent/agents/planning.py,sha256=DTanAzanhjZ4bU6kWDFTBkw3oVcdtSj3XTKYwntoN0A,23136
11
- meshagent/agents/prompt.py,sha256=sidiyLLC6Lr9KO3cUTKttd2oROlcizle_4iKoaNrfhA,1864
12
- meshagent/agents/pydantic.py,sha256=BXALTyj8O9vV-eY5ejiJoYIY4zVl9AKetsqGUxixbiY,6091
13
- meshagent/agents/single_shot_writer.py,sha256=CJ7KgekR6JUSbYZ8OdYmhBPPjEWDYNtbIjR4g1wkWAA,3405
14
- meshagent/agents/thread_schema.py,sha256=mmm1p7A6Eux98xsNXwGSNq_DjkMn3hsyaWsplc6akCM,2575
15
- meshagent/agents/version.py,sha256=v0zqRembIW__d7HVDd71J2eoXGtALnzdY8JdBVk-BPY,21
16
- meshagent/agents/worker.py,sha256=vZ6tnOyjno8N551c5HsXR8Mw3ZPmYRa4o1MZ3i7hEG4,4374
17
- meshagent/agents/writer.py,sha256=Ff8RVxdpFNKmo6zxaGkuFMz8MIKumdM0FIXX_6lbZ6Q,2738
18
- meshagent_agents-0.0.5.dist-info/LICENSE,sha256=eTt0SPW-sVNdkZe9PS_S8WfCIyLjRXRl7sUBWdlteFg,10254
19
- meshagent_agents-0.0.5.dist-info/METADATA,sha256=nSnJIv-rOhIRwum8fEIWnhMESU3D3-6HQVhSglPzKxA,896
20
- meshagent_agents-0.0.5.dist-info/WHEEL,sha256=beeZ86-EfXScwlR_HKu4SllMC9wUEj_8Z_4FJ3egI2w,91
21
- meshagent_agents-0.0.5.dist-info/top_level.txt,sha256=GlcXnHtRP6m7zlG3Df04M35OsHtNXy_DY09oFwWrH74,10
22
- meshagent_agents-0.0.5.dist-info/RECORD,,