meshagent-agents 0.0.37__py3-none-any.whl → 0.0.39__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.

@@ -1,18 +1,20 @@
1
- from meshagent.agents.agent import AgentCallContext, AgentChatContext, AgentException
2
- from meshagent.api import WebSocketClientProtocol, RequiredToolkit, RequiredSchema, Requirement
3
- from meshagent.api.schema_document import Document
4
- from meshagent.api.room_server_client import RoomClient
5
- from meshagent.tools.toolkit import Toolkit, TextResponse, Tool, ToolContext
1
+ from meshagent.agents.agent import AgentCallContext, AgentException
2
+ from meshagent.api import Requirement
3
+ from meshagent.api.messaging import TextResponse
4
+ from meshagent.tools.toolkit import Toolkit, Tool, ToolContext
6
5
  from meshagent.api.schema import MeshSchema
7
6
  from meshagent.agents.writer import Writer, WriterContext
8
7
  from meshagent.agents.adapter import LLMAdapter, ToolResponseAdapter
9
- from meshagent.api.schema import MeshSchema, ElementType, ChildProperty, ValueProperty
8
+ from meshagent.api.schema import ElementType, ChildProperty, ValueProperty
10
9
  from meshagent.api.schema_util import merge
11
10
  from meshagent.tools.document_tools import build_tools, DocumentAuthoringToolkit
12
11
  from meshagent.agents import TaskRunner
13
12
  from copy import deepcopy
14
13
  from typing import Optional
15
14
 
