cheshirecat-python-sdk 1.7.9__py3-none-any.whl → 1.8.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.
- cheshirecat_python_sdk/builders/__init__.py +1 -1
- cheshirecat_python_sdk/builders/memory.py +1 -20
- cheshirecat_python_sdk/builders/why.py +8 -8
- cheshirecat_python_sdk/client.py +5 -0
- cheshirecat_python_sdk/endpoints/__init__.py +1 -0
- cheshirecat_python_sdk/endpoints/admins.py +10 -89
- cheshirecat_python_sdk/endpoints/agentic_workflow.py +52 -0
- cheshirecat_python_sdk/endpoints/base.py +6 -3
- cheshirecat_python_sdk/endpoints/file_manager.py +12 -6
- cheshirecat_python_sdk/endpoints/memory.py +31 -1
- cheshirecat_python_sdk/endpoints/rabbit_hole.py +3 -1
- cheshirecat_python_sdk/endpoints/users.py +14 -1
- cheshirecat_python_sdk/models/api/admins.py +1 -7
- cheshirecat_python_sdk/models/api/users.py +2 -1
- cheshirecat_python_sdk/models/dtos.py +12 -6
- {cheshirecat_python_sdk-1.7.9.dist-info → cheshirecat_python_sdk-1.8.4.dist-info}/METADATA +1 -1
- {cheshirecat_python_sdk-1.7.9.dist-info → cheshirecat_python_sdk-1.8.4.dist-info}/RECORD +19 -18
- {cheshirecat_python_sdk-1.7.9.dist-info → cheshirecat_python_sdk-1.8.4.dist-info}/WHEEL +0 -0
- {cheshirecat_python_sdk-1.7.9.dist-info → cheshirecat_python_sdk-1.8.4.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
from cheshirecat_python_sdk.builders.memory import
|
|
1
|
+
from cheshirecat_python_sdk.builders.memory import MemoryPointBuilder
|
|
2
2
|
from cheshirecat_python_sdk.builders.settings_input import SettingInputBuilder
|
|
3
3
|
from cheshirecat_python_sdk.builders.why import WhyBuilder
|
|
@@ -1,26 +1,7 @@
|
|
|
1
1
|
from typing import Dict, Any
|
|
2
2
|
|
|
3
3
|
from cheshirecat_python_sdk.builders.base import BaseBuilder
|
|
4
|
-
from cheshirecat_python_sdk.models.dtos import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class MemoryBuilder(BaseBuilder):
|
|
8
|
-
def __init__(self):
|
|
9
|
-
self.declarative: Dict[str, Any] | None = None
|
|
10
|
-
|
|
11
|
-
@staticmethod
|
|
12
|
-
def create():
|
|
13
|
-
return MemoryBuilder()
|
|
14
|
-
|
|
15
|
-
def set_declarative(self, declarative: Dict[str, Any] | None = None):
|
|
16
|
-
self.declarative = declarative or {}
|
|
17
|
-
return self
|
|
18
|
-
|
|
19
|
-
def build(self):
|
|
20
|
-
memory = Memory()
|
|
21
|
-
memory.declarative = self.declarative
|
|
22
|
-
|
|
23
|
-
return memory
|
|
4
|
+
from cheshirecat_python_sdk.models.dtos import MemoryPoint
|
|
24
5
|
|
|
25
6
|
|
|
26
7
|
class MemoryPointBuilder(BaseBuilder):
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
from typing import
|
|
1
|
+
from typing import List
|
|
2
2
|
|
|
3
3
|
from cheshirecat_python_sdk.builders.base import BaseBuilder
|
|
4
|
-
from cheshirecat_python_sdk.models.dtos import
|
|
4
|
+
from cheshirecat_python_sdk.models.dtos import Why
|
|
5
5
|
|
|
6
6
|
|
|
7
7
|
class WhyBuilder(BaseBuilder):
|
|
8
8
|
def __init__(self):
|
|
9
9
|
self.input: str | None = None
|
|
10
|
-
self.intermediate_steps:
|
|
11
|
-
self.memory:
|
|
10
|
+
self.intermediate_steps: List | None = []
|
|
11
|
+
self.memory: List | None = []
|
|
12
12
|
|
|
13
13
|
@staticmethod
|
|
14
14
|
def create() -> "WhyBuilder":
|
|
@@ -18,12 +18,12 @@ class WhyBuilder(BaseBuilder):
|
|
|
18
18
|
self.input = input
|
|
19
19
|
return self
|
|
20
20
|
|
|
21
|
-
def set_intermediate_steps(self, intermediate_steps:
|
|
22
|
-
self.intermediate_steps = intermediate_steps
|
|
21
|
+
def set_intermediate_steps(self, intermediate_steps: List | None = None) -> "WhyBuilder":
|
|
22
|
+
self.intermediate_steps = intermediate_steps or []
|
|
23
23
|
return self
|
|
24
24
|
|
|
25
|
-
def set_memory(self, memory:
|
|
26
|
-
self.memory = memory
|
|
25
|
+
def set_memory(self, memory: List | None = None) -> "WhyBuilder":
|
|
26
|
+
self.memory = memory or []
|
|
27
27
|
return self
|
|
28
28
|
|
|
29
29
|
def build(self) -> Why:
|
cheshirecat_python_sdk/client.py
CHANGED
|
@@ -18,6 +18,7 @@ from cheshirecat_python_sdk.endpoints import (
|
|
|
18
18
|
UtilsEndpoint,
|
|
19
19
|
VectorDatabaseEndpoint,
|
|
20
20
|
HealthCheckEndpoint,
|
|
21
|
+
AgenticWorkflowEndpoint,
|
|
21
22
|
)
|
|
22
23
|
|
|
23
24
|
|
|
@@ -64,6 +65,10 @@ class CheshireCatClient:
|
|
|
64
65
|
def auth_handler(self):
|
|
65
66
|
return AuthHandlerEndpoint(self)
|
|
66
67
|
|
|
68
|
+
@property
|
|
69
|
+
def agentic_workflow(self):
|
|
70
|
+
return AgenticWorkflowEndpoint(self)
|
|
71
|
+
|
|
67
72
|
@property
|
|
68
73
|
def chunker(self):
|
|
69
74
|
return ChunkerEndpoint(self)
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
from cheshirecat_python_sdk.endpoints.admins import AdminsEndpoint
|
|
2
|
+
from cheshirecat_python_sdk.endpoints.agentic_workflow import AgenticWorkflowEndpoint
|
|
2
3
|
from cheshirecat_python_sdk.endpoints.auth import AuthEndpoint
|
|
3
4
|
from cheshirecat_python_sdk.endpoints.auth_handler import AuthHandlerEndpoint
|
|
4
5
|
from cheshirecat_python_sdk.endpoints.chunker import ChunkerEndpoint
|
|
@@ -1,8 +1,5 @@
|
|
|
1
|
-
from typing import List
|
|
2
|
-
|
|
3
1
|
from cheshirecat_python_sdk.endpoints.base import AbstractEndpoint, MultipartPayload
|
|
4
2
|
from cheshirecat_python_sdk.models.api.admins import (
|
|
5
|
-
AdminOutput,
|
|
6
3
|
PluginInstallOutput,
|
|
7
4
|
PluginInstallFromRegistryOutput,
|
|
8
5
|
PluginDetailsOutput,
|
|
@@ -10,89 +7,13 @@ from cheshirecat_python_sdk.models.api.admins import (
|
|
|
10
7
|
)
|
|
11
8
|
from cheshirecat_python_sdk.models.api.nested.plugins import PluginSettingsOutput
|
|
12
9
|
from cheshirecat_python_sdk.models.api.plugins import PluginCollectionOutput, PluginsSettingsOutput, PluginToggleOutput
|
|
13
|
-
from cheshirecat_python_sdk.utils import
|
|
10
|
+
from cheshirecat_python_sdk.utils import file_attributes
|
|
14
11
|
|
|
15
12
|
|
|
16
13
|
class AdminsEndpoint(AbstractEndpoint):
|
|
17
14
|
def __init__(self, client: "CheshireCatClient"):
|
|
18
15
|
super().__init__(client)
|
|
19
|
-
self.prefix = "/
|
|
20
|
-
|
|
21
|
-
def post_admin(self, username: str, password: str, permissions: dict | None = None) -> AdminOutput:
|
|
22
|
-
"""
|
|
23
|
-
Create a new admin user.
|
|
24
|
-
:param username: The username of the user.
|
|
25
|
-
:param password: The password of the user.
|
|
26
|
-
:param permissions: The permissions of the user.
|
|
27
|
-
:return: AdminOutput, the details of the user.
|
|
28
|
-
"""
|
|
29
|
-
payload = {"username": username, "password": password}
|
|
30
|
-
if permissions:
|
|
31
|
-
payload["permissions"] = permissions # type: ignore
|
|
32
|
-
|
|
33
|
-
return self.post_json(self.format_url("/users"), self.system_id, output_class=AdminOutput, payload=payload)
|
|
34
|
-
|
|
35
|
-
def get_admins(self, limit: int | None = None, skip: int | None = None) -> List[AdminOutput]:
|
|
36
|
-
"""
|
|
37
|
-
Get a list of all admin users.
|
|
38
|
-
:param limit: The maximum number of users to return.
|
|
39
|
-
:param skip: The number of users to skip.
|
|
40
|
-
:return: List[AdminOutput], the details
|
|
41
|
-
"""
|
|
42
|
-
query = {}
|
|
43
|
-
if limit:
|
|
44
|
-
query["limit"] = limit
|
|
45
|
-
if skip:
|
|
46
|
-
query["skip"] = skip
|
|
47
|
-
|
|
48
|
-
response = self.get_http_client(self.system_id).get(self.format_url("/users"), params=query)
|
|
49
|
-
response.raise_for_status()
|
|
50
|
-
|
|
51
|
-
result = []
|
|
52
|
-
for item in response.json():
|
|
53
|
-
result.append(deserialize(item, AdminOutput))
|
|
54
|
-
return result
|
|
55
|
-
|
|
56
|
-
def get_admin(self, admin_id: str) -> AdminOutput:
|
|
57
|
-
"""
|
|
58
|
-
Get the details of an admin user.
|
|
59
|
-
:param admin_id: The ID of the user.
|
|
60
|
-
:return: AdminOutput, the details of the user.
|
|
61
|
-
"""
|
|
62
|
-
return self.get(self.format_url(f"/users/{admin_id}"), self.system_id, output_class=AdminOutput)
|
|
63
|
-
|
|
64
|
-
def put_admin(
|
|
65
|
-
self,
|
|
66
|
-
admin_id: str,
|
|
67
|
-
username: str | None = None,
|
|
68
|
-
password: str | None = None,
|
|
69
|
-
permissions: dict | None = None,
|
|
70
|
-
) -> AdminOutput:
|
|
71
|
-
"""
|
|
72
|
-
Update the details of an admin user.
|
|
73
|
-
:param admin_id: The ID of the user.
|
|
74
|
-
:param username: The new username.
|
|
75
|
-
:param password: The new password.
|
|
76
|
-
:param permissions: The new permissions.
|
|
77
|
-
:return: AdminOutput, the details of the user.
|
|
78
|
-
"""
|
|
79
|
-
payload = {}
|
|
80
|
-
if username:
|
|
81
|
-
payload["username"] = username
|
|
82
|
-
if password:
|
|
83
|
-
payload["password"] = password
|
|
84
|
-
if permissions:
|
|
85
|
-
payload["permissions"] = permissions
|
|
86
|
-
|
|
87
|
-
return self.put(self.format_url(f"/users/{admin_id}"), self.system_id, output_class=AdminOutput, payload=payload)
|
|
88
|
-
|
|
89
|
-
def delete_admin(self, admin_id: str) -> AdminOutput:
|
|
90
|
-
"""
|
|
91
|
-
Delete an admin user.
|
|
92
|
-
:param admin_id: The ID of the user.
|
|
93
|
-
:return: AdminOutput, the details of the user.
|
|
94
|
-
"""
|
|
95
|
-
return self.delete(self.format_url(f"/users/{admin_id}"), self.system_id, output_class=AdminOutput)
|
|
16
|
+
self.prefix = "/plugins"
|
|
96
17
|
|
|
97
18
|
def get_available_plugins(self, plugin_name: str | None = None) -> PluginCollectionOutput:
|
|
98
19
|
"""
|
|
@@ -101,7 +22,7 @@ class AdminsEndpoint(AbstractEndpoint):
|
|
|
101
22
|
:return: PluginCollectionOutput, the details of the plugins.
|
|
102
23
|
"""
|
|
103
24
|
return self.get(
|
|
104
|
-
self.format_url("/
|
|
25
|
+
self.format_url("/installed"),
|
|
105
26
|
self.system_id,
|
|
106
27
|
output_class=PluginCollectionOutput,
|
|
107
28
|
query={"query": plugin_name} if plugin_name else None,
|
|
@@ -113,7 +34,7 @@ class AdminsEndpoint(AbstractEndpoint):
|
|
|
113
34
|
with open(path_zip, "rb") as file:
|
|
114
35
|
payload.files = [("file", file_attributes(path_zip, file))]
|
|
115
36
|
result = self.post_multipart(
|
|
116
|
-
self.format_url("/
|
|
37
|
+
self.format_url("/install/upload"),
|
|
117
38
|
self.system_id,
|
|
118
39
|
output_class=PluginInstallOutput,
|
|
119
40
|
payload=payload,
|
|
@@ -127,7 +48,7 @@ class AdminsEndpoint(AbstractEndpoint):
|
|
|
127
48
|
:return: PluginInstallFromRegistryOutput, the details of the installation.
|
|
128
49
|
"""
|
|
129
50
|
return self.post_json(
|
|
130
|
-
self.format_url("/
|
|
51
|
+
self.format_url("/install/registry"),
|
|
131
52
|
self.system_id,
|
|
132
53
|
output_class=PluginInstallFromRegistryOutput,
|
|
133
54
|
payload={"url": url},
|
|
@@ -138,7 +59,7 @@ class AdminsEndpoint(AbstractEndpoint):
|
|
|
138
59
|
Get the default settings of all the plugins.
|
|
139
60
|
:return: PluginsSettingsOutput, the details of the settings.
|
|
140
61
|
"""
|
|
141
|
-
return self.get(self.format_url("/
|
|
62
|
+
return self.get(self.format_url("/system/settings"), self.system_id, output_class=PluginsSettingsOutput)
|
|
142
63
|
|
|
143
64
|
def get_plugin_settings(self, plugin_id: str) -> PluginSettingsOutput:
|
|
144
65
|
"""
|
|
@@ -147,7 +68,7 @@ class AdminsEndpoint(AbstractEndpoint):
|
|
|
147
68
|
:return: PluginSettingsOutput, the details of the settings.
|
|
148
69
|
"""
|
|
149
70
|
return self.get(
|
|
150
|
-
self.format_url(f"/
|
|
71
|
+
self.format_url(f"/system/settings/{plugin_id}"), self.system_id, output_class=PluginSettingsOutput
|
|
151
72
|
)
|
|
152
73
|
|
|
153
74
|
def get_plugin_details(self, plugin_id: str) -> PluginDetailsOutput:
|
|
@@ -156,7 +77,7 @@ class AdminsEndpoint(AbstractEndpoint):
|
|
|
156
77
|
:param plugin_id: The ID of the plugin.
|
|
157
78
|
:return: PluginDetailsOutput, the details of the plugin.
|
|
158
79
|
"""
|
|
159
|
-
return self.get(self.format_url(f"/
|
|
80
|
+
return self.get(self.format_url(f"/system/details/{plugin_id}"), self.system_id, output_class=PluginDetailsOutput)
|
|
160
81
|
|
|
161
82
|
def delete_plugin(self, plugin_id: str) -> PluginDeleteOutput:
|
|
162
83
|
"""
|
|
@@ -164,7 +85,7 @@ class AdminsEndpoint(AbstractEndpoint):
|
|
|
164
85
|
:param plugin_id: The ID of the plugin.
|
|
165
86
|
:return: PluginDeleteOutput, the details of the plugin.
|
|
166
87
|
"""
|
|
167
|
-
return self.delete(self.format_url(f"/
|
|
88
|
+
return self.delete(self.format_url(f"/uninstall/{plugin_id}"), self.system_id, output_class=PluginDeleteOutput)
|
|
168
89
|
|
|
169
90
|
def put_toggle_plugin(self, plugin_id: str) -> PluginToggleOutput:
|
|
170
91
|
"""
|
|
@@ -173,7 +94,7 @@ class AdminsEndpoint(AbstractEndpoint):
|
|
|
173
94
|
:return: PluginToggleOutput, the toggled plugin
|
|
174
95
|
"""
|
|
175
96
|
return self.put(
|
|
176
|
-
self.format_url(f"/
|
|
97
|
+
self.format_url(f"/system/toggle/{plugin_id}"),
|
|
177
98
|
self.system_id,
|
|
178
99
|
output_class=PluginToggleOutput,
|
|
179
100
|
)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
from typing import Dict, Any
|
|
2
|
+
|
|
3
|
+
from cheshirecat_python_sdk.endpoints.base import AbstractEndpoint
|
|
4
|
+
from cheshirecat_python_sdk.models.api.factories import FactoryObjectSettingsOutput, FactoryObjectSettingOutput
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class AgenticWorkflowEndpoint(AbstractEndpoint):
|
|
8
|
+
def __init__(self, client: "CheshireCatClient"):
|
|
9
|
+
super().__init__(client)
|
|
10
|
+
self.prefix = "/agentic_workflow"
|
|
11
|
+
|
|
12
|
+
def get_agentic_workflows_settings(self, agent_id: str) -> FactoryObjectSettingsOutput:
|
|
13
|
+
"""
|
|
14
|
+
Get all agentic workflow settings for the agent with the given ID.
|
|
15
|
+
:param agent_id: The ID of the agent.
|
|
16
|
+
:return: FactoryObjectSettingsOutput, containing the settings for all agentic workflows.
|
|
17
|
+
"""
|
|
18
|
+
return self.get(
|
|
19
|
+
self.format_url("/settings"),
|
|
20
|
+
agent_id,
|
|
21
|
+
output_class=FactoryObjectSettingsOutput,
|
|
22
|
+
)
|
|
23
|
+
|
|
24
|
+
def get_agentic_workflow_settings(self, agentic_workflow: str, agent_id: str) -> FactoryObjectSettingOutput:
|
|
25
|
+
"""
|
|
26
|
+
Get the settings for the agentic workflow with the given name.
|
|
27
|
+
:param agentic_workflow: The name of the agentic workflow.
|
|
28
|
+
:param agent_id: The ID of the agent.
|
|
29
|
+
:return: FactoryObjectSettingOutput, containing the settings for the agentic workflow.
|
|
30
|
+
"""
|
|
31
|
+
return self.get(
|
|
32
|
+
self.format_url(f"/settings/{agentic_workflow}"),
|
|
33
|
+
agent_id,
|
|
34
|
+
output_class=FactoryObjectSettingOutput,
|
|
35
|
+
)
|
|
36
|
+
|
|
37
|
+
def put_agentic_workflow_settings(
|
|
38
|
+
self, agentic_workflow: str, agent_id: str, values: Dict[str, Any]
|
|
39
|
+
) -> FactoryObjectSettingOutput:
|
|
40
|
+
"""
|
|
41
|
+
Update the settings for the agentic workflow with the given name.
|
|
42
|
+
:param agentic_workflow: The name of the agentic workflow.
|
|
43
|
+
:param agent_id: The ID of the agent.
|
|
44
|
+
:param values: The new settings for the agentic workflow.
|
|
45
|
+
:return: FactoryObjectSettingOutput, containing the updated settings for the agentic workflow.
|
|
46
|
+
"""
|
|
47
|
+
return self.put(
|
|
48
|
+
self.format_url(f"/settings/{agentic_workflow}"),
|
|
49
|
+
agent_id,
|
|
50
|
+
output_class=FactoryObjectSettingOutput,
|
|
51
|
+
payload=values,
|
|
52
|
+
)
|
|
@@ -43,12 +43,13 @@ class AbstractEndpoint(ABC):
|
|
|
43
43
|
output_class: Type[T] | None = None,
|
|
44
44
|
query: Dict[str, Any] | None = None,
|
|
45
45
|
user_id: str | None = None,
|
|
46
|
+
chat_id: str | None = None,
|
|
46
47
|
) -> T:
|
|
47
48
|
options = {}
|
|
48
49
|
if query:
|
|
49
50
|
options["params"] = query
|
|
50
51
|
|
|
51
|
-
response = self.get_http_client(agent_id, user_id).get(endpoint, **options)
|
|
52
|
+
response = self.get_http_client(agent_id, user_id, chat_id).get(endpoint, **options)
|
|
52
53
|
response.raise_for_status()
|
|
53
54
|
|
|
54
55
|
if output_class is None:
|
|
@@ -103,12 +104,13 @@ class AbstractEndpoint(ABC):
|
|
|
103
104
|
output_class: Type[T] | None = None,
|
|
104
105
|
payload: Dict[str, Any] | None = None,
|
|
105
106
|
user_id: str | None = None,
|
|
107
|
+
chat_id: str | None = None,
|
|
106
108
|
) -> T:
|
|
107
109
|
options = {}
|
|
108
110
|
if payload:
|
|
109
111
|
options["json"] = payload
|
|
110
112
|
|
|
111
|
-
response = self.get_http_client(agent_id, user_id).put(endpoint, **options)
|
|
113
|
+
response = self.get_http_client(agent_id, user_id, chat_id).put(endpoint, **options)
|
|
112
114
|
response.raise_for_status()
|
|
113
115
|
|
|
114
116
|
if output_class is None:
|
|
@@ -121,13 +123,14 @@ class AbstractEndpoint(ABC):
|
|
|
121
123
|
agent_id: str,
|
|
122
124
|
output_class: Type[T] | None = None,
|
|
123
125
|
user_id: str | None = None,
|
|
126
|
+
chat_id: str | None = None,
|
|
124
127
|
payload: Dict[str, Any] | None = None,
|
|
125
128
|
) -> T:
|
|
126
129
|
options = {}
|
|
127
130
|
if payload:
|
|
128
131
|
options["json"] = payload
|
|
129
132
|
|
|
130
|
-
response = self.get_http_client(agent_id, user_id).delete(endpoint, **options)
|
|
133
|
+
response = self.get_http_client(agent_id, user_id, chat_id).delete(endpoint, **options)
|
|
131
134
|
response.raise_for_status()
|
|
132
135
|
|
|
133
136
|
if output_class is None:
|
|
@@ -53,22 +53,24 @@ class FileManagerEndpoint(AbstractEndpoint):
|
|
|
53
53
|
payload=values,
|
|
54
54
|
)
|
|
55
55
|
|
|
56
|
-
def get_file_manager_attributes(self, agent_id: str) -> FileManagerAttributes:
|
|
56
|
+
def get_file_manager_attributes(self, agent_id: str, chat_id: str | None = None) -> FileManagerAttributes:
|
|
57
57
|
"""
|
|
58
58
|
Get the attributes of the file manager for the agent specified by agent_id
|
|
59
59
|
:param agent_id: The agent id
|
|
60
|
+
:param chat_id: The chat id, optional
|
|
60
61
|
:return: FileManagerAttributes, the attributes of the file manager
|
|
61
62
|
"""
|
|
62
|
-
return self.get(self.prefix, agent_id, output_class=FileManagerAttributes)
|
|
63
|
+
return self.get(self.prefix, agent_id, output_class=FileManagerAttributes, chat_id=chat_id)
|
|
63
64
|
|
|
64
|
-
def get_file(self, agent_id: str, file_name: str) -> Response:
|
|
65
|
+
def get_file(self, agent_id: str, file_name: str, chat_id: str | None = None) -> Response:
|
|
65
66
|
"""
|
|
66
67
|
Download a file from the file manager for the agent specified by agent_id
|
|
67
68
|
:param agent_id: The agent id
|
|
68
69
|
:param file_name: The name of the file to download
|
|
70
|
+
:param chat_id: The chat id, optional
|
|
69
71
|
:return: Response, the response containing the file content
|
|
70
72
|
"""
|
|
71
|
-
response = self.get_http_client(agent_id).get(
|
|
73
|
+
response = self.get_http_client(agent_id, chat_id=chat_id).get(
|
|
72
74
|
self.format_url(f"/files/{file_name}"),
|
|
73
75
|
stream=True,
|
|
74
76
|
headers={"Accept": "application/octet-stream"}
|
|
@@ -77,27 +79,31 @@ class FileManagerEndpoint(AbstractEndpoint):
|
|
|
77
79
|
|
|
78
80
|
return response
|
|
79
81
|
|
|
80
|
-
def delete_file(self, agent_id: str, file_name: str) -> FileManagerDeletedFiles:
|
|
82
|
+
def delete_file(self, agent_id: str, file_name: str, chat_id: str | None = None) -> FileManagerDeletedFiles:
|
|
81
83
|
"""
|
|
82
84
|
Download a file from the file manager for the agent specified by agent_id
|
|
83
85
|
:param agent_id: The agent id
|
|
84
86
|
:param file_name: The name of the file to delete
|
|
87
|
+
:param chat_id: The chat id, optional
|
|
85
88
|
:return: FileManagerDeletedFiles, the response containing info about the deleted file
|
|
86
89
|
"""
|
|
87
90
|
return self.delete(
|
|
88
91
|
self.format_url(f"/files/{file_name}"),
|
|
89
92
|
agent_id,
|
|
90
93
|
output_class=FileManagerDeletedFiles,
|
|
94
|
+
chat_id=chat_id,
|
|
91
95
|
)
|
|
92
96
|
|
|
93
|
-
def delete_files(self, agent_id: str) -> FileManagerDeletedFiles:
|
|
97
|
+
def delete_files(self, agent_id: str, chat_id: str | None = None) -> FileManagerDeletedFiles:
|
|
94
98
|
"""
|
|
95
99
|
Download a file from the file manager for the agent specified by agent_id
|
|
96
100
|
:param agent_id: The agent id
|
|
101
|
+
:param chat_id: The chat id, optional
|
|
97
102
|
:return: bool, True if all files were deleted successfully
|
|
98
103
|
"""
|
|
99
104
|
return self.delete(
|
|
100
105
|
self.format_url("/files"),
|
|
101
106
|
agent_id,
|
|
102
107
|
output_class=FileManagerDeletedFiles,
|
|
108
|
+
chat_id=chat_id,
|
|
103
109
|
)
|
|
@@ -12,7 +12,7 @@ from cheshirecat_python_sdk.models.api.memories import (
|
|
|
12
12
|
MemoryPointsOutput,
|
|
13
13
|
)
|
|
14
14
|
from cheshirecat_python_sdk.models.api.nested.memories import CollectionsItem
|
|
15
|
-
from cheshirecat_python_sdk.models.dtos import Why, MemoryPoint
|
|
15
|
+
from cheshirecat_python_sdk.models.dtos import Why, MemoryPoint, FilterSource
|
|
16
16
|
|
|
17
17
|
|
|
18
18
|
class MemoryEndpoint(AbstractEndpoint):
|
|
@@ -85,6 +85,7 @@ class MemoryEndpoint(AbstractEndpoint):
|
|
|
85
85
|
user_id: str,
|
|
86
86
|
k: int | None = None,
|
|
87
87
|
metadata: Dict[str, Any] | None = None,
|
|
88
|
+
chat_id: str | None = None,
|
|
88
89
|
) -> MemoryRecallOutput:
|
|
89
90
|
"""
|
|
90
91
|
This endpoint retrieves memory points based on the input text. The text parameter is the input text for which
|
|
@@ -94,6 +95,7 @@ class MemoryEndpoint(AbstractEndpoint):
|
|
|
94
95
|
:param user_id: The user ID to filter the memory points.
|
|
95
96
|
:param k: The number of memory points to retrieve.
|
|
96
97
|
:param metadata: The metadata to filter the memory points.
|
|
98
|
+
:param chat_id: The chat id, optional
|
|
97
99
|
:return: MemoryRecallOutput, a list of memory points retrieved.
|
|
98
100
|
"""
|
|
99
101
|
query = {"text": text}
|
|
@@ -108,6 +110,7 @@ class MemoryEndpoint(AbstractEndpoint):
|
|
|
108
110
|
output_class=MemoryRecallOutput,
|
|
109
111
|
user_id=user_id,
|
|
110
112
|
query=query,
|
|
113
|
+
chat_id=chat_id,
|
|
111
114
|
)
|
|
112
115
|
|
|
113
116
|
def post_memory_point(
|
|
@@ -239,4 +242,31 @@ class MemoryEndpoint(AbstractEndpoint):
|
|
|
239
242
|
query=query,
|
|
240
243
|
)
|
|
241
244
|
|
|
245
|
+
def has_source(self, agent_id: str, filter_source: FilterSource, chat_id: str | None = None) -> bool:
|
|
246
|
+
"""
|
|
247
|
+
Checks if the given filter source exists for a specified agent.
|
|
248
|
+
|
|
249
|
+
This method determines whether a specific source, defined by the given filter_source, is associated with the
|
|
250
|
+
provided agent in the memory database.
|
|
251
|
+
It optionally considers a specific chat ID when filtering the data. The result indicates the existence of such a
|
|
252
|
+
source.
|
|
253
|
+
|
|
254
|
+
Args:
|
|
255
|
+
agent_id: Unique identifier of the agent for which the check is performed.
|
|
256
|
+
filter_source: FilterSource object that defines the source or hash to check.
|
|
257
|
+
chat_id: An optional chat identifier to narrow the scope of the check. If not provided, the check will
|
|
258
|
+
operate in a broader context.
|
|
259
|
+
|
|
260
|
+
Returns:
|
|
261
|
+
A boolean value indicating whether the specified filter source exists in the agent's memory database.
|
|
262
|
+
"""
|
|
263
|
+
metadata = {"source": filter_source.source} if filter_source.source else {"hash": filter_source.hash}
|
|
264
|
+
if chat_id:
|
|
265
|
+
metadata["chat_id"] = chat_id
|
|
266
|
+
|
|
267
|
+
collection_name = "declarative" if chat_id is None else "episodic"
|
|
268
|
+
points = self.get_memory_points(collection_name, agent_id, metadata=metadata)
|
|
269
|
+
|
|
270
|
+
return len(points.points) > 0
|
|
271
|
+
|
|
242
272
|
# END Memory Points API
|
|
@@ -158,14 +158,16 @@ class RabbitHoleEndpoint(AbstractEndpoint):
|
|
|
158
158
|
output_class=AllowedMimeTypesOutput
|
|
159
159
|
)
|
|
160
160
|
|
|
161
|
-
def get_web_sources(self, agent_id: str) -> List[str]:
|
|
161
|
+
def get_web_sources(self, agent_id: str, chat_id: str | None = None) -> List[str]:
|
|
162
162
|
"""
|
|
163
163
|
This method retrieves the web sources for the RabbitHole API. The web sources are the web URLs that are allowed
|
|
164
164
|
to be uploaded to the RabbitHole API. The web sources are returned in a list.
|
|
165
165
|
:param agent_id: The ID of the agent.
|
|
166
|
+
:param chat_id: The chat id, optional
|
|
166
167
|
:return: List[str]
|
|
167
168
|
"""
|
|
168
169
|
return self.get(
|
|
169
170
|
self.format_url("/web"),
|
|
170
171
|
agent_id,
|
|
172
|
+
chat_id=chat_id,
|
|
171
173
|
)
|
|
@@ -11,7 +11,12 @@ class UsersEndpoint(AbstractEndpoint):
|
|
|
11
11
|
self.prefix = "/users"
|
|
12
12
|
|
|
13
13
|
def post_user(
|
|
14
|
-
self,
|
|
14
|
+
self,
|
|
15
|
+
agent_id: str,
|
|
16
|
+
username: str,
|
|
17
|
+
password: str,
|
|
18
|
+
permissions: dict[str, Any] | None = None,
|
|
19
|
+
metadata: dict[str, Any] | None = None,
|
|
15
20
|
) -> UserOutput:
|
|
16
21
|
"""
|
|
17
22
|
This endpoint is used to create a new user in the system. The user is created with the specified username and
|
|
@@ -22,6 +27,7 @@ class UsersEndpoint(AbstractEndpoint):
|
|
|
22
27
|
:param username: The username of the user to create
|
|
23
28
|
:param password: The password of the user to create
|
|
24
29
|
:param permissions: The permissions of the user to create (optional)
|
|
30
|
+
:param metadata: The metadata of the user to create (optional)
|
|
25
31
|
:return UserOutput, the created user
|
|
26
32
|
"""
|
|
27
33
|
payload = {
|
|
@@ -31,6 +37,9 @@ class UsersEndpoint(AbstractEndpoint):
|
|
|
31
37
|
if permissions is not None:
|
|
32
38
|
payload["permissions"] = permissions # type: ignore
|
|
33
39
|
|
|
40
|
+
if metadata is not None:
|
|
41
|
+
payload["metadata"] = metadata # type: ignore
|
|
42
|
+
|
|
34
43
|
return self.post_json(
|
|
35
44
|
self.prefix,
|
|
36
45
|
agent_id,
|
|
@@ -75,6 +84,7 @@ class UsersEndpoint(AbstractEndpoint):
|
|
|
75
84
|
username: str | None = None,
|
|
76
85
|
password: str | None = None,
|
|
77
86
|
permissions: Dict[str, Any] | None = None,
|
|
87
|
+
metadata: Dict[str, Any] | None = None,
|
|
78
88
|
) -> UserOutput:
|
|
79
89
|
"""
|
|
80
90
|
The endpoint is used to update the user in the system. The user is identified by the userId parameter, previously
|
|
@@ -87,6 +97,7 @@ class UsersEndpoint(AbstractEndpoint):
|
|
|
87
97
|
:param username: The new username of the user (optional)
|
|
88
98
|
:param password: The new password of the user (optional)
|
|
89
99
|
:param permissions: The new permissions of the user (optional)
|
|
100
|
+
:param metadata: The new metadata of the user (optional)
|
|
90
101
|
:return UserOutput, the updated user
|
|
91
102
|
"""
|
|
92
103
|
payload = {}
|
|
@@ -96,6 +107,8 @@ class UsersEndpoint(AbstractEndpoint):
|
|
|
96
107
|
payload["password"] = password
|
|
97
108
|
if permissions is not None:
|
|
98
109
|
payload["permissions"] = permissions
|
|
110
|
+
if metadata is not None:
|
|
111
|
+
payload["metadata"] = metadata
|
|
99
112
|
|
|
100
113
|
return self.put(self.format_url(user_id), agent_id, output_class=UserOutput, payload=payload)
|
|
101
114
|
|
|
@@ -1,15 +1,9 @@
|
|
|
1
|
-
from typing import Dict,
|
|
1
|
+
from typing import Dict, Any
|
|
2
2
|
from pydantic import BaseModel
|
|
3
3
|
|
|
4
4
|
from cheshirecat_python_sdk.models.api.plugins import PluginToggleOutput
|
|
5
5
|
|
|
6
6
|
|
|
7
|
-
class AdminOutput(BaseModel):
|
|
8
|
-
username: str
|
|
9
|
-
permissions: Dict[str, List[str]]
|
|
10
|
-
id: str
|
|
11
|
-
|
|
12
|
-
|
|
13
7
|
class CreatedOutput(BaseModel):
|
|
14
8
|
created: bool
|
|
15
9
|
|
|
@@ -1,10 +1,11 @@
|
|
|
1
|
-
from typing import Dict, List
|
|
1
|
+
from typing import Dict, List, Any
|
|
2
2
|
from pydantic import BaseModel
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
class UserOutput(BaseModel):
|
|
6
6
|
username: str
|
|
7
7
|
permissions: Dict[str, List[str]]
|
|
8
|
+
metadata: Dict[str, Any] | None = None
|
|
8
9
|
id: str
|
|
9
10
|
created_at: float | None = None
|
|
10
11
|
updated_at: float | None = None
|
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
from typing import Dict, List, Any
|
|
2
|
-
from pydantic import BaseModel, Field
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class Memory(BaseModel):
|
|
6
|
-
declarative: List | None = Field(default_factory=list)
|
|
2
|
+
from pydantic import BaseModel, Field, model_validator
|
|
7
3
|
|
|
8
4
|
|
|
9
5
|
class MemoryPoint(BaseModel):
|
|
@@ -29,4 +25,14 @@ class SettingInput(BaseModel):
|
|
|
29
25
|
class Why(BaseModel):
|
|
30
26
|
input: str | None = None
|
|
31
27
|
intermediate_steps: List | None = Field(default_factory=list)
|
|
32
|
-
memory:
|
|
28
|
+
memory: List | None = Field(default_factory=list)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
class FilterSource(BaseModel):
|
|
32
|
+
source: str | None = None
|
|
33
|
+
hash: str | None = None
|
|
34
|
+
|
|
35
|
+
@model_validator(mode="after")
|
|
36
|
+
def validate_source_or_hash(self):
|
|
37
|
+
assert self.source or self.hash, "Either source or hash must be provided"
|
|
38
|
+
return self
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: cheshirecat-python-sdk
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.8.4
|
|
4
4
|
Summary: Python SDK for the Cloud-ready fork of the Cheshire Cat
|
|
5
5
|
Project-URL: Repository, https://github.com/matteocacciola/cheshirecat-python-sdk
|
|
6
6
|
Project-URL: Documentation, https://github.com/matteocacciola/cheshirecat-python-sdk#README
|
|
@@ -1,37 +1,38 @@
|
|
|
1
1
|
cheshirecat_python_sdk/__init__.py,sha256=59esRUsh_6xPlfoCz-gQYQdDgp2xbaINYWyDcTJlvys,284
|
|
2
|
-
cheshirecat_python_sdk/client.py,sha256=
|
|
2
|
+
cheshirecat_python_sdk/client.py,sha256=J9sX8FxtE6bkwshDq5AHycG1bqHEOeqZlfr9g1mb13I,2960
|
|
3
3
|
cheshirecat_python_sdk/configuration.py,sha256=7uXebZGzCuJdpgOeN5l1YXkWVIrTk4apxvjPKZFcJTE,283
|
|
4
4
|
cheshirecat_python_sdk/enums.py,sha256=qJyhl5D_oDMHqNcIivr9pTxNrZY6XkX7lGgGydk22TY,665
|
|
5
5
|
cheshirecat_python_sdk/utils.py,sha256=2pcSCREOuIAUi5El5ou2rCm-VtmzyGVd3YHcKrFHgBM,458
|
|
6
|
-
cheshirecat_python_sdk/builders/__init__.py,sha256=
|
|
6
|
+
cheshirecat_python_sdk/builders/__init__.py,sha256=MEgXtw52hpQSTZ_EGOuS6WbbuXpIJGKmnYYImyoIM-s,208
|
|
7
7
|
cheshirecat_python_sdk/builders/base.py,sha256=YyE0pLp2iYyIFQVD1hLDeR8Wg578ebzoEEEtX9G8KZw,216
|
|
8
|
-
cheshirecat_python_sdk/builders/memory.py,sha256=
|
|
8
|
+
cheshirecat_python_sdk/builders/memory.py,sha256=UqznTdPcrcmWO1WqHcpQ0AoMe-ucWrViUjR6lsvzKEM,640
|
|
9
9
|
cheshirecat_python_sdk/builders/settings_input.py,sha256=EvaCDmmYOtHWUwCgG-nWonkY6UF6g1blytBwAmH477I,762
|
|
10
|
-
cheshirecat_python_sdk/builders/why.py,sha256=
|
|
10
|
+
cheshirecat_python_sdk/builders/why.py,sha256=mz58CpjCm5nf7hDXhLqi9o5uRAaGbSHyM5v2pNTX2HU,993
|
|
11
11
|
cheshirecat_python_sdk/clients/__init__.py,sha256=i4Hqux9vihFRbXVK48yJ1k9gm4JeCHnfPgosizQZv-g,135
|
|
12
12
|
cheshirecat_python_sdk/clients/http_client.py,sha256=LnP0kr-kHRCwC-BZiysj1Zg-T3b3yuLd81wOctfcBTg,2319
|
|
13
13
|
cheshirecat_python_sdk/clients/websocket_client.py,sha256=xNjkLSEZhpHzRqIZL21V0oG3srAGFaqYveMqlma2gvI,1932
|
|
14
|
-
cheshirecat_python_sdk/endpoints/__init__.py,sha256=
|
|
15
|
-
cheshirecat_python_sdk/endpoints/admins.py,sha256=
|
|
14
|
+
cheshirecat_python_sdk/endpoints/__init__.py,sha256=N8_vA7D304QCcaP-nhz039xkykRsBc-79COL_Ge19AY,1333
|
|
15
|
+
cheshirecat_python_sdk/endpoints/admins.py,sha256=b4YpHO-Xqkd-PQxvQcXYAUmQkrTLTvEjf5R9pals-50,4116
|
|
16
|
+
cheshirecat_python_sdk/endpoints/agentic_workflow.py,sha256=u0D9t7nGWcSPXUOeTmu1-madnWLlB7dlLP8hlP9yTJ4,2197
|
|
16
17
|
cheshirecat_python_sdk/endpoints/auth.py,sha256=_22fLGznoxo2pybcQGgcsHCpLoq76P6RplmSMMgajEQ,2031
|
|
17
18
|
cheshirecat_python_sdk/endpoints/auth_handler.py,sha256=Jfi7E7L3SIzJyECbJnUenIyl6xxkJlyC31AHpAlmqSs,2117
|
|
18
|
-
cheshirecat_python_sdk/endpoints/base.py,sha256=
|
|
19
|
+
cheshirecat_python_sdk/endpoints/base.py,sha256=0X2EQxRGqR6VG5gXE5XKcscmQ7rNM9de61GBrQlKD90,4210
|
|
19
20
|
cheshirecat_python_sdk/endpoints/chunker.py,sha256=bgp-2gQpKt7W_B46eEb-KFRkd4eZJH0euwsf3N0jfC8,1979
|
|
20
21
|
cheshirecat_python_sdk/endpoints/conversation.py,sha256=jG1z7ivdD53H8JZe7WZWihoBWy2_-W951SwKXmnpmTk,3282
|
|
21
22
|
cheshirecat_python_sdk/endpoints/custom_endpoint.py,sha256=HVRQMqA5JfPr87gHtWpYcsXsE-TA-coXLcvsPKabqds,2791
|
|
22
23
|
cheshirecat_python_sdk/endpoints/embedder.py,sha256=4B2yc3KBThKGreq_KPTTCsxt2Ekktw_muZ5gBfxrrwY,1741
|
|
23
|
-
cheshirecat_python_sdk/endpoints/file_manager.py,sha256=
|
|
24
|
+
cheshirecat_python_sdk/endpoints/file_manager.py,sha256=U4kc2oR3UszK0EKzYnES_RkgF1zhaPINAW_3X2WgX7A,4614
|
|
24
25
|
cheshirecat_python_sdk/endpoints/health_check.py,sha256=qv_5imbN39PqPyuBvlNoSqXqAvTvPv7UXI4zcfH8tlg,710
|
|
25
26
|
cheshirecat_python_sdk/endpoints/large_language_model.py,sha256=SS787ZKMZQ7KQNvl7a7rfBCm6s1j3ifDfWQcrM4tn-k,2109
|
|
26
|
-
cheshirecat_python_sdk/endpoints/memory.py,sha256=
|
|
27
|
+
cheshirecat_python_sdk/endpoints/memory.py,sha256=dgfoyjZH0gL3kln31gFJ42JHfL-S-oZHmEUzBmab3bw,10446
|
|
27
28
|
cheshirecat_python_sdk/endpoints/message.py,sha256=QTUSUJcj52VhfnX9hdjsD2aLeFC43O4eU8ld5lRvITU,2607
|
|
28
29
|
cheshirecat_python_sdk/endpoints/plugins.py,sha256=FasjwNY2UVv7zfg9lvXEj2ATefPDOPQpJXzQ2BbQIYI,3474
|
|
29
|
-
cheshirecat_python_sdk/endpoints/rabbit_hole.py,sha256=
|
|
30
|
-
cheshirecat_python_sdk/endpoints/users.py,sha256=
|
|
30
|
+
cheshirecat_python_sdk/endpoints/rabbit_hole.py,sha256=KjF5IRG6ghGEji-Js5try-9FhmWsuiM5v04jA68VoVY,7316
|
|
31
|
+
cheshirecat_python_sdk/endpoints/users.py,sha256=ySpFi9ILyoT44fnAz8p4LSGTaEAMWv3RBWq72Hv73mI,5803
|
|
31
32
|
cheshirecat_python_sdk/endpoints/utils.py,sha256=yKGrFRpu6ItLnBEuc98093LbXqGYaGdgCLiWuLQJVno,2551
|
|
32
33
|
cheshirecat_python_sdk/endpoints/vector_database.py,sha256=Xu6zcopjZgcFVVmyN547piiqFcaTUtF35X0QxQHycXQ,2149
|
|
33
|
-
cheshirecat_python_sdk/models/dtos.py,sha256=
|
|
34
|
-
cheshirecat_python_sdk/models/api/admins.py,sha256=
|
|
34
|
+
cheshirecat_python_sdk/models/dtos.py,sha256=0N6Auv43Gifo0ptdZxMZXAB6QGk8NNbcf8vQGm8HClo,869
|
|
35
|
+
cheshirecat_python_sdk/models/api/admins.py,sha256=sIX4NdEntjORgVACsqkBkzte4zwD6w35BdPRRG0D7uo,661
|
|
35
36
|
cheshirecat_python_sdk/models/api/conversations.py,sha256=Ej8677MLBqZEME1lZFd4UhHokdja762zYNjV9ZaEg-I,505
|
|
36
37
|
cheshirecat_python_sdk/models/api/factories.py,sha256=_NWz0nKhaVYEbaphxe2YZGznDIUiMKb-xqA1xymME5A,594
|
|
37
38
|
cheshirecat_python_sdk/models/api/file_managers.py,sha256=V0ZBjQWmYM1t0Qpfp3W2NDI_tScOtORB0i5YMEpTiRU,301
|
|
@@ -40,10 +41,10 @@ cheshirecat_python_sdk/models/api/messages.py,sha256=PDojYuXUDXSek8nkg8QKoVdAJ2N
|
|
|
40
41
|
cheshirecat_python_sdk/models/api/plugins.py,sha256=uX8SYbcTxQSxv1IaVChEBd3rr6kc83rwq3IILnmq5EE,1996
|
|
41
42
|
cheshirecat_python_sdk/models/api/rabbit_holes.py,sha256=01FcPSIG6nq9WJhL_rQopLMSD81CU9lfP-t0xtf35Gw,285
|
|
42
43
|
cheshirecat_python_sdk/models/api/tokens.py,sha256=GavSaCq0-SRWjvLtDgrYBOdUELd7VoVXlykmIBT23ds,455
|
|
43
|
-
cheshirecat_python_sdk/models/api/users.py,sha256=
|
|
44
|
+
cheshirecat_python_sdk/models/api/users.py,sha256=_T3-8hfmlZK9cZcqBTbNMYS74yEnDrRACRQn9PNCEiQ,280
|
|
44
45
|
cheshirecat_python_sdk/models/api/nested/memories.py,sha256=ddGDsmZa2refElM0sGz9QfKHGk50wsTpkwN5qDC5bF4,946
|
|
45
46
|
cheshirecat_python_sdk/models/api/nested/plugins.py,sha256=7vrwgXh0csaUn11YKY_OWnGEnD8Fu_ewKxt024VOBEs,738
|
|
46
|
-
cheshirecat_python_sdk-1.
|
|
47
|
-
cheshirecat_python_sdk-1.
|
|
48
|
-
cheshirecat_python_sdk-1.
|
|
49
|
-
cheshirecat_python_sdk-1.
|
|
47
|
+
cheshirecat_python_sdk-1.8.4.dist-info/METADATA,sha256=f5sjZkDGm4AXlxsMLbEjOEEgD2Pyke2NMqM7zi0Ag_4,44136
|
|
48
|
+
cheshirecat_python_sdk-1.8.4.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
49
|
+
cheshirecat_python_sdk-1.8.4.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
50
|
+
cheshirecat_python_sdk-1.8.4.dist-info/RECORD,,
|
|
File without changes
|
{cheshirecat_python_sdk-1.7.9.dist-info → cheshirecat_python_sdk-1.8.4.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|