meshagent-agents 0.5.7__py3-none-any.whl → 0.5.8b1__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
@@ -12,7 +12,6 @@ from meshagent.api import (
12
12
  ToolkitDescription,
13
13
  Participant,
14
14
  RemoteParticipant,
15
- meshagent_base_url,
16
15
  StorageEntry,
17
16
  )
18
17
  from meshagent.api.protocol import Protocol
@@ -194,6 +193,8 @@ class SingleRoomAgent(Agent):
194
193
 
195
194
  installed = False
196
195
 
196
+ builtin_agents_url = "http://localhost:8080"
197
+
197
198
  for requirement in self.requires:
198
199
  if isinstance(requirement, RequiredToolkit):
199
200
  if toolkit_factory(requirement.name) is not None:
@@ -207,12 +208,12 @@ class SingleRoomAgent(Agent):
207
208
  if requirement.name not in toolkits_by_name:
208
209
  installed = True
209
210
 
210
- logger.info(f"Installing required tool {requirement.name}")
211
+ logger.info(f"calling required tool into room {requirement.name}")
211
212
 
212
213
  if requirement.name.startswith("https://"):
213
214
  url = requirement.name
214
215
  else:
215
- url = f"{meshagent_base_url()}/toolkits/{requirement.name}"
216
+ url = f"{builtin_agents_url}/toolkits/{requirement.name}"
216
217
 
