codemie-sdk-python 0.1.703__py3-none-any.whl → 0.1.705__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 CHANGED
@@ -170,8 +170,8 @@ from .models.integration import (
170
170
  from .models.a2a import (
171
171
  AgentCard,
172
172
  AgentProvider,
173
+ AgentInterface,
173
174
  AgentCapabilities,
174
- AgentAuthentication,
175
175
  AgentSkill,
176
176
  )
177
177
  from .services.a2a import A2AService
@@ -307,8 +307,8 @@ __all__ = [
307
307
  "TypeOfIntegration",
308
308
  "AgentCard",
309
309
  "AgentProvider",
310
+ "AgentInterface",
310
311
  "AgentCapabilities",
311
- "AgentAuthentication",
312
312
  "AgentSkill",
313
313
  "A2AService",
314
314
  ]
@@ -33,6 +33,7 @@ from ..services.mcp_configs import MCPConfigsService
33
33
  from ..services.cost_center import CostCenterService
34
34
  from ..services.customer_config_service import CustomerConfigService
35
35
  from ..services.project_budget_groups import ProjectBudgetGroupsService
36
+ from ..services.servicenow_integration import ServiceNowIntegrationService
36
37
 
37
38
 
38
39
  class CodeMieClient:
@@ -183,6 +184,9 @@ class CodeMieClient:
183
184
  self.project_budget_groups = ProjectBudgetGroupsService(
184
185
  self._api_domain, _token_source, verify_ssl=self._verify_ssl
185
186
  )
187
+ self.servicenow_integration = ServiceNowIntegrationService(
188
+ self._api_domain, _token_source, verify_ssl=self._verify_ssl
189
+ )
186
190
  self.a2a = A2AService(
187
191
  self._api_domain, _token_source, verify_ssl=self._verify_ssl
188
192
  )
codemie_sdk/models/a2a.py CHANGED
@@ -1,4 +1,6 @@
1
- """A2A (agent-to-agent) models."""
1
+ """A2A (agent-to-agent) models (protocol v1.0)."""
2
+
3
+ from typing import Any
2
4
 
3
5
  from pydantic import BaseModel, ConfigDict
4
6
 
@@ -8,27 +10,28 @@ class AgentProvider(BaseModel):
8
10
 
9
11
  model_config = ConfigDict(extra="ignore")
10
12
 
11
- organization: str
13
+ organization: str | None = None
12
14
  url: str | None = None
13
15
 
14
16
 
15
- class AgentCapabilities(BaseModel):
16
- """Capabilities advertised by an A2A agent card."""
17
+ class AgentInterface(BaseModel):
18
+ """A transport interface the agent exposes."""
17
19
 
18
20
  model_config = ConfigDict(extra="ignore")
19
21
 
20
- streaming: bool = False
21
- pushNotifications: bool = False
22
- stateTransitionHistory: bool = False
22
+ url: str
23
+ protocolBinding: str | None = None
24
+ protocolVersion: str | None = None
23
25
 
24
26
 
25
- class AgentAuthentication(BaseModel):
26
- """Authentication schemes advertised by an A2A agent card."""
27
+ class AgentCapabilities(BaseModel):
28
+ """Capabilities advertised by an A2A agent card."""
27
29
 
28
30
  model_config = ConfigDict(extra="ignore")
29
31
 
30
- schemes: list[str]
31
- credentials: str | None = None
32
+ streaming: bool = False
33
+ pushNotifications: bool = False
34
+ extendedAgentCard: bool = False
32
35
 
33
36
 
34
37
  class AgentSkill(BaseModel):
@@ -52,12 +55,20 @@ class AgentCard(BaseModel):
52
55
 
53
56
  name: str
54
57
  description: str | None = None
55
- url: str
58
+ supportedInterfaces: list[AgentInterface]
56
59
  provider: AgentProvider | None = None
57
60
  version: str
58
61
  documentationUrl: str | None = None
59
62
  capabilities: AgentCapabilities
60
- authentication: AgentAuthentication | None = None
61
- defaultInputModes: list[str] = ["text"]
62
- defaultOutputModes: list[str] = ["text"]
63
+ securitySchemes: dict[str, dict[str, Any]] | None = None
64
+ securityRequirements: list[dict[str, Any]] | None = None
65
+ defaultInputModes: list[str] = []
66
+ defaultOutputModes: list[str] = []
63
67
  skills: list[AgentSkill]
68
+
69
+ @property
70
+ def protocol_version(self) -> str | None:
71
+ """Protocol version of the first advertised interface."""
72
+ if self.supportedInterfaces:
73
+ return self.supportedInterfaces[0].protocolVersion
74
+ return None
@@ -0,0 +1,103 @@
1
+ # Copyright 2026 EPAM Systems, Inc. ("EPAM")
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """ServiceNow integration models for the CodeMie SDK.
16
+
17
+ The integration endpoints are callable only by the ServiceNow integration service account.
18
+ The request model is deliberately permissive: the server owns the validation rules, so the
19
+ SDK sends what the caller gives it and surfaces the server's verdict as an HTTP error.
20
+ """
21
+
22
+ from enum import Enum
23
+
24
+ from pydantic import BaseModel, ConfigDict, Field
25
+
26
+
27
+ class ServiceNowBudgetAction(str, Enum):
28
+ """Budget action requested by ServiceNow."""
29
+
30
+ SET = "set"
31
+ ADJUST = "adjust"
32
+ CANCEL = "cancel"
33
+
34
+
35
+ class ServiceNowProject(BaseModel):
36
+ """A shared project returned by the project lookup."""
37
+
38
+ model_config = ConfigDict(extra="ignore")
39
+
40
+ project_name: str
41
+ display_name: str | None = None
42
+
43
+
44
+ class ServiceNowBudgetRequest(BaseModel):
45
+ """Request body for applying a ServiceNow budget request to a project.
46
+
47
+ Attributes:
48
+ action: ``set`` replaces the budget, ``adjust`` merges into it, ``cancel`` deletes it.
49
+ request_id: ServiceNow request number, used for audit logs and new budget names.
50
+ epam_project_code: EPAM project code; names the cost center when it differs from
51
+ the CodeMie project name.
52
+ codemie_project_name: CodeMie project to manage; the server defaults it to
53
+ ``epam_project_code`` when omitted.
54
+ admin_emails: People to make project admins (ignored by ``cancel``).
55
+ amounts: Monthly budget in USD per category (``platform``, ``cli``,
56
+ ``premium_models``); required for ``set`` and ``adjust``.
57
+ """
58
+
59
+ # Non-finite amounts are sent as the JSON constants NaN / Infinity instead of null,
60
+ # so the server, not the client, rejects them.
61
+ model_config = ConfigDict(ser_json_inf_nan="constants")
62
+
63
+ action: ServiceNowBudgetAction
64
+ request_id: str
65
+ epam_project_code: str
66
+ codemie_project_name: str | None = None
67
+ admin_emails: list[str] = Field(default_factory=list)
68
+ amounts: dict[str, float] | None = None
69
+
70
+
71
+ class ServiceNowBudgetCategory(BaseModel):
72
+ """Budget of one spend category in a budget response."""
73
+
74
+ model_config = ConfigDict(extra="ignore")
75
+
76
+ category: str
77
+ max_budget: float
78
+ soft_budget: float
79
+ budget_reset_at: str | None = None
80
+
81
+
82
+ class ServiceNowBudgetGroup(BaseModel):
83
+ """Budget of a project after the request, with its categories in a fixed order."""
84
+
85
+ model_config = ConfigDict(extra="ignore")
86
+
87
+ total_amount: float
88
+ budget_duration: str
89
+ categories: list[ServiceNowBudgetCategory]
90
+
91
+
92
+ class ServiceNowBudgetResponse(BaseModel):
93
+ """Outcome of a budget request."""
94
+
95
+ model_config = ConfigDict(extra="ignore")
96
+
97
+ project_name: str
98
+ cost_center: str | None = None
99
+ created_project: bool
100
+ created_cost_center: bool
101
+ budget: ServiceNowBudgetGroup | None = None
102
+ admins_assigned: list[str] = Field(default_factory=list)
103
+ admins_pending: list[str] = Field(default_factory=list)
@@ -27,7 +27,7 @@ class A2AService:
27
27
  AgentCard: agent discovery metadata for the assistant
28
28
  """
29
29
  return self._api.get(
30
- f"/v1/a2a/assistants/{assistant_id}/.well-known/agent.json",
30
+ f"/v1/a2a/assistants/{assistant_id}/.well-known/agent-card.json",
31
31
  AgentCard,
32
32
  wrap_response=False,
33
33
  )
@@ -0,0 +1,90 @@
1
+ # Copyright 2026 EPAM Systems, Inc. ("EPAM")
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ """ServiceNow integration service for the CodeMie SDK."""
16
+
17
+ from ..models.servicenow_integration import (
18
+ ServiceNowBudgetRequest,
19
+ ServiceNowBudgetResponse,
20
+ ServiceNowProject,
21
+ )
22
+ from ..utils.http import ApiRequestHandler, TokenSource
23
+
24
+
25
+ class ServiceNowIntegrationService:
26
+ """Service for the ServiceNow integration endpoints.
27
+
28
+ Only the ServiceNow integration service account may call these endpoints; any other
29
+ caller is rejected with HTTP 403.
30
+ """
31
+
32
+ def __init__(self, api_domain: str, token: TokenSource, verify_ssl: bool = True):
33
+ """Initialize the ServiceNowIntegrationService.
34
+
35
+ Args:
36
+ api_domain: Base URL for the CodeMie API
37
+ token: Authentication token
38
+ verify_ssl: Whether to verify SSL certificates
39
+ """
40
+ self._api = ApiRequestHandler(api_domain, token, verify_ssl)
41
+
42
+ def list_projects(self, emails: list[str]) -> list[ServiceNowProject]:
43
+ """List the shared projects that any of the given users belong to.
44
+
45
+ The result is the distinct union across all emails, ordered by project name.
46
+ Emails with no active CodeMie user are skipped, and an empty list is returned
47
+ when none match. The emails are sent as given; the server rejects an empty
48
+ list or an invalid email with HTTP 422.
49
+
50
+ Args:
51
+ emails: Requester and approver emails
52
+
53
+ Returns:
54
+ List of ServiceNowProject with the project name and display name
55
+
56
+ Raises:
57
+ HTTPError: If the request fails
58
+ """
59
+ return self._api.get(
60
+ "/v1/integrations/servicenow/projects",
61
+ response_model=list[ServiceNowProject],
62
+ params={"emails": emails},
63
+ wrap_response=False,
64
+ )
65
+
66
+ def submit_budget_request(
67
+ self, request: ServiceNowBudgetRequest
68
+ ) -> ServiceNowBudgetResponse:
69
+ """Apply a ServiceNow budget request to a project.
70
+
71
+ ``set`` replaces the project budget, ``adjust`` merges into it and ``cancel``
72
+ deletes it. The project (and its cost center) is created when it does not exist,
73
+ and every resolvable ``admin_emails`` user becomes a project admin.
74
+
75
+ Args:
76
+ request: The budget request
77
+
78
+ Returns:
79
+ ServiceNowBudgetResponse with the resolved project, cost center, the budget
80
+ after the request (None after cancel) and the admin assignment outcome
81
+
82
+ Raises:
83
+ HTTPError: If the request is rejected (400, 403, 404, 409 or 422)
84
+ """
85
+ return self._api.post(
86
+ "/v1/integrations/servicenow/budgets",
87
+ response_model=ServiceNowBudgetResponse,
88
+ data=request.model_dump_json(exclude_none=True),
89
+ wrap_response=False,
90
+ )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codemie-sdk-python
3
- Version: 0.1.703
3
+ Version: 0.1.705
4
4
  Summary: CodeMie SDK for Python
5
5
  License: Apache-2.0
6
6
  Author: CodeMie
@@ -1,4 +1,4 @@
1
- codemie_sdk/__init__.py,sha256=JW5k_uftXXpJOnR5r5gCGBZqyYXqXfjRQD6nqRcUfDk,9024
1
+ codemie_sdk/__init__.py,sha256=b3eCiXsjw_q4eubzF97OEDYNJKMq4U98ekRNgvqmcuo,9014
2
2
  codemie_sdk/auth/__init__.py,sha256=IksEj223xEZtJ-cQ0AT9L0Bs9psIJ8QNzDXrPTUQ3xQ,126
3
3
  codemie_sdk/auth/credentials.py,sha256=hO0X3EQWZSlIm0ABhiJo4fIIndm2blB0JZWMaWvsuTE,7774
4
4
  codemie_sdk/builders/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -7,10 +7,10 @@ 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=3v4uRF4SGGxR5Rs6fPQRbyysbKI_QEvrTB6wJH3MUN4,9770
10
+ codemie_sdk/client/client.py,sha256=GCTLzF2CPtWI3QPMDerBcQpHuuBx06iQabP4__8SRq0,9996
11
11
  codemie_sdk/exceptions.py,sha256=uuzvtvYBMzrNGt7Q4k5RVq0Pd8eJ_tR2tLy3pF2ICDs,1148
12
12
  codemie_sdk/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- codemie_sdk/models/a2a.py,sha256=zCNLiwwg78rok04hMlGPcQQS1IbEV4OaMcA_1KxQ9xs,1588
13
+ codemie_sdk/models/a2a.py,sha256=93GGBg4vkrlnuGCtakMLgYtrD9U54Dme9Dm5sJGO2bc,1986
14
14
  codemie_sdk/models/activity_event.py,sha256=KDEzzUEfs1J9ALNo4mLP-Rq7jeTM4g-P4A5A7Z4YjzM,1072
15
15
  codemie_sdk/models/admin.py,sha256=2UGaO60ZrHHcDcV9thYBVxDyUCvtfPQhs10WswhGFJs,2298
16
16
  codemie_sdk/models/analytics.py,sha256=B9lLAddL_LylXsoOukiPqbz4HVd2itmuB6iaEbhpKiQ,10194
@@ -28,6 +28,7 @@ codemie_sdk/models/llm.py,sha256=ViADvsSAkc85YQyPUkGE3ZvMc5pnHWHO0_rOkLSTfu4,133
28
28
  codemie_sdk/models/mcp_config.py,sha256=lqHEYNWW6MhZEx2tMTryVTfq_wThnmMS7vmWxtPkbYM,3792
29
29
  codemie_sdk/models/mermaid.py,sha256=dhRgX-itvfyrt0LUg5pbSo0CTH5PewiegqcZn3hWggU,675
30
30
  codemie_sdk/models/project.py,sha256=9nMsPNw0mUHud2sAISXrJx2lXz9VKw2Dn-ABq53UgZ8,7600
31
+ codemie_sdk/models/servicenow_integration.py,sha256=xE-QYCaEWsN3znEnw9CkGiRCsAlRzv1SME4rky9k-Y0,3531
31
32
  codemie_sdk/models/skill.py,sha256=KE4lsF8TMxIQa_UE0oRDMT6XIEHqKjsDyi0HYKEp1mM,6918
32
33
  codemie_sdk/models/task.py,sha256=YHu5DRnECS2wnqIWZ_YH8Z72p1I4aV3xWFW5joxN_8Q,1442
33
34
  codemie_sdk/models/user.py,sha256=YqPWzTgIKF-7Jw6aV7RD__su1iahEJPGaDR6Px-B4bU,3848
@@ -42,7 +43,7 @@ codemie_sdk/models/workflow_state.py,sha256=uP1yLYwPpgPc17xpLwjanvlRzK6zT9qMZR-f
42
43
  codemie_sdk/models/workflow_thoughts.py,sha256=9fE380lMvC23fq677EI_JTk48Nf2jyPg3-mpj9VTx54,579
43
44
  codemie_sdk/models/workflow_transition.py,sha256=axZeiwTo4wzEwZ5GuKphmlRpWmjIuKxV15P_4V1n7LQ,794
44
45
  codemie_sdk/models/workspace.py,sha256=xYnVO1Pnd0l0PSBe2pwP80C2ZvYBc2ESo6OH_G0cOOg,1438
45
- codemie_sdk/services/a2a.py,sha256=JI_heDKmQ1qYGIES_6qPosHRyVb73tKs4v7uTGpzXx4,1026
46
+ codemie_sdk/services/a2a.py,sha256=vxMistimImheSRWWqOP0hy7aiQnv0NjoQnkUchtm73c,1031
46
47
  codemie_sdk/services/activity_event.py,sha256=KoD0DyeqJ0CmQPA4PAXH4uGIAQCgcJbYwDnv-MCckGc,3630
47
48
  codemie_sdk/services/admin.py,sha256=yk1xdBXDjpdW4OMOdBaURkZhAxak9h-TppKyhStLekc,4006
48
49
  codemie_sdk/services/analytics.py,sha256=yTvBSzDPG2r0BCBukDlnnElvFxLNniyCb8qtYu6foZU,24328
@@ -61,6 +62,7 @@ codemie_sdk/services/mcp_configs.py,sha256=bfe0QTrMqE5hEvyUlNMCjTxqL7u0AG7aZloQr
61
62
  codemie_sdk/services/mermaid.py,sha256=7cLykdrJVW576raUbON3yhuWnbGaXl8rX1QfVwbu2JE,2246
62
63
  codemie_sdk/services/project.py,sha256=v58ALdLv4BuxMkZNlkNZPikkXcCIePMoQtmKwdKCgko,14703
63
64
  codemie_sdk/services/project_budget_groups.py,sha256=B7QJt3sh_LV3lfwALZlxUq0SLR30BWafHcS6eHyOh8Y,5471
65
+ codemie_sdk/services/servicenow_integration.py,sha256=UiMlyiSxegs4gY604rDlKTDxDymKMDP-GRZ85DRlbl8,3376
64
66
  codemie_sdk/services/skill.py,sha256=0mExdeKTMNqkEpKafD0ya1WyLj9CMCFaprkggKYqnQg,13216
65
67
  codemie_sdk/services/task.py,sha256=UaYh__xGF7VKWCJKPrncVjTvx46Gz1AN9XczPVL71oA,1052
66
68
  codemie_sdk/services/user.py,sha256=W0-fkY6vIbJDlIpb2PxxljSMOdWh910BmBK-n94gBs0,6998
@@ -76,6 +78,6 @@ codemie_sdk/services/workflow_execution_state.py,sha256=u1xmGvaHjqvQS5ujhyvJ_Ac7
76
78
  codemie_sdk/services/workspace.py,sha256=eLwZ0fhi1BfOesrXaQlTdOll8q7ENP9b_jb5eybKSVw,5038
77
79
  codemie_sdk/utils/__init__.py,sha256=EzK_UrS5KHmAnE73Hci9LaObB5omjVUhIq4svh0gfwo,137
78
80
  codemie_sdk/utils/http.py,sha256=PWejBKa5pwzQ5eLVhdN8lYKEu1B1QtwGTRmZfnGFL6c,14158
79
- codemie_sdk_python-0.1.703.dist-info/METADATA,sha256=hem1C48aGo9ij50PNpWpkdjzB4z5OOqJbQXi9NutqIA,47938
80
- codemie_sdk_python-0.1.703.dist-info/WHEEL,sha256=L-WvLdSBvJWHXv5zrQxDvNRnIgoBzLUpcbuiw19KCuQ,88
81
- codemie_sdk_python-0.1.703.dist-info/RECORD,,
81
+ codemie_sdk_python-0.1.705.dist-info/METADATA,sha256=8P2ENBdpCaIToRvdEandBFq2_wEeM_qdS5iNQjTVZZE,47938
82
+ codemie_sdk_python-0.1.705.dist-info/WHEEL,sha256=L-WvLdSBvJWHXv5zrQxDvNRnIgoBzLUpcbuiw19KCuQ,88
83
+ codemie_sdk_python-0.1.705.dist-info/RECORD,,