agentx-python 0.2.1__py3-none-any.whl → 0.3.2__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_python → agentx}/__init__.py +2 -2
- {agentx_python → agentx}/agentx.py +2 -2
- {agentx_python → agentx}/resources/agent.py +1 -1
- agentx/resources/conversation.py +128 -0
- agentx/version.py +1 -0
- agentx_python-0.3.2.dist-info/METADATA +112 -0
- agentx_python-0.3.2.dist-info/RECORD +12 -0
- {agentx_python-0.2.1.dist-info → agentx_python-0.3.2.dist-info}/WHEEL +1 -1
- agentx_python-0.3.2.dist-info/top_level.txt +1 -0
- agentx_python/resources/conversation.py +0 -63
- agentx_python/version.py +0 -1
- agentx_python-0.2.1.dist-info/METADATA +0 -71
- agentx_python-0.2.1.dist-info/RECORD +0 -12
- agentx_python-0.2.1.dist-info/top_level.txt +0 -1
- {agentx_python → agentx}/resources/__init__.py +0 -0
- {agentx_python → agentx}/util.py +0 -0
- {agentx_python-0.2.1.dist-info → agentx_python-0.3.2.dist-info}/LICENSE +0 -0
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import requests
|
|
3
|
+
from typing import Optional, List, Any, Iterator
|
|
4
|
+
from pydantic import BaseModel, Field
|
|
5
|
+
from agentx.util import get_headers
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class ChatResponse(BaseModel):
|
|
9
|
+
text: str | None
|
|
10
|
+
cot: str | None
|
|
11
|
+
botId: str
|
|
12
|
+
reference: Optional[Any]
|
|
13
|
+
tasks: Optional[Any]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class Message(BaseModel):
|
|
17
|
+
id: str = Field(alias="_id")
|
|
18
|
+
conversationId: str
|
|
19
|
+
role: str # user or bot
|
|
20
|
+
botId: Optional[str] = Field(alias="bot", default=None)
|
|
21
|
+
userId: Optional[str] = Field(alias="user", default=None)
|
|
22
|
+
text: str | None
|
|
23
|
+
cot: str | None
|
|
24
|
+
createdAt: str
|
|
25
|
+
updatedAt: str
|
|
26
|
+
|
|
27
|
+
class Config:
|
|
28
|
+
populate_by_name = True
|
|
29
|
+
extra = "ignore"
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class Conversation(BaseModel):
|
|
33
|
+
agent_id: str
|
|
34
|
+
id: str = Field(alias="_id")
|
|
35
|
+
title: Optional[str] = Field(default=None) # conversation customized title
|
|
36
|
+
users: List[str]
|
|
37
|
+
agents: List[str] = Field(alias="bots")
|
|
38
|
+
createdAt: Optional[str]
|
|
39
|
+
updatedAt: Optional[str]
|
|
40
|
+
|
|
41
|
+
class Config:
|
|
42
|
+
populate_by_name = True
|
|
43
|
+
extra = "ignore"
|
|
44
|
+
|
|
45
|
+
def __init__(self, **data):
|
|
46
|
+
super().__init__(**data)
|
|
47
|
+
|
|
48
|
+
def new_conversation(self) -> "Conversation":
|
|
49
|
+
url = f"https://api.agentx.so/api/v1/access/agents/{self.agent_id}/conversations/new"
|
|
50
|
+
response = requests.post(
|
|
51
|
+
url,
|
|
52
|
+
headers=get_headers(),
|
|
53
|
+
json={"type": "chat"},
|
|
54
|
+
)
|
|
55
|
+
if response.status_code == 200:
|
|
56
|
+
new_conv = response.json()
|
|
57
|
+
new_conv["agent_id"] = self.agent_id
|
|
58
|
+
return Conversation(**new_conv)
|
|
59
|
+
else:
|
|
60
|
+
raise Exception(
|
|
61
|
+
f"Failed to create new conversation: {response.status_code} - {response.reason}"
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
def list_messages(self) -> List[Message]:
|
|
65
|
+
url = f"https://api.agentx.so/api/v1/access/agents/{self.agent_id}/conversations/{self.id}"
|
|
66
|
+
response = requests.get(url, headers=get_headers())
|
|
67
|
+
if response.status_code == 200:
|
|
68
|
+
res = response.json()
|
|
69
|
+
if res.get("messages"):
|
|
70
|
+
message_list = []
|
|
71
|
+
for message in res["messages"]:
|
|
72
|
+
if message.get("bot"):
|
|
73
|
+
message["role"] = "bot"
|
|
74
|
+
else:
|
|
75
|
+
message["role"] = "user"
|
|
76
|
+
message_list.append(Message(**message))
|
|
77
|
+
return message_list
|
|
78
|
+
else:
|
|
79
|
+
raise Exception("No messages found in the conversation.")
|
|
80
|
+
else:
|
|
81
|
+
raise Exception(
|
|
82
|
+
f"Failed to retrieve agent details: {response.status_code} - {response.reason}"
|
|
83
|
+
)
|
|
84
|
+
|
|
85
|
+
def chat(self, message: str, context: int = None):
|
|
86
|
+
url = f"https://api.agentx.so/api/v1/access/conversations/{self.id}/message"
|
|
87
|
+
response = requests.post(
|
|
88
|
+
url,
|
|
89
|
+
headers=get_headers(),
|
|
90
|
+
json={"message": message, "context": context},
|
|
91
|
+
)
|
|
92
|
+
return response.json()
|
|
93
|
+
|
|
94
|
+
def chat_stream(self, message: str, context: int = None) -> Iterator[ChatResponse]:
|
|
95
|
+
url = f"https://api.agentx.so/api/v1/access/conversations/{self.id}/jsonmessagesse"
|
|
96
|
+
response = requests.post(
|
|
97
|
+
url, headers=get_headers(), json={"message": message, "context": context}
|
|
98
|
+
)
|
|
99
|
+
result = ""
|
|
100
|
+
if response.status_code == 200:
|
|
101
|
+
buf = b""
|
|
102
|
+
for chunk in response.iter_content():
|
|
103
|
+
buf += chunk
|
|
104
|
+
try:
|
|
105
|
+
chunk = buf.decode("utf-8")
|
|
106
|
+
# yield chunk
|
|
107
|
+
except UnicodeDecodeError:
|
|
108
|
+
continue
|
|
109
|
+
result += chunk
|
|
110
|
+
buf = b""
|
|
111
|
+
try:
|
|
112
|
+
if result.count("{") == result.count("}"):
|
|
113
|
+
catch_json = json.loads(result)
|
|
114
|
+
if catch_json:
|
|
115
|
+
result = ""
|
|
116
|
+
yield ChatResponse(
|
|
117
|
+
text=catch_json.get("text"),
|
|
118
|
+
cot=catch_json.get("cot"),
|
|
119
|
+
botId=catch_json.get("botId"),
|
|
120
|
+
reference=catch_json.get("reference"),
|
|
121
|
+
tasks=catch_json.get("tasks"),
|
|
122
|
+
)
|
|
123
|
+
except json.JSONDecodeError:
|
|
124
|
+
continue
|
|
125
|
+
else:
|
|
126
|
+
raise Exception(
|
|
127
|
+
f"Failed to send message: {response.status_code} - {response.reason}"
|
|
128
|
+
)
|
agentx/version.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
VERSION = "0.3.0"
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
Metadata-Version: 2.2
|
|
2
|
+
Name: agentx-python
|
|
3
|
+
Version: 0.3.2
|
|
4
|
+
Summary: Offical Python SDK for AgentX (https://www.agentx.so/)
|
|
5
|
+
Home-page: https://github.com/AgentX-ai/AgentX-python-sdk
|
|
6
|
+
Author: Robin Wang and AgentX Team
|
|
7
|
+
Author-email: contact@agentx.so
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.6
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: urllib3>=1.26.11
|
|
15
|
+
Requires-Dist: certifi
|
|
16
|
+
Dynamic: author
|
|
17
|
+
Dynamic: author-email
|
|
18
|
+
Dynamic: classifier
|
|
19
|
+
Dynamic: description
|
|
20
|
+
Dynamic: description-content-type
|
|
21
|
+
Dynamic: home-page
|
|
22
|
+
Dynamic: requires-dist
|
|
23
|
+
Dynamic: requires-python
|
|
24
|
+
Dynamic: summary
|
|
25
|
+
|
|
26
|
+

|
|
27
|
+
|
|
28
|
+
[](https://pypi.org/project/agentx-python/)
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## Fast way to build AI Agents and create agent workforce
|
|
33
|
+
|
|
34
|
+
The official AgentX Python SDK for [AgentX](https://www.agentx.so/)
|
|
35
|
+
|
|
36
|
+
Why build AI agent with AgentX?
|
|
37
|
+
|
|
38
|
+
- Simplicity, Agent - Conversation - Message structure.
|
|
39
|
+
- Include chain-of-thoughts.
|
|
40
|
+
- Choose from most open and closed sourced LLM vendors.
|
|
41
|
+
- Built-in Voice(ASR, TTS), Image Gen, Document, CSV/excel tool, OCR, etc.
|
|
42
|
+
- Support all running MCP (model context protocol).
|
|
43
|
+
- Support RAG with built-in re-rank.
|
|
44
|
+
- Multi-agent workforce orchestration.
|
|
45
|
+
|
|
46
|
+
## Installation
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install --upgrade agentx-python
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Usage
|
|
53
|
+
|
|
54
|
+
Provide an `api_key` inline or set `AGENTX_API_KEY` as an environment variable.
|
|
55
|
+
You can get an API key from https://app.agentx.so
|
|
56
|
+
|
|
57
|
+
### Agent
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from agentx import AgentX
|
|
61
|
+
|
|
62
|
+
client = AgentX(api_key="<your api key here>")
|
|
63
|
+
|
|
64
|
+
# Get the list of agents you have
|
|
65
|
+
print(client.list_agents())
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
### Conversation
|
|
69
|
+
|
|
70
|
+
Each Conversation has `agents` and `users` tied to it.
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
# get agent
|
|
74
|
+
my_agent = client.get_agent(id="<agent id here>")
|
|
75
|
+
|
|
76
|
+
# Get the list of conversation from this agent
|
|
77
|
+
existing_conversations = my_agent.list_conversations()
|
|
78
|
+
print(existing_conversations)
|
|
79
|
+
|
|
80
|
+
# Get the list of history messages from a conversation
|
|
81
|
+
last_conversation = existing_conversations[-1]
|
|
82
|
+
msgs = last_conversation.list_messages()
|
|
83
|
+
print(msgs)
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
### Chat
|
|
87
|
+
|
|
88
|
+
A `chat` needs to happen in the conversation. You can do `stream` response too, default `False`.
|
|
89
|
+
|
|
90
|
+
```python
|
|
91
|
+
a_conversation = my_agent.get_conversation(id="<conversation id here>")
|
|
92
|
+
|
|
93
|
+
response = a_conversation.chat_stream("Hello, what is your name?")
|
|
94
|
+
for chunk in response:
|
|
95
|
+
print(chunk)
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
output looks like:
|
|
99
|
+
|
|
100
|
+
```
|
|
101
|
+
text=None cot='The user is greeting and asking for my ' botId='xxx'
|
|
102
|
+
text=None cot='name, which are casual, straightforward questions.' botId='xxx'
|
|
103
|
+
text=None cot=' I can answer these directly' botId='xxx'
|
|
104
|
+
text='Hello' cot=None botId='xxx'
|
|
105
|
+
text='!' cot=None botId='xxx'
|
|
106
|
+
text=' I' cot=None botId='xxx'
|
|
107
|
+
text=' am' cot=None botId='xxx'
|
|
108
|
+
text=' AgentX' cot=None botId='xxx'
|
|
109
|
+
text=None cot=None botId='xxx'
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
\*`cot` stands for chain-of-thoughts
|
|
@@ -0,0 +1,12 @@
|
|
|
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.2.dist-info/LICENSE,sha256=6ZbiPNFmv3xBb44LGhAa3PZYK0ROAztsd5LRFZDlGFE,1074
|
|
9
|
+
agentx_python-0.3.2.dist-info/METADATA,sha256=47m1FfWDCtAvT8frfeKYapKOBc-OHX_GSQxjhdMjDto,2956
|
|
10
|
+
agentx_python-0.3.2.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
|
|
11
|
+
agentx_python-0.3.2.dist-info/top_level.txt,sha256=s-q-HB9Gb_QdrZNacSeQyF_c25gQooMy7DlxzgLOHPk,7
|
|
12
|
+
agentx_python-0.3.2.dist-info/RECORD,,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
agentx
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
from typing import Optional, List
|
|
2
|
-
from pydantic import BaseModel, Field
|
|
3
|
-
import os
|
|
4
|
-
import requests
|
|
5
|
-
from agentx_python.util import get_headers
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
class Conversation(BaseModel):
|
|
9
|
-
agent_id: str
|
|
10
|
-
id: str
|
|
11
|
-
title: Optional[str] = Field(default=None) # conversation customized title
|
|
12
|
-
users: List[str]
|
|
13
|
-
agents: List[str]
|
|
14
|
-
createdAt: Optional[str]
|
|
15
|
-
updatedAt: Optional[str]
|
|
16
|
-
|
|
17
|
-
def __init__(self, **data):
|
|
18
|
-
super().__init__(**data)
|
|
19
|
-
|
|
20
|
-
def generate_conversation_id(self):
|
|
21
|
-
return "generate new_conversation_id"
|
|
22
|
-
|
|
23
|
-
def list_messages(self):
|
|
24
|
-
url = f"https://api.agentx.so/api/v1/access/agents/{self.agent_id}/conversations/{self.id}"
|
|
25
|
-
response = requests.get(url, headers=get_headers())
|
|
26
|
-
if response.status_code == 200:
|
|
27
|
-
return response.json()
|
|
28
|
-
else:
|
|
29
|
-
raise Exception(
|
|
30
|
-
f"Failed to retrieve agent details: {response.status_code} - {response.reason}"
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
def chat(self, message: str, stream: bool = False, context: int = None):
|
|
34
|
-
if stream:
|
|
35
|
-
return self._chat_stream(message, context)
|
|
36
|
-
else:
|
|
37
|
-
url = f"https://api.agentx.so/api/v1/access/conversations/{self.id}/message"
|
|
38
|
-
response = requests.post(
|
|
39
|
-
url,
|
|
40
|
-
headers=get_headers(),
|
|
41
|
-
json={"message": message, "context": context},
|
|
42
|
-
)
|
|
43
|
-
return response.json()
|
|
44
|
-
|
|
45
|
-
def _chat_stream(self, message: str, context: int = None):
|
|
46
|
-
url = f"https://api.agentx.so/api/v1/access/conversations/{self.id}/messagesse"
|
|
47
|
-
response = requests.post(
|
|
48
|
-
url, headers=get_headers(), json={"message": message, "context": context}
|
|
49
|
-
)
|
|
50
|
-
if response.status_code == 200:
|
|
51
|
-
buf = b""
|
|
52
|
-
for chunk in response.iter_content():
|
|
53
|
-
buf += chunk
|
|
54
|
-
try:
|
|
55
|
-
chunk = buf.decode("utf-8")
|
|
56
|
-
yield chunk
|
|
57
|
-
except UnicodeDecodeError:
|
|
58
|
-
continue
|
|
59
|
-
buf = b""
|
|
60
|
-
else:
|
|
61
|
-
raise Exception(
|
|
62
|
-
f"Failed to send message: {response.status_code} - {response.reason}"
|
|
63
|
-
)
|
agentx_python/version.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
VERSION = "0.1.0"
|
|
@@ -1,71 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.1
|
|
2
|
-
Name: agentx-python
|
|
3
|
-
Version: 0.2.1
|
|
4
|
-
Summary: Offical Python SDK for AgentX (https://www.agentx.so/)
|
|
5
|
-
Home-page: https://github.com/AgentX-ai/AgentX-python-sdk
|
|
6
|
-
Author: Robin Wang and AgentX Team
|
|
7
|
-
Author-email: contact@agentx.so
|
|
8
|
-
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
-
Classifier: Operating System :: OS Independent
|
|
11
|
-
Requires-Python: >=3.6
|
|
12
|
-
Description-Content-Type: text/markdown
|
|
13
|
-
License-File: LICENSE
|
|
14
|
-
Requires-Dist: urllib3 >=1.26.11
|
|
15
|
-
Requires-Dist: certifi
|
|
16
|
-
|
|
17
|
-
# AgentX Python SDK API library
|
|
18
|
-
|
|
19
|
-
[](https://pypi.org/project/agentx-python/)
|
|
20
|
-
|
|
21
|
-
The AgentX Python SDK provides a convenient way to access to your Agent programmatically.
|
|
22
|
-
This is a python SDK for AgentX (https://www.agentx.so/)
|
|
23
|
-
|
|
24
|
-
## Installation
|
|
25
|
-
|
|
26
|
-
```bash
|
|
27
|
-
pip install --upgrade agentx-python
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Usage
|
|
31
|
-
|
|
32
|
-
Provide an `api_key` inline or set `AGENTX_API_KEY` as an environment variable.
|
|
33
|
-
You can get an API key from https://app.agentx.so
|
|
34
|
-
|
|
35
|
-
### Agent
|
|
36
|
-
|
|
37
|
-
```
|
|
38
|
-
from agentx_python import AgentX
|
|
39
|
-
|
|
40
|
-
client = AgentX(api_key="<your api key here>")
|
|
41
|
-
|
|
42
|
-
# Get the list of agents you have
|
|
43
|
-
print(client.list_agents())
|
|
44
|
-
```
|
|
45
|
-
|
|
46
|
-
### Conversation
|
|
47
|
-
|
|
48
|
-
Each Conversation has `agents` and `users` tied to it.
|
|
49
|
-
|
|
50
|
-
```
|
|
51
|
-
# get agent
|
|
52
|
-
my_agent = client.get_agent(id="<agent id here>")
|
|
53
|
-
|
|
54
|
-
# Get the list of conversation from this agent
|
|
55
|
-
print(my_agent.list_conversations())
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
### Chat
|
|
59
|
-
|
|
60
|
-
A `chat` needs to happen in the conversation. You can do `stream` response too, default `False`.
|
|
61
|
-
|
|
62
|
-
```
|
|
63
|
-
a_conversation = my_agent.get_conversation(id="<conversation id here>")
|
|
64
|
-
|
|
65
|
-
response = a_conversation.chat("Hello, what is your name?", stream=True)
|
|
66
|
-
for chunk in response:
|
|
67
|
-
print(chunk, end="")
|
|
68
|
-
|
|
69
|
-
# output:
|
|
70
|
-
# My name is Rosita. I'm an AI assistant created by AgentX. It's nice to meet you! How can I help you today?
|
|
71
|
-
```
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
agentx_python/__init__.py,sha256=5VThp1fX_kBYM2afhhiTQZxcbg_kBeDiPExAH88ZPT4,293
|
|
2
|
-
agentx_python/agentx.py,sha256=D4R8cAam0LF8_PuHmAN7FXaRmrMTKsdzPdSs0HJkf6I,1873
|
|
3
|
-
agentx_python/util.py,sha256=grYAa8YTvoQSyuy4GvUOwq6SVBRr4DdrBlcTuZwQpzw,132
|
|
4
|
-
agentx_python/version.py,sha256=CpXi3jGlx23RvRyU7iytOMZrnspdWw4yofS8lpP1AJU,18
|
|
5
|
-
agentx_python/resources/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
6
|
-
agentx_python/resources/agent.py,sha256=wpsiiYp3ZjYaonq9wL2KDrUuCnFHvrxS9xfQgaKlLrk,1528
|
|
7
|
-
agentx_python/resources/conversation.py,sha256=zpGOpSJsRTtHbeK_pizOtuGsYxpvLOUCkb-zThB0-cs,2186
|
|
8
|
-
agentx_python-0.2.1.dist-info/LICENSE,sha256=6ZbiPNFmv3xBb44LGhAa3PZYK0ROAztsd5LRFZDlGFE,1074
|
|
9
|
-
agentx_python-0.2.1.dist-info/METADATA,sha256=oJwDiWb1rt6LXftOI5fLuswBUANA9irYFFkL7jWMP1U,1851
|
|
10
|
-
agentx_python-0.2.1.dist-info/WHEEL,sha256=GJ7t_kWBFywbagK5eo9IoUwLW6oyOeTKmQ-9iHFVNxQ,92
|
|
11
|
-
agentx_python-0.2.1.dist-info/top_level.txt,sha256=YYLKtZsKSxhcVZ9ijHXupbsRJ7lhEjETXLwAB7lG2Y8,14
|
|
12
|
-
agentx_python-0.2.1.dist-info/RECORD,,
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
agentx_python
|
|
File without changes
|
{agentx_python → agentx}/util.py
RENAMED
|
File without changes
|
|
File without changes
|