meshagent-agents 0.0.36__py3-none-any.whl → 0.0.38__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
@@ -1,21 +1,34 @@
1
- import json
2
- from copy import deepcopy
3
-
4
1
  from typing import Optional
5
2
 
6
3
  from meshagent.api.messaging import unpack_message, pack_message
7
- from meshagent.api.room_server_client import RoomException, RequiredToolkit, Requirement, RequiredSchema
8
- from meshagent.api import WebSocketClientProtocol, ToolDescription, ToolkitDescription, Participant, RemoteParticipant, meshagent_base_url, StorageEntry, JsonResponse
4
+ from meshagent.api.room_server_client import (
5
+ RoomException,
6
+ RequiredToolkit,
7
+ Requirement,
8
+ RequiredSchema,
9
+ )
10
+ from meshagent.api import (
11
+ ToolDescription,
12
+ ToolkitDescription,
13
+ Participant,
14
+ RemoteParticipant,
15
+ meshagent_base_url,
16
+ StorageEntry,
17
+ )
9
18
  from meshagent.api.protocol import Protocol
10
- from meshagent.tools.toolkit import Toolkit, Tool, ToolContext, toolkit_factory, register_toolkit_factory
11
- from meshagent.api.room_server_client import RoomClient, RoomException
19
+ from meshagent.tools.toolkit import (
20
+ Toolkit,
21
+ Tool,
22
+ ToolContext,
23
+ toolkit_factory,
24
+ register_toolkit_factory,
25
+ )
26
+ from meshagent.api.room_server_client import RoomClient
12
27
  from jsonschema import validate
13
28
  from .context import AgentCallContext, AgentChatContext
14
29
  from meshagent.api.schema_util import no_arguments_schema
15
- from meshagent.api import MeshSchema
16
30
  import logging
17
31
  import asyncio
18
- from typing import Optional, Dict, Callable, Coroutine
19
32
 
20
33
  logger = logging.getLogger("agent")
21
34
 
@@ -25,97 +38,135 @@ class AgentException(RoomException):
25
38
 
26
39
 
27
40
  class RoomTool(Tool):
28
- def __init__(self, *, toolkit_name: str, name, input_schema, title = None, description = None, rules = None, thumbnail_url = None, participant_id: Optional[str] = None, on_behalf_of_id: Optional[str] = None, defs: Optional[dict] = None):
41
+ def __init__(
42
+ self,
43
+ *,
44
+ toolkit_name: str,
45
+ name,
46
+ input_schema,
47
+ title=None,
48
+ description=None,
49
+ rules=None,
50
+ thumbnail_url=None,
51
+ participant_id: Optional[str] = None,
52
+ on_behalf_of_id: Optional[str] = None,
53
+ defs: Optional[dict] = None,
54
+ ):
29
55
  self._toolkit_name = toolkit_name
30
56
  self._participant_id = participant_id
31
57
  self._on_behalf_of_id = on_behalf_of_id
32
58
 
33
- super().__init__(name=name, input_schema=input_schema, title=title, description=description, rules=rules, thumbnail_url=thumbnail_url, defs=defs)
59
+ super().__init__(
60
+ name=name,
61
+ input_schema=input_schema,
62
+ title=title,
63
+ description=description,
64
+ rules=rules,
65
+ thumbnail_url=thumbnail_url,
66
+ defs=defs,
67
+ )
34
68
 
35
69
  async def execute(self, context, **kwargs):
