meshagent-agents 0.0.3__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 -157
- 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.3.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.3.dist-info/RECORD +0 -22
- {meshagent_agents-0.0.3.dist-info → meshagent_agents-0.0.4.dist-info}/LICENSE +0 -0
- {meshagent_agents-0.0.3.dist-info → meshagent_agents-0.0.4.dist-info}/WHEEL +0 -0
- {meshagent_agents-0.0.3.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,180 +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")
|
|
215
|
+
elif evt.type == "response.output_text.done":
|
|
216
|
+
content_element = None
|
|
156
217
|
|
|
218
|
+
llm_task = asyncio.create_task(process_llm_events())
|
|
219
|
+
llm_task.add_done_callback(done_processing_llm_events)
|
|
157
220
|
|
|
221
|
+
try:
|
|
222
|
+
while True:
|
|
223
|
+
|
|
224
|
+
while True:
|
|
158
225
|
|
|
159
|
-
|
|
160
|
-
installed = True
|
|
161
|
-
try:
|
|
162
|
-
await self.install_requirements(participant_id=participant_id)
|
|
163
|
-
except Exception as e:
|
|
164
|
-
self.room.developer.log_nowait("error", { "text" : f"unable to install requirements: {e}" })
|
|
165
|
-
|
|
166
|
-
error = "I was unable to install the tools I require to operate in the room, I may not function properly."
|
|
167
|
-
chat_context.append_user_message(message=error)
|
|
168
|
-
await self._room.messaging.send_message(
|
|
169
|
-
to=chat_with_participant,
|
|
170
|
-
type="chat",
|
|
171
|
-
message={
|
|
172
|
-
"text": error
|
|
173
|
-
}
|
|
174
|
-
)
|
|
226
|
+
received = await messages.recv()
|
|
175
227
|
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
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
|
|
180
233
|
|
|
181
|
-
|
|
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")
|
|
182
241
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
if received.type == "chat":
|
|
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}")
|
|
186
244
|
|
|
245
|
+
elif current_file != None:
|
|
246
|
+
chat_context.append_assistant_message(message=f"the user is not current viewing any files")
|
|
187
247
|
|
|
188
|
-
await self._room.messaging.send_message(to=chat_with_participant, type="thinking", message={"thinking":True})
|
|
189
248
|
|
|
190
|
-
if
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
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")
|
|
195
270
|
|
|
196
|
-
for attachment in attachments:
|
|
197
271
|
|
|
198
|
-
|
|
272
|
+
if received.type == "opened":
|
|
273
|
+
|
|
274
|
+
if opened == False:
|
|
199
275
|
|
|
200
|
-
|
|
201
|
-
chat_context.append_user_message(message=text)
|
|
276
|
+
opened = True
|
|
202
277
|
|
|
278
|
+
await self.greet(path=path, chat_context=chat_context, participant=chat_with_participant, messages=doc_messages)
|
|
203
279
|
|
|
204
|
-
|
|
205
|
-
while True:
|
|
280
|
+
if received.type == "chat":
|
|
206
281
|
|
|
207
|
-
if
|
|
282
|
+
if thread == None:
|
|
283
|
+
|
|
284
|
+
self.room.developer.log_nowait(type="thread is not open", data={})
|
|
285
|
+
|
|
208
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"] } } })
|
|
209
298
|
|
|
210
|
-
|
|
299
|
+
|
|
300
|
+
attachments = received.message.get("attachments", [])
|
|
211
301
|
|
|
212
|
-
|
|
213
|
-
break
|
|
214
|
-
|
|
302
|
+
for attachment in attachments:
|
|
215
303
|
|
|
216
|
-
|
|
217
|
-
|
|
304
|
+
chat_context.append_assistant_message(message=f"the user attached a file '{attachment["filename"]}' with the content: '{attachment["content"]}'")
|
|
305
|
+
|
|
218
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
|
+
|
|
219
324
|
toolkits = [
|
|
220
325
|
*self._toolkits,
|
|
221
326
|
*await self.get_required_tools(participant_id=chat_with_participant.id)
|
|
222
327
|
]
|
|
223
328
|
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
context=chat_context,
|
|
228
|
-
room=self._room,
|
|
329
|
+
thread_context = ChatThreadContext(
|
|
330
|
+
chat=chat_context,
|
|
331
|
+
thread=thread,
|
|
229
332
|
toolkits=toolkits,
|
|
230
|
-
tool_adapter=self._tool_adapter,
|
|
231
|
-
output_schema=step_schema,
|
|
232
333
|
)
|
|
233
334
|
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
else:
|
|
247
|
-
await self._room.messaging.send_message(
|
|
248
|
-
to=chat_with_participant,
|
|
249
|
-
type="status",
|
|
250
|
-
message={
|
|
251
|
-
"text": text
|
|
252
|
-
}
|
|
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
|
|
253
347
|
)
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
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:
|
|
257
360
|
|
|
258
|
-
|
|
361
|
+
self.room.developer.log_nowait(type="chatbot.thread.ended", data={ "path" : path })
|
|
362
|
+
|
|
363
|
+
llm_messages.close()
|
|
259
364
|
|
|
365
|
+
if thread != None:
|
|
366
|
+
await self.close_thread(path=path)
|
|
260
367
|
|
|
261
368
|
|
|
262
369
|
def _get_message_channel(self, participant_id: str) -> Chan[RoomMessage]:
|
|
@@ -264,37 +371,50 @@ class ChatBot(SingleRoomAgent):
|
|
|
264
371
|
chan = Chan[RoomMessage]()
|
|
265
372
|
self._message_channels[participant_id] = chan
|
|
266
373
|
|
|
267
|
-
def thread_done(task: asyncio.Task):
|
|
268
|
-
|
|
269
|
-
self._message_channels.pop(participant_id)
|
|
270
|
-
try:
|
|
271
|
-
task.result()
|
|
272
|
-
logger.info("ending chat thread")
|
|
273
|
-
except Exception as e:
|
|
274
|
-
logger.error("chat thread error", exc_info=e)
|
|
275
|
-
|
|
276
|
-
task = asyncio.create_task(self._spawn_thread(participant_id=participant_id, messages=chan))
|
|
277
|
-
task.add_done_callback(thread_done)
|
|
278
|
-
|
|
279
374
|
chan = self._message_channels[participant_id]
|
|
280
375
|
|
|
281
376
|
return chan
|
|
282
377
|
|
|
283
|
-
async def
|
|
378
|
+
async def stop(self):
|
|
379
|
+
await super().stop()
|
|
284
380
|
|
|
285
|
-
|
|
381
|
+
for thread in self._thread_tasks.values():
|
|
382
|
+
thread.cancel()
|
|
383
|
+
|
|
384
|
+
self._thread_tasks.clear()
|
|
286
385
|
|
|
386
|
+
async def start(self, *, room):
|
|
287
387
|
|
|
388
|
+
await super().start(room=room)
|
|
389
|
+
|
|
288
390
|
await self.room.local_participant.set_attribute("empty_state_title", self._empty_state_title)
|
|
289
391
|
|
|
290
392
|
def on_message(message: RoomMessage):
|
|
393
|
+
|
|
291
394
|
messages = self._get_message_channel(participant_id=message.from_participant_id)
|
|
292
395
|
if message.type == "chat" or message.type == "opened":
|
|
293
396
|
messages.send_nowait(message)
|
|
294
|
-
|
|
295
|
-
elif message.type == "typing":
|
|
296
397
|
|
|
398
|
+
path = message.message["path"]
|
|
399
|
+
logger.info(f"received message for thread {path}")
|
|
297
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":
|
|
298
418
|
def callback(task: asyncio.Task):
|
|
299
419
|
try:
|
|
300
420
|
task.result()
|
|
@@ -315,7 +435,7 @@ class ChatBot(SingleRoomAgent):
|
|
|
315
435
|
|
|
316
436
|
room.messaging.on("message", on_message)
|
|
317
437
|
|
|
318
|
-
if self.
|
|
438
|
+
if self._auto_greet_message != None:
|
|
319
439
|
def on_participant_added(participant:RemoteParticipant):
|
|
320
440
|
|
|
321
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=EsPOhw4CV4REJTmV1CPFG-Oxj7O-0vU1eTyPxcYPUq8,12257
|
|
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=k5tJXhBQJ4l9fKHJ76K5w98zBHoYvNk9r-UNH6eQ2-k,21
|
|
16
|
-
meshagent/agents/worker.py,sha256=vZ6tnOyjno8N551c5HsXR8Mw3ZPmYRa4o1MZ3i7hEG4,4374
|
|
17
|
-
meshagent/agents/writer.py,sha256=Ff8RVxdpFNKmo6zxaGkuFMz8MIKumdM0FIXX_6lbZ6Q,2738
|
|
18
|
-
meshagent_agents-0.0.3.dist-info/LICENSE,sha256=eTt0SPW-sVNdkZe9PS_S8WfCIyLjRXRl7sUBWdlteFg,10254
|
|
19
|
-
meshagent_agents-0.0.3.dist-info/METADATA,sha256=MiPmYESj4KOhJD5p-vUfKQuFG1iq_wCgcMtyzfl5A_s,896
|
|
20
|
-
meshagent_agents-0.0.3.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
|
|
21
|
-
meshagent_agents-0.0.3.dist-info/top_level.txt,sha256=GlcXnHtRP6m7zlG3Df04M35OsHtNXy_DY09oFwWrH74,10
|
|
22
|
-
meshagent_agents-0.0.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|