wiil-python 0.0.3__tar.gz → 0.0.5__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 (129) hide show
  1. {wiil_python-0.0.3 → wiil_python-0.0.5}/PKG-INFO +1 -1
  2. {wiil_python-0.0.3 → wiil_python-0.0.5}/pyproject.toml +1 -1
  3. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/client/http_client.py +6 -6
  4. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/business_mgt/service_appointment.py +4 -16
  5. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/service_mgt/__init__.py +15 -3
  6. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/service_mgt/dynamic_agent_status.py +10 -1
  7. wiil_python-0.0.5/wiil/resources/service_mgt/dynamic_phone_agent.py +312 -0
  8. wiil_python-0.0.5/wiil/resources/service_mgt/dynamic_web_agent.py +318 -0
  9. wiil_python-0.0.5/wiil/resources/service_mgt/provisioning_configs.py +338 -0
  10. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/service_mgt/support_models.py +31 -0
  11. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil_python.egg-info/PKG-INFO +1 -1
  12. wiil_python-0.0.3/wiil/resources/service_mgt/dynamic_phone_agent.py +0 -114
  13. wiil_python-0.0.3/wiil/resources/service_mgt/dynamic_web_agent.py +0 -108
  14. wiil_python-0.0.3/wiil/resources/service_mgt/provisioning_configs.py +0 -128
  15. {wiil_python-0.0.3 → wiil_python-0.0.5}/README.md +0 -0
  16. {wiil_python-0.0.3 → wiil_python-0.0.5}/setup.cfg +0 -0
  17. {wiil_python-0.0.3 → wiil_python-0.0.5}/setup.py +0 -0
  18. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/__init__.py +0 -0
  19. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/client/__init__.py +0 -0
  20. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/client/async_wiil_client.py +0 -0
  21. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/client/types.py +0 -0
  22. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/client/wiil_client.py +0 -0
  23. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/client/will_service.py +0 -0
  24. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/errors/__init__.py +0 -0
  25. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/errors/exceptions.py +0 -0
  26. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/__init__.py +0 -0
  27. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/account/__init__.py +0 -0
  28. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/account/organization.py +0 -0
  29. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/account/project.py +0 -0
  30. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/account/supported_business_verticals.py +0 -0
  31. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/assistant_setups/__init__.py +0 -0
  32. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/assistant_setups/assistant_setup_result.py +0 -0
  33. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/assistant_setups/base_assistant_setup.py +0 -0
  34. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/assistant_setups/phone_assistant_setup.py +0 -0
  35. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/assistant_setups/web_assistant_setup.py +0 -0
  36. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/base.py +0 -0
  37. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/business_mgt/__init__.py +0 -0
  38. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/business_mgt/appointment_additional_info.py +0 -0
  39. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/business_mgt/appointment_field_config.py +0 -0
  40. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/business_mgt/customer.py +0 -0
  41. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/business_mgt/menu_config.py +0 -0
  42. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/business_mgt/menu_order.py +0 -0
  43. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/business_mgt/order.py +0 -0
  44. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/business_mgt/product_config.py +0 -0
  45. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/business_mgt/product_order.py +0 -0
  46. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/business_mgt/property_config.py +0 -0
  47. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/business_mgt/property_inquiry.py +0 -0
  48. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/business_mgt/reservation.py +0 -0
  49. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/business_mgt/reservation_resource.py +0 -0
  50. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/business_mgt/service_config.py +0 -0
  51. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/business_mgt/service_person.py +0 -0
  52. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/conversation/__init__.py +0 -0
  53. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/conversation/conversation_config.py +0 -0
  54. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/conversation/conversation_message.py +0 -0
  55. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/conversation/translation_config.py +0 -0
  56. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/conversation/translation_conversation.py +0 -0
  57. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/request/__init__.py +0 -0
  58. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/request/paginated_query.py +0 -0
  59. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/request/paginated_result.py +0 -0
  60. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/service_mgt/__init__.py +0 -0
  61. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/service_mgt/agent_config.py +0 -0
  62. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/service_mgt/call_transfer_config.py +0 -0
  63. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/service_mgt/deployment_config.py +0 -0
  64. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/service_mgt/dynamic_setup/__init__.py +0 -0
  65. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/service_mgt/dynamic_setup/base_agent_setup.py +0 -0
  66. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/service_mgt/dynamic_setup/phone_agent_setup.py +0 -0
  67. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/service_mgt/dynamic_setup/web_agent_setup.py +0 -0
  68. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/service_mgt/instruction_config.py +0 -0
  69. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/service_mgt/interaction_channels.py +0 -0
  70. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/service_mgt/knowledge.py +0 -0
  71. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/service_mgt/phone_config.py +0 -0
  72. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/service_mgt/phone_number.py +0 -0
  73. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/service_mgt/provisioning_config.py +0 -0
  74. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/service_mgt/support_llm.py +0 -0
  75. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/service_mgt/voice_language.py +0 -0
  76. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/type_definitions/__init__.py +0 -0
  77. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/type_definitions/account_definitions.py +0 -0
  78. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/type_definitions/business_definitions.py +0 -0
  79. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/type_definitions/conversation_definitions.py +0 -0
  80. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/type_definitions/dynamic_fields/__init__.py +0 -0
  81. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/type_definitions/dynamic_fields/field_definition.py +0 -0
  82. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/type_definitions/dynamic_fields/field_types.py +0 -0
  83. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/type_definitions/knowledge_definitions.py +0 -0
  84. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/models/type_definitions/service_config_definitions.py +0 -0
  85. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/py.typed +0 -0
  86. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/__init__.py +0 -0
  87. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/account/__init__.py +0 -0
  88. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/account/organizations.py +0 -0
  89. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/account/projects.py +0 -0
  90. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/business_mgt/__init__.py +0 -0
  91. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/business_mgt/business_services.py +0 -0
  92. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/business_mgt/customers.py +0 -0
  93. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/business_mgt/menu_orders.py +0 -0
  94. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/business_mgt/menus.py +0 -0
  95. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/business_mgt/product_orders.py +0 -0
  96. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/business_mgt/products.py +0 -0
  97. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/business_mgt/property_config.py +0 -0
  98. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/business_mgt/property_inquiry.py +0 -0
  99. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/business_mgt/reservation_resources.py +0 -0
  100. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/business_mgt/reservations.py +0 -0
  101. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/business_mgt/service_appointments.py +0 -0
  102. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/service_mgt/agent_configs.py +0 -0
  103. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/service_mgt/conversation_configs.py +0 -0
  104. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/service_mgt/deployment_channels.py +0 -0
  105. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/service_mgt/deployment_configs.py +0 -0
  106. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/service_mgt/instruction_configs.py +0 -0
  107. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/service_mgt/knowledge_sources.py +0 -0
  108. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/service_mgt/phone_configs.py +0 -0
  109. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/service_mgt/telephony_provider.py +0 -0
  110. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/resources/service_mgt/translation_sessions.py +0 -0
  111. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/services/__init__.py +0 -0
  112. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/services/ott/__init__.py +0 -0
  113. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/services/ott/models.py +0 -0
  114. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/services/ott/service.py +0 -0
  115. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/services/translation/__init__.py +0 -0
  116. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/services/translation/models.py +0 -0
  117. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/services/translation/service.py +0 -0
  118. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/types/__init__.py +0 -0
  119. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/types/account_types.py +0 -0
  120. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/types/business_types.py +0 -0
  121. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/types/conversation_types.py +0 -0
  122. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/types/knowledge_types.py +0 -0
  123. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/types/paginated_quest.py +0 -0
  124. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/types/paginated_result.py +0 -0
  125. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil/types/service_types.py +0 -0
  126. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil_python.egg-info/SOURCES.txt +0 -0
  127. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil_python.egg-info/dependency_links.txt +0 -0
  128. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil_python.egg-info/requires.txt +0 -0
  129. {wiil_python-0.0.3 → wiil_python-0.0.5}/wiil_python.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wiil-python