36
- return await context.room.agents.invoke_tool(
70
+ return await context.room.agents.invoke_tool(
37
71
  toolkit=self._toolkit_name,
38
72
  tool=self.name,
39
73
  participant_id=self._participant_id,
40
74
  on_behalf_of_id=self._on_behalf_of_id,
41
75
  arguments=kwargs,
42
-
43
76
  )
44
-
45
- class Agent:
46
77
 
47
- def __init__(self, *, name: str, title: Optional[str] = None, description: Optional[str] = None, requires: Optional[list[Requirement]] = None, labels: Optional[list[str]] = None):
48
-
78
+
79
+ class Agent:
80
+ def __init__(
81
+ self,
82
+ *,
83
+ name: str,
84
+ title: Optional[str] = None,
85
+ description: Optional[str] = None,
86
+ requires: Optional[list[Requirement]] = None,
87
+ labels: Optional[list[str]] = None,
88
+ ):
49
89
  self._name = name
50
- if title == None:
90
+ if title is None:
51
91
  title = name
52
92
  self._title = title
53
- if description == None:
93
+ if description is None:
54
94
  description = ""
55
95
 
56
96
  self._description = description
57
- if requires == None:
97
+ if requires is None:
58
98
  requires = []
59
99
 
60
100
  self.init_requirements(requires)
61
101
  self._requires = requires
62
-
63
- if labels == None:
102
+
103
+ if labels is None:
64
104
  labels = []
65
-
105
+
66
106
  self._labels = labels
67
107
 
68
108
  @property
69
109
  def name(self):
70
110
  return self._name
71
-
111
+
72
112
  @property
73
113
  def description(self):
74
114
  return self._description
75
-
115
+
76
116
  @property
77
117
  def title(self):
78
118
  return self._title
79
-
119
+
80
120
  @property
81
121
  def requires(self):
82
122
  return self._requires
83
-
123
+
84
124
  @property
85
125
  def labels(self):
86
126
  return self._labels
87
-
127
+
88
128
  def init_requirements(self, requires): ...
89
-
129
+
90
130
  async def init_chat_context(self) -> AgentChatContext:
91
- return AgentChatContext()
131
+ return AgentChatContext()
92
132
 
93
133
  def to_json(self) -> dict:
94
134
  return {
95
- "name" : self.name,
96
- "title" : self.title,
97
- "description" : self.description,
98
- "requires" : list(map(lambda x: x.to_json(), self.requires)),
99
- "labels" : self.labels
135
+ "name": self.name,
136
+ "title": self.title,
137
+ "description": self.description,
138
+ "requires": list(map(lambda x: x.to_json(), self.requires)),
139
+ "labels": self.labels,
100
140
  }
101
141
 
102
- class SingleRoomAgent(Agent):
103
142
 
104
- def __init__(self, *, name, title = None, description = None, requires = None, labels: Optional[list[str]] = None):
105
- super().__init__(name=name, title=title, description=description, requires=requires, labels=labels)
143
+ class SingleRoomAgent(Agent):
144
+ def __init__(
145
+ self,
146
+ *,
147
+ name,
148
+ title=None,
149
+ description=None,
150
+ requires=None,
151
+ labels: Optional[list[str]] = None,
152
+ ):
153
+ super().__init__(
154
+ name=name,
155
+ title=title,
156
+ description=description,
157
+ requires=requires,
158
+ labels=labels,
159
+ )
106
160
  self._room = None
107
161
 
108
-
109
162
  async def start(self, *, room: RoomClient) -> None:
110
-
111
- if self._room != None:
163
+ if self._room is not None:
112
164
  raise RoomException("room is already started")
113
-
165
+
114
166
  self._room = room
115
167
 
116
168
  await self.install_requirements()
117
169
 
118
-
119
170
  async def stop(self) -> None:
120
171
  self._room = None
121
172
  pass
@@ -123,70 +174,70 @@ class SingleRoomAgent(Agent):
123
174
  @property
124
175
  def room(self):
125
176
  return self._room
126
-
177
+
127
178
  async def install_requirements(self, participant_id: Optional[str] = None):
128
-
129
179
  schemas_by_name = dict[str, StorageEntry]()
130
180
 
131
181
  schemas = await self._room.storage.list(path=".schemas")
132
-
182
+
133
183
  for schema in schemas:
134
184
  schemas_by_name[schema.name] = schema
135
185
 
136
186
  toolkits_by_name = dict[str, ToolkitDescription]()
137
187
 
138
- visible_tools = await self._room.agents.list_toolkits(participant_id=participant_id)
139
-
188
+ visible_tools = await self._room.agents.list_toolkits(
189
+ participant_id=participant_id
190
+ )
191
+
140
192
  for toolkit_description in visible_tools:
141
193
  toolkits_by_name[toolkit_description.name] = toolkit_description
142
194
 
143
195
  installed = False
144
196
 
145
197
  for requirement in self.requires:
146
-
147
198
  if isinstance(requirement, RequiredToolkit):
148
-
149
- if toolkit_factory(requirement.name) != None:
199
+ if toolkit_factory(requirement.name) is not None:
150
200
  # no need to install something we can create from a factory
151
201
  continue
152
202
 
153
203
  if requirement.name == "ui":
154
204
  # TODO: maybe requirements can be marked as non installable?
155
205
  continue
156
-
206
+
157
207
  if requirement.name not in toolkits_by_name:
158
-
159
208
  installed = True
160
209
 
161
210
  logger.info(f"Installing required tool {requirement.name}")
162
-
211
+
163
212
  if requirement.name.startswith("https://"):
164
213
  url = requirement.name
165
214
  else:
166
215
  url = f"{meshagent_base_url()}/toolkits/{requirement.name}"
167
216
 
168
- await self._room.agents.make_call(url=url, name=requirement.name, arguments={})
169
-
170
- elif isinstance(requirement, RequiredSchema):
217
+ await self._room.agents.make_call(
218
+ url=url, name=requirement.name, arguments={}
219
+ )
171
220
 
221
+ elif isinstance(requirement, RequiredSchema):
172
222
  if requirement.name not in schemas_by_name:
173
-
174
223
  installed = True
175
224
 
176
225
  schema_path = f".schemas/{requirement.name}.json"
177
-
226
+
178
227
  if await self._room.storage.exists(path=schema_path):
179
228
  # Schema is already in the room
180
229
  pass
181
230
  else:
182
231
  logger.info(f"Installing required tool {requirement.name}")
183
-
232
+
184
233
  if requirement.name.startswith("https://"):
185
234
  url = requirement.name
186
235
  else:
187
236
  url = f"{meshagent_base_url()}/schemas/{requirement.name}"
188
-
189
- await self._room.agents.make_call(url=url, name=requirement.name, arguments={})
237
+
238
+ await self._room.agents.make_call(
239
+ url=url, name=requirement.name, arguments={}
240
+ )
190
241
 
191
242
  else:
192
243
  raise RoomException("unsupported requirement")
@@ -195,43 +246,39 @@ class SingleRoomAgent(Agent):
195
246
  await asyncio.sleep(5)
196
247
 
197
248
  async def get_required_toolkits(self, context: ToolContext) -> list[Toolkit]:
198
-
199
-
200
249
  tool_target = context.caller
201
- if context.on_behalf_of != None:
250
+ if context.on_behalf_of is not None:
202
251
  tool_target = context.on_behalf_of
203
252
 
204
253
  toolkits_by_name = dict[str, ToolkitDescription]()
205
254
 
206
255
  toolkits = list[Toolkit]()
207
256
 
208
- visible_tools = await self._room.agents.list_toolkits(participant_id=tool_target.id)
257
+ visible_tools = await self._room.agents.list_toolkits(
258
+ participant_id=tool_target.id
259
+ )
209
260
 
210
261
  for toolkit_description in visible_tools:
211
262
  toolkits_by_name[toolkit_description.name] = toolkit_description
212
263
 
213
-
214
264
  for required_toolkit in self.requires:
215
-
216
265
  if isinstance(required_toolkit, RequiredToolkit):
217
-
218
- if toolkit_factory(required_toolkit.name) != None:
219
-
220
-
221
- toolkit = await toolkit_factory(required_toolkit.name)(context, required_toolkit)
266
+ if toolkit_factory(required_toolkit.name) is not None:
267
+ toolkit = await toolkit_factory(required_toolkit.name)(
268
+ context, required_toolkit
269
+ )
222
270
  toolkits.append(toolkit)
223
271
  continue
224
272
 
225
-
226
273
  toolkit = toolkits_by_name.get(required_toolkit.name, None)
227
- if toolkit == None:
228
- raise RoomException(f"unable to locate required toolkit {required_toolkit.name}")
274
+ if toolkit is None:
275
+ raise RoomException(
276
+ f"unable to locate required toolkit {required_toolkit.name}"
277
+ )
229
278
 
230
279
  room_tools = list[RoomTool]()
231
-
232
-
233
- if required_toolkit.tools == None:
234
280
 
281
+ if required_toolkit.tools is None:
235
282
  for tool_description in toolkit.tools:
236
283
  tool = RoomTool(
237
284
  on_behalf_of_id=tool_target.id,
@@ -242,7 +289,7 @@ class SingleRoomAgent(Agent):
242
289
  title=tool_description.title,
243
290
  thumbnail_url=tool_description.thumbnail_url,
244
291
  participant_id=tool_target.id,
245
- defs = tool_description.defs
292
+ defs=tool_description.defs,
246
293
  )
247
294
  room_tools.append(tool)
248
295
 
@@ -252,10 +299,11 @@ class SingleRoomAgent(Agent):
252
299
  tools_by_name[tool_description.name] = tool_description
253
300
 
254
301
  for required_tool in required_toolkit.tools:
255
-
256
302
  tool_description = tools_by_name.get(required_tool, None)
257
- if tool_description == None:
258
- raise RoomException(f"unable to locate required tool {required_tool}")
303
+ if tool_description is None:
304
+ raise RoomException(
305
+ f"unable to locate required tool {required_tool}"
306
+ )
259
307
 
260
308
  tool = RoomTool(
261
309
  on_behalf_of_id=tool_target.id,
@@ -266,60 +314,78 @@ class SingleRoomAgent(Agent):
266
314
  title=tool_description.title,
267
315
  thumbnail_url=tool_description.thumbnail_url,
268
316
  participant_id=tool_target.id,
269
- defs = tool_description.defs
317
+ defs=tool_description.defs,
270
318
  )
271
319
  room_tools.append(tool)
272
320
 
273
- toolkits.append(Toolkit(
274
- name = toolkit.name,
275
- title = toolkit.title,
276
- description = toolkit.description,
277
- thumbnail_url = toolkit.thumbnail_url,
278
- tools = room_tools,
279
- ))
321
+ toolkits.append(
322
+ Toolkit(
323
+ name=toolkit.name,
324
+ title=toolkit.title,
325
+ description=toolkit.description,
326
+ thumbnail_url=toolkit.thumbnail_url,
327
+ tools=room_tools,
328
+ )
329
+ )
280
330
 
281
331
  return toolkits
282
-
283
- class TaskRunner(SingleRoomAgent):
284
332
 
285
- 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):
286
- super().__init__(name=name, title=title, description=description, requires=requires, labels=labels)
287
333
 