15
+ from meshagent.api.schema_util import prompt_schema
16
+ import logging
17
+
16
18
  reasoning_rules = [
17
19
  "If an ask_user tool call is available, plans should include a series of questions to ask the user to help refine.",
18
20
  "If an ask_user tool call is available, ask a maximum of one question per step",
@@ -21,32 +23,32 @@ reasoning_rules = [
21
23
  "Do not use tool calls to write estimates of progress or plans",
22
24
  "You are a document generation service",
23
25
  "The user is asking for a document to be created",
24
- "You must use tool calls must to generate the answer to the user's question as document"
26
+ "You must use tool calls must to generate the answer to the user's question as document",
25
27
  ]
26
28
 
27
29
  goto_next_step_message = """
28
30
  execute the next step, and provide the result of the step.
29
31
  """
30
32
 
33
+
31
34
  def is_reasoning_done(*, context: AgentCallContext, response: dict) -> bool:
32
35
  parsed = response["response"]["data"][0]
33
36
  if "abort" in parsed:
34
37
  abort = parsed["abort"]
35
38
  reason = abort["reason"]
36
39
  raise AgentException(reason)
37
-
40
+
38
41
  elif "progress" in parsed:
39
42
  result = parsed["progress"]
40
-
43
+
41
44
  if "done" not in result or result["done"]:
42
45
  logger.info("Done generating response %s", result)
43
46
  return True
44
47
  else:
45
48
  context.chat.append_user_message(goto_next_step_message)
46
49
  return False
47
-
50
+
48
51
  elif "plan" in parsed:
49
- plan = parsed["plan"]
50
52
  context.chat.append_user_message(goto_next_step_message)
51
53
  return False
52
54
  else:
@@ -54,29 +56,57 @@ def is_reasoning_done(*, context: AgentCallContext, response: dict) -> bool:
54
56
  context.chat.append_user_message("this response did not conform to the schema")
55
57
  return False
56
58
 
57
- def reasoning_schema(*, description: str, elements: Optional[list[ElementType]] = None, has_done_property: bool = True, has_abort: bool = True) -> MeshSchema:
58
59
 
59
- if elements == None:
60
+ def reasoning_schema(
61
+ *,
62
+ description: str,
63
+ elements: Optional[list[ElementType]] = None,
64
+ has_done_property: bool = True,
65
+ has_abort: bool = True,
66
+ ) -> MeshSchema:
67
+ if elements is None:
60
68
  elements = []
61
69
 
62
70
  progress_properties = [
63
- ValueProperty(name="percentage", description="an estimate for how complete the task is so far", type="string"),
64
- ValueProperty(name="next", description="a very short description of the next step", type="string"),
71
+ ValueProperty(
72
+ name="percentage",
73
+ description="an estimate for how complete the task is so far",
74
+ type="string",
75
+ ),
76
+ ValueProperty(
77
+ name="next",
78
+ description="a very short description of the next step",
79
+ type="string",
80
+ ),
65
81
  ]
66
82
 
67
83
  if has_done_property:
68
- progress_properties.append( ValueProperty(name="done", description="whether there is more work to do. the program will continue will continue to send messages to the LLM to refine the answer until done is set to true.", type="boolean") )
84
+ progress_properties.append(
85
+ ValueProperty(
86
+ name="done",
87
+ description="whether there is more work to do. the program will continue will continue to send messages to the LLM to refine the answer until done is set to true.",
88
+ type="boolean",
89
+ )
90
+ )
69
91
 
70
92
  elements = elements.copy()
71
93
 
72
94
  if has_abort:
73
- elements.append(ElementType(
74
- tag_name="abort",
75
- description="return if the task cannot completed because the user cancelled a request or errors could not be resolved",
76
- properties=[
77
- ValueProperty(name="reason", description="the reason the task was aborted", type="string")
78
- ]
79
- )),
95
+ (
96
+ elements.append(
97
+ ElementType(
98
+ tag_name="abort",
99
+ description="return if the task cannot completed because the user cancelled a request or errors could not be resolved",
100
+ properties=[
101
+ ValueProperty(
102
+ name="reason",
103
+ description="the reason the task was aborted",
104
+ type="string",
105
+ )
106
+ ],
107
+ )
108
+ ),
109
+ )
80
110
 
81
111
  return MeshSchema(
82
112
  root_tag_name="response",
@@ -85,88 +115,109 @@ def reasoning_schema(*, description: str, elements: Optional[list[ElementType]]
85
115
  tag_name="response",
86
116
  description="a response for a task",
87
117
  properties=[
88
- ChildProperty(name="data", description="the response for a task, should contain a single item", child_tag_names=[
89
- "plan","progress",
90
- *map(lambda x: x.tag_name, elements)
91
- ])
92
- ]
118
+ ChildProperty(
119
+ name="data",
120
+ description="the response for a task, should contain a single item",
121
+ child_tag_names=[
122
+ "plan",
123
+ "progress",
124
+ *map(lambda x: x.tag_name, elements),
125
+ ],
126
+ )
127
+ ],
93
128
  ),
94
129
  ElementType(
95
130
  tag_name="plan",
96
131
  description="a plan will be output for each task to describe the work that will be done, the work will be performed using tool calls.",
97
132
  properties=[
98
- ChildProperty(name="steps", description="the steps for the plan", child_tag_names=["step"])
99
- ]
133
+ ChildProperty(
134
+ name="steps",
135
+ description="the steps for the plan",
136
+ child_tag_names=["step"],
137
+ )
138
+ ],
100
139
  ),
101
140
  ElementType(
102
141
  tag_name="step",
103
142
  description="a step in the plan",
104
143
  properties=[
105
- ValueProperty(name="description", description="a short sentence description description of the work that will be performed to complete the user's request.", type="string")
144
+ ValueProperty(
145
+ name="description",
146
+ description="a short sentence description description of the work that will be performed to complete the user's request.",
147
+ type="string",
148
+ )
106
149
  ],
107
150
  ),
108
151
  ElementType(
109
152
  tag_name="progress",
110
153
  description="the progress of the task",
111
- properties=progress_properties
154
+ properties=progress_properties,
112
155
  ),
