codemie-sdk-python 0.1.226__py3-none-any.whl → 0.1.256__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.
- codemie_sdk/__init__.py +27 -1
- codemie_sdk/client/client.py +14 -0
- codemie_sdk/models/assistant.py +53 -0
- codemie_sdk/models/datasource.py +45 -0
- codemie_sdk/models/integration.py +1 -1
- codemie_sdk/models/vendor_guardrail.py +152 -0
- codemie_sdk/models/workflow_execution_payload.py +4 -0
- codemie_sdk/services/assistant.py +214 -0
- codemie_sdk/services/datasource.py +67 -0
- codemie_sdk/services/files.py +21 -0
- codemie_sdk/services/vendor_guardrail.py +375 -0
- codemie_sdk/services/workflow.py +10 -1
- codemie_sdk/services/workflow_execution.py +26 -4
- codemie_sdk/utils/http.py +21 -7
- {codemie_sdk_python-0.1.226.dist-info → codemie_sdk_python-0.1.256.dist-info}/METADATA +129 -9
- {codemie_sdk_python-0.1.226.dist-info → codemie_sdk_python-0.1.256.dist-info}/RECORD +17 -15
- {codemie_sdk_python-0.1.226.dist-info → codemie_sdk_python-0.1.256.dist-info}/WHEEL +0 -0
codemie_sdk/__init__.py
CHANGED
|
@@ -60,11 +60,25 @@ 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
|
-
__version__ = "0.2.
|
|
81
|
+
__version__ = "0.2.12"
|
|
68
82
|
__all__ = [
|
|
69
83
|
"CodeMieClient",
|
|
70
84
|
"VendorType",
|
|
@@ -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
|
]
|
codemie_sdk/client/client.py
CHANGED
|
@@ -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:
|
|
@@ -116,6 +120,7 @@ class CodeMieClient:
|
|
|
116
120
|
"localhost",
|
|
117
121
|
"127.0.0.1",
|
|
118
122
|
"0.0.0.0",
|
|
123
|
+
"192.168",
|
|
119
124
|
]
|
|
120
125
|
return any(pattern in domain_lower for pattern in localhost_patterns)
|
|
121
126
|
|
|
@@ -147,6 +152,12 @@ class CodeMieClient:
|
|
|
147
152
|
self.conversations = ConversationService(
|
|
148
153
|
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
149
154
|
)
|
|
155
|
+
self.files = FileOperationService(
|
|
156
|
+
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
157
|
+
)
|
|
158
|
+
self.webhook = WebhookService(
|
|
159
|
+
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
160
|
+
)
|
|
150
161
|
self.vendor_assistants = VendorAssistantService(
|
|
151
162
|
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
152
163
|
)
|
|
@@ -156,4 +167,7 @@ class CodeMieClient:
|
|
|
156
167
|
self.vendor_knowledgebases = VendorKnowledgeBaseService(
|
|
157
168
|
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
158
169
|
)
|
|
170
|
+
self.vendor_guardrails = VendorGuardrailService(
|
|
171
|
+
self._api_domain, self._token, verify_ssl=self._verify_ssl
|
|
172
|
+
)
|
|
159
173
|
return self._token
|
codemie_sdk/models/assistant.py
CHANGED
|
@@ -53,6 +53,16 @@ class Context(BaseModel):
|
|
|
53
53
|
name: str
|
|
54
54
|
|
|
55
55
|
|
|
56
|
+
class PromptVariable(BaseModel):
|
|
57
|
+
"""Model for assistant prompt variables."""
|
|
58
|
+
|
|
59
|
+
model_config = ConfigDict(extra="ignore")
|
|
60
|
+
|
|
61
|
+
key: str
|
|
62
|
+
description: Optional[str] = None
|
|
63
|
+
default_value: str
|
|
64
|
+
|
|
65
|
+
|
|
56
66
|
class MCPServerConfig(BaseModel):
|
|
57
67
|
"""
|
|
58
68
|
Configuration for an MCP server.
|
|
@@ -137,6 +147,17 @@ class AssistantBase(BaseModel):
|
|
|
137
147
|
icon_url: Optional[str] = None
|
|
138
148
|
|
|
139
149
|
|
|
150
|
+
class AssistantListResponse(BaseModel):
|
|
151
|
+
"""Model for assistant list response."""
|
|
152
|
+
|
|
153
|
+
model_config = ConfigDict(extra="ignore")
|
|
154
|
+
|
|
155
|
+
id: str
|
|
156
|
+
name: str
|
|
157
|
+
slug: Optional[str] = None
|
|
158
|
+
created_by: Optional[User] = None
|
|
159
|
+
|
|
160
|
+
|
|
140
161
|
class Assistant(AssistantBase):
|
|
141
162
|
"""Full assistant model with additional fields."""
|
|
142
163
|
|
|
@@ -164,6 +185,8 @@ class Assistant(AssistantBase):
|
|
|
164
185
|
user_abilities: Optional[List[Any]] = None
|
|
165
186
|
mcp_servers: List[MCPServerDetails] = Field(default_factory=list)
|
|
166
187
|
assistant_ids: List[str] = Field(default_factory=list)
|
|
188
|
+
version_count: Optional[int] = None
|
|
189
|
+
prompt_variables: Optional[List[PromptVariable]] = Field(default=None)
|
|
167
190
|
|
|
168
191
|
|
|
169
192
|
class AssistantRequestBase(AssistantBase):
|
|
@@ -191,6 +214,7 @@ class AssistantRequestBase(AssistantBase):
|
|
|
191
214
|
top_p: Optional[float] = None
|
|
192
215
|
mcp_servers: List[MCPServerDetails] = Field(default_factory=list)
|
|
193
216
|
assistant_ids: List[str] = Field(default_factory=list)
|
|
217
|
+
prompt_variables: List[PromptVariable] = Field(default_factory=list)
|
|
194
218
|
|
|
195
219
|
|
|
196
220
|
class AssistantCreateRequest(AssistantRequestBase):
|
|
@@ -205,6 +229,27 @@ class AssistantUpdateRequest(AssistantRequestBase):
|
|
|
205
229
|
pass
|
|
206
230
|
|
|
207
231
|
|
|
232
|
+
class AssistantVersion(BaseModel):
|
|
233
|
+
"""Immutable snapshot of assistant configuration for a specific version."""
|
|
234
|
+
|
|
235
|
+
model_config = ConfigDict(extra="ignore", use_enum_values=True)
|
|
236
|
+
|
|
237
|
+
version_number: int
|
|
238
|
+
created_date: datetime
|
|
239
|
+
created_by: Optional[User] = None
|
|
240
|
+
change_notes: Optional[str] = None
|
|
241
|
+
description: Optional[str] = None
|
|
242
|
+
system_prompt: str
|
|
243
|
+
llm_model_type: Optional[str] = None
|
|
244
|
+
temperature: Optional[float] = None
|
|
245
|
+
top_p: Optional[float] = None
|
|
246
|
+
context: List[Context] = Field(default_factory=list)
|
|
247
|
+
toolkits: List[ToolKitDetails] = Field(default_factory=list)
|
|
248
|
+
mcp_servers: List[MCPServerDetails] = Field(default_factory=list)
|
|
249
|
+
assistant_ids: List[str] = Field(default_factory=list)
|
|
250
|
+
prompt_variables: List[PromptVariable] = Field(default_factory=list)
|
|
251
|
+
|
|
252
|
+
|
|
208
253
|
class ChatRole(str, Enum):
|
|
209
254
|
"""Enum for chat message roles."""
|
|
210
255
|
|
|
@@ -263,6 +308,14 @@ class AssistantChatRequest(BaseModel):
|
|
|
263
308
|
default=None, description="DataSource in conversation history"
|
|
264
309
|
)
|
|
265
310
|
stream: bool = Field(default=False, description="Enable streaming response")
|
|
311
|
+
propagate_headers: bool = Field(
|
|
312
|
+
default=False,
|
|
313
|
+
description="Enable propagation of X-* HTTP headers to MCP servers during tool execution",
|
|
314
|
+
)
|
|
315
|
+
custom_metadata: Optional[dict[str, Any]] = Field(
|
|
316
|
+
default=None,
|
|
317
|
+
description="Custom metadata for the AI Assistant",
|
|
318
|
+
)
|
|
266
319
|
top_k: int = Field(default=10, description="Top K results to consider")
|
|
267
320
|
system_prompt: str = Field(default="", description="Override system prompt")
|
|
268
321
|
background_task: bool = Field(default=False, description="Run as background task")
|
codemie_sdk/models/datasource.py
CHANGED
|
@@ -25,6 +25,8 @@ 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"
|
|
29
|
+
AZURE_DEVOPS_WIKI = "knowledge_base_azure_devops_wiki"
|
|
28
30
|
|
|
29
31
|
|
|
30
32
|
class DataSourceStatus(str, Enum):
|
|
@@ -46,6 +48,15 @@ class DataSourceProcessingInfo(BaseModel):
|
|
|
46
48
|
processed_documents_count: Optional[int] = Field(None, alias="documents_count_key")
|
|
47
49
|
|
|
48
50
|
|
|
51
|
+
class ElasticsearchStatsResponse(BaseModel):
|
|
52
|
+
"""Response model for Elasticsearch index statistics."""
|
|
53
|
+
|
|
54
|
+
model_config = ConfigDict(extra="ignore")
|
|
55
|
+
|
|
56
|
+
index_name: str = Field(..., description="Name of the index in Elasticsearch")
|
|
57
|
+
size_in_bytes: int = Field(..., ge=0, description="Size of the index in bytes")
|
|
58
|
+
|
|
59
|
+
|
|
49
60
|
# Base request models
|
|
50
61
|
class Confluence(BaseModel):
|
|
51
62
|
"""Model for Confluence-specific response fields"""
|
|
@@ -259,6 +270,40 @@ class UpdateFileDataSourceRequest(BaseUpdateDataSourceRequest):
|
|
|
259
270
|
super().__init__(type=DataSourceType.FILE, **data)
|
|
260
271
|
|
|
261
272
|
|
|
273
|
+
class CodeAnalysisDataSourceRequest(BaseModel):
|
|
274
|
+
"""Model for provider-based datasource creation requests"""
|
|
275
|
+
|
|
276
|
+
model_config = ConfigDict(extra="ignore", populate_by_name=True)
|
|
277
|
+
|
|
278
|
+
name: str = Field(..., description="Datasource name")
|
|
279
|
+
description: Optional[str] = Field(None, description="Datasource description")
|
|
280
|
+
project_name: str = Field(..., description="Project name")
|
|
281
|
+
project_space_visible: bool = Field(False, alias="projectSpaceVisible")
|
|
282
|
+
branch: Optional[str] = Field(None, description="Git branch")
|
|
283
|
+
api_url: str = Field(..., description="Repository URL")
|
|
284
|
+
access_token: str = Field(..., description="Access token for repository")
|
|
285
|
+
analyzer: Optional[str] = Field(
|
|
286
|
+
None, description="Code analyzer type (e.g., Java, Python)"
|
|
287
|
+
)
|
|
288
|
+
datasource_root: str = Field("/", description="Root directory to analyze")
|
|
289
|
+
|
|
290
|
+
|
|
291
|
+
class CodeExplorationDataSourceRequest(BaseModel):
|
|
292
|
+
"""Model for CodeExplorationToolkit datasource creation requests"""
|
|
293
|
+
|
|
294
|
+
model_config = ConfigDict(extra="ignore", populate_by_name=True)
|
|
295
|
+
|
|
296
|
+
name: str = Field(..., description="Datasource name")
|
|
297
|
+
description: Optional[str] = Field(None, description="Datasource description")
|
|
298
|
+
project_name: str = Field(..., description="Project name")
|
|
299
|
+
project_space_visible: bool = Field(False, alias="projectSpaceVisible")
|
|
300
|
+
code_analysis_datasource_ids: List[str] = Field(
|
|
301
|
+
...,
|
|
302
|
+
alias="code_analysis_datasource_ids",
|
|
303
|
+
description="List of CodeAnalysisToolkit datasource IDs",
|
|
304
|
+
)
|
|
305
|
+
|
|
306
|
+
|
|
262
307
|
class DataSource(BaseModel):
|
|
263
308
|
model_config = ConfigDict(
|
|
264
309
|
extra="ignore",
|
|
@@ -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")
|
|
@@ -15,3 +15,7 @@ class WorkflowExecutionCreateRequest(BaseModel):
|
|
|
15
15
|
file_name: Optional[str] = Field(
|
|
16
16
|
None, description="File name associated with the workflow execution"
|
|
17
17
|
)
|
|
18
|
+
propagate_headers: bool = Field(
|
|
19
|
+
default=False,
|
|
20
|
+
description="Enable propagation of X-* HTTP headers to MCP servers during tool execution",
|
|
21
|
+
)
|
|
@@ -170,16 +170,153 @@ 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,
|
|
176
311
|
request: AssistantChatRequest,
|
|
312
|
+
headers: Optional[Dict[str, str]] = None,
|
|
177
313
|
) -> Union[requests.Response, BaseModelResponse]:
|
|
178
314
|
"""Send a chat request to an assistant.
|
|
179
315
|
|
|
180
316
|
Args:
|
|
181
317
|
assistant_id: ID of the assistant to chat with
|
|
182
318
|
request: Chat request details
|
|
319
|
+
headers: Optional additional HTTP headers (e.g., X-* for MCP propagation)
|
|
183
320
|
|
|
184
321
|
Returns:
|
|
185
322
|
Chat response or streaming response
|
|
@@ -198,6 +335,7 @@ class AssistantService:
|
|
|
198
335
|
BaseModelResponse,
|
|
199
336
|
json_data=request.model_dump(exclude_none=True, by_alias=True),
|
|
200
337
|
stream=request.stream,
|
|
338
|
+
extra_headers=headers,
|
|
201
339
|
)
|
|
202
340
|
if not request.stream and pydantic_schema:
|
|
203
341
|
# we do conversion to the BaseModel here because self._parse_response don't see actual request model,
|
|
@@ -206,6 +344,82 @@ class AssistantService:
|
|
|
206
344
|
|
|
207
345
|
return response
|
|
208
346
|
|
|
347
|
+
def chat_with_version(
|
|
348
|
+
self,
|
|
349
|
+
assistant_id: str,
|
|
350
|
+
version_number: int,
|
|
351
|
+
request: AssistantChatRequest,
|
|
352
|
+
) -> Union[requests.Response, BaseModelResponse]:
|
|
353
|
+
"""Send a chat request to a specific assistant version.
|
|
354
|
+
|
|
355
|
+
Uses the stable chat endpoint with an explicit `version` parameter to
|
|
356
|
+
ensure compatibility with environments that don't expose
|
|
357
|
+
/versions/{version}/model.
|
|
358
|
+
|
|
359
|
+
Args:
|
|
360
|
+
assistant_id: ID of the assistant to chat with
|
|
361
|
+
version_number: version to pin chat to
|
|
362
|
+
request: Chat request details
|
|
363
|
+
|
|
364
|
+
Returns:
|
|
365
|
+
Chat response or streaming response
|
|
366
|
+
"""
|
|
367
|
+
pydantic_schema = None
|
|
368
|
+
if issubclass(request.output_schema, BaseModel):
|
|
369
|
+
pydantic_schema = deepcopy(request.output_schema)
|
|
370
|
+
request.output_schema = request.output_schema.model_json_schema()
|
|
371
|
+
|
|
372
|
+
payload = request.model_dump(exclude_none=True, by_alias=True)
|
|
373
|
+
payload["version"] = version_number
|
|
374
|
+
|
|
375
|
+
response = self._api.post(
|
|
376
|
+
f"/v1/assistants/{assistant_id}/model",
|
|
377
|
+
BaseModelResponse,
|
|
378
|
+
json_data=payload,
|
|
379
|
+
stream=request.stream,
|
|
380
|
+
)
|
|
381
|
+
if not request.stream and pydantic_schema:
|
|
382
|
+
response.generated = pydantic_schema.model_validate(response.generated)
|
|
383
|
+
|
|
384
|
+
return response
|
|
385
|
+
|
|
386
|
+
def chat_by_slug(
|
|
387
|
+
self,
|
|
388
|
+
assistant_slug: str,
|
|
389
|
+
request: AssistantChatRequest,
|
|
390
|
+
headers: Optional[Dict[str, str]] = None,
|
|
391
|
+
) -> Union[requests.Response, BaseModelResponse]:
|
|
392
|
+
"""Send a chat request to an assistant by slug.
|
|
393
|
+
|
|
394
|
+
Args:
|
|
395
|
+
assistant_slug: Slug of the assistant to chat with
|
|
396
|
+
request: Chat request details
|
|
397
|
+
headers: Optional additional HTTP headers (e.g., X-* for MCP propagation)
|
|
398
|
+
|
|
399
|
+
Returns:
|
|
400
|
+
Chat response or streaming response
|
|
401
|
+
"""
|
|
402
|
+
pydantic_schema = None
|
|
403
|
+
if (
|
|
404
|
+
request.output_schema is not None
|
|
405
|
+
and inspect.isclass(request.output_schema)
|
|
406
|
+
and issubclass(request.output_schema, BaseModel)
|
|
407
|
+
):
|
|
408
|
+
pydantic_schema = deepcopy(request.output_schema)
|
|
409
|
+
request.output_schema = request.output_schema.model_json_schema()
|
|
410
|
+
|
|
411
|
+
response = self._api.post(
|
|
412
|
+
f"/v1/assistants/slug/{assistant_slug}/model",
|
|
413
|
+
BaseModelResponse,
|
|
414
|
+
json_data=request.model_dump(exclude_none=True, by_alias=True),
|
|
415
|
+
stream=request.stream,
|
|
416
|
+
extra_headers=headers,
|
|
417
|
+
)
|
|
418
|
+
if not request.stream and pydantic_schema:
|
|
419
|
+
response.generated = pydantic_schema.model_validate(response.generated)
|
|
420
|
+
|
|
421
|
+
return response
|
|
422
|
+
|
|
209
423
|
def upload_file_to_chat(self, file_path: Path):
|
|
210
424
|
"""Upload a file to assistant chat and return the response containing file_url."""
|
|
211
425
|
|