amigo_sdk 0.9.0__py3-none-any.whl → 0.11.0__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.
amigo_sdk/__init__.py CHANGED
@@ -1,8 +1,4 @@
1
- __version__ = "0.9.0"
1
+ __version__ = "0.11.0"
2
2
  from .sdk_client import AmigoClient, AsyncAmigoClient
3
3
 
4
- __all__ = [
5
- "__version__",
6
- "AmigoClient",
7
- "AsyncAmigoClient",
8
- ]
4
+ __all__ = ["__version__", "AmigoClient", "AsyncAmigoClient"]
@@ -1,6 +1,6 @@
1
1
  # generated by datamodel-codegen:
2
2
  # filename: <stdin>
3
- # timestamp: 2025-08-25T20:27:06+00:00
3
+ # timestamp: 2025-08-27T15:09:46+00:00
4
4
 
5
5
  from __future__ import annotations
6
6
 
@@ -9078,6 +9078,11 @@ class ToolInstance(BaseModel):
9078
9078
  )
9079
9079
 
9080
9080
 
9081
+ class ToolVersionInstanceToolRepo(Enum):
9082
+ main = 'main'
9083
+ team = 'team'
9084
+
9085
+
9081
9086
  class TotalARRMetricInput(BaseModel):
9082
9087
  type: Literal['total-arr'] = Field(..., title='Type')
9083
9088
 
@@ -9453,11 +9458,17 @@ class AmigoLibPydanticBaseModelStrippedNonemptyString1(RootModel[str]):
9453
9458
  root: str = Field(..., min_length=1)
9454
9459
 
9455
9460
 
9456
- class AmigoLibPydanticBaseModelStrippedNonemptyString2(RootModel[str]):
9457
- root: str = Field(..., max_length=256, min_length=1)
9461
+ class AmigoLibPydanticBaseModelStrippedNonemptyString2(
9462
+ AmigoLibPydanticBaseModelStrippedNonemptyString1
9463
+ ):
9464
+ pass
9458
9465
 
9459
9466
 
9460
9467
  class AmigoLibPydanticBaseModelStrippedNonemptyString3(RootModel[str]):
9468
+ root: str = Field(..., max_length=256, min_length=1)
9469
+
9470
+
9471
+ class AmigoLibPydanticBaseModelStrippedNonemptyString4(RootModel[str]):
9461
9472
  root: str = Field(..., max_length=3, min_length=1)
9462
9473
 
9463
9474
 
@@ -9785,7 +9796,7 @@ class MetricUpdateMetricRequest(BaseModel):
9785
9796
 
9786
9797
 
9787
9798
  class OrganizationCreateAgentRequest(BaseModel):