288
- if toolkits == None:
334
+ class TaskRunner(SingleRoomAgent):
335
+ def __init__(
336
+ self,
337
+ *,
338
+ name,
339
+ title=None,
340
+ description=None,
341
+ requires=None,
342
+ supports_tools: Optional[bool] = None,
343
+ input_schema: dict,
344
+ output_schema: dict,
345
+ labels: Optional[list[str]] = None,
346
+ toolkits: Optional[list[Toolkit]] = None,
347
+ ):
348
+ super().__init__(
349
+ name=name,
350
+ title=title,
351
+ description=description,
352
+ requires=requires,
353
+ labels=labels,
354
+ )
355
+
356
+ if toolkits is None:
289
357
  toolkits = []
290
358
 
291
359
  self._toolkits = toolkits
292
360
 
293
- self._registration_id = None
361
+ self._registration_id = None
294
362
 
295
- if input_schema == None:
363
+ if input_schema is None:
296
364
  input_schema = no_arguments_schema(
297
365
  description="execute the agent",
298
366
  )
299
367
 
300
- if supports_tools == None:
368
+ if supports_tools is None:
301
369
  supports_tools = False
302
-
370
+
303
371
  self._supports_tools = supports_tools
304
372
  self._input_schema = input_schema
305
373
  self._output_schema = output_schema
