meshagent-agents 0.0.1__py3-none-any.whl → 0.0.4__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/__init__.py +1 -0
- meshagent/agents/adapter.py +8 -3
- meshagent/agents/agent.py +15 -7
- meshagent/agents/chat.py +277 -145
- meshagent/agents/context.py +16 -0
- meshagent/agents/indexer.py +0 -3
- meshagent/agents/planning.py +2 -2
- meshagent/agents/prompt.py +9 -3
- meshagent/agents/pydantic.py +32 -2
- meshagent/agents/single_shot_writer.py +1 -1
- meshagent/agents/thread_schema.py +59 -0
- meshagent/agents/version.py +1 -1
- {meshagent_agents-0.0.1.dist-info → meshagent_agents-0.0.4.dist-info}/METADATA +4 -4
- meshagent_agents-0.0.4.dist-info/RECORD +22 -0
- meshagent/agents/schema.py +0 -50
- meshagent_agents-0.0.1.dist-info/RECORD +0 -22
- {meshagent_agents-0.0.1.dist-info → meshagent_agents-0.0.4.dist-info}/LICENSE +0 -0
- {meshagent_agents-0.0.1.dist-info → meshagent_agents-0.0.4.dist-info}/WHEEL +0 -0
- {meshagent_agents-0.0.1.dist-info → meshagent_agents-0.0.4.dist-info}/top_level.txt +0 -0
meshagent/agents/__init__.py
CHANGED
meshagent/agents/adapter.py
CHANGED
|
@@ -3,7 +3,7 @@ from .agent import AgentChatContext
|
|
|
3
3
|
from jsonschema import validate
|
|
4
4
|
from meshagent.tools.toolkit import Response, Toolkit
|
|
5
5
|
from meshagent.api import RoomClient
|
|
6
|
-
from typing import Any, Optional
|
|
6
|
+
from typing import Any, Optional, Callable
|
|
7
7
|
|
|
8
8
|
class ToolResponseAdapter(ABC):
|
|
9
9
|
def __init__(self):
|
|
@@ -14,15 +14,19 @@ class ToolResponseAdapter(ABC):
|
|
|
14
14
|
pass
|
|
15
15
|
|
|
16
16
|
@abstractmethod
|
|
17
|
-
async def
|
|
17
|
+
async def create_messages(self, *, context: AgentChatContext, tool_call: Any, room: RoomClient, response: Response) -> list:
|
|
18
18
|
pass
|
|
19
19
|
|
|
20
20
|
|
|
21
|
-
class LLMAdapter(ABC):
|
|
21
|
+
class LLMAdapter[T](ABC):
|
|
22
22
|
|
|
23
23
|
def create_chat_context(self) -> AgentChatContext:
|
|
24
24
|
return AgentChatContext()
|
|
25
25
|
|
|
26
|
+
@abstractmethod
|
|
27
|
+
async def check_for_termination(self, *, context: AgentChatContext, room: RoomClient):
|
|
28
|
+
return True
|
|
29
|
+
|
|
26
30
|
@abstractmethod
|
|
27
31
|
async def next(self,
|
|
28
32
|
*,
|
|
@@ -31,6 +35,7 @@ class LLMAdapter(ABC):
|
|
|
31
35
|
toolkits: Toolkit,
|
|
32
36
|
tool_adapter: Optional[ToolResponseAdapter] = None,
|
|
33
37
|
output_schema: Optional[dict] = None,
|
|
38
|
+
event_handler: Optional[Callable[[T],None]] = None
|
|
34
39
|
) -> Any:
|
|
35
40
|
pass
|
|
36
41
|
|
meshagent/agents/agent.py
CHANGED
|
@@ -8,11 +8,9 @@ from meshagent.api import WebSocketClientProtocol, ToolDescription, ToolkitDescr
|
|
|
8
8
|
from meshagent.api.protocol import Protocol
|
|
9
9
|
from meshagent.tools.toolkit import Toolkit, Tool, ToolContext
|
|
10
10
|
from meshagent.api.room_server_client import RoomClient, RoomException
|
|
11
|
-
from meshagent.api.schema_document import Document
|
|
12
11
|
from jsonschema import validate
|
|
13
|
-
from typing import Callable, Awaitable
|
|
14
12
|
from .context import AgentCallContext, AgentChatContext
|
|
15
|
-
from .
|
|
13
|
+
from meshagent.api.schema_util import no_arguments_schema
|
|
16
14
|
import logging
|
|
17
15
|
import asyncio
|
|
18
16
|
from typing import Optional
|
|
@@ -45,6 +43,7 @@ class RoomTool(Tool):
|
|
|
45
43
|
class Agent:
|
|
46
44
|
|
|
47
45
|
def __init__(self, *, name: str, title: Optional[str] = None, description: Optional[str] = None, requires: Optional[list[Requirement]] = None, labels: Optional[list[str]] = None):
|
|
46
|
+
|
|
48
47
|
self._name = name
|
|
49
48
|
if title == None:
|
|
50
49
|
title = name
|
|
@@ -55,6 +54,8 @@ class Agent:
|
|
|
55
54
|
self._description = description
|
|
56
55
|
if requires == None:
|
|
57
56
|
requires = []
|
|
57
|
+
|
|
58
|
+
self.init_requirements(requires)
|
|
58
59
|
self._requires = requires
|
|
59
60
|
|
|
60
61
|
if labels == None:
|
|
@@ -82,6 +83,8 @@ class Agent:
|
|
|
82
83
|
def labels(self):
|
|
83
84
|
return self._labels
|
|
84
85
|
|
|
86
|
+
def init_requirements(self, requires): ...
|
|
87
|
+
|
|
85
88
|
async def init_chat_context(self) -> AgentChatContext:
|
|
86
89
|
return AgentChatContext()
|
|
87
90
|
|
|
@@ -100,6 +103,7 @@ class SingleRoomAgent(Agent):
|
|
|
100
103
|
super().__init__(name=name, title=title, description=description, requires=requires, labels=labels)
|
|
101
104
|
self._room = None
|
|
102
105
|
|
|
106
|
+
|
|
103
107
|
async def start(self, *, room: RoomClient) -> None:
|
|
104
108
|
|
|
105
109
|
if self._room != None:
|
|
@@ -107,6 +111,9 @@ class SingleRoomAgent(Agent):
|
|
|
107
111
|
|
|
108
112
|
self._room = room
|
|
109
113
|
|
|
114
|
+
await self.install_requirements()
|
|
115
|
+
|
|
116
|
+
|
|
110
117
|
async def stop(self) -> None:
|
|
111
118
|
self._room = None
|
|
112
119
|
pass
|
|
@@ -121,7 +128,6 @@ class SingleRoomAgent(Agent):
|
|
|
121
128
|
|
|
122
129
|
schemas = await self._room.storage.list(path=".schemas")
|
|
123
130
|
|
|
124
|
-
|
|
125
131
|
for schema in schemas:
|
|
126
132
|
schemas_by_name[schema.name] = schema
|
|
127
133
|
|
|
@@ -137,6 +143,11 @@ class SingleRoomAgent(Agent):
|
|
|
137
143
|
for requirement in self.requires:
|
|
138
144
|
|
|
139
145
|
if isinstance(requirement, RequiredToolkit):
|
|
146
|
+
|
|
147
|
+
if requirement.name == "meshagent.ui":
|
|
148
|
+
# TODO: maybe requirements can be marked as non installable?
|
|
149
|
+
continue
|
|
150
|
+
|
|
140
151
|
if requirement.name not in toolkits_by_name:
|
|
141
152
|
|
|
142
153
|
installed = True
|
|
@@ -369,9 +380,6 @@ class TaskRunner(SingleRoomAgent):
|
|
|
369
380
|
)
|
|
370
381
|
|
|
371
382
|
|
|
372
|
-
await self.install_requirements(participant_id=caller.id)
|
|
373
|
-
|
|
374
|
-
|
|
375
383
|
context = AgentCallContext(chat=chat_context, room=self.room, caller=caller)
|
|
376
384
|
|
|
377
385
|
for toolkit_json in toolkits_json:
|
meshagent/agents/chat.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
from .agent import SingleRoomAgent, AgentChatContext
|
|
1
|
+
from .agent import SingleRoomAgent, AgentChatContext, AgentCallContext
|
|
2
2
|
from meshagent.api.chan import Chan
|
|
3
|
-
from meshagent.api import RoomMessage, RoomException, RoomClient, RemoteParticipant
|
|
3
|
+
from meshagent.api import RoomMessage, RoomException, RoomClient, RemoteParticipant, RequiredSchema, Requirement, Element, MeshDocument
|
|
4
4
|
from meshagent.tools import Toolkit
|
|
5
5
|
from .adapter import LLMAdapter, ToolResponseAdapter
|
|
6
6
|
import asyncio
|
|
@@ -8,6 +8,10 @@ from typing import Optional
|
|
|
8
8
|
import logging
|
|
9
9
|
from meshagent.tools import MultiToolkit
|
|
10
10
|
import urllib
|
|
11
|
+
import uuid
|
|
12
|
+
import datetime
|
|
13
|
+
|
|
14
|
+
from openai.types.responses import ResponseStreamEvent
|
|
11
15
|
|
|
12
16
|
logging.basicConfig()
|
|
13
17
|
logger = logging.getLogger("chat")
|
|
@@ -16,8 +20,38 @@ logger.setLevel(logging.INFO)
|
|
|
16
20
|
|
|
17
21
|
# todo: thread should stop when participant stops?
|
|
18
22
|
|
|
23
|
+
def get_thread_participants(*, room: RoomClient, thread: MeshDocument) -> list[RemoteParticipant]:
|
|
24
|
+
|
|
25
|
+
results = list[RemoteParticipant]()
|
|
26
|
+
|
|
27
|
+
for prop in thread.root.get_children():
|
|
28
|
+
|
|
29
|
+
if prop.tag_name == "members":
|
|
30
|
+
|
|
31
|
+
for member in prop.get_children():
|
|
32
|
+
|
|
33
|
+
for online in room.messaging.get_participants():
|
|
34
|
+
|
|
35
|
+
if online.get_attribute("name") == member.get_attribute("name"):
|
|
36
|
+
|
|
37
|
+
results.append(online)
|
|
38
|
+
|
|
39
|
+
return results
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class ChatThreadContext:
|
|
43
|
+
def __init__(self, *, chat: AgentChatContext, thread: MeshDocument, toolkits: list[Toolkit], participants: Optional[list[RemoteParticipant]] = None):
|
|
44
|
+
self.thread = thread
|
|
45
|
+
self.toolkits = toolkits
|
|
46
|
+
if participants == None:
|
|
47
|
+
participants = []
|
|
48
|
+
|
|
49
|
+
self.participants = participants
|
|
50
|
+
self.chat = chat
|
|
51
|
+
|
|
19
52
|
class ChatBot(SingleRoomAgent):
|
|
20
|
-
def __init__(self, *, name, title = None, description = None, requires = None,
|
|
53
|
+
def __init__(self, *, name, title = None, description = None, requires : Optional[list[Requirement]] = None, llm_adapter: LLMAdapter, tool_adapter: Optional[ToolResponseAdapter] = None, toolkits: Optional[list[Toolkit]] = None, rules : Optional[list[str]] = None, auto_greet_message : Optional[str] = None, empty_state_title : Optional[str] = None, labels: Optional[str] = None):
|
|
54
|
+
|
|
21
55
|
super().__init__(
|
|
22
56
|
name=name,
|
|
23
57
|
title=title,
|
|
@@ -42,30 +76,60 @@ class ChatBot(SingleRoomAgent):
|
|
|
42
76
|
|
|
43
77
|
self._rules = rules
|
|
44
78
|
self._is_typing = dict[str,asyncio.Task]()
|
|
45
|
-
self._auto_greet_prompt = auto_greet_prompt
|
|
46
79
|
self._auto_greet_message = auto_greet_message
|
|
47
80
|
|
|
48
81
|
if empty_state_title == None:
|
|
49
82
|
empty_state_title = "How can I help you?"
|
|
50
83
|
self._empty_state_title = empty_state_title
|
|
51
84
|
|
|
85
|
+
self._thread_tasks = dict[str,asyncio.Task]()
|
|
52
86
|
|
|
53
|
-
|
|
87
|
+
def init_requirements(self, requires: list[Requirement]):
|
|
88
|
+
if requires == None:
|
|
54
89
|
|
|
55
|
-
|
|
56
|
-
|
|
90
|
+
requires = [
|
|
91
|
+
RequiredSchema(
|
|
92
|
+
name="thread"
|
|
93
|
+
)
|
|
94
|
+
]
|
|
95
|
+
|
|
96
|
+
else:
|
|
97
|
+
|
|
98
|
+
thread_schema = list(n for n in requires if (isinstance(n, RequiredSchema) and n.name == "thread"))
|
|
99
|
+
if len(thread_schema) == 0:
|
|
100
|
+
requires.append(
|
|
101
|
+
RequiredSchema(
|
|
102
|
+
name="thread"
|
|
103
|
+
)
|
|
104
|
+
)
|
|
105
|
+
|
|
106
|
+
async def _send_and_save_chat(self, messages: Element, path: str, to: RemoteParticipant, id: str, text: str):
|
|
107
|
+
|
|
108
|
+
await self.room.messaging.send_message(to=to, type="chat", message={ "path" : path, "text" : text })
|
|
109
|
+
|
|
110
|
+
messages.append_child(tag_name="message", attributes={
|
|
111
|
+
"id" : id,
|
|
112
|
+
"text" : text,
|
|
113
|
+
"created_at" : datetime.datetime.now(datetime.timezone.utc).isoformat().replace("+00:00","Z"),
|
|
114
|
+
"author_name" : self.room.local_participant.get_attribute("name"),
|
|
115
|
+
})
|
|
57
116
|
|
|
117
|
+
|
|
118
|
+
async def greet(self, *, messages: Element, path: str, chat_context: AgentChatContext, participant: RemoteParticipant):
|
|
119
|
+
|
|
58
120
|
if self._auto_greet_message != None:
|
|
59
121
|
chat_context.append_user_message(self._auto_greet_message)
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
122
|
+
await self._send_and_save_chat(id=str(uuid.uuid4()), to=RemoteParticipant(id=participant.id), messages=messages, path=path, text= self._auto_greet_message)
|
|
123
|
+
|
|
63
124
|
|
|
64
|
-
async def
|
|
125
|
+
async def get_thread_participants(self, *, thread: MeshDocument):
|
|
126
|
+
return get_thread_participants(room=self._room, thread=thread)
|
|
127
|
+
|
|
128
|
+
async def init_thread_context(self, *, thread_context: ChatThreadContext) -> list[Toolkit]:
|
|
65
129
|
|
|
66
130
|
toaster = None
|
|
67
131
|
|
|
68
|
-
for toolkit in toolkits:
|
|
132
|
+
for toolkit in thread_context.toolkits:
|
|
69
133
|
|
|
70
134
|
if toolkit.name == "meshagent.ui":
|
|
71
135
|
|
|
@@ -83,168 +147,223 @@ class ChatBot(SingleRoomAgent):
|
|
|
83
147
|
|
|
84
148
|
return MultiToolkit(required=[ toaster ], base_toolkit=toolkit )
|
|
85
149
|
|
|
86
|
-
toolkits = list(map(multi_tool, toolkits))
|
|
150
|
+
toolkits = list(map(multi_tool, thread_context.toolkits))
|
|
87
151
|
|
|
88
|
-
|
|
152
|
+
thread_context.toolkits = toolkits
|
|
89
153
|
|
|
90
|
-
|
|
154
|
+
|
|
155
|
+
async def init_chat_context(self) -> AgentChatContext:
|
|
156
|
+
context = self._llm_adapter.create_chat_context()
|
|
157
|
+
context.append_rules(self._rules)
|
|
158
|
+
return context
|
|
91
159
|
|
|
92
|
-
|
|
93
|
-
chat_context = await self.init_chat_context()
|
|
94
|
-
|
|
160
|
+
async def open_thread(self, *, path: str):
|
|
95
161
|
|
|
96
|
-
chat_context.append_rules(
|
|
97
|
-
rules=[
|
|
98
|
-
*self._rules,
|
|
99
|
-
"think step by step",
|
|
100
|
-
]
|
|
101
|
-
)
|
|
102
162
|
|
|
103
|
-
|
|
104
|
-
|
|
163
|
+
return await self.room.sync.open(path=path)
|
|
164
|
+
|
|
165
|
+
async def close_thread(self, *, path: str):
|
|
105
166
|
|
|
106
|
-
|
|
107
|
-
if participant.id == participant_id:
|
|
108
|
-
chat_with_participant = participant
|
|
109
|
-
break
|
|
167
|
+
return await self.room.sync.close(path=path)
|
|
110
168
|
|
|
111
|
-
if chat_with_participant == None:
|
|
112
|
-
raise RoomException(f"caller did not have messaging turned on")
|
|
113
|
-
|
|
114
|
-
messaging = self._room.messaging
|
|
115
169
|
|
|
170
|
+
async def _spawn_thread(self, path: str, messages: Chan[RoomMessage]):
|
|
171
|
+
|
|
172
|
+
self.room.developer.log_nowait(type="chatbot.thread.started", data={ "path" : path })
|
|
173
|
+
chat_context = await self.init_chat_context()
|
|
174
|
+
opened = False
|
|
175
|
+
thread = None
|
|
176
|
+
doc_messages = None
|
|
116
177
|
current_file = None
|
|
178
|
+
llm_messages = Chan[ResponseStreamEvent]()
|
|
117
179
|
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
"properties" : {
|
|
124
|
-
"text" : {
|
|
125
|
-
"description" : "a reply to the user or status to display during an intermediate step",
|
|
126
|
-
"type" : "string"
|
|
127
|
-
},
|
|
128
|
-
"finished" : {
|
|
129
|
-
"description" : "whether the agent has finished answering the user's last message. you MUST set this to true if there are no more tool calls to be made or you are stuck in a loop.",
|
|
130
|
-
"type" : "boolean"
|
|
131
|
-
}
|
|
132
|
-
}
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
installed = False
|
|
136
|
-
|
|
137
|
-
while True:
|
|
138
|
-
|
|
139
|
-
while True:
|
|
180
|
+
def done_processing_llm_events(task: asyncio.Task):
|
|
181
|
+
try:
|
|
182
|
+
task.result()
|
|
183
|
+
except Exception as e:
|
|
184
|
+
logger.error("error sending delta", exc_info=e)
|
|
140
185
|
|
|
141
|
-
|
|
186
|
+
async def process_llm_events():
|
|
142
187
|
|
|
143
|
-
|
|
188
|
+
partial = ""
|
|
189
|
+
content_element = None
|
|
190
|
+
context_message = None
|
|
144
191
|
|
|
192
|
+
async for evt in llm_messages:
|
|
145
193
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
194
|
+
#await self.room.messaging.send_message(to=chat_with_participant, type="llm.event", message=evt)
|
|
195
|
+
|
|
196
|
+
if evt.type == "response.content_part.added":
|
|
197
|
+
partial = ""
|
|
198
|
+
content_element = doc_messages.append_child(tag_name="message", attributes={
|
|
199
|
+
"text" : "",
|
|
200
|
+
"created_at" : datetime.datetime.now(datetime.timezone.utc).isoformat().replace("+00:00","Z"),
|
|
201
|
+
"author_name" : self.room.local_participant.get_attribute("name"),
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
context_message = {
|
|
205
|
+
"role" : "assistant",
|
|
206
|
+
"content" : ""
|
|
207
|
+
}
|
|
208
|
+
chat_context.messages.append(context_message)
|
|
209
|
+
|
|
210
|
+
elif evt.type == "response.output_text.delta":
|
|
211
|
+
partial += evt.delta
|
|
212
|
+
content_element["text"] = partial
|
|
213
|
+
context_message["content"] = partial
|
|
150
214
|
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
elif current_file != None:
|
|
155
|
-
chat_context.append_assistant_message(message=f"the user is not current viewing any files")
|
|
156
|
-
|
|
215
|
+
elif evt.type == "response.output_text.done":
|
|
216
|
+
content_element = None
|
|
157
217
|
|
|
218
|
+
llm_task = asyncio.create_task(process_llm_events())
|
|
219
|
+
llm_task.add_done_callback(done_processing_llm_events)
|
|
158
220
|
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
221
|
+
try:
|
|
222
|
+
while True:
|
|
223
|
+
|
|
224
|
+
while True:
|
|
162
225
|
|
|
226
|
+
received = await messages.recv()
|
|
163
227
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
228
|
+
chat_with_participant = None
|
|
229
|
+
for participant in self._room.messaging.get_participants():
|
|
230
|
+
if participant.id == received.from_participant_id:
|
|
231
|
+
chat_with_participant = participant
|
|
232
|
+
break
|
|
168
233
|
|
|
169
|
-
|
|
234
|
+
if chat_with_participant == None:
|
|
235
|
+
logger.warning("participant does not have messaging enabled, skipping message")
|
|
236
|
+
continue
|
|
237
|
+
|
|
238
|
+
if current_file != chat_with_participant.get_attribute("current_file"):
|
|
239
|
+
logger.info(f"participant is now looking at {chat_with_participant.get_attribute("current_file")}")
|
|
240
|
+
current_file = chat_with_participant.get_attribute("current_file")
|
|
170
241
|
|
|
171
|
-
|
|
242
|
+
if current_file != None:
|
|
243
|
+
chat_context.append_assistant_message(message=f"the user is currently viewing the file at the path: {current_file}")
|
|
172
244
|
|
|
173
|
-
|
|
245
|
+
elif current_file != None:
|
|
246
|
+
chat_context.append_assistant_message(message=f"the user is not current viewing any files")
|
|
174
247
|
|
|
175
|
-
|
|
176
|
-
await self._room.messaging.send_message(to=chat_with_participant, type="thinking", message={"thinking":True})
|
|
177
|
-
|
|
178
|
-
if chat_with_participant.id == received.from_participant_id:
|
|
179
|
-
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"] } } })
|
|
180
248
|
|
|
181
|
-
|
|
182
|
-
|
|
249
|
+
if thread == None:
|
|
250
|
+
thread = await self.open_thread(path=path)
|
|
251
|
+
|
|
252
|
+
for prop in thread.root.get_children():
|
|
253
|
+
|
|
254
|
+
if prop.tag_name == "messages":
|
|
255
|
+
|
|
256
|
+
doc_messages = prop
|
|
257
|
+
|
|
258
|
+
for element in doc_messages.get_children():
|
|
259
|
+
|
|
260
|
+
if isinstance(element, Element):
|
|
261
|
+
|
|
262
|
+
msg = element["text"]
|
|
263
|
+
if element["author_name"] == self.room.local_participant.get_attribute("name"):
|
|
264
|
+
chat_context.append_assistant_message(msg)
|
|
265
|
+
else:
|
|
266
|
+
chat_context.append_user_message(msg)
|
|
267
|
+
|
|
268
|
+
if doc_messages == None:
|
|
269
|
+
raise Exception("thread was not properly initialized")
|
|
183
270
|
|
|
184
|
-
for attachment in attachments:
|
|
185
271
|
|
|
186
|
-
|
|
272
|
+
if received.type == "opened":
|
|
273
|
+
|
|
274
|
+
if opened == False:
|
|
187
275
|
|
|
188
|
-
|
|
189
|
-
chat_context.append_user_message(message=text)
|
|
276
|
+
opened = True
|
|
190
277
|
|
|
278
|
+
await self.greet(path=path, chat_context=chat_context, participant=chat_with_participant, messages=doc_messages)
|
|
191
279
|
|
|
192
|
-
|
|
193
|
-
while True:
|
|
280
|
+
if received.type == "chat":
|
|
194
281
|
|
|
195
|
-
if
|
|
282
|
+
if thread == None:
|
|
283
|
+
|
|
284
|
+
self.room.developer.log_nowait(type="thread is not open", data={})
|
|
285
|
+
|
|
196
286
|
break
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
text = received.message["text"]
|
|
290
|
+
|
|
291
|
+
|
|
292
|
+
for participant in get_thread_participants(room=self._room, thread=thread):
|
|
293
|
+
# TODO: async gather
|
|
294
|
+
await self._room.messaging.send_message(to=participant, type="thinking", message={"thinking":True, "path": path})
|
|
295
|
+
|
|
296
|
+
if chat_with_participant.id == received.from_participant_id:
|
|
297
|
+
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"] } } })
|
|
197
298
|
|
|
198
|
-
|
|
299
|
+
|
|
300
|
+
attachments = received.message.get("attachments", [])
|
|
199
301
|
|
|
200
|
-
|
|
201
|
-
break
|
|
202
|
-
|
|
302
|
+
for attachment in attachments:
|
|
203
303
|
|
|
204
|
-
|
|
205
|
-
|
|
304
|
+
chat_context.append_assistant_message(message=f"the user attached a file '{attachment["filename"]}' with the content: '{attachment["content"]}'")
|
|
305
|
+
|
|
206
306
|
|
|
307
|
+
chat_context.append_user_message(message=text)
|
|
308
|
+
|
|
309
|
+
|
|
310
|
+
# if user is typing, wait for typing to stop
|
|
311
|
+
while True:
|
|
312
|
+
|
|
313
|
+
if chat_with_participant.id not in self._is_typing:
|
|
314
|
+
break
|
|
315
|
+
|
|
316
|
+
await asyncio.sleep(.5)
|
|
317
|
+
|
|
318
|
+
if messages.empty() == True:
|
|
319
|
+
break
|
|
320
|
+
|
|
321
|
+
|
|
322
|
+
try:
|
|
323
|
+
|
|
207
324
|
toolkits = [
|
|
208
325
|
*self._toolkits,
|
|
209
326
|
*await self.get_required_tools(participant_id=chat_with_participant.id)
|
|
210
327
|
]
|
|
211
328
|
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
context=chat_context,
|
|
216
|
-
room=self._room,
|
|
329
|
+
thread_context = ChatThreadContext(
|
|
330
|
+
chat=chat_context,
|
|
331
|
+
thread=thread,
|
|
217
332
|
toolkits=toolkits,
|
|
218
|
-
tool_adapter=self._tool_adapter,
|
|
219
|
-
output_schema=step_schema,
|
|
220
333
|
)
|
|
221
334
|
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
else:
|
|
235
|
-
await self._room.messaging.send_message(
|
|
236
|
-
to=chat_with_participant,
|
|
237
|
-
type="status",
|
|
238
|
-
message={
|
|
239
|
-
"text": text
|
|
240
|
-
}
|
|
335
|
+
await self.init_thread_context(thread_context=thread_context)
|
|
336
|
+
|
|
337
|
+
def handle_event(evt):
|
|
338
|
+
llm_messages.send_nowait(evt)
|
|
339
|
+
|
|
340
|
+
try:
|
|
341
|
+
response = await self._llm_adapter.next(
|
|
342
|
+
context=chat_context,
|
|
343
|
+
room=self._room,
|
|
344
|
+
toolkits=toolkits,
|
|
345
|
+
tool_adapter=self._tool_adapter,
|
|
346
|
+
event_handler=handle_event
|
|
241
347
|
)
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
348
|
+
except Exception as e:
|
|
349
|
+
logger.error("An error was encountered", exc_info=e)
|
|
350
|
+
await self._send_and_save_chat(messages=doc_messages, to=chat_with_participant, path=path, id=str(uuid.uuid4()), text="There was an error while communicating with the LLM. Please try again later.")
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
finally:
|
|
354
|
+
for participant in get_thread_participants(room=self._room, thread=thread):
|
|
355
|
+
# TODO: async gather
|
|
356
|
+
await self._room.messaging.send_message(to=participant, type="thinking", message={"thinking":False, "path" : path})
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
finally:
|
|
245
360
|
|
|
246
|
-
|
|
361
|
+
self.room.developer.log_nowait(type="chatbot.thread.ended", data={ "path" : path })
|
|
362
|
+
|
|
363
|
+
llm_messages.close()
|
|
247
364
|
|
|
365
|
+
if thread != None:
|
|
366
|
+
await self.close_thread(path=path)
|
|
248
367
|
|
|
249
368
|
|
|
250
369
|
def _get_message_channel(self, participant_id: str) -> Chan[RoomMessage]:
|
|
@@ -252,37 +371,50 @@ class ChatBot(SingleRoomAgent):
|
|
|
252
371
|
chan = Chan[RoomMessage]()
|
|
253
372
|
self._message_channels[participant_id] = chan
|
|
254
373
|
|
|
255
|
-
def thread_done(task: asyncio.Task):
|
|
256
|
-
|
|
257
|
-
self._message_channels.pop(participant_id)
|
|
258
|
-
try:
|
|
259
|
-
task.result()
|
|
260
|
-
logger.info("ending chat thread")
|
|
261
|
-
except Exception as e:
|
|
262
|
-
logger.error("chat thread error", exc_info=e)
|
|
263
|
-
|
|
264
|
-
task = asyncio.create_task(self._spawn_thread(participant_id=participant_id, messages=chan))
|
|
265
|
-
task.add_done_callback(thread_done)
|
|
266
|
-
|
|
267
374
|
chan = self._message_channels[participant_id]
|
|
268
375
|
|
|
269
376
|
return chan
|
|
270
377
|
|
|
271
|
-
async def
|
|
378
|
+
async def stop(self):
|
|
379
|
+
await super().stop()
|
|
272
380
|
|
|
273
|
-
|
|
381
|
+
for thread in self._thread_tasks.values():
|
|
382
|
+
thread.cancel()
|
|
383
|
+
|
|
384
|
+
self._thread_tasks.clear()
|
|
274
385
|
|
|
386
|
+
async def start(self, *, room):
|
|
275
387
|
|
|
388
|
+
await super().start(room=room)
|
|
389
|
+
|
|
276
390
|
await self.room.local_participant.set_attribute("empty_state_title", self._empty_state_title)
|
|
277
391
|
|
|
278
392
|
def on_message(message: RoomMessage):
|
|
393
|
+
|
|
279
394
|
messages = self._get_message_channel(participant_id=message.from_participant_id)
|
|
280
395
|
if message.type == "chat" or message.type == "opened":
|
|
281
396
|
messages.send_nowait(message)
|
|
282
|
-
|
|
283
|
-
elif message.type == "typing":
|
|
284
397
|
|
|
398
|
+
path = message.message["path"]
|
|
399
|
+
logger.info(f"received message for thread {path}")
|
|
285
400
|
|
|
401
|
+
if path not in self._thread_tasks or self._thread_tasks[path].cancelled:
|
|
402
|
+
|
|
403
|
+
def thread_done(task: asyncio.Task):
|
|
404
|
+
|
|
405
|
+
self._message_channels.pop(message.from_participant_id)
|
|
406
|
+
try:
|
|
407
|
+
task.result()
|
|
408
|
+
except Exception as e:
|
|
409
|
+
logger.error(f"The chat thread ended with an error {e}", exc_info=e)
|
|
410
|
+
|
|
411
|
+
|
|
412
|
+
task = asyncio.create_task(self._spawn_thread(messages=messages, path=path))
|
|
413
|
+
task.add_done_callback(thread_done)
|
|
414
|
+
|
|
415
|
+
self._thread_tasks[path] = task
|
|
416
|
+
|
|
417
|
+
elif message.type == "typing":
|
|
286
418
|
def callback(task: asyncio.Task):
|
|
287
419
|
try:
|
|
288
420
|
task.result()
|
|
@@ -303,7 +435,7 @@ class ChatBot(SingleRoomAgent):
|
|
|
303
435
|
|
|
304
436
|
room.messaging.on("message", on_message)
|
|
305
437
|
|
|
306
|
-
if self.
|
|
438
|
+
if self._auto_greet_message != None:
|
|
307
439
|
def on_participant_added(participant:RemoteParticipant):
|
|
308
440
|
|
|
309
441
|
# will spawn the initial thread
|
meshagent/agents/context.py
CHANGED
|
@@ -16,6 +16,9 @@ class AgentChatContext:
|
|
|
16
16
|
if system_role == None:
|
|
17
17
|
system_role = "system"
|
|
18
18
|
self._system_role = system_role
|
|
19
|
+
|
|
20
|
+
self._previous_response_id = None
|
|
21
|
+
self._previous_messages = list[dict]()
|
|
19
22
|
|
|
20
23
|
@property
|
|
21
24
|
def messages(self):
|
|
@@ -24,6 +27,19 @@ class AgentChatContext:
|
|
|
24
27
|
@property
|
|
25
28
|
def system_role(self):
|
|
26
29
|
return self._system_role
|
|
30
|
+
|
|
31
|
+
@property
|
|
32
|
+
def previous_messages(self):
|
|
33
|
+
return self._previous_messages
|
|
34
|
+
|
|
35
|
+
@property
|
|
36
|
+
def previous_response_id(self):
|
|
37
|
+
return self._previous_response_id
|
|
38
|
+
|
|
39
|
+
def create_response(self, id: str):
|
|
40
|
+
self._previous_response_id = id
|
|
41
|
+
self._previous_messages.extend(self.messages)
|
|
42
|
+
self.messages.clear()
|
|
27
43
|
|
|
28
44
|
def append_rules(self, rules: list[str]):
|
|
29
45
|
|
meshagent/agents/indexer.py
CHANGED
|
@@ -283,9 +283,6 @@ class StorageIndexer(SingleRoomAgent):
|
|
|
283
283
|
|
|
284
284
|
self._index_task = asyncio.create_task(self._indexer())
|
|
285
285
|
self._index_task.add_done_callback(index_task)
|
|
286
|
-
|
|
287
|
-
await self.install_requirements()
|
|
288
|
-
|
|
289
286
|
|
|
290
287
|
async def stop(self):
|
|
291
288
|
await super().stop()
|
meshagent/agents/planning.py
CHANGED
|
@@ -7,7 +7,7 @@ from meshagent.api.schema import MeshSchema
|
|
|
7
7
|
from meshagent.agents.writer import Writer, WriterContext
|
|
8
8
|
from meshagent.agents.adapter import LLMAdapter, ToolResponseAdapter
|
|
9
9
|
from meshagent.api.schema import MeshSchema, ElementType, ChildProperty, ValueProperty
|
|
10
|
-
from meshagent.
|
|
10
|
+
from meshagent.api.schema_util import merge
|
|
11
11
|
from meshagent.tools.document_tools import build_tools, DocumentAuthoringToolkit
|
|
12
12
|
from meshagent.agents import TaskRunner
|
|
13
13
|
from copy import deepcopy
|
|
@@ -120,7 +120,7 @@ def reasoning_schema(*, description: str, elements: Optional[list[ElementType]]
|
|
|
120
120
|
*elements
|
|
121
121
|
])
|
|
122
122
|
|
|
123
|
-
from .
|
|
123
|
+
from meshagent.api.schema_util import prompt_schema
|
|
124
124
|
import logging
|
|
125
125
|
logging.basicConfig()
|
|
126
126
|
logger = logging.getLogger("planning_agent")
|
meshagent/agents/prompt.py
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
|
|
2
2
|
from .adapter import LLMAdapter, Toolkit, ToolResponseAdapter
|
|
3
|
-
from .
|
|
3
|
+
from meshagent.api.schema_util import prompt_schema
|
|
4
4
|
from .agent import AgentCallContext
|
|
5
5
|
from typing import Optional
|
|
6
6
|
from meshagent.agents import TaskRunner
|
|
7
|
+
from meshagent.api import RequiredToolkit
|
|
7
8
|
|
|
8
9
|
# An agent that takes a simple prompt and gets the result
|
|
9
10
|
class PromptAgent(TaskRunner):
|
|
@@ -16,7 +17,10 @@ class PromptAgent(TaskRunner):
|
|
|
16
17
|
tools: list[Toolkit] = [],
|
|
17
18
|
rules: list[str] = [],
|
|
18
19
|
title: Optional[str] = None,
|
|
19
|
-
description: Optional[str] = None
|
|
20
|
+
description: Optional[str] = None,
|
|
21
|
+
requires: Optional[list[RequiredToolkit]] = None,
|
|
22
|
+
supports_tools: Optional[bool] = None,
|
|
23
|
+
labels: Optional[list[str]] = None
|
|
20
24
|
):
|
|
21
25
|
super().__init__(
|
|
22
26
|
name=name,
|
|
@@ -26,7 +30,9 @@ class PromptAgent(TaskRunner):
|
|
|
26
30
|
description=description
|
|
27
31
|
),
|
|
28
32
|
output_schema=output_schema,
|
|
29
|
-
|
|
33
|
+
requires=requires,
|
|
34
|
+
supports_tools=supports_tools,
|
|
35
|
+
labels=labels
|
|
30
36
|
)
|
|
31
37
|
self.rules = rules
|
|
32
38
|
self.tools = tools
|
meshagent/agents/pydantic.py
CHANGED
|
@@ -6,12 +6,13 @@ from .agent import AgentCallContext
|
|
|
6
6
|
from .writer import Writer, WriterContext
|
|
7
7
|
import logging
|
|
8
8
|
from typing import Optional
|
|
9
|
+
from meshagent.api import RoomClient
|
|
9
10
|
|
|
10
11
|
from .agent import TaskRunner, RequiredToolkit, Requirement, RequiredSchema
|
|
11
12
|
|
|
12
13
|
from .adapter import ToolResponseAdapter
|
|
13
|
-
|
|
14
|
-
from meshagent.tools.pydantic import
|
|
14
|
+
from meshagent.tools.toolkit import Tool, Response, ToolContext
|
|
15
|
+
from meshagent.tools.pydantic import get_pydantic_ai_tool_definition
|
|
15
16
|
|
|
16
17
|
from typing import Sequence
|
|
17
18
|
import pydantic_ai
|
|
@@ -19,6 +20,35 @@ import pydantic_ai
|
|
|
19
20
|
logger = logging.getLogger("pydantic_agent")
|
|
20
21
|
logger.setLevel(logging.INFO)
|
|
21
22
|
|
|
23
|
+
|
|
24
|
+
def get_pydantic_ai_tool(*, room: RoomClient, tool: Tool, response_adapter: ToolResponseAdapter) -> pydantic_ai.tools.Tool:
|
|
25
|
+
async def prepare(ctx: pydantic_ai.RunContext, tool_def: pydantic_ai.tools.ToolDefinition):
|
|
26
|
+
return get_pydantic_ai_tool_definition(tool=tool)
|
|
27
|
+
|
|
28
|
+
async def execute(**kwargs):
|
|
29
|
+
response = await tool.execute(context=ToolContext(room=room, caller=room.local_participant), **kwargs)
|
|
30
|
+
return await response_adapter.to_plain_text(room=room, response=response)
|
|
31
|
+
|
|
32
|
+
return pydantic_ai.Tool(
|
|
33
|
+
name=tool.name,
|
|
34
|
+
takes_ctx=False,
|
|
35
|
+
description=tool.description,
|
|
36
|
+
prepare=prepare,
|
|
37
|
+
function=execute
|
|
38
|
+
)
|
|
39
|
+
|
|
40
|
+
def get_pydantic_ai_tools_from_context(*, context: AgentCallContext, response_adapter: ToolResponseAdapter) -> list[pydantic_ai.tools.Tool]:
|
|
41
|
+
|
|
42
|
+
tools = list[pydantic_ai.tools.Tool]()
|
|
43
|
+
|
|
44
|
+
for toolkit in context.toolkits:
|
|
45
|
+
|
|
46
|
+
for tool in toolkit.tools:
|
|
47
|
+
|
|
48
|
+
tools.append(get_pydantic_ai_tool(room=context.room, tool=tool, response_adapter=response_adapter))
|
|
49
|
+
|
|
50
|
+
return tools
|
|
51
|
+
|
|
22
52
|
class PydanticAgent[TInput:BaseModel, TOutput:BaseModel](TaskRunner):
|
|
23
53
|
def __init__(self,
|
|
24
54
|
*,
|
|
@@ -3,7 +3,7 @@ from meshagent.api.schema import ValueProperty, ChildProperty
|
|
|
3
3
|
from meshagent.tools import Toolkit
|
|
4
4
|
from meshagent.agents.writer import Writer, WriterContext
|
|
5
5
|
from meshagent.agents.adapter import LLMAdapter, ToolResponseAdapter
|
|
6
|
-
from .
|
|
6
|
+
from meshagent.api.schema_util import prompt_schema, merge
|
|
7
7
|
from typing import Optional
|
|
8
8
|
from meshagent.api import Requirement
|
|
9
9
|
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
from meshagent.api.schema import MeshSchema, ElementType, ChildProperty, ValueProperty
|
|
2
|
+
|
|
3
|
+
thread_schema = MeshSchema(
|
|
4
|
+
root_tag_name="thread",
|
|
5
|
+
elements=[
|
|
6
|
+
ElementType(
|
|
7
|
+
tag_name="thread",
|
|
8
|
+
description="a thread of messages",
|
|
9
|
+
properties=[
|
|
10
|
+
ChildProperty(name="properties", description="the messages in the thread", ordered=True, child_tag_names=[
|
|
11
|
+
"members", "messages"
|
|
12
|
+
]),
|
|
13
|
+
]
|
|
14
|
+
),
|
|
15
|
+
ElementType(
|
|
16
|
+
tag_name="members",
|
|
17
|
+
description="the members of this thread",
|
|
18
|
+
properties=[
|
|
19
|
+
ChildProperty(name="items", child_tag_names=["member"], description="the messages in this thread")
|
|
20
|
+
]
|
|
21
|
+
),
|
|
22
|
+
ElementType(
|
|
23
|
+
tag_name="messages",
|
|
24
|
+
description="the messages of this thread",
|
|
25
|
+
properties=[
|
|
26
|
+
ChildProperty(name="items", child_tag_names=["message"], description="the messages in this thread")
|
|
27
|
+
]
|
|
28
|
+
),
|
|
29
|
+
ElementType(
|
|
30
|
+
tag_name="member",
|
|
31
|
+
description="a member of this thread",
|
|
32
|
+
properties=[
|
|
33
|
+
ValueProperty(name="name", description="the name of the member", type="string"),
|
|
34
|
+
ValueProperty(name="type", description="the type of member", type="string", enum=[
|
|
35
|
+
"user", "agent"
|
|
36
|
+
]),
|
|
37
|
+
]
|
|
38
|
+
),
|
|
39
|
+
ElementType(
|
|
40
|
+
tag_name="file",
|
|
41
|
+
description="a file attachment",
|
|
42
|
+
properties=[
|
|
43
|
+
ValueProperty(name="path", description="the path of the file in the room", type="string"),
|
|
44
|
+
]
|
|
45
|
+
),
|
|
46
|
+
ElementType(
|
|
47
|
+
tag_name="message",
|
|
48
|
+
description="a message sent in the conversation",
|
|
49
|
+
properties=[
|
|
50
|
+
ValueProperty(name="id", description="the id of the message", type="string"),
|
|
51
|
+
ValueProperty(name="text", description="the text of the message", type="string"),
|
|
52
|
+
ValueProperty(name="created_at", description="the date that the message was sent in ISO format", type="string"),
|
|
53
|
+
ValueProperty(name="author_name", description="the name of the author of the post", type="string"),
|
|
54
|
+
ValueProperty(name="author_ref", description="a reference to author identity in another system", type="string"),
|
|
55
|
+
ChildProperty(name="attachments", child_tag_names=["file"], description="a list of message attachments")
|
|
56
|
+
]
|
|
57
|
+
),
|
|
58
|
+
]
|
|
59
|
+
)
|
meshagent/agents/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
__version__ = "0.0.
|
|
1
|
+
__version__ = "0.0.4"
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.2
|
|
2
2
|
Name: meshagent-agents
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.4
|
|
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.
|
|
17
|
-
Requires-Dist: meshagent-tools>=0.0.
|
|
18
|
-
Requires-Dist: meshagent-openai>=0.0.
|
|
16
|
+
Requires-Dist: meshagent-api>=0.0.4
|
|
17
|
+
Requires-Dist: meshagent-tools>=0.0.4
|
|
18
|
+
Requires-Dist: meshagent-openai>=0.0.4
|
|
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
|
|
@@ -0,0 +1,22 @@
|
|
|
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=1NsmQECm2WqHhKcegDz40p9FX4dY9W3hjjgztScVc1s,17409
|
|
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=2GWffEF1rjyrveUGdfR8y3cl3JUnX0gJjr8Ryy_u4JQ,21
|
|
16
|
+
meshagent/agents/worker.py,sha256=vZ6tnOyjno8N551c5HsXR8Mw3ZPmYRa4o1MZ3i7hEG4,4374
|
|
17
|
+
meshagent/agents/writer.py,sha256=Ff8RVxdpFNKmo6zxaGkuFMz8MIKumdM0FIXX_6lbZ6Q,2738
|
|
18
|
+
meshagent_agents-0.0.4.dist-info/LICENSE,sha256=eTt0SPW-sVNdkZe9PS_S8WfCIyLjRXRl7sUBWdlteFg,10254
|
|
19
|
+
meshagent_agents-0.0.4.dist-info/METADATA,sha256=64GXsnluH0GU9-tYdqzYFBWZuXlU-XzqyLarqvB_cnQ,896
|
|
20
|
+
meshagent_agents-0.0.4.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
|
21
|
+
meshagent_agents-0.0.4.dist-info/top_level.txt,sha256=GlcXnHtRP6m7zlG3Df04M35OsHtNXy_DY09oFwWrH74,10
|
|
22
|
+
meshagent_agents-0.0.4.dist-info/RECORD,,
|
meshagent/agents/schema.py
DELETED
|
@@ -1,50 +0,0 @@
|
|
|
1
|
-
from copy import deepcopy
|
|
2
|
-
|
|
3
|
-
def validation_schema(description: str):
|
|
4
|
-
return {
|
|
5
|
-
"type" : "object",
|
|
6
|
-
"description" : description,
|
|
7
|
-
"required" : [ "is_valid", "message" ],
|
|
8
|
-
"additionalProperties" : False,
|
|
9
|
-
"properties" : {
|
|
10
|
-
"is_valid" : {
|
|
11
|
-
"type" : "boolean",
|
|
12
|
-
},
|
|
13
|
-
"message" : {
|
|
14
|
-
"type" : "string",
|
|
15
|
-
},
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
def prompt_schema(description: str):
|
|
20
|
-
return {
|
|
21
|
-
"type" : "object",
|
|
22
|
-
"description" : description,
|
|
23
|
-
"required" : [ "prompt" ],
|
|
24
|
-
"additionalProperties" : False,
|
|
25
|
-
"properties" : {
|
|
26
|
-
"prompt" : {
|
|
27
|
-
"description" : "a prompt that will be used by the agent to create a response",
|
|
28
|
-
"type" : "string",
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
def no_arguments_schema(description: str):
|
|
34
|
-
return {
|
|
35
|
-
"description" : description,
|
|
36
|
-
"type" : "object",
|
|
37
|
-
"required" : [],
|
|
38
|
-
"additionalProperties" : False,
|
|
39
|
-
"properties" : {
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
def merge(*, schema: dict, additional_properties: dict) -> dict:
|
|
44
|
-
schema = deepcopy(schema)
|
|
45
|
-
|
|
46
|
-
for k,v in additional_properties.items():
|
|
47
|
-
schema["required"].append(k)
|
|
48
|
-
schema["properties"][k] = v
|
|
49
|
-
|
|
50
|
-
return schema
|
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
meshagent/agents/__init__.py,sha256=morriYsu4jkd6oboNO-s531uRTns_br6f4CV_AC7omg,303
|
|
2
|
-
meshagent/agents/adapter.py,sha256=fBNmLtHHgZbgWIqGDUPu5PrUV8qM-_E4kWWvHFWmZqg,1066
|
|
3
|
-
meshagent/agents/agent.py,sha256=VrjUH_scLe4CuZwsrnGMKVvi4NeUcAahd4K9CGEpwwk,15537
|
|
4
|
-
meshagent/agents/chat.py,sha256=JhEscOBipq5liAC_DrPYqyi3v_3td1x25mH5d0GWS5o,11565
|
|
5
|
-
meshagent/agents/context.py,sha256=yph6EW5byiKh8znumr6WgN5Us1x6SDPBS3PQo40_krg,2744
|
|
6
|
-
meshagent/agents/development.py,sha256=04VYL1Q_BWUTQeVuiVOpyjcs8bzUIX1eQ4VyTtjc5s0,926
|
|
7
|
-
meshagent/agents/hosting.py,sha256=e2wMGbWFt0WO3CJaTQehwbucftgUNVTgRsrBWiYDgcU,4973
|
|
8
|
-
meshagent/agents/indexer.py,sha256=7JYCnP-A_nqV5l7zhDgyoXhplNldL0_x4ERGhZ0Cx1k,19443
|
|
9
|
-
meshagent/agents/listener.py,sha256=kKFaWPmvmk1aCAlI55AAU3-QnOWCSZbf621xZz10rbs,5388
|
|
10
|
-
meshagent/agents/planning.py,sha256=CAnfX_ushG4OAvMCUnMs4XNYBoyc7PV_lgvTIMjhjrw,23116
|
|
11
|
-
meshagent/agents/prompt.py,sha256=PfdH_7_Re1jEPfDmkwtG74-SwyVA7uRXFk_4_s0us6k,1556
|
|
12
|
-
meshagent/agents/pydantic.py,sha256=MUAcc5HWEvnOPPR2DkFVvGykG00_W8BuPwFPrbzher8,4904
|
|
13
|
-
meshagent/agents/schema.py,sha256=Efzd-srpHazNq-jZ7bMNZX_TZJOBbfYfDHXbpLu_hhY,1292
|
|
14
|
-
meshagent/agents/single_shot_writer.py,sha256=-wMqQTYVYrh_P5Gc9PROOiTeJefdgNGWAYeRFZ2sQVk,3387
|
|
15
|
-
meshagent/agents/version.py,sha256=ugyuFliEqtAwQmH4sTlc16YXKYbFWDmfyk87fErB8-8,21
|
|
16
|
-
meshagent/agents/worker.py,sha256=vZ6tnOyjno8N551c5HsXR8Mw3ZPmYRa4o1MZ3i7hEG4,4374
|
|
17
|
-
meshagent/agents/writer.py,sha256=Ff8RVxdpFNKmo6zxaGkuFMz8MIKumdM0FIXX_6lbZ6Q,2738
|
|
18
|
-
meshagent_agents-0.0.1.dist-info/LICENSE,sha256=eTt0SPW-sVNdkZe9PS_S8WfCIyLjRXRl7sUBWdlteFg,10254
|
|
19
|
-
meshagent_agents-0.0.1.dist-info/METADATA,sha256=EPKnWFmGl4SIn5Xy17PyisiCqpLWrkpOkvRkqHAvt2g,896
|
|
20
|
-
meshagent_agents-0.0.1.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
|
21
|
-
meshagent_agents-0.0.1.dist-info/top_level.txt,sha256=GlcXnHtRP6m7zlG3Df04M35OsHtNXy_DY09oFwWrH74,10
|
|
22
|
-
meshagent_agents-0.0.1.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|