codemie-sdk-python 0.1.227__tar.gz → 0.1.229__tar.gz

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.
Files changed (45) hide show
  1. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/PKG-INFO +45 -1
  2. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/README.md +44 -0
  3. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/pyproject.toml +1 -1
  4. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/__init__.py +26 -0
  5. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/client/client.py +7 -0
  6. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/models/assistant.py +21 -0
  7. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/models/datasource.py +1 -0
  8. codemie_sdk_python-0.1.229/src/codemie_sdk/models/vendor_guardrail.py +152 -0
  9. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/services/assistant.py +174 -0
  10. codemie_sdk_python-0.1.229/src/codemie_sdk/services/vendor_guardrail.py +375 -0
  11. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/auth/__init__.py +0 -0
  12. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/auth/credentials.py +0 -0
  13. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/client/__init__.py +0 -0
  14. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/exceptions.py +0 -0
  15. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/models/__init__.py +0 -0
  16. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/models/common.py +0 -0
  17. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/models/conversation.py +0 -0
  18. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/models/file_operation.py +0 -0
  19. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/models/integration.py +0 -0
  20. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/models/llm.py +0 -0
  21. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/models/task.py +0 -0
  22. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/models/user.py +0 -0
  23. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/models/vendor_assistant.py +0 -0
  24. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/models/vendor_knowledgebase.py +0 -0
  25. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/models/vendor_workflow.py +0 -0
  26. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/models/workflow.py +0 -0
  27. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/models/workflow_execution_payload.py +0 -0
  28. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/models/workflow_state.py +0 -0
  29. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/models/workflow_thoughts.py +0 -0
  30. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/services/conversation.py +0 -0
  31. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/services/datasource.py +0 -0
  32. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/services/files.py +0 -0
  33. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/services/integration.py +0 -0
  34. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/services/llm.py +0 -0
  35. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/services/task.py +0 -0
  36. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/services/user.py +0 -0
  37. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/services/vendor_assistant.py +0 -0
  38. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/services/vendor_knowledgebase.py +0 -0
  39. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/services/vendor_workflow.py +0 -0
  40. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/services/webhook.py +0 -0
  41. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/services/workflow.py +0 -0
  42. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/services/workflow_execution.py +0 -0
  43. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/services/workflow_execution_state.py +0 -0
  44. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/utils/__init__.py +0 -0
  45. {codemie_sdk_python-0.1.227 → codemie_sdk_python-0.1.229}/src/codemie_sdk/utils/http.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: codemie-sdk-python
3
- Version: 0.1.227
3
+ Version: 0.1.229
4
4
  Summary: CodeMie SDK for Python
5
5
  Author: Vadym Vlasenko
6
6
  Author-email: vadym_vlasenko@epam.com
@@ -831,6 +831,50 @@ client = CodeMieClient(
831
831
  )
832
832
  ```
833
833
 
834
+ ### Assistant Versioning via SDK
835
+
836
+ The Python SDK exposes full assistant versioning capabilities delivered in EPMCDME-8285.
837
+
838
+ - List versions
839
+ ```python
840
+ versions = client.assistants.list_versions("assistant-id", page=0, per_page=20)
841
+ print([v.version_number for v in versions])
842
+ ```
843
+
844
+ - Get specific version
845
+ ```python
846
+ version = client.assistants.get_version("assistant-id", 2)
847
+ print(version.system_prompt)
848
+ ```
849
+
850
+ - Compare two versions
851
+ ```python
852
+ from codemie_sdk.models.assistant import AssistantVersionDiff
853
+
854
+ diff: AssistantVersionDiff = client.assistants.compare_versions("assistant-id", 1, 3)
855
+ print(diff.summary)
856
+ ```
857
+
858
+ - Rollback to a version
859
+ ```python
860
+ resp = client.assistants.rollback_to_version("assistant-id", 2)
861
+ print(resp)
862
+ ```
863
+
864
+ - Chat with a specific version
865
+ ```python
866
+ from codemie_sdk.models.assistant import AssistantChatRequest
867
+
868
+ req = AssistantChatRequest(text="Hi", stream=False)
869
+ resp = client.assistants.chat_with_version("assistant-id", 2, req)
870
+ print(resp.generated)
871
+ ```
872
+
873
+ Quick CLI example
874
+ ```bash
875
+ python codemie-sdk/examples/assistant_versions.py <assistant_id> [version_number]
876
+ ```
877
+
834
878
  ## Support
835
879
  For providing credentials please contact AI/Run CodeMie Team: Vadym_Vlasenko@epam.com or Nikita_Levyankov@epam.com
836
880
 
@@ -818,6 +818,50 @@ client = CodeMieClient(
818
818
  )
819
819
  ```
820
820
 