306
-
307
374
 
308
-
309
375
  async def validate_arguments(self, arguments: dict):
310
376
  validate(arguments, self.input_schema)
311
377
 
312
378
  async def validate_response(self, response: dict):
313
- if self.output_schema != None:
379
+ if self.output_schema is not None:
314
380
  validate(response, self.output_schema)
315
381
 
316
382
  async def ask(self, *, context: AgentCallContext, arguments: dict) -> dict:
317
383
  raise Exception("Not implemented")
318
-
384
+
319
385
  @property
320
386
  def supports_tools(self):
321
387
  return self._supports_tools
322
-
388
+
323
389
  @property
324
390
  def input_schema(self):
325
391
  return self._input_schema
@@ -330,203 +396,240 @@ class TaskRunner(SingleRoomAgent):
330
396
 
331
397
  def to_json(self) -> dict:
332
398
  return {
333
- "name" : self.name,
334
- "title" : self.title,
335
- "description" : self.description,
336
- "input_schema" : self.input_schema,
337
- "output_schema" : self.output_schema,
338
- "requires" : list(map(lambda x: x.to_json(), self.requires)),
339
- "supports_tools" : self.supports_tools,
340
- "labels" : self.labels
399
+ "name": self.name,
400
+ "title": self.title,
401
+ "description": self.description,
402
+ "input_schema": self.input_schema,
403
+ "output_schema": self.output_schema,
404
+ "requires": list(map(lambda x: x.to_json(), self.requires)),
405
+ "supports_tools": self.supports_tools,
406
+ "labels": self.labels,
341
407
  }