9788
- agent_name: AmigoLibPydanticBaseModelStrippedNonemptyString2 = Field(
9799
+ agent_name: AmigoLibPydanticBaseModelStrippedNonemptyString3 = Field(
9789
9800
  ..., description='The name of the new agent.'
9790
9801
  )
9791
9802
 
@@ -10472,7 +10483,7 @@ class OrganizationCreateOrganizationResponse(BaseModel):
10472
10483
 
10473
10484
 
10474
10485
  class OrganizationCreateServiceHierarchicalStateMachineRequest(BaseModel):
10475
- state_machine_name: AmigoLibPydanticBaseModelStrippedNonemptyString2 = Field(
10486
+ state_machine_name: AmigoLibPydanticBaseModelStrippedNonemptyString3 = Field(
10476
10487
  ..., description='The name of the new state machine.'
10477
10488
  )
10478
10489
 
@@ -11082,11 +11093,6 @@ class ToolModifyToolRequest(BaseModel):
11082
11093
  )
11083
11094
 
11084
11095
 
11085
- class ToolPublishToolVersionRequestBranch(Enum):
11086
- main = 'main'
11087
- team = 'team'
11088
-
11089
-
11090
11096
  class ToolPublishToolVersionRequestBumpType(Enum):
11091
11097
  major = 'major'
11092
11098
  minor = 'minor'
@@ -11094,10 +11100,10 @@ class ToolPublishToolVersionRequestBumpType(Enum):
11094
11100
 
11095
11101
 
11096
11102
  class ToolPublishToolVersionRequest(BaseModel):
11097
- branch: ToolPublishToolVersionRequestBranch = Field(
11103
+ repo: ToolVersionInstanceToolRepo = Field(
11098
11104
  ...,
11099
- description="The branch of the tools repo to publish the tool version from. If `team`, then it's published from the release branch of the organization's\nAzure DevOps team. If `main`, then it's published from the main branch of the tools repo.",
11100
- title='Branch',
11105
+ description="The repo to publish the tool version from. If `team`, then it's published from the repo of the organization's Azure DevOps team. If `main`, then it's published\nfrom the `tools-main` repo.",
11106
+ title='Repo',
11101
11107
  )
11102
11108
  project_path: str = Field(
11103
11109
  ...,
@@ -11642,7 +11648,7 @@ class GetConversationMessagesParametersQuery(BaseModel):
11642
11648
  [], description='The IDs of the messages to retrieve.', title='Id'
11643
11649
  )
11644
11650
  message_type: Optional[List[MessageType]] = Field(
11645
- ['agent-message', 'external-event', 'user-message'],
11651
+ ['external-event', 'user-message', 'agent-message'],
11646
11652
  description='The type of messages to retrieve.',
11647
11653
  title='Message Type',
11648
11654
  )
@@ -13786,14 +13792,14 @@ class ToolVersionInstance(BaseModel):
13786
13792
  input_schema: Dict[str, Any] = Field(
13787
13793
  ..., description='The input schema of the tool.', title='Input Schema'
13788
13794
  )
13789
- tool_branch_name: str = Field(
13795
+ tool_repo: ToolVersionInstanceToolRepo = Field(
13790
13796
  ...,
13791
- description='The name of the branch in the tool repository that this version corresponds to.',
13792
- title='Tool Branch Name',
13797
+ description='Whether this tool is published from the main repository or the team-specific repository.',
13798
+ title='Tool Repo',
13793
13799
  )
13794
13800
  tool_commit_hash: str = Field(
13795
13801
  ...,
13796
- description='The commit hash of the tool within the `tool_branch_name`.',
13802
+ description='The commit hash of the tool within the repository.',
13797
13803
  title='Tool Commit Hash',
13798
13804
  )
13799
13805
  amigo_scaffold_commit_hash: str = Field(
@@ -14205,7 +14211,7 @@ class OrganizationCreateOrganizationRequest(BaseModel):
14205
14211
  title='Onboarding Instructions',
14206
14212
  )
14207
14213
  )
14208
- azure_devops_team_name: AmigoLibPydanticBaseModelStrippedNonemptyString1 = Field(
14214
+ azure_devops_team_name: AmigoLibPydanticBaseModelStrippedNonemptyString2 = Field(
14209
14215
  ...,
14210
14216
  description="The name of the Azure DevOps team to create (if it doesn't exist) for this organization. All orgs with the same Azure DevOps team name will share access to the same Azure DevOps resources, namely\nthe source code for tools.",
14211
14217
  )
@@ -14353,7 +14359,7 @@ class OrganizationModifyOrganizationRequest(BaseModel):
14353
14359
 
14354
14360
 
14355
14361
  class RoleCreateRoleRequest(BaseModel):
14356
- role_name: AmigoLibPydanticBaseModelStrippedNonemptyString2 = Field(
14362
+ role_name: AmigoLibPydanticBaseModelStrippedNonemptyString3 = Field(
14357
14363
  ...,
14358
14364
  description='The name of the role to create. The role must have a max length of 256 characters.',
14359
14365
  )
@@ -15206,7 +15212,7 @@ class MetricSearchMetricsResponse(BaseModel):
15206
15212
 
15207
15213
 
15208
15214
  class OrganizationCreateAgentVersionRequest(BaseModel):
15209
- initials: Optional[AmigoLibPydanticBaseModelStrippedNonemptyString3] = Field(
15215
+ initials: Optional[AmigoLibPydanticBaseModelStrippedNonemptyString4] = Field(
15210
15216
  None, description="The agent's initials."
15211
15217
  )
15212
15218
  identity: Optional[IdentityInput] = Field(
amigo_sdk/http_client.py CHANGED
@@ -1,6 +1,7 @@
1
1
  import asyncio
2
2
  import datetime as dt
3
3
  import random
4
+ import threading
4
5
  import time
5
6
  from collections.abc import AsyncIterator, Iterator
6
7
  from dataclasses import dataclass
@@ -333,7 +334,7 @@ class AmigoHttpClient:
333
334
  self,
334
335
  method: str,
335
336
  path: str,
336
- abort_flag: list[bool] | None = None,
337
+ abort_event: threading.Event | None = None,
337
338
  **kwargs,
338
339
  ) -> Iterator[str]:
339
340
  kwargs.setdefault("headers", {})
@@ -343,23 +344,23 @@ class AmigoHttpClient:
343
344
 
344
345
  def _yield_from_response(resp: httpx.Response) -> Iterator[str]:
345
346
  _raise_status_with_body_sync(resp)
346
- if abort_flag and abort_flag[0]:
347
+ if abort_event and abort_event.is_set():
347
348
  return
348
349
  for line in resp.iter_lines():
349
- if abort_flag and abort_flag[0]:
350
+ if abort_event and abort_event.is_set():
350
351
  return
351
352
  line_stripped = (line or "").strip()
352
353
  if not line_stripped:
353
354
  continue
354
355
  yield line_stripped
355
356
 
356
- if abort_flag and abort_flag[0]:
357
+ if abort_event and abort_event.is_set():
357
358
  return iter(())
358
359
  with self._client.stream(method, path, **kwargs) as resp:
359
360
  if resp.status_code == 401:
360
361
  self._token = None
361
362
  headers["Authorization"] = f"Bearer {self._ensure_token()}"
362
- if abort_flag and abort_flag[0]:
363
+ if abort_event and abort_event.is_set():
363
364
  return iter(())
364
365
  with self._client.stream(method, path, **kwargs) as retry_resp:
365
366
  for ln in _yield_from_response(retry_resp):
amigo_sdk/models.py ADDED
@@ -0,0 +1 @@
1
+ from .generated.model import * # noqa: F403
@@ -1,4 +1,5 @@
1
1
  import asyncio
2
+ import threading
2
3
  from collections.abc import AsyncGenerator, Iterator
3
4
  from datetime import datetime
4
5
  from typing import Any, Literal
@@ -219,7 +220,7 @@ class ConversationResource:
219
220
  self,
220
221
  body: ConversationCreateConversationRequest,
221
222
  params: CreateConversationParametersQuery,
222
- abort_flag: list[bool] | None = None,
223
+ abort_event: threading.Event | None = None,
223
224
  ) -> Iterator[ConversationCreateConversationResponse]:
224
225
  def _iter():
225
226
  for line in self._http.stream_lines(
@@ -228,7 +229,7 @@ class ConversationResource:
228
229
  params=params.model_dump(mode="json", exclude_none=True),
229
230
  json=body.model_dump(mode="json", exclude_none=True),
230
231
  headers={"Accept": "application/x-ndjson"},
231
- abort_flag=abort_flag,
232
+ abort_event=abort_event,
232
233
  ):
233
234
  yield ConversationCreateConversationResponse.model_validate_json(line)
234
235
 
@@ -238,7 +239,7 @@ class ConversationResource:
238
239
  self,
239
240
  conversation_id: str,
240
241
  params: InteractWithConversationParametersQuery,
241
- abort_flag: list[bool] | None = None,
242
+ abort_event: threading.Event | None = None,
242
243
  *,
243
244
  text_message: str | None = None,
244
245
  audio_bytes: bytes | None = None,
@@ -248,7 +249,7 @@ class ConversationResource:
248
249
  request_kwargs: dict[str, Any] = {
249
250
  "params": params.model_dump(mode="json", exclude_none=True),
250
251
  "headers": {"Accept": "application/x-ndjson"},
251
- "abort_flag": abort_flag,
252
+ "abort_event": abort_event,
252
253
  }
253
254
  req_format = getattr(params, "request_format", None)
254
255
  if req_format == Format.text:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: amigo_sdk
3
- Version: 0.9.0
3
+ Version: 0.11.0
4
4
  Summary: Amigo AI Python SDK
5
5
  Author: Amigo AI
6
6
  License-File: LICENSE
@@ -50,7 +50,7 @@ This SDK auto-generates its types from the latest [Amigo OpenAPI schema](https:/
50
50
 
51
51
  ```python
52
52
  from amigo_sdk import AmigoClient
53
- from amigo_sdk.generated.model import GetConversationsParametersQuery
53
+ from amigo_sdk.models import GetConversationsParametersQuery
54
54
 
55
55
  # Initialize and use the client synchronously
56
56
  with AmigoClient(
@@ -65,9 +65,38 @@ with AmigoClient(
65
65
  print("Conversations:", conversations)
66
66
  ```
67
67
 
68
+ ## Quick Start (async)
69
+
70
+ ```python
71
+ import asyncio
72
+
73
+ from amigo_sdk import AsyncAmigoClient
74
+ from amigo_sdk.models import GetConversationsParametersQuery
75
+
76
+
77
+ async def main():
78
+ async with AsyncAmigoClient(
79
+ api_key="your-api-key",
80
+ api_key_id="your-api-key-id",
81
+ user_id="user-id",
82
+ organization_id="your-organization-id",
83
+ ) as client:
84
+ conversations = await client.conversation.get_conversations(
85
+ GetConversationsParametersQuery(limit=10, sort_by=["-created_at"])
86
+ )
87
+ print("Conversations:", conversations)
88
+
89
+
90
+ asyncio.run(main())
91
+ ```
92
+
68
93
  ## Examples
69
94
 
70
- For more SDK usage examples see checkout the [examples/](examples/README.md) folder.
95
+ For more SDK usage examples see the [examples overview](examples/README.md). Direct links:
96
+
97
+ - **Conversation (sync)**: [examples/conversation/conversation.py](examples/conversation/conversation.py)
98
+ - **Conversation (async)**: [examples/conversation/conversation_async.py](examples/conversation/conversation_async.py)
99
+ - **User management (sync)**: [examples/user/user-management.py](examples/user/user-management.py)
71
100
 
72
101
  ## Configuration
73
102
 
@@ -133,6 +162,43 @@ The SDK provides access to the following resources:
133
162
  - **Conversation**: Manage conversations
134
163
  - **User**: Manage users
135
164
 
165
+ ## Generated types
166
+
167
+ The SDK ships with Pydantic models generated from the latest OpenAPI schema.
168
+
169
+ - **Importing types**: Import directly from `amigo_sdk.models`
170
+
171
+ ```python
172
+ from amigo_sdk.models import (
173
+ GetConversationsParametersQuery,
174
+ ConversationCreateConversationRequest,
175
+ GetUsersParametersQuery,
176
+ )
177
+ ```
178
+
179
+ - **Using types when calling SDK functions**: Pass request/query models to resource methods.
180
+
181
+ ```python
182
+ from amigo_sdk import AmigoClient
183
+ from amigo_sdk.models import GetConversationsParametersQuery
184
+
185
+ with AmigoClient() as client:
186
+ conversations = client.conversation.get_conversations(
187
+ GetConversationsParametersQuery(limit=20, sort_by=["-created_at"])
188
+ )
189
+ ```
190
+
191
+ - **Parsing returned objects**: Responses are Pydantic models. Access fields directly or convert to dict/JSON.
192
+
193
+ ```python
194
+ # Access fields
195
+ first = conversations.conversations[0]
196
+ print(first.id, first.created_at)
197
+
198
+ # Convert to plain dict for logging/serialization
199
+ print(first.model_dump(mode="json"))
200
+ ```
201
+
136
202
  ## Error Handling
137
203
 
138
204
  The SDK provides typed error handling:
@@ -162,6 +228,20 @@ except Exception as error:
162
228
  print("Unexpected error:", error)
163
229
  ```
164
230
 
231
+ ## Retries
232
+
233
+ The HTTP client includes sensible, configurable retries:
234
+
235
+ - **Defaults**:
236
+
237
+ - max attempts: 3
238
+ - backoff base: 0.25s (exponential with full jitter)
239
+ - max delay per attempt: 30s
240
+ - retry on status: {408, 429, 500, 502, 503, 504}
241
+ - retry on methods: {"GET"}
242
+ - special-case: POST is retried on 429 when `Retry-After` is present
243
+ - 401 triggers a one-time token refresh and immediate retry
244
+
165
245
  ## Development
166
246
 
167
247
  For detailed development setup, testing, and contribution guidelines, see [CONTRIBUTING.md](CONTRIBUTING.md).
@@ -0,0 +1,18 @@
1
+ amigo_sdk/__init__.py,sha256=MNEge8Pwx6KfzTaKsnEQdwJ4t9xpa5JWOMZude9UL70,139
2
+ amigo_sdk/_retry_utils.py,sha256=kFjw9Wqye6MB5-B4rjLxsbSNcfYBIztcollIoncd1hY,2142
3
+ amigo_sdk/auth.py,sha256=WaM9PcEcnaC6CzNsgRKueHkdSAxNbRylzpR_3Q6guQ0,1765
4
+ amigo_sdk/config.py,sha256=0eZIo-hcJ8ODftKAr-mwB-FGJxGO5PT5T4dRpyWPqAg,1491
5
+ amigo_sdk/errors.py,sha256=RkRyF5eAASd8fIOS6YvL9rLDvLAYWqHfpHSCR7jqvl4,4840
6
+ amigo_sdk/http_client.py,sha256=v25UoUbXcMeHTnfJMcrl8RSSwCVkKUL1Jv-0HoXP1B4,13507
7
+ amigo_sdk/models.py,sha256=V-G6iL43_ZNOPDcatCJCSszGWGz-nzp_RSyGNm-rBAc,45
8
+ amigo_sdk/sdk_client.py,sha256=Kr9M9o66pOLu0T2VDvqdYMmPZzgKJyTELu7BSPgGrYQ,6152
9
+ amigo_sdk/generated/model.py,sha256=1iw7NL8cMOWN8KcYP_P3oai0JMWgwhjSWVEZAb2BWy4,427233
10
+ amigo_sdk/resources/conversation.py,sha256=5PkJOvLKqnriSS9K9hKw2VRPxRLTuABEbCyPy1fz1r0,14817
11
+ amigo_sdk/resources/organization.py,sha256=yX4UlOHNegRzFW4gCJrCxjiLCAGnGegasjviR1yad_Q,1211
12
+ amigo_sdk/resources/service.py,sha256=SiwEHXCQk4r1b_tGv47M08VuB7RALDHJQzWlpuD937g,1571
13
+ amigo_sdk/resources/user.py,sha256=i4t5aVzBI37KwAtLKSDWTMwf4D4KQdSDoUiblFe1u7o,3529
14
+ amigo_sdk-0.11.0.dist-info/METADATA,sha256=blllxaFKFVLxLkoEmft0TnniC8_6Qg_yEi_Xwgc2uO4,8350
15
+ amigo_sdk-0.11.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
16
+ amigo_sdk-0.11.0.dist-info/entry_points.txt,sha256=ivKZ8S9W6SH796zUDHeM-qHodrwmkmUItophi-jJWK0,82
17
+ amigo_sdk-0.11.0.dist-info/licenses/LICENSE,sha256=tx3FiTVbGxwBUOxQbNh05AAQlC2jd5hGvNpIkSfVbCo,1062
18
+ amigo_sdk-0.11.0.dist-info/RECORD,,
@@ -1,17 +0,0 @@
1
- amigo_sdk/__init__.py,sha256=kCOODDDBTcYl4OwHYOLi80txgJizsTwkNb49c88xU0M,153
2
- amigo_sdk/_retry_utils.py,sha256=kFjw9Wqye6MB5-B4rjLxsbSNcfYBIztcollIoncd1hY,2142
3
- amigo_sdk/auth.py,sha256=WaM9PcEcnaC6CzNsgRKueHkdSAxNbRylzpR_3Q6guQ0,1765
4
- amigo_sdk/config.py,sha256=0eZIo-hcJ8ODftKAr-mwB-FGJxGO5PT5T4dRpyWPqAg,1491
5
- amigo_sdk/errors.py,sha256=RkRyF5eAASd8fIOS6YvL9rLDvLAYWqHfpHSCR7jqvl4,4840
6
- amigo_sdk/http_client.py,sha256=z8h8FKHRxGzULRz_C60mL5PfYSAv8e_RHUndVo0vHrM,13452
7
- amigo_sdk/sdk_client.py,sha256=Kr9M9o66pOLu0T2VDvqdYMmPZzgKJyTELu7BSPgGrYQ,6152
8
- amigo_sdk/generated/model.py,sha256=jYhncFPqXUiwOSmV6OJT82TpkmjG5LZH_gFRFr7mTEs,427161
9
- amigo_sdk/resources/conversation.py,sha256=pGM2vtUsem8ClVfzZne1qqKZdM4o7aWaRdAYXXKEMFw,14784
10
- amigo_sdk/resources/organization.py,sha256=yX4UlOHNegRzFW4gCJrCxjiLCAGnGegasjviR1yad_Q,1211
11
- amigo_sdk/resources/service.py,sha256=SiwEHXCQk4r1b_tGv47M08VuB7RALDHJQzWlpuD937g,1571
12
- amigo_sdk/resources/user.py,sha256=i4t5aVzBI37KwAtLKSDWTMwf4D4KQdSDoUiblFe1u7o,3529
13
- amigo_sdk-0.9.0.dist-info/METADATA,sha256=KOQJZyfLcA-ZbG8w22B24yP4XUvUDiUbeUct_4gWMyE,5982
14
- amigo_sdk-0.9.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
15
- amigo_sdk-0.9.0.dist-info/entry_points.txt,sha256=ivKZ8S9W6SH796zUDHeM-qHodrwmkmUItophi-jJWK0,82
16
- amigo_sdk-0.9.0.dist-info/licenses/LICENSE,sha256=tx3FiTVbGxwBUOxQbNh05AAQlC2jd5hGvNpIkSfVbCo,1062
17
- amigo_sdk-0.9.0.dist-info/RECORD,,