217
218
  await self._room.agents.make_call(
218
219
  url=url, name=requirement.name, arguments={}
@@ -227,7 +228,7 @@ class SingleRoomAgent(Agent):
227
228
  if requirement.name.startswith("https://"):
228
229
  url = requirement.name
229
230
  else:
230
- url = f"{meshagent_base_url()}/schemas/{requirement.name}"
231
+ url = f"{builtin_agents_url}/schemas/{requirement.name}"
231
232
 
232
233
  await self._room.agents.make_call(
233
234
  url=url, name=requirement.name, arguments={}
meshagent/agents/chat.py CHANGED
@@ -448,7 +448,7 @@ class ChatBot(SingleRoomAgent):
448
448
  if doc_messages is None:
449
449
  raise Exception("thread was not properly initialized")
450
450
 
451
- async def prepare_llm_context(self, *, context: ChatThreadContext):
451
+ async def prepare_llm_context(self, *, thread_context: ChatThreadContext):
452
452
  """
453
453
  called prior to sending the request to the LLM in case the agent needs to modify the context prior to sending
454
454
  """
@@ -736,7 +736,7 @@ class ChatBot(SingleRoomAgent):
736
736
  )
737
737
 
738
738
  await self.prepare_llm_context(
739
- context=thread_context
739
+ thread_context=thread_context
740
740
  )
741
741
 
742
742
  llm_messages = asyncio.Queue[ResponseStreamEvent]()
@@ -22,7 +22,7 @@ async def connect_development_agent(*, room_name: str, agent: SingleRoomAgent):
22
22
  signal.signal(signal.SIGABRT, clean_termination)
23
23
 
24
24
  await asyncio.wait(
25
- [asyncio.ensure_future(room.protocol.wait_for_close()), term],
25
+ [asyncio.create_task(room.protocol.wait_for_close()), term],
26
26
  return_when=asyncio.FIRST_COMPLETED,
27
27
  )
28
28
 
@@ -74,7 +74,7 @@ class RemoteTaskRunnerServer[T: TaskRunner](WebhookServer):
74
74
  await agent.start(room=room)
75
75
 
76
76
  done, pending = await asyncio.wait(
77
- [dismissed, asyncio.ensure_future(room.protocol.wait_for_close())],
77
+ [dismissed, asyncio.create_task(room.protocol.wait_for_close())],
78
78
  return_when=asyncio.FIRST_COMPLETED,
79
79
  )
80
80
 
@@ -158,7 +158,7 @@ class RemoteAgentServer[T: SingleRoomAgent](WebhookServer):
158
158
  await agent.start(room=room)
159
159
 
160
160
  done, pending = await asyncio.wait(
161
- [dismissed, asyncio.ensure_future(room.protocol.wait_for_close())],
161
+ [dismissed, asyncio.create_task(room.protocol.wait_for_close())],
162
162
  return_when=asyncio.FIRST_COMPLETED,
163
163
  )
164
164
 
@@ -0,0 +1,169 @@
1
+ from typing import Optional
2
+
3
+ from jsonschema import validate, ValidationError
4
+ from meshagent.api.schema_util import prompt_schema, merge
5
+ from meshagent.api import Requirement
6
+ from meshagent.tools import Toolkit
7
+ from meshagent.agents import TaskRunner
8
+ from meshagent.agents.agent import AgentCallContext
9
+ from meshagent.agents.adapter import LLMAdapter, ToolResponseAdapter
10
+ from meshagent.api.messaging import TextResponse
11
+
12
+
13
+ class LLMTaskRunner(TaskRunner):
14
+ """
15
+ A Task Runner that uses an LLM execution loop until the task is complete.
16
+ """
17
+
18
+ def __init__(
19
+ self,
20
+ *,
21
+ name: str,
22
+ llm_adapter: LLMAdapter,
23
+ title: Optional[str] = None,
24
+ description: Optional[str] = None,
25
+ tool_adapter: Optional[ToolResponseAdapter] = None,
26
+ toolkits: Optional[list[Toolkit]] = None,
27
+ requires: Optional[list[Requirement]] = None,
28
+ supports_tools: bool = True,
29
+ input_prompt: bool = True,
30
+ input_schema: Optional[dict] = None,
31
+ output_schema: Optional[dict] = None,
32
+ rules: Optional[list[str]] = None,
33
+ labels: Optional[list[str]] = None,
34
+ ):
35
+ if input_schema is None:
36
+ if input_prompt:
37
+ input_schema = prompt_schema(
38
+ description="use a prompt to generate content"
39
+ )
40
+ else:
41
+ input_schema = {
42
+ "type": "object",
43
+ "additionalProperties": False,
44
+ "required": [],
45
+ "properties": {},
46
+ }
47
+
48
+ static_toolkits = list(toolkits or [])
49
+
50
+ super().__init__(
51
+ name=name,
52
+ title=title,
53
+ description=description,
54
+ input_schema=input_schema,
55
+ output_schema=output_schema,
56
+ requires=requires,
57
+ supports_tools=supports_tools,
58
+ labels=labels,
59
+ toolkits=static_toolkits,
60
+ )
61
+
62
+ self._extra_rules = rules or []
63
+ self._llm_adapter = llm_adapter
64
+ self._tool_adapter = tool_adapter
65
+ self.toolkits = static_toolkits
66
+
67
+ async def init_chat_context(self):
68
+ chat = self._llm_adapter.create_chat_context()
69
+ if self._extra_rules:
70
+ chat.append_rules(self._extra_rules)
71
+ return chat
72
+
73
+ async def ask(self, *, context: AgentCallContext, arguments: dict):
74
+ prompt = arguments.get("prompt")
75
+ if prompt is None:
76
+ raise ValueError("`prompt` is required")
77
+
78
+ context.chat.append_user_message(prompt)
79
+
80
+ combined_toolkits: list[Toolkit] = [*self.toolkits, *context.toolkits]
81
+
82
+ resp = await self._llm_adapter.next(
83
+ context=context.chat,
84
+ room=context.room,
85
+ toolkits=combined_toolkits,
86
+ tool_adapter=self._tool_adapter,
87
+ output_schema=self.output_schema,
88
+ )
89
+
90
+ # Validate the LLM output against the declared output schema if one was provided
91
+ if self.output_schema:
92
+ try:
93
+ validate(instance=resp, schema=self.output_schema)
94
+ except ValidationError as exc:
95
+ raise RuntimeError("LLM output failed schema validation") from exc
96
+ # If no output schema was provided return a TextResponse
97
+ else:
98
+ resp = TextResponse(text=resp)
99
+
100
+ return resp
101
+
102
+
103
+ class DynamicLLMTaskRunner(LLMTaskRunner):
104
+ """
105
+ Same capabilities as LLMTaskRunner, but the caller supplies an arbitrary JSON-schema (`output_schema`) at runtime
106
+ """
107
+
108
+ def __init__(
109
+ self,
110
+ *,
111
+ name: str,
112
+ llm_adapter: LLMAdapter,
113
+ supports_tools: bool = True,
114
+ title: Optional[str] = None,
115
+ description: Optional[str] = None,
116
+ tool_adapter: Optional[ToolResponseAdapter] = None,
117
+ toolkits: Optional[list[Toolkit]] = None,
118
+ rules: Optional[list[str]] = None,
119
+ ):
120
+ input_schema = merge(
121
+ schema=prompt_schema(description="use a prompt to generate content"),
122
+ additional_properties={"output_schema": {"type": "object"}},
123
+ )
124
+ super().__init__(
125
+ name=name,
126
+ llm_adapter=llm_adapter,
127
+ supports_tools=supports_tools,
128
+ title=title,
129
+ description=description,
130
+ tool_adapter=tool_adapter,
131
+ toolkits=toolkits,
132
+ rules=rules,
133
+ input_prompt=True,
134
+ input_schema=input_schema,
135
+ output_schema=None,
136
+ )
137
+
138
+ async def ask(self, *, context: AgentCallContext, arguments: dict):
139
+ prompt = arguments.get("prompt")
140
+ if prompt is None:
141
+ raise ValueError("`prompt` is required")
142
+
143
+ # Parse and pass JSON output schema provided at runtime
144
+ output_schema_raw = arguments.get("output_schema")
145
+ if output_schema_raw is None:
146
+ raise ValueError("`output_schema` is required for DynamicLLMTaskRunner")
147
+
148
+ # Make sure provided schema is a dict
149
+ if not isinstance(output_schema_raw, dict):
150
+ raise TypeError("`output_schema` must be a dict (JSON-schema object)")
151
+
152
+ context.chat.append_user_message(prompt)
153
+
154
+ combined_toolkits: list[Toolkit] = [*self.toolkits, *context.toolkits]
155
+
156
+ resp = await self._llm_adapter.next(
157
+ context=context.chat,
158
+ room=context.room,
159
+ toolkits=combined_toolkits,
160
+ tool_adapter=self._tool_adapter,
161
+ output_schema=output_schema_raw,
162
+ )
163
+
164
+ try:
165
+ validate(instance=resp, schema=output_schema_raw)
166
+ except ValidationError as exc:
167
+ raise RuntimeError("LLM output failed caller schema validation") from exc
168
+
169
+ return resp
meshagent/agents/mail.py CHANGED
@@ -284,10 +284,7 @@ class MailWorker(Worker):
284
284
 
285
285
  async def process_message(self, *, chat_context, room, message, toolkits):
286
286
  thread_context = MailThreadContext(chat=chat_context, room_address=message)
287
- toolkits = [
288
- *toolkits,
289
- *await self.get_thread_toolkits(thread_context=thread_context),
290
- ]
287
+ toolkits = (await self.get_thread_toolkits(thread_context=thread_context),)
291
288
 
292
289
  logger.info(f"processing message {message}")
293
290
  reply = await super().process_message(
meshagent/agents/utils.py CHANGED
@@ -1,5 +1,4 @@
1
1
  from meshagent.api import RoomClient, Requirement, RoomException, Participant
2
- from meshagent.tools import validate_openai_schema
3
2
  import json
4
3
  from typing import Optional
5
4
  import asyncio
@@ -35,7 +34,6 @@ async def generate_json(
35
34
  if prompt is None:
36
35
  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."
37
36
 
38
- validate_openai_schema(output_schema)
39
37
  return await room.agents.ask(
40
38
  on_behalf_of=on_behalf_of,
41
39
  agent="meshagent.schema_planner",
@@ -1 +1 @@
1
- __version__ = "0.5.7"
1
+ __version__ = "0.5.8-beta.1"
@@ -1,30 +1,30 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: meshagent-agents
3
- Version: 0.5.7
3
+ Version: 0.5.8b1
4
4
  Summary: Agent Building Blocks for Meshagent
5
5
  License-Expression: Apache-2.0
6
6
  Project-URL: Documentation, https://docs.meshagent.com
7
7
  Project-URL: Website, https://www.meshagent.com
8
8
  Project-URL: Source, https://www.meshagent.com
9
- Requires-Python: >=3.12
9
+ Requires-Python: >=3.13
10
10
  Description-Content-Type: text/markdown
11
11
  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.7
16
- Requires-Dist: meshagent-tools~=0.5.7
17
- Requires-Dist: meshagent-openai~=0.5.7
15
+ Requires-Dist: meshagent-api~=0.5.8-beta.1
16
+ Requires-Dist: meshagent-tools~=0.5.8-beta.1
17
+ Requires-Dist: meshagent-openai~=0.5.8-beta.1
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.7; extra == "all"
21
+ Requires-Dist: meshagent-api[all]~=0.5.8-beta.1; 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.7; extra == "sync"
27
+ Requires-Dist: meshagent-api[sync]~=0.5.8-beta.1; extra == "sync"
28
28
  Provides-Extra: mail
29
29
  Requires-Dist: aiosmtplib~=4.0.1; extra == "mail"
30
30
  Provides-Extra: rag
@@ -1,20 +1,21 @@
1
1
  meshagent/agents/__init__.py,sha256=d2cplyLH8xqDWqP_GoPQ8ApHzuv8Iiq4rz-vYBlGMTw,706
2
2
  meshagent/agents/adapter.py,sha256=dMuejpjl__bdZ-Qmt-k4e81g-i10vZup7WE1JCZ_Sy4,1392
3
- meshagent/agents/agent.py,sha256=w14hM63YXiH15VEF1T2eZCvggvrUkE00a1kQkaMRBM0,20354
4
- meshagent/agents/chat.py,sha256=K1uLlUylKiWhuSh_gqQ2GajIZ3Pf5fc309adg14Z0Rk,32870
3
+ meshagent/agents/agent.py,sha256=30Ey107T7Gk494UdWu3G0vmX6S-9qEEPfhD6AcBTyDg,20387
4
+ meshagent/agents/chat.py,sha256=MLcgh_3HVgHMNmZZNRAhIpqLdo9hPcnwtcI_mFJAGJE,32884
5
5
  meshagent/agents/context.py,sha256=6txCXA22aHQaikvIKED6YjPyasM_bPqGqCE4HGj04_E,4035
6
- meshagent/agents/development.py,sha256=AEBkkycNZDRLYIdmX2LkrVZv715ALswiwSR9CiV3HE4,894
7
- meshagent/agents/hosting.py,sha256=tCcswAweEhlMxGaBR_m2YvUkwZiaHbTBT64urRHfK7I,5446
6
+ meshagent/agents/development.py,sha256=JdCbR72nkqFTe5TK1ejmu9BgLuCWYzJRq-C2Soa3BFo,892
7
+ meshagent/agents/hosting.py,sha256=95jKCzaHknX_1hTD2yMlOrzBSqlqBCFsmZ9ms3zKUlk,5442
8
8
  meshagent/agents/indexer.py,sha256=xFEzAmwAxhKu9xHppnxFUFlzeRHMfVk6MatRyka0ZW8,19367
9
9
  meshagent/agents/listener.py,sha256=q5z216FMVW-a7FBs706u3IuB81VArfucxEHaHvPFHEo,5139
10
- meshagent/agents/mail.py,sha256=NQUbLuUzk0xFCb_ROvD8ZWW3VnkN7pKMGJcJzcB8p3Q,12348
10
+ meshagent/agents/llmrunner.py,sha256=ovHWsAsDqDCjmXLqXvx5B9Zwh9DaZMzvWU2dIL90syw,5739
11
+ meshagent/agents/mail.py,sha256=mdSPzpSbAoOeyP2XFTyhip4iWq8YIS8lBsQhhyKcaqU,12302
11
12
  meshagent/agents/planning.py,sha256=69HLEkOR_24mZ1mcUCQVX_DgPfX5TVA7EJYCHENH6M0,21980
12
13
  meshagent/agents/prompt.py,sha256=OSSqbzaugyQtuvYxTY5UcZQWyeV73e3GUJz_iC5xZkA,1883
13
14
  meshagent/agents/pydantic.py,sha256=RrdOESZg-n_FyxbfkOBwRPVxV39IOjxK2unsyAGn9as,6278
14
15
  meshagent/agents/single_shot_writer.py,sha256=miWVMo4NX8Hib0yHwDmiwuk8GraJwg1JzljsgFyTl4Y,3237
15
16
  meshagent/agents/thread_schema.py,sha256=OGQ-H5c2fJgNOYHC3Pas8iqTi2RUSxP2bytf0SK-SYc,4208
16
- meshagent/agents/utils.py,sha256=6D9GXpYu9xx5XlfD3DiGFdyOwq46e5-sTYOF_FYep1o,1446
17
- meshagent/agents/version.py,sha256=KiyyYbyEe0O858kmiWcg1RdmqGUYtk_JqRmc3_Ev2Q8,22
17
+ meshagent/agents/utils.py,sha256=2Z3r7cUpKDZig8MVCrBwZRBUambeX4esZovDWme9uVE,1353
18
+ meshagent/agents/version.py,sha256=UuWI1khJCTSIH7nHgIpNJWoeqg5GBLawnAjdq1dfb8w,29
18
19
  meshagent/agents/worker.py,sha256=SkrPhxIQ-Chyjg-eZGOlehkbrVYmsas8zmZnrTsAl3o,3910
19
20
  meshagent/agents/writer.py,sha256=dXglYgHwBrBJIaapMqBDyD3kmwSyi94tOdHH44itODc,2682
20
21
  meshagent/agents/schemas/__init__.py,sha256=_xAhrkxvFdfer3NolrynragGxcLElGR51LSribT3deU,299
@@ -23,8 +24,8 @@ meshagent/agents/schemas/gallery.py,sha256=65IsrH2wiFIR-DNo8est-nCOC72i1Aa5EmVNU
23
24
  meshagent/agents/schemas/presentation.py,sha256=aaMzkFQryurbHd1fbzTQPdN7v8QIhsjXuvbE8ZiuXNY,1589
24
25
  meshagent/agents/schemas/schema.py,sha256=8OXGCLVouoPg6eHBU9mgf1pTGTMvVZqiKNq15wkQJe0,5310
25
26
  meshagent/agents/schemas/super_editor_document.py,sha256=iRv4Q-DE_5kUdsAD5Rm4GwHek8L_7ZEpxIZ1x2dWjdg,1813
26
- meshagent_agents-0.5.7.dist-info/licenses/LICENSE,sha256=eTt0SPW-sVNdkZe9PS_S8WfCIyLjRXRl7sUBWdlteFg,10254
27
- meshagent_agents-0.5.7.dist-info/METADATA,sha256=hDOxKUU6XtCX82qVFZbjmtrERgZAvSrv-fW5zbdk9mE,3773
28
- meshagent_agents-0.5.7.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
29
- meshagent_agents-0.5.7.dist-info/top_level.txt,sha256=GlcXnHtRP6m7zlG3Df04M35OsHtNXy_DY09oFwWrH74,10
30
- meshagent_agents-0.5.7.dist-info/RECORD,,
27
+ meshagent_agents-0.5.8b1.dist-info/licenses/LICENSE,sha256=eTt0SPW-sVNdkZe9PS_S8WfCIyLjRXRl7sUBWdlteFg,10254
28
+ meshagent_agents-0.5.8b1.dist-info/METADATA,sha256=FVNk59GJcWT8kj7cpU6cjgAmc5I0tmQcte1beB64tnA,3810
29
+ meshagent_agents-0.5.8b1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
30
+ meshagent_agents-0.5.8b1.dist-info/top_level.txt,sha256=GlcXnHtRP6m7zlG3Df04M35OsHtNXy_DY09oFwWrH74,10
31
+ meshagent_agents-0.5.8b1.dist-info/RECORD,,