342
-
408
+
343
409
  async def _register(self):
344
- self._registration_id = (await self._room.send_request("agent.register_agent", {
345
- "name": self.name,
346
- "title" : self.title,
347
- "description" : self.description,
348
- "input_schema" : self.input_schema,
349
- "output_schema" : self.output_schema,
350
- "requires" : list(map(lambda x : x.to_json(), self.requires)),
351
- "supports_tools" : self.supports_tools,
352
- "labels" : self.labels
353
- }))["id"]
354
-
410
+ self._registration_id = (
411
+ await self._room.send_request(
412
+ "agent.register_agent",
413
+ {
414
+ "name": self.name,
415
+ "title": self.title,
416
+ "description": self.description,
417
+ "input_schema": self.input_schema,
418
+ "output_schema": self.output_schema,
419
+ "requires": list(map(lambda x: x.to_json(), self.requires)),
420
+ "supports_tools": self.supports_tools,
421
+ "labels": self.labels,
422
+ },
423
+ )
424
+ )["id"]
355
425
 
356
426
  async def _unregister(self):
357
- await self._room.send_request("agent.unregister_agent", {
358
- "id": self._registration_id
359
- })
360
- self._registration_id = None
361
-
427
+ await self._room.send_request(
428
+ "agent.unregister_agent", {"id": self._registration_id}
429
+ )
430
+ self._registration_id = None
362
431
 
363
432
  async def start(self, *, room: RoomClient):
364
-
365
433
  await super().start(room=room)
366
434
 
367
435
  self._room.protocol.register_handler("agent.ask", self._ask)
368
436
  await self._register()
369
-
370
437
 
371
- async def stop(self):
438
+ async def stop(self):
372
439
  if self.room.protocol.is_open:
373
440
  await self._unregister()
374
441
  else:
375
- logger.info(f"disconnected '{self.name}' from room, this will automatically happen when all the users leave the room. agents will not keep the room open")
442
+ logger.info(
443
+ f"disconnected '{self.name}' from room, this will automatically happen when all the users leave the room. agents will not keep the room open"
444
+ )
376
445
 
377
446
  self._room.protocol.unregister_handler("agent.ask", self._ask)
378
447
 
379
448
  await super().stop()
380
449
 
381
- async def _ask(self, protocol:Protocol, message_id:int, msg_type:str, data:bytes):
382
-
383
-
450
+ async def _ask(
451
+ self, protocol: Protocol, message_id: int, msg_type: str, data: bytes
452
+ ):
384
453
  async def worker():
385
454
  # Decode and parse the message
386
455
  message, _ = unpack_message(data)
387
456
  logger.info("agent got message %s", message)
388
457
  args = message["arguments"]
389
- task_id = message["task_id"]
390
- context_json = message["context"]
458
+ task_id = message["task_id"]
391
459
  toolkits_json = message["toolkits"]
392
-
393
- #context_json = message["context"]
460
+
461
+ # context_json = message["context"]
394
462
 
395
463
  chat_context = None
396
464
 
397
465
  try:
398
466
  chat_context = await self.init_chat_context()
399
467
 
