codemie-sdk-python 0.1.689__py3-none-any.whl → 0.1.691__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.
@@ -18,6 +18,7 @@ from ..services.skill import SkillService
18
18
  from ..services.task import TaskService
19
19
  from ..services.user import UserService
20
20
  from ..services.workflow import WorkflowService
21
+ from ..services.workspace import WorkspaceService
21
22
  from ..services.files import FileOperationService
22
23
  from ..services.webhook import WebhookService
23
24
  from ..services.vendor_assistant import VendorAssistantService
@@ -185,6 +186,9 @@ class CodeMieClient:
185
186
  self.a2a = A2AService(
186
187
  self._api_domain, _token_source, verify_ssl=self._verify_ssl
187
188
  )
189
+ self.workspaces = WorkspaceService(
190
+ self._api_domain, _token_source, verify_ssl=self._verify_ssl
191
+ )
188
192
 
189
193
  @property
190
194
  def token(self) -> str:
@@ -176,6 +176,24 @@ class ProjectUpdateRequest(BaseModel):
176
176
  chargeback_attribution: str | None = None
177
177
 
178
178
 
179
+ class ProjectOwnershipUpdateRequest(BaseModel):
180
+ """Request to transfer project ownership to another user."""
181
+
182
+ model_config = ConfigDict(extra="ignore")
183
+
184
+ user_id: str
185
+
186
+
187
+ class ProjectOwnershipUpdateResponse(BaseModel):
188
+ """Response after transferring project ownership."""
189
+
190
+ model_config = ConfigDict(extra="ignore")
191
+
192
+ name: str
193
+ created_by: str
194
+ message: str
195
+
196
+
179
197
  class ProjectDeleteResponse(BaseModel):
180
198
  """Response after deleting a project."""
181
199
 
@@ -45,6 +45,23 @@ class SkillBase(BaseModel):
45
45
  mcp_servers: list[MCPServerDetails] = Field(default_factory=list)
46
46
 
47
47
 
48
+ class SkillCompanionFileMetadata(BaseModel):
49
+ """Metadata of a companion (bundle) file stored alongside a skill."""
50
+
51
+ model_config = ConfigDict(extra="ignore")
52
+
53
+ path: str
54
+ mime_type: str = "text/plain"
55
+ encoding: str = "text"
56
+ size_bytes: int = 0
57
+
58
+
59
+ class SkillCompanionFilePayload(SkillCompanionFileMetadata):
60
+ """Companion file sent on skill create/update, or returned with its content."""
61
+
62
+ content: str
63
+
64
+
48
65
  class SkillListResponse(SkillBase):
49
66
  """Skill list item response."""
50
67
 
@@ -61,6 +78,8 @@ class SkillDetailResponse(SkillListResponse):
61
78
  content: str
62
79
  slug: str | None = None
63
80
  icon_url: str | None = Field(None, alias="iconUrl")
81
+ companion_files: list[SkillCompanionFileMetadata] = Field(default_factory=list)
82
+ bundle_warning: str | None = None
64
83
 
65
84
 
66
85
  class SkillCreateRequest(BaseModel):
@@ -74,6 +93,7 @@ class SkillCreateRequest(BaseModel):
74
93
  categories: list[str] | None = Field(default_factory=list)
75
94
  enabled_builtin_subagents: list[str] | None = None
76
95
  mcp_servers: list[MCPServerDetails] | None = Field(default_factory=list)
96
+ companion_files: list[SkillCompanionFilePayload] | None = None
77
97
 
78
98
 
79
99
  class SkillUpdateRequest(BaseModel):
@@ -87,6 +107,7 @@ class SkillUpdateRequest(BaseModel):
87
107
  categories: list[str] | None = None
88
108
  enabled_builtin_subagents: list[str] | None = None
89
109
  mcp_servers: list[MCPServerDetails] | None = None
110
+ companion_files: list[SkillCompanionFilePayload] | None = None
90
111
 
91
112
 
92
113
  class SkillImportRequest(BaseModel):
@@ -227,3 +248,6 @@ class SkillConfigResponse(BaseModel):
227
248
 
228
249
  max_content_length: int
229
250
  min_content_length: int