821
+ ### Assistant Versioning via SDK
822
+
823
+ The Python SDK exposes full assistant versioning capabilities delivered in EPMCDME-8285.
824
+
825
+ - List versions
826
+ ```python
827
+ versions = client.assistants.list_versions("assistant-id", page=0, per_page=20)
828
+ print([v.version_number for v in versions])
829
+ ```
830
+
831
+ - Get specific version
832
+ ```python
833
+ version = client.assistants.get_version("assistant-id", 2)
834
+ print(version.system_prompt)
835
+ ```
836
+
837
+ - Compare two versions
838
+ ```python
839
+ from codemie_sdk.models.assistant import AssistantVersionDiff
840
+
841
+ diff: AssistantVersionDiff = client.assistants.compare_versions("assistant-id", 1, 3)
842
+ print(diff.summary)
843
+ ```
844
+
845
+ - Rollback to a version
846
+ ```python
847
+ resp = client.assistants.rollback_to_version("assistant-id", 2)
848
+ print(resp)
849
+ ```
850
+
851
+ - Chat with a specific version
852
+ ```python
853
+ from codemie_sdk.models.assistant import AssistantChatRequest
854
+
855
+ req = AssistantChatRequest(text="Hi", stream=False)
856
+ resp = client.assistants.chat_with_version("assistant-id", 2, req)
857
+ print(resp.generated)
858
+ ```
859
+
860
+ Quick CLI example
861
+ ```bash
862
+ python codemie-sdk/examples/assistant_versions.py <assistant_id> [version_number]
863
+ ```
864
+
821
865
  ## Support
822
866
  For providing credentials please contact AI/Run CodeMie Team: Vadym_Vlasenko@epam.com or Nikita_Levyankov@epam.com
823
867
 
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "codemie-sdk-python"
3
- version = "0.1.227"
3
+ version = "0.1.229"
4
4
  description = "CodeMie SDK for Python"