400
- caller : Participant | None = None
401
- on_behalf_of : Participant | None = None
402
- on_behalf_of_id = message.get("on_behalf_of_id", None)
403
-
468
+ caller: Participant | None = None
469
+ on_behalf_of: Participant | None = None
470
+ on_behalf_of_id = message.get("on_behalf_of_id", None)
471
+
404
472
  for participant in self._room.messaging.get_participants():
405
473
  if message["caller_id"] == participant.id:
406
474
  caller = participant
407
475
  break
408
-
476
+
409
477
  if on_behalf_of_id == participant.id:
410
478
  on_behalf_of = participant
411
479
  break
412
480
 
413
- if caller == None:
481
+ if caller is None:
414
482
  caller = RemoteParticipant(
415
- id=message["caller_id"],
416
- role="user",
417
- attributes={}
483
+ id=message["caller_id"], role="user", attributes={}
418
484
  )
419
485
 
420
- if on_behalf_of_id != None and on_behalf_of == None:
486
+ if on_behalf_of_id is not None and on_behalf_of is None:
421
487
  on_behalf_of = RemoteParticipant(
422
- id=message["on_behalf_of_id"],
423
- role="user",
424
- attributes={}
488
+ id=message["on_behalf_of_id"], role="user", attributes={}
425
489
  )
426
-
490
+
427
491
  tool_target = caller
428
- if on_behalf_of != None:
492
+ if on_behalf_of is not None:
429
493
  tool_target = on_behalf_of
430
494
 
431
-
432
495
  toolkits = [
433
496
  *self._toolkits,
434
- *await self.get_required_toolkits(context=ToolContext(room=self.room, caller=caller, on_behalf_of=on_behalf_of, caller_context={ "chat": chat_context.to_json() }))
497
+ *await self.get_required_toolkits(
498
+ context=ToolContext(
499
+ room=self.room,
500
+ caller=caller,
501
+ on_behalf_of=on_behalf_of,
502
+ caller_context={"chat": chat_context.to_json()},
503
+ )
504
+ ),
435
505
  ]
436
506
 
437
- context = AgentCallContext(chat=chat_context, room=self.room, caller=caller, on_behalf_of=on_behalf_of, toolkits=toolkits)
438
-
507
+ context = AgentCallContext(
508
+ chat=chat_context,
509
+ room=self.room,
510
+ caller=caller,
511
+ on_behalf_of=on_behalf_of,
512
+ toolkits=toolkits,
513
+ )
514
+
439
515
  for toolkit_json in toolkits_json:
440
516
  tools = []
441
517
  for tool_json in toolkit_json["tools"]:
442
- tools.append(RoomTool(
443
- on_behalf_of_id=on_behalf_of_id,
444
- participant_id=tool_target.id,
445
- toolkit_name=toolkit_json["name"],
446
- name=tool_json["name"],
447
- title=tool_json["title"],
448
- description=tool_json["description"],
449
- input_schema=tool_json["input_schema"],
450
- thumbnail_url=toolkit_json["thumbnail_url"],
451
- defs=tool_json.get("defs", None)
452
- ))
453
-
454
- context.toolkits.append(Toolkit(
455
- name=toolkit_json["name"],
456
- title=toolkit_json["title"],
457
- description=toolkit_json["description"],
458
- thumbnail_url=toolkit_json["thumbnail_url"],
459
- tools=tools,
460
- ))
518
+ tools.append(
519
+ RoomTool(
520
+ on_behalf_of_id=on_behalf_of_id,
521
+ participant_id=tool_target.id,
522
+ toolkit_name=toolkit_json["name"],
523
+ name=tool_json["name"],
524
+ title=tool_json["title"],
525
+ description=tool_json["description"],
526
+ input_schema=tool_json["input_schema"],
527
+ thumbnail_url=toolkit_json["thumbnail_url"],
528
+ defs=tool_json.get("defs", None),
529
+ )
530
+ )
461
531
 
532
+ context.toolkits.append(
533
+ Toolkit(
534
+ name=toolkit_json["name"],
535
+ title=toolkit_json["title"],
536
+ description=toolkit_json["description"],
537
+ thumbnail_url=toolkit_json["thumbnail_url"],
538
+ tools=tools,
539
+ )
540
+ )
462
541
 
463
-
464
542
  response = await self.ask(context=context, arguments=args)