113
156
  ElementType(
114
157
  tag_name="thinking",
115
158
  description="use to log information that will not be included in the final answer",
116
159
  properties=[
117
- ValueProperty(name="text", description="used to log thoughts or progress", type="string"),
160
+ ValueProperty(
161
+ name="text",
162
+ description="used to log thoughts or progress",
163
+ type="string",
164
+ ),
118
165
  ],
119
166
  ),
120
- *elements
121
- ])
167
+ *elements,
168
+ ],
169
+ )
122
170
 
123
- from meshagent.api.schema_util import prompt_schema
124
- import logging
125
171
 
126
172
  logger = logging.getLogger("planning_agent")
127
173
 
128
174
 
129
-
130
175
  class PlanningWriter(Writer):
131
-
132
- def __init__(self, *, name: str, llm_adapter: LLMAdapter, tool_adapter: Optional[ToolResponseAdapter] = None, max_iterations : int = 100, toolkits: Optional[list[Tool]] = None, title: Optional[str] = None, description: Optional[str] = None, rules: Optional[list[str]] | None = None, requires: Optional[list[Requirement]] = None, supports_tools: Optional[bool] = None):
133
-
176
+ def __init__(
177
+ self,
178
+ *,
179
+ name: str,
180
+ llm_adapter: LLMAdapter,
181
+ tool_adapter: Optional[ToolResponseAdapter] = None,
182
+ max_iterations: int = 100,
183
+ toolkits: Optional[list[Tool]] = None,
184
+ title: Optional[str] = None,
185
+ description: Optional[str] = None,
186
+ rules: Optional[list[str]] | None = None,
187
+ requires: Optional[list[Requirement]] = None,
188
+ supports_tools: Optional[bool] = None,
189
+ ):
134
190
  super().__init__(
135
191
  name=name,
136
192
  description=description,
137
193
  title=title,
138
194
  input_schema=merge(
139
- schema=prompt_schema(description="use a prompt to generate content"),
140
- additional_properties={
141
- "path" : { "type" : "string" }
142
- }),
195
+ schema=prompt_schema(description="use a prompt to generate content"),
196
+ additional_properties={"path": {"type": "string"}},
197
+ ),
143
198
  output_schema={
144
- "type" : "object",
145
- "additionalProperties" : False,
146
- "required" : [],
147
- "properties" : {
148
- }
199
+ "type": "object",
200
+ "additionalProperties": False,
201
+ "required": [],
202
+ "properties": {},
149
203
  },
150
- requires = requires,
151
- supports_tools = supports_tools
204
+ requires=requires,
205
+ supports_tools=supports_tools,
152
206
  )
153
207
 
154
- if rules == None:
208
+ if rules is None:
155
209
  rules = []
156
210
 
157
211
  self._rules = rules
158
212
 
159
213
  self._llm_adapter = llm_adapter
160
- self._tool_adapter = tool_adapter
214
+ self._tool_adapter = tool_adapter
161
215
  self._max_iterations = max_iterations
162
- if toolkits == None:
216
+ if toolkits is None:
163
217
  toolkits = []
164
218
  self.toolkits = toolkits
165
219
 
166
- self._planning_rules : list[str] = [
167
- *reasoning_rules,
168
- *rules
169
- ]
220
+ self._planning_rules: list[str] = [*reasoning_rules, *rules]
170
221
 
171
222
  async def init_chat_context(self):
172
223
  chat = await super().init_chat_context()
@@ -174,20 +225,17 @@ class PlanningWriter(Writer):
174
225
  all_rules = self._planning_rules.copy()
175
226
  chat.append_rules(rules=all_rules)
176
227
  return chat
177
-
178
- async def write(self, writer_context: WriterContext, arguments: dict):
179
228
 
180
- writer_context.call_context.chat.append_rules(f"your are writing to the document at the path {writer_context.path}")
229
+ async def write(self, writer_context: WriterContext, arguments: dict):
230
+ writer_context.call_context.chat.append_rules(
231
+ f"your are writing to the document at the path {writer_context.path}"
232
+ )
181
233
 
182
234
  arguments = arguments.copy()