251
+ bundle_seed_max_file_count: int | None = None
252
+ bundle_seed_max_file_size_bytes: int | None = None
253
+ bundle_seed_max_total_size_bytes: int | None = None
@@ -0,0 +1,57 @@
1
+ """Models for agent workspace data structures."""
2
+
3
+ from pydantic import BaseModel, ConfigDict, Field
4
+
5
+
6
+ class Workspace(BaseModel):
7
+ """Agent workspace that belongs to one conversation (or workflow execution)."""
8
+
9
+ model_config = ConfigDict(extra="ignore")
10
+
11
+ id: str
12
+ conversation_id: str
13
+ user_id: str | None = None
14
+ name: str | None = None
15
+ status: str | None = None
16
+
17
+
18
+ class WorkspaceFileItem(BaseModel):
19
+ """One file listed in a workspace."""
20
+
21
+ model_config = ConfigDict(extra="ignore")
22
+
23
+ path: str
24
+ mime_type: str | None = None
25
+ checksum: str | None = None
26
+ size: int | None = None
27
+ version: int | None = None
28
+
29
+
30
+ class WorkspaceFileContent(WorkspaceFileItem):
31
+ """A workspace file with its content (text, or base64 for images)."""
32
+
33
+ is_binary: bool = False
34
+ content: str | None = None
35
+ content_encoding: str | None = None
36
+
37
+
38
+ class WorkspaceDeleteFileResponse(BaseModel):
39
+ """Result of deleting a workspace file."""
40
+
41
+ model_config = ConfigDict(extra="ignore")
42
+
43
+ message: str
44
+ deleted: bool
45
+
46
+
47
+ class ExecuteWorkspaceScriptResponse(BaseModel):
48
+ """Result of running a script stored in a workspace."""
49
+
50
+ model_config = ConfigDict(extra="ignore", populate_by_name=True)
51
+
52
+ message: str
53
+ output: str
54
+ workspace_files: list[WorkspaceFileItem] = Field(
55
+ default_factory=list, alias="workspaceFiles"
56
+ )
57
+ warnings: list[str] = Field(default_factory=list)
@@ -30,6 +30,8 @@ from ..models.project import (
30
30
  ProjectCreateResponse,
31
31
  ProjectDeleteResponse,
32
32
  ProjectDetailResponse,
33
+ ProjectOwnershipUpdateRequest,
34
+ ProjectOwnershipUpdateResponse,
33
35
  ProjectUpdateRequest,
34
36
  ProjectUpdateResponse,
35
37
  )
@@ -217,6 +219,33 @@ class ProjectService:
217
219
  response_model=ProjectDeleteResponse,
218
220
  )
219
221
 
222
+ def transfer_ownership(
223
+ self,
224
+ project_name: str,
225
+ user_id: str,
226
+ ) -> ProjectOwnershipUpdateResponse:
227
+ """Transfer ownership of a project to another active user.
228
+
229
+ Args:
230
+ project_name: Project name
231
+ user_id: ID of the user who becomes the new owner
232
+
233
+ Returns:
234
+ ProjectOwnershipUpdateResponse with the project name, new owner id and message
235
+
236
+ Raises:
237
+ HTTPException: 404 if the project or the target user is not found, or the
238
+ caller may not manage the project; 403 if the project is personal
239
+ """
240
+ payload = ProjectOwnershipUpdateRequest(user_id=user_id)
241
+
242
+ return self._api.put(
243
+ f"/v1/projects/{project_name}/ownership",
244
+ response_model=ProjectOwnershipUpdateResponse,
245
+ json_data=payload.model_dump(),
246
+ wrap_response=False,
247
+ )
248
+
220
249
  # Assignment endpoints
221
250
 