3
- Version: 0.0.3
3
+ Version: 0.0.5
4
4
  Summary: Official Python SDK for WIIL Platform - AI-powered conversational services for intelligent customer interactions, voice processing, real-time translation, and business management
5
5
  Author-email: WIIL <dev-support@wiil.io>
6
6
  License: MIT
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "wiil-python"
7
- version = "0.0.3"
7
+ version = "0.0.5"
8
8
  description = "Official Python SDK for WIIL Platform - AI-powered conversational services for intelligent customer interactions, voice processing, real-time translation, and business management"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.8"
@@ -181,9 +181,9 @@ class HttpClient:
181
181
  try:
182
182
  if isinstance(data, dict):
183
183
  validated_data = schema(**data)
184
- data = validated_data.model_dump(exclude_none=True)
184
+ data = validated_data.model_dump(by_alias=True, exclude_none=True)
185
185
  elif isinstance(data, BaseModel):
186
- data = data.model_dump(exclude_none=True)
186
+ data = data.model_dump(by_alias=True, exclude_none=True)
187
187
  except ValidationError as e:
188
188
  raise WiilValidationError(
189
189
  'Request validation failed',
@@ -275,9 +275,9 @@ class HttpClient:
275
275
  try:
276
276
  if isinstance(data, dict):
277
277
  validated_data = schema(**data)
278
- data = validated_data.model_dump(exclude_none=True)
278
+ data = validated_data.model_dump(by_alias=True, exclude_none=True)
279
279
  elif isinstance(data, BaseModel):
280
- data = data.model_dump(exclude_none=True)
280
+ data = data.model_dump(by_alias=True, exclude_none=True)
281
281
  except ValidationError as e:
282
282
  raise WiilValidationError(
283
283
  'Request validation failed',
@@ -369,9 +369,9 @@ class HttpClient:
369
369
  try:
370
370
  if isinstance(data, dict):
371
371
  validated_data = schema(**data)
372
- data = validated_data.model_dump(exclude_none=True)
372
+ data = validated_data.model_dump(by_alias=True, exclude_none=True)
373
373
  elif isinstance(data, BaseModel):
374
- data = data.model_dump(exclude_none=True)
374
+ data = data.model_dump(by_alias=True, exclude_none=True)
375
375
  except ValidationError as e:
376
376
  raise WiilValidationError(
377
377
  'Request validation failed',
@@ -6,7 +6,7 @@ calendar integration and service provider assignment.
6
6
 
7
7
  from typing import Optional
8
8
 
9
- from pydantic import BaseModel as PydanticBaseModel
9
+ from pydantic import BaseModel as PydanticBaseModel
10
10
  from pydantic import ConfigDict, EmailStr, Field
11
11
 
12
12
  from wiil.models.base import BaseModel
@@ -154,12 +154,9 @@ class CreateServiceAppointment(PydanticBaseModel):
154
154
  create_data = CreateServiceAppointment(
155
155
  business_service_id="service_123",
156
156
  customer_id="cust_456",
157
- customer_name="Jane Smith",
158
- customer_email="jane@example.com",
159
157
  start_time=1234567890,
160
158
  duration=45,
161
- total_price=75.00,
162
- status=AppointmentStatus.PENDING
159
+ total_price=75.00
163
160
  )
164
161
  ```
165
162
  """
@@ -172,19 +169,15 @@ class CreateServiceAppointment(PydanticBaseModel):
172
169
 
173
170
  business_service_id: str = Field(..., alias="businessServiceId")
174
171
  customer_id: str = Field(..., alias="customerId")
175
- customer_name: Optional[str] = Field(None, alias="customerName")
176
- customer_email: Optional[EmailStr] = Field(None, alias="customerEmail")
177
172
  start_time: int = Field(..., alias="startTime")
178
173
  end_time: Optional[int] = Field(None, alias="endTime")
179
- duration: Optional[int] = Field(30, gt=0)
180
- total_price: Optional[float] = Field(0.0, ge=0, alias="totalPrice")
174
+ duration: Optional[int] = Field(None, gt=0)
175
+ total_price: Optional[float] = Field(None, ge=0, alias="totalPrice")
181
176
  deposit_paid: float = Field(0.0, ge=0, alias="depositPaid")
182
- status: AppointmentStatus = AppointmentStatus.PENDING
183
177
  assigned_user_account_id: Optional[str] = Field(None, alias="assignedUserAccountId")
184
178
  calendar_id: Optional[str] = Field(None, alias="calendarId")
185
179
  calendar_event_id: Optional[str] = Field(None, alias="calendarEventId")
186
180
  calendar_provider: Optional[CalendarProvider] = Field(None, alias="calendarProvider")
187
- service_conversation_config_id: Optional[str] = Field(None, alias="serviceConversationConfigId")
188
181
 
189
182
 
190
183
  class UpdateServiceAppointment(PydanticBaseModel):
@@ -196,7 +189,6 @@ class UpdateServiceAppointment(PydanticBaseModel):
196
189
  ```python
197
190
  update_data = UpdateServiceAppointment(
198
191
  id="appt_123",
199
- status=AppointmentStatus.COMPLETED,
200
192
  end_time=1234567950
201
193
  )
202
194
  ```
@@ -211,17 +203,13 @@ class UpdateServiceAppointment(PydanticBaseModel):
211
203
  id: str
212
204
  business_service_id: Optional[str] = Field(None, alias="businessServiceId")
213
205
  customer_id: Optional[str] = Field(None, alias="customerId")
214
- customer_name: Optional[str] = Field(None, alias="customerName")
215
- customer_email: Optional[EmailStr] = Field(None, alias="customerEmail")
216
206
  start_time: Optional[int] = Field(None, alias="startTime")
217
207
  end_time: Optional[int] = Field(None, alias="endTime")
218
208
  duration: Optional[int] = Field(None, gt=0)
219
209
  total_price: Optional[float] = Field(None, ge=0, alias="totalPrice")
220
210
  deposit_paid: Optional[float] = Field(None, ge=0, alias="depositPaid")
221
- status: Optional[AppointmentStatus] = None
222
211
  assigned_user_account_id: Optional[str] = Field(None, alias="assignedUserAccountId")
223
212
  calendar_id: Optional[str] = Field(None, alias="calendarId")
224
213
  calendar_event_id: Optional[str] = Field(None, alias="calendarEventId")
225
214
  calendar_provider: Optional[CalendarProvider] = Field(None, alias="calendarProvider")
226
215
  cancel_reason: Optional[str] = Field(None, alias="cancelReason")
227
- service_conversation_config_id: Optional[str] = Field(None, alias="serviceConversationConfigId")
@@ -19,9 +19,18 @@ from wiil.resources.service_mgt.translation_sessions import TranslationSessionsR
19
19
  from wiil.resources.service_mgt.knowledge_sources import KnowledgeSourcesResource
20
20
  from wiil.resources.service_mgt.support_models import SupportModelsResource
21
21
  from wiil.resources.service_mgt.telephony_provider import TelephonyProviderResource
22
- from wiil.resources.service_mgt.dynamic_agent_status import DynamicAgentStatusResource
23
- from wiil.resources.service_mgt.dynamic_web_agent import DynamicWebAgentResource
24
- from wiil.resources.service_mgt.dynamic_phone_agent import DynamicPhoneAgentResource
22
+ from wiil.resources.service_mgt.dynamic_agent_status import (
23
+ DynamicAgentStatusResource,
24
+ PollTimeoutError,
25
+ )
26
+ from wiil.resources.service_mgt.dynamic_web_agent import (
27
+ DynamicWebAgentResource,
28
+ WebAgentCreateOptions,
29
+ )
30
+ from wiil.resources.service_mgt.dynamic_phone_agent import (
31
+ DynamicPhoneAgentResource,
32
+ PhoneAgentCreateOptions,
33
+ )
25
34
 
26
35
  __all__ = [
27
36
  'AgentConfigurationsResource',
@@ -36,6 +45,9 @@ __all__ = [
36
45
  'SupportModelsResource',
37
46
  'TelephonyProviderResource',
38
47
  'DynamicAgentStatusResource',
48
+ 'PollTimeoutError',
39
49
  'DynamicWebAgentResource',
50
+ 'WebAgentCreateOptions',
40
51
  'DynamicPhoneAgentResource',
52
+ 'PhoneAgentCreateOptions',
41
53
  ]
@@ -2,10 +2,19 @@
2
2
 
3
3
  from wiil.client.http_client import HttpClient
4
4
  from wiil.models.service_mgt.dynamic_setup import (
5
+ DynamicAgentProcessingState,
5
6
  DynamicAgentSetupResult,
6
7
  )
7
8
 
8
9
 
10
+ class PollTimeoutError(Exception):
11
+ """Raised when polling times out before completion."""
12
+
13
+ def __init__(self, message: str, last_state: DynamicAgentProcessingState):
14
+ super().__init__(message)
15
+ self.last_state = last_state
16
+
17
+
9
18
  class DynamicAgentStatusResource:
10
19
  """Resource class for checking dynamic agent setup status.
11
20
 
@@ -32,4 +41,4 @@ class DynamicAgentStatusResource:
32
41
  )
33
42
 
34
43
 
35
- __all__ = ['DynamicAgentStatusResource']
44
+ __all__ = ['DynamicAgentStatusResource', 'PollTimeoutError']
@@ -0,0 +1,312 @@
1
+ """Dynamic Phone Agent resource for phone-based AI agents."""
2
+
3
+ import time
4
+ from dataclasses import dataclass
5
+ from typing import Callable, Optional
6
+
7
+ from wiil.client.http_client import HttpClient
8
+ from wiil.errors import WiilValidationError
9
+ from wiil.models.service_mgt.dynamic_setup import (
10
+ DynamicAgentProcessingState,
11
+ DynamicPhoneAgentSetup,
12
+ DynamicPhoneAgentSetupResult,
13
+ DynamicSTTModelConfiguration,
14
+ DynamicTTSModelConfiguration,
15
+ UpdateDynamicPhoneAgent,
16
+ )
17
+ from wiil.resources.service_mgt.dynamic_agent_status import PollTimeoutError
18
+
19
+
20
+ @dataclass
21
+ class PhoneAgentCreateOptions:
22
+ """Options for configuring agent creation behavior."""
23
+
24
+ poll_until_complete: bool = True
25
+ """Whether to poll until setup completes."""
26
+
27
+ poll_interval: float = 5.0
28
+ """Polling interval in seconds."""
29
+
30
+ poll_timeout: float = 120.0
31
+ """Maximum wait time in seconds before timing out."""
32
+
33
+ on_progress: Optional[Callable[[DynamicAgentProcessingState], None]] = None
34
+ """Callback invoked on each poll with the current processing state."""
35
+
36
+ silent: bool = False
37
+ """Whether to suppress console logging."""
38
+
39
+
40
+ class DynamicPhoneAgentResource:
41
+ """Resource class for managing dynamic phone agent provisioning.
42
+
43
+ Provides methods for creating and updating dynamic phone agent
44
+ configurations. Dynamic phone agents enable AI-powered phone
45
+ interactions with configurable STT and TTS capabilities.
46
+
47
+ Example:
48
+ >>> from wiil.models.type_definitions import (
49
+ ... AgentCapabilities,
50
+ ... AgentRoleTemplateIdentifier,
51
+ ... )
52
+ >>>
53
+ >>> client = WiilClient(api_key='your-api-key')
54
+ >>>
55
+ >>> # Create with polling (waits for completion)
56
+ >>> result = client.dynamic_phone_agent.create(
57
+ ... DynamicPhoneAgentSetup(
58
+ ... assistant_name='Alex',
59
+ ... capabilities=[AgentCapabilities.APPOINTMENT_MANAGEMENT],
60
+ ... role_template_identifier=(
61
+ ... AgentRoleTemplateIdentifier.CUSTOMER_SUPPORT_GENERAL
62
+ ... ),
63
+ ... )
64
+ ... )
65
+ >>>
66
+ >>> # Create without waiting
67
+ >>> result = client.dynamic_phone_agent.create(
68
+ ... data,
69
+ ... options=PhoneAgentCreateOptions(poll_until_complete=False)
70
+ ... )
71
+ """
72
+
73
+ def __init__(self, http: HttpClient):
74
+ self._http = http
75
+ self._base_path = '/dynamic-setup/phone-agent'
76
+ self._status_path = '/dynamic-setup'
77
+
78
+ def create(
79
+ self,
80
+ data: DynamicPhoneAgentSetup,
81
+ options: Optional[PhoneAgentCreateOptions] = None
82
+ ) -> DynamicPhoneAgentSetupResult:
83
+ """Create and provision a new dynamic phone agent.
84
+
85
+ Args:
86
+ data: Phone agent configuration data
87
+ options: Creation options for polling and logging behavior
88
+
89
+ Returns:
90
+ The setup result including provisioned phone number
91
+
92
+ Raises:
93
+ WiilValidationError: When validation fails or model not supported
94
+ WiilAPIError: When the API returns an error
95
+ PollTimeoutError: When polling times out before completion
96
+ """
97
+ opts = options or PhoneAgentCreateOptions()
98
+ start_time = time.time()
99
+ agent_name = data.assistant_name
100
+
101
+ # Validate model configurations before proceeding
102
+ self._validate_model_configurations(
103
+ data.stt_configuration,
104
+ data.tts_configuration
105
+ )
106
+
107
+ # Log initial creation
108
+ if not opts.silent:
109
+ self._log(f'Creating agent "{agent_name}"...')
110
+
111
+ # Create the agent
112
+ initial_result = self._http.post(
113
+ self._base_path,
114
+ data.model_dump(by_alias=True, exclude_none=True),
115
+ schema=DynamicPhoneAgentSetup,
116
+ response_model=DynamicPhoneAgentSetupResult
117
+ )
118
+
119
+ # If not polling, return immediately
120
+ if not opts.poll_until_complete:
121
+ if not opts.silent:
122
+ self._log(f'Setup initiated (ID: {initial_result.id})')
123
+ return initial_result
124
+
125
+ # Check if already complete
126
+ if initial_result.processing_state.status in ('completed', 'failed'):
127
+ self._log_final_result(initial_result, start_time, opts.silent)
128
+ return initial_result
129
+
130
+ # Poll until complete
131
+ while True:
132
+ result = self._http.get(
133
+ f'{self._status_path}/{initial_result.id}',
134
+ response_model=DynamicPhoneAgentSetupResult
135
+ )
136
+ last_state = result.processing_state
137
+
138
+ # Log progress
139
+ if not opts.silent:
140
+ self._log_progress(last_state)
141
+
142
+ # Invoke callback
143
+ if opts.on_progress:
144
+ opts.on_progress(last_state)
145
+
146
+ # Check for terminal states
147
+ if last_state.status in ('completed', 'failed'):
148
+ self._log_final_result(result, start_time, opts.silent)
149
+ return result
150
+
151
+ # Check for timeout
152
+ elapsed = time.time() - start_time
153
+ if elapsed >= opts.poll_timeout:
154
+ if not opts.silent:
155
+ self._log(f'Timeout after {self._format_duration(elapsed)}')
156
+ msg = (
157
+ f'Polling timed out after {opts.poll_timeout}s. '
158
+ f'Last status: {last_state.status} '
159
+ f'at {last_state.progress_percentage}%'
160
+ )
161
+ raise PollTimeoutError(msg, last_state)
162
+
163
+ # Wait before next poll
164
+ time.sleep(opts.poll_interval)
165
+
166
+ def update(
167
+ self,
168
+ data: UpdateDynamicPhoneAgent
169
+ ) -> DynamicPhoneAgentSetupResult:
170
+ """Update an existing dynamic phone agent configuration.
171
+
172
+ Args:
173
+ data: Phone agent update data (must include id)
174
+
175
+ Returns:
176
+ The updated phone agent setup result
177
+
178
+ Raises:
179
+ WiilValidationError: When input validation fails
180
+ WiilAPIError: When phone agent is not found or API error
181
+ """
182
+ # Validate model configurations before proceeding
183
+ self._validate_model_configurations(
184
+ data.stt_configuration,
185
+ data.tts_configuration
186
+ )
187
+
188
+ return self._http.patch(
189
+ self._base_path,
190
+ data.model_dump(by_alias=True, exclude_none=True),
191
+ schema=UpdateDynamicPhoneAgent,
192
+ response_model=DynamicPhoneAgentSetupResult
193
+ )
194
+
195
+ def _validate_model_configurations(
196
+ self,
197
+ stt_config: Optional[DynamicSTTModelConfiguration],
198
+ tts_config: Optional[DynamicTTSModelConfiguration]
199
+ ) -> None:
200
+ """Validate STT and TTS model configs against support registry."""
201
+ has_stt = (
202
+ stt_config
203
+ and stt_config.provider_type
204
+ and stt_config.provider_model_id
205
+ )
206
+ if has_stt:
207
+ self._validate_model(
208
+ stt_config.provider_type,
209
+ stt_config.provider_model_id,
210
+ 'STT'
211
+ )
212
+
213
+ has_tts = (
214
+ tts_config
215
+ and tts_config.provider_type
216
+ and tts_config.provider_model_id
217
+ )
218
+ if has_tts:
219
+ self._validate_model(
220
+ tts_config.provider_type,
221
+ tts_config.provider_model_id,
222
+ 'TTS'
223
+ )
224
+
225
+ def _validate_model(
226
+ self,
227
+ provider_type: str,
228
+ provider_model_id: str,
229
+ model_type: str
230
+ ) -> None:
231
+ """Validate a single model against the support registry."""
232
+ is_supported = self._http.get(
233
+ f'/support-models/supports/{provider_type}/{provider_model_id}',
234
+ response_model=bool
235
+ )
236
+
237
+ if not is_supported:
238
+ msg = (
239
+ f'Unsupported {model_type} model: '
240
+ f'{provider_type}/{provider_model_id}. '
241
+ f'Verify the model is available in the support registry.'
242
+ )
243
+ raise WiilValidationError(msg)
244
+
245
+ def _log(self, message: str) -> None:
246
+ """Log a message with agent context."""
247
+ print(f'[Phone Agent] {message}')
248
+
249
+ def _log_progress(self, state: DynamicAgentProcessingState) -> None:
250
+ """Log progress with a visual progress bar."""
251
+ bar = self._create_progress_bar(state.progress_percentage)
252
+ status_msg = state.message or self._get_status_message(state.status)
253
+ pct = state.progress_percentage
254
+ print(f'[Phone Agent] {bar} {pct}% | {status_msg}')
255
+
256
+ def _log_final_result(
257
+ self,
258
+ result: DynamicPhoneAgentSetupResult,
259
+ start_time: float,
260
+ silent: bool
261
+ ) -> None:
262
+ """Log the final result with summary."""
263
+ if silent:
264
+ return
265
+
266
+ elapsed = time.time() - start_time
267
+ duration = self._format_duration(elapsed)
268
+
269
+ is_success = (
270
+ result.processing_state.status == 'completed' and result.success
271
+ )
272
+ if is_success:
273
+ bar = self._create_progress_bar(100)
274
+ print(f'[Phone Agent] {bar} 100% | Setup complete')
275
+ print(f'[Phone Agent] Ready in {duration}')
276
+ if result.phone_number:
277
+ print(f' -> Phone: {result.phone_number}')
278
+ if result.agent_configuration_id:
279
+ print(f' -> Agent ID: {result.agent_configuration_id}')
280
+ if result.instruction_configuration_id:
281
+ inst_id = result.instruction_configuration_id
282
+ print(f' -> Instruction ID: {inst_id}')
283
+ else:
284
+ print(f'[Phone Agent] Setup failed after {duration}')
285
+ if result.error_message:
286
+ print(f' -> Error: {result.error_message}')
287
+
288
+ def _create_progress_bar(self, percentage: int) -> str:
289
+ """Create a visual progress bar."""
290
+ total = 20
291
+ filled = round((percentage / 100) * total)
292
+ empty = total - filled
293
+ return '█' * filled + '░' * empty
294
+
295
+ def _get_status_message(self, status: str) -> str:
296
+ """Get a human-readable status message."""
297
+ messages = {
298
+ 'pending': 'Initializing...',
299
+ 'in_progress': 'Processing...',
300
+ 'completed': 'Setup complete',
301
+ 'failed': 'Setup failed',
302
+ }
303
+ return messages.get(status, status)
304
+
305
+ def _format_duration(self, seconds: float) -> str:
306
+ """Format duration in human-readable form."""
307
+ if seconds < 1:
308
+ return f'{int(seconds * 1000)}ms'
309
+ return f'{seconds:.1f}s'
310
+
311
+
312
+ __all__ = ['DynamicPhoneAgentResource', 'PhoneAgentCreateOptions']