183
235
  self.pop_path(arguments=arguments)
184
-
236
+
185
237
  execute = goto_next_step_message
186
238
 
187
- react = """
188
- based on what you know know, either execute the next task or formulate a new plan. If you have sufficient information to complete the task, return a final answer.
189
- """
190
-
191
239
  prompt = arguments["prompt"]
192
240
 
193
241
  writer_context.call_context.chat.append_user_message(message=prompt)
@@ -197,41 +245,51 @@ class PlanningWriter(Writer):
197
245
  i = 0
198
246
  while i < self._max_iterations:
199
247
  i += 1
200
-
248
+
201
249
  try:
202
250
  logger.info("COMPLETION STARTING: Step %s", i)
203
-
251
+
204
252
  base_args = arguments.copy()
205
253
  base_args.pop("path")
206
-
254
+
207
255
  toolkits = [
208
256
  DocumentAuthoringToolkit(),
209
257
  Toolkit(
210
258
  name="meshagent.planning-writer.tools",
211
- tools=build_tools(document_type="document", schema=writer_context.document.schema, documents={writer_context.path : writer_context.document})),
259
+ tools=build_tools(
260
+ document_type="document",
261
+ schema=writer_context.document.schema,
262
+ documents={writer_context.path: writer_context.document},
263
+ ),
264
+ ),
212
265
  *self.toolkits,
213
- *writer_context.call_context.toolkits
266
+ *writer_context.call_context.toolkits,
214
267
  ]
215
268
 
216
- responses = await self._llm_adapter.next(context=writer_context.call_context.chat, room=writer_context.room, toolkits=toolkits, tool_adapter=self._tool_adapter, output_schema=rs)
269
+ responses = await self._llm_adapter.next(
270
+ context=writer_context.call_context.chat,
271
+ room=writer_context.room,
272
+ toolkits=toolkits,
273
+ tool_adapter=self._tool_adapter,
274
+ output_schema=rs,
275
+ )
217
276
 
218
277
  logger.info("COMPLETION RESPONSE %s", responses)
219
-
278
+
220
279
  except Exception as e:
221
280
  logger.error("Unable to execute reasoning completion task", exc_info=e)
222
281
  # retry
223
- raise(e)
224
-
282
+ raise (e)
283
+
225
284
  parsed = responses["response"]["data"][0]
226
285
  if "abort" in parsed:
227
286
  abort = parsed["abort"]
228
287
  reason = abort["reason"]
229
288
  raise AgentException(reason)
230
-
289
+
231
290
  elif "progress" in parsed:
232
291
  result = parsed["progress"]
233
292
 
234
-
235
293
  if "done" not in result or result["done"]:
236
294
  logger.info("Done generating response %s", result)
237
295
  return {}
@@ -239,36 +297,52 @@ class PlanningWriter(Writer):
239
297
  writer_context.call_context.chat.append_user_message(execute)
240
298
  continue
241
299
  elif "plan" in parsed:
242
- plan = parsed["plan"]
243
300
  writer_context.call_context.chat.append_user_message(execute)
244
301
  continue
245
302
  else:
246
303
  logger.info("recieved invalid response, %s", parsed)
247
- writer_context.call_context.chat.append_user_message("this response did not conform to the schema")
304
+ writer_context.call_context.chat.append_user_message(
305
+ "this response did not conform to the schema"
306
+ )
248
307
  continue
249
308
 
250
-
251
- class PlanningResponder(TaskRunner):
252
309
 
