agentx-python 0.3.3__py3-none-any.whl → 0.4.1__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.
- agentx/agentx.py +25 -10
- agentx/resources/agent.py +1 -1
- agentx/resources/workforce.py +119 -0
- agentx/version.py +1 -1
- {agentx_python-0.3.3.dist-info → agentx_python-0.4.1.dist-info}/METADATA +56 -3
- agentx_python-0.4.1.dist-info/RECORD +13 -0
- {agentx_python-0.3.3.dist-info → agentx_python-0.4.1.dist-info}/WHEEL +1 -1
- agentx_python-0.3.3.dist-info/RECORD +0 -12
- {agentx_python-0.3.3.dist-info → agentx_python-0.4.1.dist-info/licenses}/LICENSE +0 -0
- {agentx_python-0.3.3.dist-info → agentx_python-0.4.1.dist-info}/top_level.txt +0 -0
agentx/agentx.py
CHANGED
|
@@ -5,6 +5,7 @@ import logging
|
|
|
5
5
|
|
|
6
6
|
from agentx.util import get_headers
|
|
7
7
|
from agentx.resources.agent import Agent
|
|
8
|
+
from agentx.resources.workforce import Workforce
|
|
8
9
|
|
|
9
10
|
|
|
10
11
|
class AgentX:
|
|
@@ -37,15 +38,29 @@ class AgentX:
|
|
|
37
38
|
response = requests.get(url, headers=get_headers())
|
|
38
39
|
# Check if response was successful
|
|
39
40
|
if response.status_code == 200:
|
|
40
|
-
return [
|
|
41
|
-
Agent(
|
|
42
|
-
id=agent_res.get("_id"),
|
|
43
|
-
name=agent_res.get("name"),
|
|
44
|
-
avatar=agent_res.get("avatar"),
|
|
45
|
-
createdAt=agent_res.get("createdAt"),
|
|
46
|
-
updatedAt=agent_res.get("updatedAt"),
|
|
47
|
-
)
|
|
48
|
-
for agent_res in response.json()
|
|
49
|
-
]
|
|
41
|
+
return [Agent(**agent) for agent in response.json()]
|
|
50
42
|
else:
|
|
51
43
|
raise Exception(f"Failed to list agents: {response.reason}")
|
|
44
|
+
|
|
45
|
+
@staticmethod
|
|
46
|
+
def list_workforces() -> List["Workforce"]:
|
|
47
|
+
"""List all workforces/teams."""
|
|
48
|
+
url = "https://api.agentx.so/api/v1/access/teams"
|
|
49
|
+
response = requests.get(url, headers=get_headers())
|
|
50
|
+
if response.status_code == 200:
|
|
51
|
+
return [Workforce(**workforce) for workforce in response.json()]
|
|
52
|
+
else:
|
|
53
|
+
raise Exception(
|
|
54
|
+
f"Failed to list workforces: {response.status_code} - {response.reason}"
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
def get_profile(self):
|
|
58
|
+
"""Get the current user's profile information."""
|
|
59
|
+
url = "https://api.agentx.so/api/v1/access/getProfile"
|
|
60
|
+
response = requests.get(url, headers=get_headers())
|
|
61
|
+
if response.status_code == 200:
|
|
62
|
+
return response.json()
|
|
63
|
+
else:
|
|
64
|
+
raise Exception(
|
|
65
|
+
f"Failed to get profile: {response.status_code} - {response.reason}"
|
|
66
|
+
)
|
agentx/resources/agent.py
CHANGED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
from typing import Optional, List, Dict, Any, Iterator
|
|
2
|
+
from pydantic import BaseModel, Field
|
|
3
|
+
import requests
|
|
4
|
+
import os
|
|
5
|
+
import json
|
|
6
|
+
import logging
|
|
7
|
+
from agentx.util import get_headers
|
|
8
|
+
from agentx.resources.agent import Agent
|
|
9
|
+
from agentx.resources.conversation import Conversation, ChatResponse
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class User(BaseModel):
|
|
13
|
+
id: str = Field(alias="_id")
|
|
14
|
+
name: str
|
|
15
|
+
email: str
|
|
16
|
+
deleted: bool
|
|
17
|
+
createdAt: str
|
|
18
|
+
updatedAt: str
|
|
19
|
+
avatar: str
|
|
20
|
+
status: int
|
|
21
|
+
customer: str
|
|
22
|
+
resetPwdToken: Optional[str] = None
|
|
23
|
+
defaultWorkspace: str
|
|
24
|
+
workspaces: List[str]
|
|
25
|
+
|
|
26
|
+
class Config:
|
|
27
|
+
populate_by_name = True
|
|
28
|
+
extra = "ignore"
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class Workforce(BaseModel):
|
|
32
|
+
id: str = Field(alias="_id")
|
|
33
|
+
agents: List[Agent]
|
|
34
|
+
name: str
|
|
35
|
+
image: str
|
|
36
|
+
description: str
|
|
37
|
+
manager: Agent
|
|
38
|
+
creator: User
|
|
39
|
+
context: int
|
|
40
|
+
references: bool
|
|
41
|
+
workspace: str
|
|
42
|
+
createdAt: str
|
|
43
|
+
updatedAt: str
|
|
44
|
+
|
|
45
|
+
class Config:
|
|
46
|
+
populate_by_name = True
|
|
47
|
+
extra = "ignore"
|
|
48
|
+
|
|
49
|
+
def new_conversation(self) -> Conversation:
|
|
50
|
+
"""Create a new conversation for this workforce."""
|
|
51
|
+
url = f"https://api.agentx.so/api/v1/access/teams/{self.id}/conversations/new"
|
|
52
|
+
response = requests.post(
|
|
53
|
+
url,
|
|
54
|
+
headers=get_headers(),
|
|
55
|
+
json={"type": "chat"},
|
|
56
|
+
)
|
|
57
|
+
if response.status_code == 200:
|
|
58
|
+
conv_data = response.json()
|
|
59
|
+
# Set the agent_id to the manager's ID since this is a workforce conversation
|
|
60
|
+
conv_data["agent_id"] = self.manager.id
|
|
61
|
+
return Conversation(**conv_data)
|
|
62
|
+
else:
|
|
63
|
+
raise Exception(
|
|
64
|
+
f"Failed to create new conversation: {response.status_code} - {response.reason}"
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
def list_conversations(self) -> List[Conversation]:
|
|
68
|
+
"""List all conversations for this workforce."""
|
|
69
|
+
url = f"https://api.agentx.so/api/v1/access/teams/{self.id}/conversations"
|
|
70
|
+
response = requests.get(url, headers=get_headers())
|
|
71
|
+
if response.status_code == 200:
|
|
72
|
+
conversations = []
|
|
73
|
+
for conv_data in response.json():
|
|
74
|
+
# Set the agent_id to the manager's ID since this is a workforce conversation
|
|
75
|
+
conv_data["agent_id"] = self.manager.id
|
|
76
|
+
conversations.append(Conversation(**conv_data))
|
|
77
|
+
return conversations
|
|
78
|
+
else:
|
|
79
|
+
raise Exception(
|
|
80
|
+
f"Failed to list conversations: {response.status_code} - {response.reason}"
|
|
81
|
+
)
|
|
82
|
+
|
|
83
|
+
def chat_stream(
|
|
84
|
+
self, conversation_id: str, message: str, context: int = -1
|
|
85
|
+
) -> Iterator[ChatResponse]:
|
|
86
|
+
"""Send a message to a team conversation and stream the response."""
|
|
87
|
+
url = f"https://api.agentx.so/api/v1/access/teams/conversations/{conversation_id}/jsonmessagesse"
|
|
88
|
+
response = requests.post(
|
|
89
|
+
url, headers=get_headers(), json={"message": message, "context": context}
|
|
90
|
+
)
|
|
91
|
+
result = ""
|
|
92
|
+
if response.status_code == 200:
|
|
93
|
+
buf = b""
|
|
94
|
+
for chunk in response.iter_content():
|
|
95
|
+
buf += chunk
|
|
96
|
+
try:
|
|
97
|
+
chunk = buf.decode("utf-8")
|
|
98
|
+
except UnicodeDecodeError:
|
|
99
|
+
continue
|
|
100
|
+
result += chunk
|
|
101
|
+
buf = b""
|
|
102
|
+
try:
|
|
103
|
+
if result.count("{") == result.count("}"):
|
|
104
|
+
catch_json = json.loads(result)
|
|
105
|
+
if catch_json:
|
|
106
|
+
result = ""
|
|
107
|
+
yield ChatResponse(
|
|
108
|
+
text=catch_json.get("text"),
|
|
109
|
+
cot=catch_json.get("cot"),
|
|
110
|
+
botId=catch_json.get("botId"),
|
|
111
|
+
reference=catch_json.get("reference"),
|
|
112
|
+
tasks=catch_json.get("tasks"),
|
|
113
|
+
)
|
|
114
|
+
except json.JSONDecodeError:
|
|
115
|
+
continue
|
|
116
|
+
else:
|
|
117
|
+
raise Exception(
|
|
118
|
+
f"Failed to send message: {response.status_code} - {response.reason}"
|
|
119
|
+
)
|
agentx/version.py
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
VERSION = "0.
|
|
1
|
+
VERSION = "0.4.1"
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: agentx-python
|
|
3
|
-
Version: 0.
|
|
4
|
-
Summary:
|
|
3
|
+
Version: 0.4.1
|
|
4
|
+
Summary: Official Python SDK for AgentX (https://www.agentx.so/)
|
|
5
5
|
Home-page: https://github.com/AgentX-ai/AgentX-python-sdk
|
|
6
6
|
Author: Robin Wang and AgentX Team
|
|
7
7
|
Author-email: contact@agentx.so
|
|
@@ -13,12 +13,16 @@ Description-Content-Type: text/markdown
|
|
|
13
13
|
License-File: LICENSE
|
|
14
14
|
Requires-Dist: urllib3>=1.26.11
|
|
15
15
|
Requires-Dist: certifi
|
|
16
|
+
Requires-Dist: requests
|
|
17
|
+
Requires-Dist: pydantic
|
|
18
|
+
Requires-Dist: pydantic_core
|
|
16
19
|
Dynamic: author
|
|
17
20
|
Dynamic: author-email
|
|
18
21
|
Dynamic: classifier
|
|
19
22
|
Dynamic: description
|
|
20
23
|
Dynamic: description-content-type
|
|
21
24
|
Dynamic: home-page
|
|
25
|
+
Dynamic: license-file
|
|
22
26
|
Dynamic: requires-dist
|
|
23
27
|
Dynamic: requires-python
|
|
24
28
|
Dynamic: summary
|
|
@@ -42,6 +46,8 @@ Why build AI agent with AgentX?
|
|
|
42
46
|
- Support all running MCP (model context protocol).
|
|
43
47
|
- Support RAG with built-in re-rank.
|
|
44
48
|
- Multi-agent workforce orchestration.
|
|
49
|
+
- Multiple agents working together with a designated manager agent.
|
|
50
|
+
- Cross vendor LLM orchestration.
|
|
45
51
|
|
|
46
52
|
## Installation
|
|
47
53
|
|
|
@@ -110,3 +116,50 @@ text=None cot=None botId='xxx'
|
|
|
110
116
|
```
|
|
111
117
|
|
|
112
118
|
\*`cot` stands for chain-of-thoughts
|
|
119
|
+
|
|
120
|
+
### Workforce
|
|
121
|
+
|
|
122
|
+
A Workforce (team) consists of multiple agents working together with a designated manager agent.
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
from agentx import AgentX
|
|
126
|
+
|
|
127
|
+
client = AgentX(api_key="<your api key here>")
|
|
128
|
+
|
|
129
|
+
# Get the list of workforces/teams you have
|
|
130
|
+
workforces = client.list_workforces()
|
|
131
|
+
print(workforces)
|
|
132
|
+
|
|
133
|
+
# Get a specific workforce
|
|
134
|
+
workforce = workforces[0] # or any specific workforce
|
|
135
|
+
print(f"Workforce: {workforce.name}")
|
|
136
|
+
print(f"Manager: {workforce.manager.name}")
|
|
137
|
+
print(f"Agents: {[agent.name for agent in workforce.agents]}")
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
#### Workforce Conversations
|
|
141
|
+
|
|
142
|
+
```python
|
|
143
|
+
# Create a new conversation with the workforce
|
|
144
|
+
conversation = workforce.new_conversation()
|
|
145
|
+
|
|
146
|
+
# List all existing conversations for the workforce
|
|
147
|
+
conversations = workforce.list_conversations()
|
|
148
|
+
print(conversations)
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
#### Chat with Workforce
|
|
152
|
+
|
|
153
|
+
Chat with the entire workforce team and get streaming responses from all agents.
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
# Stream chat with the workforce
|
|
157
|
+
response = workforce.chat_stream(conversation.id, "How can you help me with this project?")
|
|
158
|
+
for chunk in response:
|
|
159
|
+
if chunk.text:
|
|
160
|
+
print(chunk.text, end="")
|
|
161
|
+
if chunk.cot:
|
|
162
|
+
print(f" [COT: {chunk.cot}]")
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
The workforce chat allows you to leverage multiple specialized agents working together to provide comprehensive responses to your queries.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
agentx/__init__.py,sha256=AiY83tsCtjSMIBVsvNuxOgSU4i-rCREQrqDrNmCoSd0,279
|
|
2
|
+
agentx/agentx.py,sha256=KqOdK8xtqdBZh8jlQehzeUdKK8PQ1vcmU2P3iBF9UQc,2502
|
|
3
|
+
agentx/util.py,sha256=grYAa8YTvoQSyuy4GvUOwq6SVBRr4DdrBlcTuZwQpzw,132
|
|
4
|
+
agentx/version.py,sha256=Z4S0cUqfWFIxSvanoTDQh676x2hjV4pKRi-FEpPk-k4,18
|
|
5
|
+
agentx/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
+
agentx/resources/agent.py,sha256=SCXuRudp145e-g3R9ohugiPLPgmQt5ARgkbdAoqtIFQ,1542
|
|
7
|
+
agentx/resources/conversation.py,sha256=Xwy3IfFF6C7U7Xu6BNC32IOPqmaKNwCBTbN2w4FpI8w,4485
|
|
8
|
+
agentx/resources/workforce.py,sha256=9yPrh3zrlbD_D8EruntT8dhQyTZDyxvocYS3VeP3LVw,4143
|
|
9
|
+
agentx_python-0.4.1.dist-info/licenses/LICENSE,sha256=6ZbiPNFmv3xBb44LGhAa3PZYK0ROAztsd5LRFZDlGFE,1074
|
|
10
|
+
agentx_python-0.4.1.dist-info/METADATA,sha256=HVnzmSzzTX1VNHQqzxuxKfkMImttFVxz9Lta14hLtjY,4518
|
|
11
|
+
agentx_python-0.4.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
12
|
+
agentx_python-0.4.1.dist-info/top_level.txt,sha256=s-q-HB9Gb_QdrZNacSeQyF_c25gQooMy7DlxzgLOHPk,7
|
|
13
|
+
agentx_python-0.4.1.dist-info/RECORD,,
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
agentx/__init__.py,sha256=AiY83tsCtjSMIBVsvNuxOgSU4i-rCREQrqDrNmCoSd0,279
|
|
2
|
-
agentx/agentx.py,sha256=kmpAgnvtLdA3ytn0TJuDmchOQZydjuD4NSP77K3tsYM,1859
|
|
3
|
-
agentx/util.py,sha256=grYAa8YTvoQSyuy4GvUOwq6SVBRr4DdrBlcTuZwQpzw,132
|
|
4
|
-
agentx/version.py,sha256=OgfvlOui_Z4FwAja2bTJgiUkMeuAXZ561wYewaEr6SQ,18
|
|
5
|
-
agentx/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
agentx/resources/agent.py,sha256=SMu4H1UDL31Bub4hnaySoySeckgAchRSaAaHDpXa1L8,1521
|
|
7
|
-
agentx/resources/conversation.py,sha256=Xwy3IfFF6C7U7Xu6BNC32IOPqmaKNwCBTbN2w4FpI8w,4485
|
|
8
|
-
agentx_python-0.3.3.dist-info/LICENSE,sha256=6ZbiPNFmv3xBb44LGhAa3PZYK0ROAztsd5LRFZDlGFE,1074
|
|
9
|
-
agentx_python-0.3.3.dist-info/METADATA,sha256=HErykm3XrfFIvbeXV_WBgCbIOpU0Dz3yW4YJp5EZu2Q,3008
|
|
10
|
-
agentx_python-0.3.3.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
11
|
-
agentx_python-0.3.3.dist-info/top_level.txt,sha256=s-q-HB9Gb_QdrZNacSeQyF_c25gQooMy7DlxzgLOHPk,7
|
|
12
|
-
agentx_python-0.3.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|