5
5
  authors = [
6
6
  "Vadym Vlasenko <vadym_vlasenko@epam.com>",
@@ -60,9 +60,23 @@ from .models.vendor_knowledgebase import (
60
60
  VendorKnowledgeBaseInstallResponse,
61
61
  VendorKnowledgeBaseUninstallResponse,
62
62
  )
63
+ from .models.vendor_guardrail import (
64
+ VendorGuardrailSetting,
65
+ VendorGuardrailSettingsResponse,
66
+ VendorGuardrail,
67
+ VendorGuardrailStatus,
68
+ VendorGuardrailsResponse,
69
+ VendorGuardrailVersion,
70
+ VendorGuardrailVersionsResponse,
71
+ VendorGuardrailInstallRequest,
72
+ VendorGuardrailInstallSummary,
73
+ VendorGuardrailInstallResponse,
74
+ VendorGuardrailUninstallResponse,
75
+ )
63
76
  from .services.vendor_assistant import VendorAssistantService
64
77
  from .services.vendor_workflow import VendorWorkflowService
65
78
  from .services.vendor_knowledgebase import VendorKnowledgeBaseService
79
+ from .services.vendor_guardrail import VendorGuardrailService
66
80
 
67
81
  __version__ = "0.2.11"
68
82
  __all__ = [
@@ -106,4 +120,16 @@ __all__ = [
106
120
  "VendorKnowledgeBaseInstallResponse",
107
121
  "VendorKnowledgeBaseUninstallResponse",
108
122
  "VendorKnowledgeBaseService",
123
+ "VendorGuardrailSetting",
124
+ "VendorGuardrailSettingsResponse",
125
+ "VendorGuardrail",
126
+ "VendorGuardrailStatus",
127
+ "VendorGuardrailsResponse",
128
+ "VendorGuardrailVersion",
129
+ "VendorGuardrailVersionsResponse",
130
+ "VendorGuardrailInstallRequest",
131
+ "VendorGuardrailInstallSummary",
132
+ "VendorGuardrailInstallResponse",
133
+ "VendorGuardrailUninstallResponse",
134
+ "VendorGuardrailService",
109
135
  ]
@@ -16,6 +16,7 @@ from ..services.webhook import WebhookService
16
16
  from ..services.vendor_assistant import VendorAssistantService
17
17
  from ..services.vendor_workflow import VendorWorkflowService
18
18
  from ..services.vendor_knowledgebase import VendorKnowledgeBaseService
19
+ from ..services.vendor_guardrail import VendorGuardrailService
19
20
 
20
21
 
21
22
  class CodeMieClient:
@@ -101,6 +102,9 @@ class CodeMieClient:
101
102
  self.vendor_knowledgebases = VendorKnowledgeBaseService(
102
103
  self._api_domain, self._token, verify_ssl=self._verify_ssl
103
104
  )
105
+ self.vendor_guardrails = VendorGuardrailService(
106
+ self._api_domain, self._token, verify_ssl=self._verify_ssl
107
+ )
104
108
 
105
109
  @property
106
110
  def token(self) -> str:
@@ -156,4 +160,7 @@ class CodeMieClient:
156
160
  self.vendor_knowledgebases = VendorKnowledgeBaseService(
157
161
  self._api_domain, self._token, verify_ssl=self._verify_ssl
158
162
  )
163
+ self.vendor_guardrails = VendorGuardrailService(
164
+ self._api_domain, self._token, verify_ssl=self._verify_ssl
165
+ )
159
166
  return self._token
@@ -164,6 +164,7 @@ class Assistant(AssistantBase):
164
164
  user_abilities: Optional[List[Any]] = None
165
165
  mcp_servers: List[MCPServerDetails] = Field(default_factory=list)
166
166
  assistant_ids: List[str] = Field(default_factory=list)
167
+ version_count: Optional[int] = None
167
168
 
168
169
 
169
170
  class AssistantRequestBase(AssistantBase):
@@ -205,6 +206,26 @@ class AssistantUpdateRequest(AssistantRequestBase):
205
206
  pass
206
207
 
207
208
 
209
+ class AssistantVersion(BaseModel):
210
+ """Immutable snapshot of assistant configuration for a specific version."""
211
+
212
+ model_config = ConfigDict(extra="ignore", use_enum_values=True)
213
+
214
+ version_number: int
215
+ created_date: datetime
216
+ created_by: Optional[User] = None
217
+ change_notes: Optional[str] = None
218
+ description: Optional[str] = None
219
+ system_prompt: str
220
+ llm_model_type: Optional[str] = None
221
+ temperature: Optional[float] = None
222
+ top_p: Optional[float] = None
223
+ context: List[Context] = Field(default_factory=list)
224
+ toolkits: List[ToolKitDetails] = Field(default_factory=list)
225
+ mcp_servers: List[MCPServerDetails] = Field(default_factory=list)
226
+ assistant_ids: List[str] = Field(default_factory=list)
227
+
228
+
208
229
  class ChatRole(str, Enum):
209
230
  """Enum for chat message roles."""
210
231
 
@@ -25,6 +25,7 @@ class DataSourceType(str, Enum):
25
25
  CHUNK_SUMMARY = "chunk-summary"
26
26
  JSON = "knowledge_base_json"
27
27
  BEDROCK = "knowledge_base_bedrock"
28
+ PLATFORM = "platform_marketplace_assistant"
28
29
 
29
30
 
30
31
  class DataSourceStatus(str, Enum):
@@ -0,0 +1,152 @@
1
+ """Models for vendor guardrail settings."""
2
+
3
+ from datetime import datetime
4
+ from enum import Enum
5
+ from typing import Optional, List
6
+
7
+ from pydantic import BaseModel, ConfigDict, Field
8
+
9
+ from .vendor_assistant import PaginationInfo, TokenPagination
10
+
11
+
12
+ class VendorGuardrailSetting(BaseModel):
13
+ """Model representing a vendor guardrail setting."""
14
+
15
+ model_config = ConfigDict(extra="ignore")
16
+
17
+ setting_id: str = Field(..., description="Unique identifier for the setting")
18
+ setting_name: str = Field(..., description="Name of the setting")
19
+ project: str = Field(..., description="Project associated with the setting")
20
+ entities: List[str] = Field(
21
+ default_factory=list, description="List of entities associated with the setting"
22
+ )
23
+ invalid: Optional[bool] = Field(None, description="Whether the setting is invalid")
24
+ error: Optional[str] = Field(
25
+ None, description="Error message if the setting is invalid"
26
+ )
27
+
28
+
29
+ class VendorGuardrailSettingsResponse(BaseModel):
30
+ """Response model for vendor guardrail settings list."""
31
+
32
+ model_config = ConfigDict(extra="ignore")
33
+
34
+ data: List[VendorGuardrailSetting] = Field(
35
+ ..., description="List of vendor guardrail settings"
36
+ )
37
+ pagination: PaginationInfo = Field(..., description="Pagination information")
38
+
39
+
40
+ class VendorGuardrailStatus(str, Enum):
41
+ """Status of vendor guardrail."""
42
+
43
+ PREPARED = "PREPARED"
44
+ NOT_PREPARED = "NOT_PREPARED"
45
+
46
+
47
+ class VendorGuardrail(BaseModel):
48
+ """Model representing a vendor guardrail."""
49
+
50
+ model_config = ConfigDict(extra="ignore")
51
+
52
+ id: str = Field(..., description="Unique identifier for the guardrail")
53
+ name: str = Field(..., description="Name of the guardrail")
54
+ status: VendorGuardrailStatus = Field(..., description="Status of the guardrail")
55
+ description: Optional[str] = Field(None, description="Description of the guardrail")
56
+ version: str = Field(..., description="Version of the guardrail")
57
+ createdAt: datetime = Field(
58
+ ..., description="Creation timestamp", alias="createdAt"
59
+ )
60
+ updatedAt: datetime = Field(
61
+ ..., description="Last update timestamp", alias="updatedAt"
62
+ )
63
+
64
+
65
+ class VendorGuardrailsResponse(BaseModel):
66
+ """Response model for vendor guardrails list."""
67
+
68
+ model_config = ConfigDict(extra="ignore")
69
+
70
+ data: List[VendorGuardrail] = Field(..., description="List of vendor guardrails")
71
+ pagination: TokenPagination = Field(
72
+ ..., description="Token-based pagination information"
73
+ )
74
+
75
+
76
+ class VendorGuardrailVersion(BaseModel):
77
+ """Model representing a vendor guardrail version."""
78
+
79
+ model_config = ConfigDict(extra="ignore")
80
+
81
+ id: str = Field(..., description="Unique identifier for the guardrail")
82
+ version: str = Field(..., description="Version of the guardrail")
83
+ name: str = Field(..., description="Name of the guardrail")
84
+ status: VendorGuardrailStatus = Field(..., description="Status of the version")
85
+ description: Optional[str] = Field(None, description="Description of the version")
86
+ blockedInputMessaging: Optional[str] = Field(
87
+ None,
88
+ description="Message to display when input is blocked by guardrail",
89
+ alias="blockedInputMessaging",
90
+ )
91
+ blockedOutputsMessaging: Optional[str] = Field(
92
+ None,
93
+ description="Message to display when output is blocked by guardrail",
94
+ alias="blockedOutputsMessaging",
95
+ )
96
+ createdAt: datetime = Field(
97
+ ..., description="Creation timestamp", alias="createdAt"
98
+ )
99
+ updatedAt: datetime = Field(
100
+ ..., description="Last update timestamp", alias="updatedAt"
101
+ )
102
+
103
+
104
+ class VendorGuardrailVersionsResponse(BaseModel):
105
+ """Response model for vendor guardrail versions list."""
106
+
107
+ model_config = ConfigDict(extra="ignore")
108
+
109
+ data: List[VendorGuardrailVersion] = Field(
110
+ ..., description="List of vendor guardrail versions"
111
+ )
112
+ pagination: TokenPagination = Field(
113
+ ..., description="Token-based pagination information"
114
+ )
115
+
116
+
117
+ class VendorGuardrailInstallRequest(BaseModel):
118
+ """Model for a single guardrail installation request."""
119
+
120
+ model_config = ConfigDict(extra="ignore")
121
+
122
+ id: str = Field(..., description="Guardrail ID to install")
123
+ version: str = Field(..., description="Version to use for the guardrail")
124
+ setting_id: str = Field(..., description="Vendor setting ID")
125
+
126
+
127
+ class VendorGuardrailInstallSummary(BaseModel):
128
+ """Model for guardrail installation summary."""
129
+
130
+ model_config = ConfigDict(extra="ignore")
131
+
132
+ guardrailId: str = Field(..., description="Installed guardrail ID")
133
+ version: str = Field(..., description="Version used for installation")
134
+ aiRunId: str = Field(..., description="AI run ID for the installation")
135
+
136
+
137
+ class VendorGuardrailInstallResponse(BaseModel):
138
+ """Response model for guardrail installation."""
139
+
140
+ model_config = ConfigDict(extra="ignore")
141
+
142
+ summary: List[VendorGuardrailInstallSummary] = Field(
143
+ ..., description="List of installation summaries"
144
+ )
145
+
146
+
147
+ class VendorGuardrailUninstallResponse(BaseModel):
148
+ """Response model for guardrail uninstallation."""
149
+
150
+ model_config = ConfigDict(extra="ignore")
151
+
152
+ success: bool = Field(..., description="Whether the uninstallation was successful")
@@ -170,6 +170,141 @@ class AssistantService:
170
170
  """
171
171
  return self._api.get(f"/v1/assistants/prebuilt/{slug}", Assistant)
172
172
 
173
+ def list_versions(
174
+ self, assistant_id: str, page: int = 0, per_page: Optional[int] = None
175
+ ):
176
+ """List assistant versions.
177
+
178
+ Args:
179
+ assistant_id: Assistant identifier
180
+ page: Page number for pagination
181
+ per_page: Items per page (optional). If not provided, backend defaults are used.
182
+
183
+ Returns:
184
+ List of AssistantVersion objects
185
+ """
186
+
187
+ params: Dict[str, Any] = {"page": page}
188
+ if per_page is not None:
189
+ params["per_page"] = per_page
190
+ from ..models.assistant import AssistantVersion
191
+
192
+ raw = self._api.get(
193
+ f"/v1/assistants/{assistant_id}/versions",
194
+ dict,
195
+ params=params,
196
+ wrap_response=False,
197
+ )
198
+ items = []
199
+ if isinstance(raw, list):
200
+ items = raw
201
+ elif isinstance(raw, dict):
202
+ items = raw.get("data") or raw.get("versions") or []
203
+ else:
204
+ items = []
205
+ return [AssistantVersion.model_validate(it) for it in items]
206
+
207
+ def get_version(self, assistant_id: str, version_number: int):
208
+ """Get a specific assistant version by number.
209
+
210
+ Args:
211
+ assistant_id: Assistant identifier
212
+ version_number: Version number to retrieve
213
+
214
+ Returns:
215
+ AssistantVersion object
216
+ """
217
+ from ..models.assistant import AssistantVersion
218
+
219
+ raw = self._api.get(
220
+ f"/v1/assistants/{assistant_id}/versions/{version_number}", AssistantVersion
221
+ )
222
+ if isinstance(raw, dict):
223
+ return AssistantVersion.model_validate(raw)
224
+ return raw
225
+
226
+ def compare_versions(self, assistant_id: str, v1: int, v2: int) -> Dict[str, Any]:
227
+ """Compare two assistant versions and return diff summary.
228
+
229
+ Args:
230
+ assistant_id: Assistant identifier
231
+ v1: First version number
232
+ v2: Second version number
233
+
234
+ Returns:
235
+ Generic dictionary with comparison result (diff, summary, etc.)
236
+ """
237
+ return self._api.get(
238
+ f"/v1/assistants/{assistant_id}/versions/{v1}/compare/{v2}",
239
+ dict,
240
+ )
241
+
242
+ def rollback_to_version(
243
+ self, assistant_id: str, version_number: int, change_notes: Optional[str] = None
244
+ ) -> dict:
245
+ """Rollback assistant to a specific version. Creates a new version mirroring target.
246
+
247
+ Args:
248
+ assistant_id: Assistant identifier
249
+ version_number: Target version to rollback to
250
+ change_notes: Optional description of why rollback is performed
251
+
252
+ Returns:
253
+ Backend response (dict)
254
+ """
255
+ payload: Dict[str, Any] = {}
256
+ if change_notes:
257
+ payload["change_notes"] = change_notes
258
+ try:
259
+ return self._api.post(
260
+ f"/v1/assistants/{assistant_id}/versions/{version_number}/rollback",
261
+ dict,
262
+ json_data=payload,
263
+ )
264
+ except requests.HTTPError as err:
265
+ try:
266
+ assistant = self.get(assistant_id)
267
+ version = self.get_version(assistant_id, version_number)
268
+
269
+ update_req = AssistantUpdateRequest(
270
+ name=assistant.name,
271
+ description=assistant.description or "",
272
+ system_prompt=version.system_prompt,
273
+ project=assistant.project,
274
+ llm_model_type=version.llm_model_type or assistant.llm_model_type,
275
+ temperature=version.temperature
276
+ if hasattr(version, "temperature")
277
+ else assistant.temperature,
278
+ top_p=version.top_p
279
+ if hasattr(version, "top_p")
280
+ else assistant.top_p,
281
+ context=version.context
282
+ if hasattr(version, "context")
283
+ else assistant.context,
284
+ toolkits=version.toolkits
285
+ if hasattr(version, "toolkits")
286
+ else assistant.toolkits,
287
+ user_prompts=assistant.user_prompts,
288
+ shared=assistant.shared,
289
+ is_react=assistant.is_react,
290
+ is_global=assistant.is_global,
291
+ slug=assistant.slug,
292
+ mcp_servers=version.mcp_servers
293
+ if hasattr(version, "mcp_servers")
294
+ else assistant.mcp_servers,
295
+ assistant_ids=version.assistant_ids
296
+ if hasattr(version, "assistant_ids")
297
+ else assistant.assistant_ids,
298
+ )
299
+ resp = self.update(assistant_id, update_req)
300
+ resp["_rollback_fallback"] = True
301
+ resp["_target_version"] = version_number
302
+ if change_notes:
303
+ resp["change_notes"] = change_notes
304
+ return resp
305
+ except Exception:
306
+ raise err
307
+
173
308
  def chat(
174
309
  self,
175
310
  assistant_id: str,
@@ -206,6 +341,45 @@ class AssistantService:
206
341
 
207
342
  return response
208
343
 
344
+ def chat_with_version(
345
+ self,
346
+ assistant_id: str,
347
+ version_number: int,
348
+ request: AssistantChatRequest,
349
+ ) -> Union[requests.Response, BaseModelResponse]:
350
+ """Send a chat request to a specific assistant version.
351
+
352
+ Uses the stable chat endpoint with an explicit `version` parameter to
353
+ ensure compatibility with environments that don't expose
354
+ /versions/{version}/model.
355
+
356
+ Args:
357
+ assistant_id: ID of the assistant to chat with
358
+ version_number: version to pin chat to
359
+ request: Chat request details
360
+
361
+ Returns:
362
+ Chat response or streaming response
363
+ """
364
+ pydantic_schema = None
365
+ if issubclass(request.output_schema, BaseModel):
366
+ pydantic_schema = deepcopy(request.output_schema)
367
+ request.output_schema = request.output_schema.model_json_schema()
368
+
369
+ payload = request.model_dump(exclude_none=True, by_alias=True)
370
+ payload["version"] = version_number
371
+
372
+ response = self._api.post(
373
+ f"/v1/assistants/{assistant_id}/model",
374
+ BaseModelResponse,
375
+ json_data=payload,
376
+ stream=request.stream,
377
+ )
378
+ if not request.stream and pydantic_schema:
379
+ response.generated = pydantic_schema.model_validate(response.generated)
380
+
381
+ return response
382
+
209
383
  def upload_file_to_chat(self, file_path: Path):
210
384
  """Upload a file to assistant chat and return the response containing file_url."""
211
385
 
@@ -0,0 +1,375 @@
1
+ """Vendor guardrail service implementation for managing cloud vendor guardrail settings."""
2
+
3
+ from typing import Union, Optional, List
4
+
5
+ from ..models.vendor_assistant import VendorType
6
+ from ..models.vendor_guardrail import (
7
+ VendorGuardrailSettingsResponse,
8
+ VendorGuardrailsResponse,
9
+ VendorGuardrail,
10
+ VendorGuardrailVersion,
11
+ VendorGuardrailVersionsResponse,
12
+ VendorGuardrailInstallRequest,
13
+ VendorGuardrailInstallResponse,
14
+ VendorGuardrailUninstallResponse,
15
+ )
16
+ from ..utils import ApiRequestHandler
17
+
18
+
19
+ class VendorGuardrailService:
20
+ """Service for managing cloud vendor guardrail settings (AWS, Azure, GCP)."""
21
+
22
+ def __init__(self, api_domain: str, token: str, verify_ssl: bool = True):
23
+ """Initialize the vendor guardrail service.
24
+
25
+ Args:
26
+ api_domain: Base URL for the CodeMie API
27
+ token: Authentication token
28
+ verify_ssl: Whether to verify SSL certificates
29
+ """
30
+ self._api = ApiRequestHandler(api_domain, token, verify_ssl)
31
+
32
+ def get_guardrail_settings(
33
+ self,
34
+ vendor: Union[VendorType, str],
35
+ page: int = 0,
36
+ per_page: int = 10,
37
+ ) -> VendorGuardrailSettingsResponse:
38
+ """Get guardrail settings for a specific cloud vendor.
39
+
40
+ Args:
41
+ vendor: Cloud vendor type (aws, azure, gcp). Can be VendorType enum or string.
42
+ page: Page number for pagination (0-based)
43
+ per_page: Number of items per page
44
+
45
+ Returns:
46
+ VendorGuardrailSettingsResponse containing list of settings and pagination info
47
+
48
+ Example:
49
+ >>> # Using enum
50
+ >>> settings = client.vendor_guardrails.get_guardrail_settings(VendorType.AWS, page=0, per_page=10)
51
+ >>> # Using string
52
+ >>> settings = client.vendor_guardrails.get_guardrail_settings("aws", page=0, per_page=10)
53
+ >>> # Access settings data
54
+ >>> for setting in settings.data:
55
+ ... print(f"Setting: {setting.setting_name}, Project: {setting.project}")
56
+ ... if setting.invalid:
57
+ ... print(f"Error: {setting.error}")
58
+ """
59
+ # Convert enum to string value if needed
60
+ vendor_str = vendor.value if isinstance(vendor, VendorType) else vendor
61
+
62
+ params = {
63
+ "page": page,
64
+ "per_page": per_page,
65
+ }
66
+
67
+ return self._api.get(
68
+ f"/v1/vendors/{vendor_str}/guardrails/settings",
69
+ VendorGuardrailSettingsResponse,
70
+ params=params,
71
+ wrap_response=False,
72
+ )
73
+
74
+ def get_guardrails(
75
+ self,
76
+ vendor: Union[VendorType, str],
77
+ setting_id: str,
78
+ per_page: int = 10,
79
+ next_token: Optional[str] = None,
80
+ ) -> VendorGuardrailsResponse:
81
+ """Get guardrails for a specific vendor setting.
82
+
83
+ Args:
84
+ vendor: Cloud vendor type (aws, azure, gcp). Can be VendorType enum or string.
85
+ setting_id: ID of the vendor setting to retrieve guardrails for
86
+ per_page: Number of items per page
87
+ next_token: Token for pagination (optional, for retrieving next page)
88
+
89
+ Returns:
90
+ VendorGuardrailsResponse containing list of guardrails and pagination token
91
+
92
+ Example:
93
+ >>> # Get first page
94
+ >>> guardrails = client.vendor_guardrails.get_guardrails(
95
+ ... vendor=VendorType.AWS,
96
+ ... setting_id="cac90788-39b7-4ffe-8b57-e8b047fa1f6c",
97
+ ... per_page=8
98
+ ... )
99
+ >>> # Access guardrail data
100
+ >>> for guardrail in guardrails.data:
101
+ ... print(f"Name: {guardrail.name}, Status: {guardrail.status}")
102
+ ... print(f"Version: {guardrail.version}, Description: {guardrail.description}")
103
+ >>> # Get next page if available
104
+ >>> if guardrails.pagination.next_token:
105
+ ... next_page = client.vendor_guardrails.get_guardrails(
106
+ ... vendor=VendorType.AWS,
107
+ ... setting_id="cac90788-39b7-4ffe-8b57-e8b047fa1f6c",
108
+ ... per_page=8,
109
+ ... next_token=guardrails.pagination.next_token
110
+ ... )
111
+ """
112
+ # Convert enum to string value if needed
113
+ vendor_str = vendor.value if isinstance(vendor, VendorType) else vendor
114
+
115
+ params = {
116
+ "setting_id": setting_id,
117
+ "per_page": per_page,
118
+ }
119
+
120
+ if next_token:
121
+ params["next_token"] = next_token
122
+
123
+ return self._api.get(
124
+ f"/v1/vendors/{vendor_str}/guardrails",
125
+ VendorGuardrailsResponse,
126
+ params=params,
127
+ wrap_response=False,
128
+ )
129
+
130
+ def get_guardrail(
131
+ self,
132
+ vendor: Union[VendorType, str],
133
+ guardrail_id: str,
134
+ setting_id: str,
135
+ ) -> VendorGuardrail:
136
+ """Get a specific guardrail by ID for a vendor setting.
137
+
138
+ Args:
139
+ vendor: Cloud vendor type (aws, azure, gcp). Can be VendorType enum or string.
140
+ guardrail_id: ID of the guardrail to retrieve
141
+ setting_id: ID of the vendor setting
142
+
143
+ Returns:
144
+ VendorGuardrail containing guardrail details
145
+
146
+ Example:
147
+ >>> guardrail = client.vendor_guardrails.get_guardrail(
148
+ ... vendor=VendorType.AWS,
149
+ ... guardrail_id="lss9vxro9oxg",
150
+ ... setting_id="cac90788-39b7-4ffe-8b57-e8b047fa1f6c"
151
+ ... )
152
+ >>> print(f"Name: {guardrail.name}, Status: {guardrail.status}")
153
+ >>> print(f"Version: {guardrail.version}, Description: {guardrail.description}")
154
+ """
155
+ # Convert enum to string value if needed
156
+ vendor_str = vendor.value if isinstance(vendor, VendorType) else vendor
157
+
158
+ params = {
159
+ "setting_id": setting_id,
160
+ }
161
+
162
+ return self._api.get(
163
+ f"/v1/vendors/{vendor_str}/guardrails/{guardrail_id}",
164
+ VendorGuardrail,
165
+ params=params,
166
+ wrap_response=False,
167
+ )
168
+
169
+ def get_guardrail_version(
170
+ self,
171
+ vendor: Union[VendorType, str],
172
+ guardrail_id: str,
173
+ version: str,
174
+ setting_id: str,
175
+ ) -> VendorGuardrailVersion:
176
+ """Get a specific version of a vendor guardrail with detailed information.
177
+
178
+ Args:
179
+ vendor: Cloud vendor type (aws, azure, gcp). Can be VendorType enum or string.
180
+ guardrail_id: ID of the guardrail to retrieve
181
+ version: Version number to retrieve (e.g., "1", "2", "DRAFT")
182
+ setting_id: ID of the vendor setting
183
+
184
+ Returns:
185
+ VendorGuardrailVersion containing detailed version information including
186
+ blocked messaging settings and timestamps
187
+
188
+ Example:
189
+ >>> version_details = client.vendor_guardrails.get_guardrail_version(
190
+ ... vendor=VendorType.AWS,
191
+ ... guardrail_id="lss9vxro9oxg",
192
+ ... version="1",
193
+ ... setting_id="cac90788-39b7-4ffe-8b57-e8b047fa1f6c"
194
+ ... )
195
+ >>> print(f"Name: {version_details.name}")
196
+ >>> print(f"Version: {version_details.version}")
197
+ >>> print(f"Status: {version_details.status}")
198
+ >>> print(f"Blocked Input Message: {version_details.blockedInputMessaging}")
199
+ >>> print(f"Blocked Output Message: {version_details.blockedOutputsMessaging}")
200
+ """
201
+ # Convert enum to string value if needed
202
+ vendor_str = vendor.value if isinstance(vendor, VendorType) else vendor
203
+
204
+ params = {
205
+ "setting_id": setting_id,
206
+ }
207
+
208
+ return self._api.get(
209
+ f"/v1/vendors/{vendor_str}/guardrails/{guardrail_id}/{version}",
210
+ VendorGuardrailVersion,
211
+ params=params,
212
+ wrap_response=False,
213
+ )
214
+
215
+ def get_guardrail_versions(
216
+ self,
217
+ vendor: Union[VendorType, str],
218
+ guardrail_id: str,
219
+ setting_id: str,
220
+ per_page: int = 10,
221
+ next_token: Optional[str] = None,
222
+ ) -> VendorGuardrailVersionsResponse:
223
+ """Get versions for a specific vendor guardrail.
224
+
225
+ Args:
226
+ vendor: Cloud vendor type (aws, azure, gcp). Can be VendorType enum or string.
227
+ guardrail_id: ID of the guardrail to retrieve versions for
228
+ setting_id: ID of the vendor setting
229
+ per_page: Number of items per page
230
+ next_token: Token for pagination (optional, for retrieving next page)
231
+
232
+ Returns:
233
+ VendorGuardrailVersionsResponse containing list of versions and pagination token
234
+
235
+ Example:
236
+ >>> # Get first page of versions
237
+ >>> versions = client.vendor_guardrails.get_guardrail_versions(
238
+ ... vendor=VendorType.AWS,
239
+ ... guardrail_id="lss9vxro9oxg",
240
+ ... setting_id="cac90788-39b7-4ffe-8b57-e8b047fa1f6c",
241
+ ... per_page=5
242
+ ... )
243
+ >>> for version in versions.data:
244
+ ... print(f"{version.name} (v{version.version}): {version.status}")
245
+ >>> # Get next page if available
246
+ >>> if versions.pagination.next_token:
247
+ ... next_page = client.vendor_guardrails.get_guardrail_versions(
248
+ ... vendor=VendorType.AWS,
249
+ ... guardrail_id="lss9vxro9oxg",
250
+ ... setting_id="cac90788-39b7-4ffe-8b57-e8b047fa1f6c",
251
+ ... per_page=5,
252
+ ... next_token=versions.pagination.next_token
253
+ ... )
254
+ """
255
+ # Convert enum to string value if needed
256
+ vendor_str = vendor.value if isinstance(vendor, VendorType) else vendor
257
+
258
+ params = {
259
+ "setting_id": setting_id,
260
+ "per_page": per_page,
261
+ }
262
+
263
+ if next_token:
264
+ params["next_token"] = next_token
265
+
266
+ return self._api.get(
267
+ f"/v1/vendors/{vendor_str}/guardrails/{guardrail_id}/versions",
268
+ VendorGuardrailVersionsResponse,
269
+ params=params,
270
+ wrap_response=False,
271
+ )
272
+
273
+ def install_guardrails(
274
+ self,
275
+ vendor: Union[VendorType, str],
276
+ guardrails: List[VendorGuardrailInstallRequest],
277
+ ) -> VendorGuardrailInstallResponse:
278
+ """Install/activate vendor guardrails.
279
+
280
+ Args:
281
+ vendor: Cloud vendor type (aws, azure, gcp). Can be VendorType enum or string.
282
+ guardrails: List of guardrail installation requests with guardrail ID, version, and setting ID
283
+
284
+ Returns:
285
+ VendorGuardrailInstallResponse containing installation summary with AI run IDs
286
+
287
+ Example:
288
+ >>> from codemie_sdk import VendorGuardrailInstallRequest
289
+ >>> # Install single guardrail
290
+ >>> install_request = VendorGuardrailInstallRequest(
291
+ ... id="lss9vxro9oxg",
292
+ ... version="1",
293
+ ... setting_id="cac90788-39b7-4ffe-8b57-e8b047fa1f6c"
294
+ ... )
295
+ >>> response = client.vendor_guardrails.install_guardrails(
296
+ ... vendor=VendorType.AWS,
297
+ ... guardrails=[install_request]
298
+ ... )
299
+ >>> for item in response.summary:
300
+ ... print(f"Installed {item.guardrailId} version {item.version} with run ID: {item.aiRunId}")
301
+ >>>
302
+ >>> # Install multiple guardrails
303
+ >>> requests = [
304
+ ... VendorGuardrailInstallRequest(
305
+ ... id="GUARDRAIL_ID_1",
306
+ ... version="1",
307
+ ... setting_id="SETTING_ID"
308
+ ... ),
309
+ ... VendorGuardrailInstallRequest(
310
+ ... id="GUARDRAIL_ID_2",
311
+ ... version="2",
312
+ ... setting_id="SETTING_ID"
313
+ ... )
314
+ ... ]
315
+ >>> response = client.vendor_guardrails.install_guardrails(
316
+ ... vendor=VendorType.AWS,
317
+ ... guardrails=requests
318
+ ... )
319
+ """
320
+ # Convert enum to string value if needed
321
+ vendor_str = vendor.value if isinstance(vendor, VendorType) else vendor
322
+
323
+ # Convert list of Pydantic models to list of dicts
324
+ payload = [guardrail.model_dump(by_alias=True) for guardrail in guardrails]
325
+
326
+ return self._api.post(
327
+ f"/v1/vendors/{vendor_str}/guardrails",
328
+ VendorGuardrailInstallResponse,
329
+ json_data=payload,
330
+ wrap_response=False,
331
+ )
332
+
333
+ def uninstall_guardrail(
334
+ self,
335
+ vendor: Union[VendorType, str],
336
+ ai_run_id: str,
337
+ ) -> VendorGuardrailUninstallResponse:
338
+ """Uninstall/deactivate a vendor guardrail.
339
+
340
+ Args:
341
+ vendor: Cloud vendor type (aws, azure, gcp). Can be VendorType enum or string.
342
+ ai_run_id: AI run ID returned from the install operation
343
+
344
+ Returns:
345
+ VendorGuardrailUninstallResponse with success status
346
+
347
+ Example:
348
+ >>> # First, install a guardrail
349
+ >>> install_request = VendorGuardrailInstallRequest(
350
+ ... id="lss9vxro9oxg",
351
+ ... version="1",
352
+ ... setting_id="cac90788-39b7-4ffe-8b57-e8b047fa1f6c"
353
+ ... )
354
+ >>> install_response = client.vendor_guardrails.install_guardrails(
355
+ ... vendor=VendorType.AWS,
356
+ ... guardrails=[install_request]
357
+ ... )
358
+ >>> ai_run_id = install_response.summary[0].aiRunId
359
+ >>>
360
+ >>> # Later, uninstall the guardrail using the AI run ID
361
+ >>> response = client.vendor_guardrails.uninstall_guardrail(
362
+ ... vendor=VendorType.AWS,
363
+ ... ai_run_id=ai_run_id
364
+ ... )
365
+ >>> if response.success:
366
+ ... print("Guardrail successfully uninstalled!")
367
+ """
368
+ # Convert enum to string value if needed
369
+ vendor_str = vendor.value if isinstance(vendor, VendorType) else vendor
370
+
371
+ return self._api.delete(
372
+ f"/v1/vendors/{vendor_str}/guardrails/{ai_run_id}",
373
+ VendorGuardrailUninstallResponse,
374
+ wrap_response=False,
375
+ )