253
- def __init__(self, *, name:str, llm_adapter: LLMAdapter, tool_adapter: Optional[ToolResponseAdapter] = None, output_schema: dict, max_iterations : int = 100, toolkits: Optional[list[Toolkit]] = None, title: Optional[str] = None, description: Optional[str] = None, requires: Optional[list[Requirement]] = None, supports_tools : bool = True, input_prompt: bool = True, rules: Optional[list[str]] = None, labels: Optional[list[str]] = None):
254
- if isinstance(output_schema, dict) == False:
255
- raise Exception("schema must be a dict, got: {type}".format(type=type(output_schema)))
310
+ class PlanningResponder(TaskRunner):
311
+ def __init__(
312
+ self,
313
+ *,
314
+ name: str,
315
+ llm_adapter: LLMAdapter,
316
+ tool_adapter: Optional[ToolResponseAdapter] = None,
317
+ output_schema: dict,
318
+ max_iterations: int = 100,
319
+ toolkits: Optional[list[Toolkit]] = None,
320
+ title: Optional[str] = None,
321
+ description: Optional[str] = None,
322
+ requires: Optional[list[Requirement]] = None,
323
+ supports_tools: bool = True,
324
+ input_prompt: bool = True,
325
+ rules: Optional[list[str]] = None,
326
+ labels: Optional[list[str]] = None,
327
+ ):
328
+ if not isinstance(output_schema, dict):
329
+ raise Exception(
330
+ "schema must be a dict, got: {type}".format(type=type(output_schema))
331
+ )
256
332
 
257
333
  self._input_prompt = input_prompt
258
334
 
259
- if rules == None:
335
+ if rules is None:
260
336
  rules = []
261
337
 
262
-
263
338
  if input_prompt:
264
339
  input_schema = prompt_schema(description="use a prompt to generate content")
265
340
  else:
266
341
  input_schema = {
267
- "type" : "object",
268
- "additionalProperties" : False,
269
- "required" : [],
270
- "properties" : {
271
- }
342
+ "type": "object",
343
+ "additionalProperties": False,
344
+ "required": [],
345
+ "properties": {},
272
346
  }
273
347
 
274
348
  super().__init__(
@@ -280,20 +354,17 @@ class PlanningResponder(TaskRunner):
280
354
  requires=requires,
281
355
  supports_tools=supports_tools,
282
356
  labels=labels,
283
- toolkits=toolkits
357
+ toolkits=toolkits,
284
358
  )
285
-
359
+
286
360
  self._max_iterations = max_iterations
287
361
 
288
- self._planning_rules : list[str] = [
289
- *rules,
290
- *reasoning_rules
291
- ]
362
+ self._planning_rules: list[str] = [*rules, *reasoning_rules]
292
363
 
293
364
  self._responses = dict()
294
365
 
295
366
  self._llm_adapter = llm_adapter
296
- self._tool_adapter = tool_adapter
367
+ self._tool_adapter = tool_adapter
297
368
 
298
369
  async def init_chat_context(self):
299
370
  chat = self._llm_adapter.create_chat_context()
@@ -302,48 +373,56 @@ class PlanningResponder(TaskRunner):
302
373
  chat.append_rules(rules=all_rules)
303
374
  return chat
304
375
 
305
-
306
376
  async def ask(self, context: AgentCallContext, arguments: dict):
307
-
308
377
  class ResponseTool(Tool):
309
- def __init__(self, output_schema: dict, context: AgentCallContext, parent:PlanningResponder):
378
+ def __init__(
379
+ self,
380
+ output_schema: dict,
381
+ context: AgentCallContext,
382
+ parent: PlanningResponder,
383
+ ):
310
384
  super().__init__(
311
385
  name="respond",
312
- title="respond",
313
- description="send the response to the user",
314
- input_schema=output_schema
386
+ title="respond",
387
+ description="send the response to the user",
388
+ input_schema=output_schema,
315
389
  )
316
390
  self.parent = parent
317
- self.context = context
391
+ self.context = context
318
392
 
319
393
  async def execute(self, *, context: ToolContext, **kwargs):
320
394
  self.parent._responses[self.context] = kwargs
321
395
  return TextResponse(text="the response was sent")
322
-
396
+
323
397
  class ResponseToolkit(Toolkit):
324
398
  def __init__(self, output_schema, context, parent):