465
-
466
- await protocol.send(type="agent.ask_response", data=pack_message({
467
- "task_id" : task_id,
468
- "answer" : response,
469
- "caller_context" : {
470
- "chat" : chat_context.to_json()
471
- }
472
- }))
543
+
544
+ await protocol.send(
545
+ type="agent.ask_response",
546
+ data=pack_message(
547
+ {
548
+ "task_id": task_id,
549
+ "answer": response,
550
+ "caller_context": {"chat": chat_context.to_json()},
551
+ }
552
+ ),
553
+ )
473
554
 
474
555
  except Exception as e:
475
556
  logger.error("Task runner failed to complete task", exc_info=e)
476
- if chat_context != None:
477
-
478
- await protocol.send(type="agent.ask_response", data=pack_message({
479
- "task_id" : task_id,
480
- "error" : str(e),
481
- "caller_context" : {
482
- "chat" : chat_context.to_json()
483
- }
484
- }))
557
+ if chat_context is not None:
558
+ await protocol.send(
559
+ type="agent.ask_response",
560
+ data=pack_message(
561
+ {
562
+ "task_id": task_id,
563
+ "error": str(e),
564
+ "caller_context": {"chat": chat_context.to_json()},
565
+ }
566
+ ),
567
+ )
485
568
  else:
486
- await protocol.send(type="agent.ask_response", data=pack_message({
487
- "task_id" : task_id,
488
- "error" : str(e),
489
- }))
569
+ await protocol.send(
570
+ type="agent.ask_response",
571
+ data=pack_message(
572
+ {
573
+ "task_id": task_id,
574
+ "error": str(e),
575
+ }
576
+ ),
577
+ )
490
578
 
491
579
  def on_done(task: asyncio.Task):
492
580
  task.result()
493
581
 
494
582
  task = asyncio.create_task(worker())
495
- task.add_done_callback(on_done)
583
+ task.add_done_callback(on_done)
496
584
 
497
585
 
498
586
  class RunTaskTool(Tool):
499
- def __init__(self, *, name: str, agent_name: str, input_schema: dict, rules = None, thumbnail_url = None, title: Optional[str] = None, description: Optional[str] = None):
500
- super().__init__(name=name, input_schema=input_schema, rules=rules, thumbnail_url=thumbnail_url, title=title, description=description)
587
+ def __init__(
588
+ self,
589
+ *,
590
+ name: str,
591
+ agent_name: str,
592
+ input_schema: dict,
593
+ rules=None,
594
+ thumbnail_url=None,
595
+ title: Optional[str] = None,
596
+ description: Optional[str] = None,
597
+ ):
598
+ super().__init__(
599
+ name=name,
600
+ input_schema=input_schema,
601
+ rules=rules,
602
+ thumbnail_url=thumbnail_url,
603
+ title=title,
604
+ description=description,
605
+ )
501
606
 
502
607
  self._agent_name = agent_name
503
608
 
504
609
  async def execute(self, context: ToolContext, **kwargs):
505
610
  return await context.room.agents.ask(agent=self._agent_name, arguments=kwargs)
506
-
507
611
 
508
- async def make_run_task_tool(context: ToolContext, toolkit: RequiredToolkit):
509
612
 
613
+ async def make_run_task_tool(context: ToolContext, toolkit: RequiredToolkit):
510
614
  agents = await context.room.agents.list_agents()
511
615
  tools = []
512
616
  for agent_name in toolkit.tools:
513
617
  agent = next((x for x in agents if x.name == agent_name), None)
514
618
 
515
- if agent == None:
619
+ if agent is None:
516
620
  raise RoomException(f"agent was not found in the room {agent_name}")
517
-
621
+
518
622
  tools.append(
519
623
  RunTaskTool(
520
624
  agent_name=agent_name,
521
625
  name=f"run_{agent_name}",
522
626
  input_schema=agent.input_schema,
523
627
  title=agent.title,
524
- description=agent.description
525
- ))
628
+ description=agent.description,
629
+ )
630
+ )
631
+
632
+ return Toolkit(name="agents", tools=tools)
526
633
 
527
- return Toolkit(
528
- name="agents",
529
- tools=tools
530
- )
531
634
 
532
635
  register_toolkit_factory("agents", make_run_task_tool)