222
251
  def assign_user_to_project(
@@ -9,6 +9,8 @@ from ..models.skill import (
9
9
  SkillAttachRequest,
10
10
  SkillBulkAttachRequest,
11
11
  SkillCategory,
12
+ SkillCompanionFileMetadata,
13
+ SkillCompanionFilePayload,
12
14
  SkillConfigResponse,
13
15
  SkillCreateRequest,
14
16
  SkillDetailResponse,
@@ -116,6 +118,38 @@ class SkillService:
116
118
  """
117
119
  return self._api.delete(f"/v1/skills/{skill_id}", dict)
118
120
 
121
+ # Companion (bundle) files
122
+
123
+ def list_companion_files(self, skill_id: str) -> list[SkillCompanionFileMetadata]:
124
+ """List the metadata of a skill's bundled companion files.
125
+
126
+ Args:
127
+ skill_id: Skill identifier
128
+
129
+ Returns:
130
+ Companion file metadata (path, mime type, encoding, size), without content
131
+ """
132
+ return self._api.get(
133
+ f"/v1/skills/{skill_id}/companion-files",
134
+ list[SkillCompanionFileMetadata],
135
+ )
136
+
137
+ def get_companion_file(self, skill_id: str, path: str) -> SkillCompanionFilePayload:
138
+ """Get one companion file of a skill, with its content, by its relative path.
139
+
140
+ Args:
141
+ skill_id: Skill identifier
142
+ path: Relative companion file path, e.g. ``references/guide.md``
143
+
144
+ Returns:
145
+ The companion file including its stored content
146
+ """
147
+ return self._api.get(
148
+ f"/v1/skills/{skill_id}/companion-files/content",
149
+ SkillCompanionFilePayload,
150
+ params={"path": path},
151
+ )
152
+
119
153
  # Import/Export Operations
120
154
 
121
155
  def import_skill(self, request: SkillImportRequest) -> SkillDetailResponse:
@@ -391,10 +425,11 @@ class SkillService:
391
425
  )
392
426
 
393
427
  def get_config(self) -> SkillConfigResponse:
394
- """Get effective skill content-length limits.
428
+ """Get effective skill content-length and bundle-seed limits.
395
429
 
396
430
  Returns:
397
- Skill config with max_content_length and min_content_length
431
+ Skill config with max_content_length, min_content_length and the
432
+ bundle_seed_max_* ceilings applied when skill files are placed in a workspace
398
433
  """
399
434
  return self._api.get("/v1/skills/config", SkillConfigResponse)
400
435
 
@@ -0,0 +1,160 @@
1
+ """Agent workspace service implementation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from ..models.workspace import (
6
+ ExecuteWorkspaceScriptResponse,
7
+ Workspace,
8
+ WorkspaceDeleteFileResponse,
9
+ WorkspaceFileContent,
10
+ WorkspaceFileItem,
11
+ )
12
+ from ..utils.http import ApiRequestHandler, TokenSource
13
+
14
+
15
+ class WorkspaceService:
16
+ """Service for the files of agent workspaces (one workspace per conversation)."""
17
+
18
+ def __init__(self, api_domain: str, token: TokenSource, verify_ssl: bool = True):
19
+ """Initialize the workspace service.
20
+
21
+ Args:
22
+ api_domain: Base URL for the CodeMie API
23
+ token: Authentication token
24
+ verify_ssl: Whether to verify SSL certificates. Default: True
25
+ """
26
+ self._api = ApiRequestHandler(api_domain, token, verify_ssl)
27
+
28
+ def create(self, conversation_id: str, name: str | None = None) -> Workspace:
29
+ """Create the workspace of a conversation, or return the existing one.
30
+
31
+ Args:
32
+ conversation_id: Conversation (or workflow execution) identifier
33
+ name: Optional display name
34
+
35
+ Returns:
36
+ The workspace of the conversation
37
+ """
38
+ return self._api.post(
39
+ "/v1/workspaces",
40
+ Workspace,
41
+ json_data={"conversation_id": conversation_id, "name": name},
42
+ )
43
+
44
+ def get_by_conversation(self, conversation_id: str) -> Workspace:
45
+ """Get the workspace of a conversation.
46
+
47
+ Args:
48
+ conversation_id: Conversation (or workflow execution) identifier
49
+
50
+ Returns:
51
+ The workspace of the conversation
52
+
53
+ Raises:
54
+ requests.HTTPError: 400 when the conversation has no workspace
55
+ """
56
+ return self._api.get(
57
+ f"/v1/workspaces/conversations/{conversation_id}", Workspace
58
+ )
59
+
60
+ def list_files(
61
+ self, workspace_id: str, glob: str | None = None
62
+ ) -> list[WorkspaceFileItem]:
63
+ """List the files of a workspace.
64
+
65
+ Args:
66
+ workspace_id: Workspace identifier
67
+ glob: Optional glob filter on the file path
68
+
69
+ Returns:
70
+ Files currently in the workspace (deleted files are not listed)
71
+ """
72
+ return self._api.get(
73
+ f"/v1/workspaces/{workspace_id}/files",
74
+ list[WorkspaceFileItem],
75
+ params={"glob": glob} if glob else None,
76
+ )
77
+
78
+ def write_file(
79
+ self, workspace_id: str, file_path: str, content: str
80
+ ) -> WorkspaceFileItem:
81
+ """Create or overwrite a text file in a workspace.
82
+
83
+ Args:
84
+ workspace_id: Workspace identifier
85
+ file_path: Workspace-relative path
86
+ content: UTF-8 text content
87
+
88
+ Returns:
89
+ The written file
90
+
91
+ Raises:
92
+ requests.HTTPError: 400 when the path is invalid or reserved
93
+ """
94
+ return self._api.put(
95
+ f"/v1/workspaces/{workspace_id}/files",
96
+ WorkspaceFileItem,
97
+ json_data={"file_path": file_path, "content": content},
98
+ )
99
+
100
+ def read_file(self, workspace_id: str, file_path: str) -> WorkspaceFileContent:
101
+ """Read a file of a workspace.
102
+
103
+ Args:
104
+ workspace_id: Workspace identifier
105
+ file_path: Workspace-relative path
106
+
107
+ Returns:
108
+ The file with its content
109
+
110
+ Raises:
111
+ requests.HTTPError: 400 when the file does not exist
112
+ """
113
+ return self._api.get(
114
+ f"/v1/workspaces/{workspace_id}/files/content",
115
+ WorkspaceFileContent,
116
+ params={"file_path": file_path},
117
+ )
118
+
119
+ def delete_file(
120
+ self, workspace_id: str, file_path: str
121
+ ) -> WorkspaceDeleteFileResponse:
122
+ """Delete a file from a workspace (the file stays deleted for later requests).
123
+
124
+ Args:
125
+ workspace_id: Workspace identifier
126
+ file_path: Workspace-relative path
127
+
128
+ Returns:
129
+ Whether a file was deleted
130
+
131
+ Raises:
132
+ requests.HTTPError: 400 when the path is invalid or reserved
133
+ """
134
+ return self._api.delete(
135
+ f"/v1/workspaces/{workspace_id}/files",
136
+ WorkspaceDeleteFileResponse,
137
+ params={"file_path": file_path},
138
+ )
139
+
140
+ def execute_script(
141
+ self,
142
+ workspace_id: str,
143
+ script_path: str,
144
+ export_files: list[str] | None = None,
145
+ ) -> ExecuteWorkspaceScriptResponse:
146
+ """Run a Python script stored in a workspace.
147
+
148
+ Args:
149
+ workspace_id: Workspace identifier
150
+ script_path: Workspace-relative path of the script
151
+ export_files: Optional workspace files to export from the run
152
+
153
+ Returns:
154
+ Script output, exported files and warnings about skipped workspace files
155
+ """
156
+ return self._api.post(
157
+ f"/v1/workspaces/{workspace_id}/execute",
158
+ ExecuteWorkspaceScriptResponse,
159
+ json_data={"script_path": script_path, "export_files": export_files},
160
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: codemie-sdk-python
3
- Version: 0.1.689
3
+ Version: 0.1.691
4
4
  Summary: CodeMie SDK for Python
5
5
  Author: Vadym Vlasenko
6
6
  Author-email: vadym_vlasenko@epam.com
@@ -7,7 +7,7 @@ codemie_sdk/builders/workflow/builder.py,sha256=bb_1uUe0AFhWuqe60Dao_1E-INxPwa7b
7
7
  codemie_sdk/builders/workflow/definition.py,sha256=YsKFoYC_VdKsTO2_AobSduP-MGjImEddn_0W5HzPZHQ,14338
8
8
  codemie_sdk/builders/workflow/publish.py,sha256=wrXFDNX0LpRTULp8zm5DD6hEmAqEwIMxPm0mSs82xjQ,7370
9
9
  codemie_sdk/client/__init__.py,sha256=yf6C39MmrJ6gK9ZHMhBeynKwUUYVSUTQbKxU8-4qpKg,101
10
- codemie_sdk/client/client.py,sha256=d86R8eT_dwX2a4K0HKk4UfshHlTvuY9dMcQYZ0ztQX0,9593
10
+ codemie_sdk/client/client.py,sha256=3v4uRF4SGGxR5Rs6fPQRbyysbKI_QEvrTB6wJH3MUN4,9770
11
11
  codemie_sdk/exceptions.py,sha256=uuzvtvYBMzrNGt7Q4k5RVq0Pd8eJ_tR2tLy3pF2ICDs,1148
12
12
  codemie_sdk/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
13
  codemie_sdk/models/a2a.py,sha256=zCNLiwwg78rok04hMlGPcQQS1IbEV4OaMcA_1KxQ9xs,1588
@@ -27,8 +27,8 @@ codemie_sdk/models/integration.py,sha256=yBV28vZ8oN0oNRNHdDPL3UUSJqNga1YodABIfX8
27
27
  codemie_sdk/models/llm.py,sha256=ViADvsSAkc85YQyPUkGE3ZvMc5pnHWHO0_rOkLSTfu4,1333
28
28
  codemie_sdk/models/mcp_config.py,sha256=mvD2utb4fthjNGAIkZKEkTtHSQQyF2WEYrA7tn-e0Lo,2184
29
29
  codemie_sdk/models/mermaid.py,sha256=dhRgX-itvfyrt0LUg5pbSo0CTH5PewiegqcZn3hWggU,675
30
- codemie_sdk/models/project.py,sha256=_iE45WdlAufZIW0XyqwxExOhHhSVY-YLs--68phj5tQ,6983
31
- codemie_sdk/models/skill.py,sha256=JIVHubDlPL8tH62AQRL0nMd0vieN6MPGckj9Kuqp7RA,6068
30
+ codemie_sdk/models/project.py,sha256=MWBWg_G373v8OHX_INqvZZg6TlRY0w8G_HDBqPa_CL0,7370
31
+ codemie_sdk/models/skill.py,sha256=KE4lsF8TMxIQa_UE0oRDMT6XIEHqKjsDyi0HYKEp1mM,6918
32
32
  codemie_sdk/models/task.py,sha256=YHu5DRnECS2wnqIWZ_YH8Z72p1I4aV3xWFW5joxN_8Q,1442
33
33
  codemie_sdk/models/user.py,sha256=YqPWzTgIKF-7Jw6aV7RD__su1iahEJPGaDR6Px-B4bU,3848
34
34
  codemie_sdk/models/vendor_assistant.py,sha256=vdpFq8aRlLj7IgRMWTA6pkrq8HZty8rgwA-kWrKKf3A,6357
@@ -41,6 +41,7 @@ codemie_sdk/models/workflow_execution_payload.py,sha256=0nhbiXyZlvbhB2SB6B_T6s2b
41
41
  codemie_sdk/models/workflow_state.py,sha256=uP1yLYwPpgPc17xpLwjanvlRzK6zT9qMZR-fAkvwFGg,1322
42
42
  codemie_sdk/models/workflow_thoughts.py,sha256=9fE380lMvC23fq677EI_JTk48Nf2jyPg3-mpj9VTx54,579
43
43
  codemie_sdk/models/workflow_transition.py,sha256=axZeiwTo4wzEwZ5GuKphmlRpWmjIuKxV15P_4V1n7LQ,794
44
+ codemie_sdk/models/workspace.py,sha256=xYnVO1Pnd0l0PSBe2pwP80C2ZvYBc2ESo6OH_G0cOOg,1438
44
45
  codemie_sdk/services/a2a.py,sha256=JI_heDKmQ1qYGIES_6qPosHRyVb73tKs4v7uTGpzXx4,1026
45
46
  codemie_sdk/services/activity_event.py,sha256=KoD0DyeqJ0CmQPA4PAXH4uGIAQCgcJbYwDnv-MCckGc,3630
46
47
  codemie_sdk/services/admin.py,sha256=yk1xdBXDjpdW4OMOdBaURkZhAxak9h-TppKyhStLekc,4006
@@ -58,9 +59,9 @@ codemie_sdk/services/integration.py,sha256=n4ggDedJ2GCI5mTgZNfrYE49uzLsp_BKYKMdT
58
59
  codemie_sdk/services/llm.py,sha256=GQWIi359f99uU4YRnAdpbyae1kXp1G5OpVgJNIIn7-8,1132
59
60
  codemie_sdk/services/mcp_configs.py,sha256=MrCiWJ6-ezXE9NOTgOfHDhfyQokaumGp1rwB4IAKXzs,2466
60
61
  codemie_sdk/services/mermaid.py,sha256=7cLykdrJVW576raUbON3yhuWnbGaXl8rX1QfVwbu2JE,2246
61
- codemie_sdk/services/project.py,sha256=ajs5ZEc7L9k6qJGjX28_LF6mrExC-uYvWhd3AuQBX_w,13309
62
+ codemie_sdk/services/project.py,sha256=2O57E63mkt5Z-OwTksxiKplRDHwh6MV_COaztXO7j4A,14298
62
63
  codemie_sdk/services/project_budget_groups.py,sha256=B7QJt3sh_LV3lfwALZlxUq0SLR30BWafHcS6eHyOh8Y,5471
63
- codemie_sdk/services/skill.py,sha256=bwU21qGQFm85BdqkPeNJiWyzoyJL7SfEGmUs1XTyfks,11971
64
+ codemie_sdk/services/skill.py,sha256=0mExdeKTMNqkEpKafD0ya1WyLj9CMCFaprkggKYqnQg,13216
64
65
  codemie_sdk/services/task.py,sha256=UaYh__xGF7VKWCJKPrncVjTvx46Gz1AN9XczPVL71oA,1052
65
66
  codemie_sdk/services/user.py,sha256=W0-fkY6vIbJDlIpb2PxxljSMOdWh910BmBK-n94gBs0,6998
66
67
  codemie_sdk/services/vendor_assistant.py,sha256=Vwa0rH8TYTCV1iAeKuSP5skbX8V04NLXE0g9VQRKqGI,13484
@@ -72,8 +73,9 @@ codemie_sdk/services/webhook.py,sha256=jYPEyJ0Q0IydMF9D2UoURsr6PgdfbKs4fr5L6ix8e
72
73
  codemie_sdk/services/workflow.py,sha256=D-20pUo6Lm3ef3WKTv-nwGMN1Dx5tmNwqeWCR0XcpoM,10439
73
74
  codemie_sdk/services/workflow_execution.py,sha256=GuI1uBtd1NGvRVHElMsgPBZlIRDP9CK73ISJABkpCs4,7225
74
75
  codemie_sdk/services/workflow_execution_state.py,sha256=u1xmGvaHjqvQS5ujhyvJ_Ac7ByjKem2Qe8q0swsmoWw,2045
76
+ codemie_sdk/services/workspace.py,sha256=eLwZ0fhi1BfOesrXaQlTdOll8q7ENP9b_jb5eybKSVw,5038
75
77
  codemie_sdk/utils/__init__.py,sha256=EzK_UrS5KHmAnE73Hci9LaObB5omjVUhIq4svh0gfwo,137
76
78
  codemie_sdk/utils/http.py,sha256=PWejBKa5pwzQ5eLVhdN8lYKEu1B1QtwGTRmZfnGFL6c,14158
77
- codemie_sdk_python-0.1.689.dist-info/METADATA,sha256=WPbexxhcK0uQUzQGZYxprgICOcaYa_9j9GMDoqyca84,47441
78
- codemie_sdk_python-0.1.689.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
79
- codemie_sdk_python-0.1.689.dist-info/RECORD,,
79
+ codemie_sdk_python-0.1.691.dist-info/METADATA,sha256=5Ik4BOiQjqb5jMGCNjQ5pNYNJfoNzP1Ea64_l1EpWyY,47441
80
+ codemie_sdk_python-0.1.691.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
81
+ codemie_sdk_python-0.1.691.dist-info/RECORD,,