325
-
326
- tools = [
327
- ResponseTool(output_schema=output_schema, context=context, parent=parent)
399
+ tools = [
400
+ ResponseTool(
401
+ output_schema=output_schema, context=context, parent=parent
402
+ )
328
403
  ]
329
404
 
330
405
  super().__init__(
331
406
  name="meshagent.responder",
332
407
  title="responder",
333
408
  description="tools for responding",
334
- tools=tools
409
+ tools=tools,
335
410
  )
336
-
337
411
 
338
- context.toolkits.append(ResponseToolkit(output_schema=self.output_schema, context=context, parent=self))
339
-
412
+ context.toolkits.append(
413
+ ResponseToolkit(
414
+ output_schema=self.output_schema, context=context, parent=self
415
+ )
416
+ )
417
+
340
418
  execute = goto_next_step_message
341
419
 
342
- react = """
343
- based on what you know know, either execute the next task or formulate a new plan. If you have sufficient information to complete the task, return a final answer.
344
- """
345
-
346
- rs = reasoning_schema(description="uses tools", elements=[], has_done_property=True, has_abort=True).to_json()
420
+ rs = reasoning_schema(
421
+ description="uses tools",
422
+ elements=[],
423
+ has_done_property=True,
424
+ has_abort=True,
425
+ ).to_json()
347
426
 
348
427
  if self._input_prompt:
349
428
  prompt = arguments["prompt"]
@@ -353,122 +432,135 @@ class PlanningResponder(TaskRunner):
353
432
  i = 0
354
433
  while i < self._max_iterations:
355
434
  i += 1
356
-
435
+
357
436
  try:
358
437
  logger.info("COMPLETION STARTING: Step %s", i)
359
-
360
- responses = await self._llm_adapter.next(context=context.chat, room=room, toolkits=context.toolkits, tool_adapter=self._tool_adapter, output_schema=rs)
438
+
439
+ responses = await self._llm_adapter.next(
440
+ context=context.chat,
441
+ room=room,
442
+ toolkits=context.toolkits,
443
+ tool_adapter=self._tool_adapter,
444
+ output_schema=rs,
445
+ )
361
446
 
362
447
  logger.info("COMPLETION RESPONSE %s", responses)
363
-
448
+
364
449
  except Exception as e:
365
450
  logger.error("Unable to execute reasoning completion task", exc_info=e)
366
451
  # retry
367
- raise(e)
368
-
452
+ raise (e)
453
+
369
454
  parsed = responses["response"]["data"][0]
370
455
 
371
456
  if "abort" in parsed:
372
457
  abort = parsed["abort"]
373
458
  reason = abort["reason"]
374
459
  raise AgentException(reason)
375
-
460
+
376
461
  elif "progress" in parsed:
377
462
  result = parsed["progress"]
378
463
 
379
- if "done" in result and result["done"]:
464
+ if "done" in result and result["done"]:
380
465
  if context not in self._responses:
381
- context.chat.append_user_message("you must call the respond tool")
466
+ context.chat.append_user_message(
467
+ "you must call the respond tool"
468
+ )
382
469
  continue
383
-
470
+
384
471
  final_answer = self._responses.pop(context)
385
472
  logger.info("Done generating response %s", final_answer)
386
473
  return final_answer
387
-
474
+
388
475
  else:
389
476
  context.chat.append_user_message(execute)
390
477
  continue
391
478
  elif "plan" in parsed:
392
- plan = parsed["plan"]
393
479
  context.chat.append_user_message(execute)
394
480
  continue
395
481
  else:
396
482
  logger.info("recieved invalid response, %s", parsed)
397
- context.chat.append_user_message("this response did not conform to the schema")
483
+ context.chat.append_user_message(
484
+ "this response did not conform to the schema"
485
+ )
398
486
  continue
399
487
 
400
-
401
488
  return {}
402
489
 
403
- class DynamicPlanningResponder(TaskRunner):
404
490
 
405
- def __init__(self, *, name: str, llm_adapter: LLMAdapter, tool_adapter: Optional[ToolResponseAdapter] = None, max_iterations : int = 100, toolkits: Optional[list[Toolkit]] = None, title: Optional[str] = None, description: Optional[str] = None):
406
-
491
+ class DynamicPlanningResponder(TaskRunner):
492
+ def __init__(
493
+ self,
494
+ *,
495
+ name: str,
496
+ llm_adapter: LLMAdapter,
497
+ tool_adapter: Optional[ToolResponseAdapter] = None,
498
+ max_iterations: int = 100,
499
+ toolkits: Optional[list[Toolkit]] = None,
500
+ title: Optional[str] = None,
501
+ description: Optional[str] = None,
502
+ ):
407
503
  super().__init__(
408
504
  name=name,
409
505
  title=title,
410
506
  description=description,
411
507
  input_schema=merge(
412
- schema=prompt_schema(
413
- description="use a prompt to generate content"),
414
- additional_properties={
415
- "output_schema" : { "type" : "object" }
416
- }
508
+ schema=prompt_schema(description="use a prompt to generate content"),
509
+ additional_properties={"output_schema": {"type": "object"}},
417
510
  ),
418
- output_schema=None)
419
-
511
+ output_schema=None,
512
+ )
513
+
420
514
  self._max_iterations = max_iterations
421
515
 
422
- self._planning_rules : list[str] = [
423
- *reasoning_rules
424
- ]
516
+ self._planning_rules: list[str] = [*reasoning_rules]
425
517
 
426
518
  self._responses = dict()
427
519
 
428
520
  self._llm_adapter = llm_adapter
429
- self._tool_adapter = tool_adapter
521
+ self._tool_adapter = tool_adapter
430
522
 
431
- if toolkits == None:
523
+ if toolkits is None:
432
524
  toolkits = []
433
-
525
+
434
526
  self.toolkits = toolkits
435
-
436
527
 
437
528
  async def init_chat_context(self):
438
- chat = self._llm_adapter.create_chat_context()
529
+ chat = self._llm_adapter.create_chat_context()
439
530
 
440
531
  all_rules = self._planning_rules.copy()
441
532
  chat.append_rules(rules=all_rules)
442
533
  return chat
443
534
 
444
-
445
535
  async def ask(self, context: AgentCallContext, arguments: dict):
446
-
447
536
  dynamic_schema = arguments["output_schema"]
448
537
 
449
-
450
538
  class ResponseTool(Tool):
451
- def __init__(self, output_schema: dict, context: AgentCallContext, parent:PlanningResponder):
452
-
539
+ def __init__(
540
+ self,
541
+ output_schema: dict,
542
+ context: AgentCallContext,
543
+ parent: PlanningResponder,
544
+ ):
453
545
  output_schema = deepcopy(output_schema)
454
-
546
+
455
547
  schema = {
456
- "type" : "object",
457
- "additionalProperties" : False,
458
- "required" : [ "summary", "data"],
459
- "properties" : {
460
- "summary" : {
461
- "type" : "string",
462
- "description" : "a summary of the data structure"
548
+ "type": "object",
549
+ "additionalProperties": False,
550
+ "required": ["summary", "data"],
551
+ "properties": {
552
+ "summary": {
553
+ "type": "string",
554
+ "description": "a summary of the data structure",
463
555
  },
464
- "data": output_schema
465
- }
556
+ "data": output_schema,
557
+ },
466
558
  }
467
559
 
468
560
  if "$defs" in output_schema:
469
561
  schema["$defs"] = output_schema["$defs"]
470
562
  del output_schema["$defs"]
471
-
563
+
472
564
  super().__init__(
473
565
  name="respond",
474
566
  title="respond",
@@ -476,7 +568,7 @@ class DynamicPlanningResponder(TaskRunner):
476
568
  description="send the response to the user",
477
569
  )
478
570
  self.parent = parent
479
- self.context = context
571
+ self.context = context
480
572
 
481
573
  async def execute(self, *, context: ToolContext, **kwargs):
482
574
  self.parent._responses[self.context] = kwargs
@@ -486,79 +578,82 @@ class DynamicPlanningResponder(TaskRunner):
486
578
  def __init__(self, output_schema, context, parent):
487
579
  super().__init__(
488
580
  name="meshagent.dynamic_response",
489
- tools=[
490
- ResponseTool(output_schema=output_schema, context=context, parent=parent)
491
- ]
581
+ tools=[
582
+ ResponseTool(
583
+ output_schema=output_schema, context=context, parent=parent
584
+ )
585
+ ],
492
586
  )
493
587
 
494
- context.toolkits.append(ResponseToolkit(output_schema=dynamic_schema, context=context, parent=self))
495
-
588
+ context.toolkits.append(
589
+ ResponseToolkit(output_schema=dynamic_schema, context=context, parent=self)
590
+ )
591
+
496
592
  execute = goto_next_step_message
497
593
 
498
- react = """
499
- based on what you know know, either execute the next task or formulate a new plan. If you have sufficient information to complete the task, return a final answer.
500
- """
501
-
502
594
  rs = reasoning_schema(description="uses tools", elements=[]).to_json()
503
595
 
504
596
  prompt = arguments["prompt"]
505
597
 
506
598
  context.chat.append_user_message(message=prompt)
507
-
599
+
508
600
  room = context.room
509
-
601
+
510
602
  i = 0
511
603
  while i < self._max_iterations:
512
604
  i += 1
513
-
605
+
514
606
  try:
515
607
  logger.info("COMPLETION STARTING: Step %s", i)
516
-
517
- toolkits = [
518
- *self.toolkits,
519
- *context.toolkits
520
- ]
521
608
 
522
- responses = await self._llm_adapter.next(context=context.chat, room=room, toolkits=toolkits, tool_adapter=self._tool_adapter, output_schema=rs)
609
+ toolkits = [*self.toolkits, *context.toolkits]
523
610
 
611
+ responses = await self._llm_adapter.next(
612
+ context=context.chat,
613
+ room=room,
614
+ toolkits=toolkits,
615
+ tool_adapter=self._tool_adapter,
616
+ output_schema=rs,
617
+ )
524
618
 
525
619
  logger.info("COMPLETION RESPONSE %s", responses)
526
-
620
+
527
621
  except Exception as e:
528
622
  logger.error("Unable to execute reasoning completion task", exc_info=e)
529
623
  # retry
530
- raise(e)
531
-
624
+ raise (e)
625
+
532
626
  parsed = responses["response"]["data"][0]
533
627
 
534
628
  if "abort" in parsed:
535
629
  abort = parsed["abort"]
536
630
  reason = abort["reason"]
537
631
  raise AgentException(reason)
538
-
632
+
539
633
  elif "progress" in parsed:
540
634
  result = parsed["progress"]
541
635
 
542
- if "done" not in result or result["done"]:
636
+ if "done" not in result or result["done"]:
543
637
  if context not in self._responses:
544
- context.chat.append_user_message("you must call the respond tool")
638
+ context.chat.append_user_message(
639
+ "you must call the respond tool"
640
+ )
545
641
  continue
546
-
642
+
547
643
  final_answer = self._responses.pop(context)
548
-
644
+
549
645
  logger.info("Done generating response %s", final_answer)
550
646
  return final_answer["data"]
551
-
647
+
552
648
  else:
553
649
  context.chat.append_user_message(execute)
554
650
  continue
555
651
  elif "plan" in parsed:
556
- plan = parsed["plan"]
557
652
  context.chat.append_user_message(execute)
558
653
  continue
559
654
  else:
560
655
  logger.info("recieved invalid response, %s", parsed)
561
- context.chat.append_user_message("this response did not conform to the schema")
656
+ context.chat.append_user_message(
657
+ "this response did not conform to the schema"
658
+ )
562
659
  continue
563
-
564
-