wiil-python 0.0.3__py3-none-any.whl → 0.0.4__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.
@@ -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']
@@ -1,74 +1,190 @@
1
- """Dynamic Phone Agent resource for managing phone agent configurations."""
1
+ """Dynamic Phone Agent resource for phone-based AI agents."""
2
2
 
3
- from typing import Any, Dict, Optional
4
- from urllib.parse import urlencode
3
+ import time
4
+ from dataclasses import dataclass
5
+ from typing import Callable, Optional
5
6
 
6
7
  from wiil.client.http_client import HttpClient
8
+ from wiil.errors import WiilValidationError
7
9
  from wiil.models.service_mgt.dynamic_setup import (
10
+ DynamicAgentProcessingState,
8
11
  DynamicPhoneAgentSetup,
9
12
  DynamicPhoneAgentSetupResult,
13
+ DynamicSTTModelConfiguration,
14
+ DynamicTTSModelConfiguration,
10
15
  UpdateDynamicPhoneAgent,
11
16
  )
12
- from wiil.types import PaginatedResult, PaginationRequest
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."""
13
38
 
14
39
 
15
40
  class DynamicPhoneAgentResource:
16
- """Resource class for managing dynamic phone agents in the WIIL Platform.
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.
17
46
 
18
- Provides methods for creating, retrieving, updating, deleting, and listing
19
- dynamic phone agent configurations. Phone agents are deployed on telephony
20
- channels for voice-based customer interactions.
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
+ ... )
21
71
  """
22
72
 
23
73
  def __init__(self, http: HttpClient):
24
74
  self._http = http
25
- self._base_path = '/dynamic-phone-agent'
75
+ self._base_path = '/dynamic-setup/phone-agent'
76
+ self._status_path = '/dynamic-setup'
26
77
 
27
78
  def create(
28
79
  self,
29
- data: DynamicPhoneAgentSetup
80
+ data: DynamicPhoneAgentSetup,
81
+ options: Optional[PhoneAgentCreateOptions] = None
30
82
  ) -> DynamicPhoneAgentSetupResult:
31
- """Create a new dynamic phone agent.
83
+ """Create and provision a new dynamic phone agent.
32
84
 
33
85
  Args:
34
- data: Phone agent setup data
86
+ data: Phone agent configuration data
87
+ options: Creation options for polling and logging behavior
35
88
 
36
89
  Returns:
37
- The setup result with processing status
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
38
96
  """
39
- return self._http.post(
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(
40
113
  self._base_path,
41
114
  data.model_dump(by_alias=True, exclude_none=True),
42
115
  schema=DynamicPhoneAgentSetup,
43
116
  response_model=DynamicPhoneAgentSetupResult
44
117
  )
45
118
 
46
- def get(self, agent_id: str) -> DynamicPhoneAgentSetupResult:
47
- """Retrieve a dynamic phone agent by ID.
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
48
124
 
49
- Args:
50
- agent_id: Phone agent ID
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
51
129
 
52
- Returns:
53
- The phone agent setup result
54
- """
55
- return self._http.get(
56
- f'{self._base_path}/{agent_id}',
57
- response_model=DynamicPhoneAgentSetupResult
58
- )
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)
59
165
 
60
166
  def update(
61
167
  self,
62
168
  data: UpdateDynamicPhoneAgent
63
169
  ) -> DynamicPhoneAgentSetupResult:
64
- """Update an existing dynamic phone agent.
170
+ """Update an existing dynamic phone agent configuration.
65
171
 
66
172
  Args:
67
173
  data: Phone agent update data (must include id)
68
174
 
69
175
  Returns:
70
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
71
181
  """
182
+ # Validate model configurations before proceeding
183
+ self._validate_model_configurations(
184
+ data.stt_configuration,
185
+ data.tts_configuration
186
+ )
187
+
72
188
  return self._http.patch(
73
189
  self._base_path,
74
190
  data.model_dump(by_alias=True, exclude_none=True),
@@ -76,39 +192,121 @@ class DynamicPhoneAgentResource:
76
192
  response_model=DynamicPhoneAgentSetupResult
77
193
  )
78
194
 
79
- def delete(self, agent_id: str) -> bool:
80
- """Delete a dynamic phone agent.
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
+ )
81
212
 
82
- Args:
83
- agent_id: Phone agent ID
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
+ )
84
224
 
85
- Returns:
86
- True if deletion was successful
87
- """
88
- return self._http.delete(f'{self._base_path}/{agent_id}')
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}')
89
248
 
90
- def list(
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(
91
257
  self,
92
- params: Optional[PaginationRequest] = None
93
- ) -> PaginatedResult[DynamicPhoneAgentSetupResult]:
94
- """List dynamic phone agents with pagination.
258
+ result: DynamicPhoneAgentSetupResult,
259
+ start_time: float,
260
+ silent: bool
261
+ ) -> None:
262
+ """Log the final result with summary."""
263
+ if silent:
264
+ return
95
265
 
96
- Args:
97
- params: Pagination parameters
266
+ elapsed = time.time() - start_time
267
+ duration = self._format_duration(elapsed)
98
268
 
99
- Returns:
100
- Paginated list of phone agent setup results
101
- """
102
- query_params: Dict[str, Any] = {}
103
- if params:
104
- query_params['page'] = params.page
105
- query_params['pageSize'] = params.page_size
106
-
107
- query_string = f'?{urlencode(query_params)}' if query_params else ''
108
- return self._http.get(
109
- f'{self._base_path}{query_string}',
110
- response_model=PaginatedResult[DynamicPhoneAgentSetupResult]
269
+ is_success = (
270
+ result.processing_state.status == 'completed' and result.success
111
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'
112
310
 
113
311
 
114
- __all__ = ['DynamicPhoneAgentResource']
312
+ __all__ = ['DynamicPhoneAgentResource', 'PhoneAgentCreateOptions']
@@ -1,68 +1,195 @@
1
- """Dynamic Web Agent resource for managing web agent configurations."""
1
+ """Dynamic Web Agent resource for web-based AI agents."""
2
2
 
3
- from typing import Any, Dict, Optional
4
- from urllib.parse import urlencode
3
+ import time
4
+ from dataclasses import dataclass
5
+ from typing import Callable, Optional
5
6
 
6
7
  from wiil.client.http_client import HttpClient
8
+ from wiil.errors import WiilValidationError
7
9
  from wiil.models.service_mgt.dynamic_setup import (
10
+ DynamicAgentProcessingState,
11
+ DynamicSTTModelConfiguration,
12
+ DynamicTTSModelConfiguration,
8
13
  DynamicWebAgentSetup,
9
14
  DynamicWebAgentSetupResult,
10
15
  UpdateDynamicWebAgent,
11
16
  )
12
- from wiil.types import PaginatedResult, PaginationRequest
17
+ from wiil.resources.service_mgt.dynamic_agent_status import PollTimeoutError
18
+
19
+
20
+ @dataclass
21
+ class WebAgentCreateOptions:
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."""
13
38
 
14
39
 
15
40
  class DynamicWebAgentResource:
16
- """Resource class for managing dynamic web agents in the WIIL Platform.
41
+ """Resource class for managing dynamic web agent provisioning.
42
+
43
+ Provides methods for creating and updating dynamic web agent
44
+ configurations. Dynamic web agents enable AI-powered web
45
+ interactions with configurable STT and TTS capabilities.
46
+ Setup results include integration snippets for websites.
17
47
 
18
- Provides methods for creating, retrieving, updating, deleting, and listing
19
- dynamic web agent configurations. Web agents are deployed on web channels
20
- for customer interactions via chat widgets.
48
+ Example:
49
+ >>> from wiil.models.type_definitions import (
50
+ ... AgentCapabilities,
51
+ ... AgentRoleTemplateIdentifier,
52
+ ... OttCommunicationType,
53
+ ... )
54
+ >>>
55
+ >>> client = WiilClient(api_key='your-api-key')
56
+ >>>
57
+ >>> # Create with polling (waits for completion)
58
+ >>> result = client.dynamic_web_agent.create(
59
+ ... DynamicWebAgentSetup(
60
+ ... assistant_name='Emma',
61
+ ... website_url='https://example.com',
62
+ ... communication_type=OttCommunicationType.TEXT,
63
+ ... capabilities=[AgentCapabilities.APPOINTMENT_MANAGEMENT],
64
+ ... role_template_identifier=(
65
+ ... AgentRoleTemplateIdentifier.CUSTOMER_SUPPORT_GENERAL
66
+ ... ),
67
+ ... )
68
+ ... )
69
+ >>> print('Integration snippets:', result.integration_snippets)
70
+ >>>
71
+ >>> # Create without waiting
72
+ >>> result = client.dynamic_web_agent.create(
73
+ ... data,
74
+ ... options=WebAgentCreateOptions(poll_until_complete=False)
75
+ ... )
21
76
  """
22
77
 
23
78
  def __init__(self, http: HttpClient):
24
79
  self._http = http
25
- self._base_path = '/dynamic-web-agent'
80
+ self._base_path = '/dynamic-setup/web-agent'
81
+ self._status_path = '/dynamic-setup'
26
82
 
27
- def create(self, data: DynamicWebAgentSetup) -> DynamicWebAgentSetupResult:
28
- """Create a new dynamic web agent.
83
+ def create(
84
+ self,
85
+ data: DynamicWebAgentSetup,
86
+ options: Optional[WebAgentCreateOptions] = None
87
+ ) -> DynamicWebAgentSetupResult:
88
+ """Create and provision a new dynamic web agent.
29
89
 
30
90
  Args:
31
- data: Web agent setup data
91
+ data: Web agent configuration data
92
+ options: Creation options for polling and logging behavior
32
93
 
33
94
  Returns:
34
- The setup result with processing status
95
+ The setup result including integration snippets
96
+
97
+ Raises:
98
+ WiilValidationError: When validation fails or model not supported
99
+ WiilAPIError: When the API returns an error
100
+ PollTimeoutError: When polling times out before completion
35
101
  """
36
- return self._http.post(
102
+ opts = options or WebAgentCreateOptions()
103
+ start_time = time.time()
104
+ agent_name = data.assistant_name
105
+
106
+ # Validate model configurations before proceeding
107
+ self._validate_model_configurations(
108
+ data.stt_configuration,
109
+ data.tts_configuration
110
+ )
111
+
112
+ # Log initial creation
113
+ if not opts.silent:
114
+ self._log(f'Creating agent "{agent_name}"...')
115
+
116
+ # Create the agent
117
+ initial_result = self._http.post(
37
118
  self._base_path,
38
119
  data.model_dump(by_alias=True, exclude_none=True),
39
120
  schema=DynamicWebAgentSetup,
40
121
  response_model=DynamicWebAgentSetupResult
41
122
  )
42
123
 
43
- def get(self, agent_id: str) -> DynamicWebAgentSetupResult:
44
- """Retrieve a dynamic web agent by ID.
124
+ # If not polling, return immediately
125
+ if not opts.poll_until_complete:
126
+ if not opts.silent:
127
+ self._log(f'Setup initiated (ID: {initial_result.id})')
128
+ return initial_result
45
129
 
46
- Args:
47
- agent_id: Web agent ID
130
+ # Check if already complete
131
+ if initial_result.processing_state.status in ('completed', 'failed'):
132
+ self._log_final_result(initial_result, start_time, opts.silent)
133
+ return initial_result
48
134
 
49
- Returns:
50
- The web agent setup result
51
- """
52
- return self._http.get(
53
- f'{self._base_path}/{agent_id}',
54
- response_model=DynamicWebAgentSetupResult
55
- )
135
+ # Poll until complete
136
+ while True:
137
+ result = self._http.get(
138
+ f'{self._status_path}/{initial_result.id}',
139
+ response_model=DynamicWebAgentSetupResult
140
+ )
141
+ last_state = result.processing_state
142
+
143
+ # Log progress
144
+ if not opts.silent:
145
+ self._log_progress(last_state)
146
+
147
+ # Invoke callback
148
+ if opts.on_progress:
149
+ opts.on_progress(last_state)
150
+
151
+ # Check for terminal states
152
+ if last_state.status in ('completed', 'failed'):
153
+ self._log_final_result(result, start_time, opts.silent)
154
+ return result
155
+
156
+ # Check for timeout
157
+ elapsed = time.time() - start_time
158
+ if elapsed >= opts.poll_timeout:
159
+ if not opts.silent:
160
+ self._log(f'Timeout after {self._format_duration(elapsed)}')
161
+ msg = (
162
+ f'Polling timed out after {opts.poll_timeout}s. '
163
+ f'Last status: {last_state.status} '
164
+ f'at {last_state.progress_percentage}%'
165
+ )
166
+ raise PollTimeoutError(msg, last_state)
56
167
 
57
- def update(self, data: UpdateDynamicWebAgent) -> DynamicWebAgentSetupResult:
58
- """Update an existing dynamic web agent.
168
+ # Wait before next poll
169
+ time.sleep(opts.poll_interval)
170
+
171
+ def update(
172
+ self,
173
+ data: UpdateDynamicWebAgent
174
+ ) -> DynamicWebAgentSetupResult:
175
+ """Update an existing dynamic web agent configuration.
59
176
 
60
177
  Args:
61
178
  data: Web agent update data (must include id)
62
179
 
63
180
  Returns:
64
181
  The updated web agent setup result
182
+
183
+ Raises:
184
+ WiilValidationError: When input validation fails
185
+ WiilAPIError: When web agent is not found or API error
65
186
  """
187
+ # Validate model configurations before proceeding
188
+ self._validate_model_configurations(
189
+ data.stt_configuration,
190
+ data.tts_configuration
191
+ )
192
+
66
193
  return self._http.patch(
67
194
  self._base_path,
68
195
  data.model_dump(by_alias=True, exclude_none=True),
@@ -70,39 +197,122 @@ class DynamicWebAgentResource:
70
197
  response_model=DynamicWebAgentSetupResult
71
198
  )
72
199
 
73
- def delete(self, agent_id: str) -> bool:
74
- """Delete a dynamic web agent.
200
+ def _validate_model_configurations(
201
+ self,
202
+ stt_config: Optional[DynamicSTTModelConfiguration],
203
+ tts_config: Optional[DynamicTTSModelConfiguration]
204
+ ) -> None:
205
+ """Validate STT and TTS model configs against support registry."""
206
+ has_stt = (
207
+ stt_config
208
+ and stt_config.provider_type
209
+ and stt_config.provider_model_id
210
+ )
211
+ if has_stt:
212
+ self._validate_model(
213
+ stt_config.provider_type,
214
+ stt_config.provider_model_id,
215
+ 'STT'
216
+ )
75
217
 
76
- Args:
77
- agent_id: Web agent ID
218
+ has_tts = (
219
+ tts_config
220
+ and tts_config.provider_type
221
+ and tts_config.provider_model_id
222
+ )
223
+ if has_tts:
224
+ self._validate_model(
225
+ tts_config.provider_type,
226
+ tts_config.provider_model_id,
227
+ 'TTS'
228
+ )
78
229
 
79
- Returns:
80
- True if deletion was successful
81
- """
82
- return self._http.delete(f'{self._base_path}/{agent_id}')
230
+ def _validate_model(
231
+ self,
232
+ provider_type: str,
233
+ provider_model_id: str,
234
+ model_type: str
235
+ ) -> None:
236
+ """Validate a single model against the support registry."""
237
+ is_supported = self._http.get(
238
+ f'/support-models/supports/{provider_type}/{provider_model_id}',
239
+ response_model=bool
240
+ )
241
+
242
+ if not is_supported:
243
+ msg = (
244
+ f'Unsupported {model_type} model: '
245
+ f'{provider_type}/{provider_model_id}. '
246
+ f'Verify the model is available in the support registry.'
247
+ )
248
+ raise WiilValidationError(msg)
83
249
 
84
- def list(
250
+ def _log(self, message: str) -> None:
251
+ """Log a message with agent context."""
252
+ print(f'[Web Agent] {message}')
253
+
254
+ def _log_progress(self, state: DynamicAgentProcessingState) -> None:
255
+ """Log progress with a visual progress bar."""
256
+ bar = self._create_progress_bar(state.progress_percentage)
257
+ status_msg = state.message or self._get_status_message(state.status)
258
+ pct = state.progress_percentage
259
+ print(f'[Web Agent] {bar} {pct}% | {status_msg}')
260
+
261
+ def _log_final_result(
85
262
  self,
86
- params: Optional[PaginationRequest] = None
87
- ) -> PaginatedResult[DynamicWebAgentSetupResult]:
88
- """List dynamic web agents with pagination.
263
+ result: DynamicWebAgentSetupResult,
264
+ start_time: float,
265
+ silent: bool
266
+ ) -> None:
267
+ """Log the final result with summary."""
268
+ if silent:
269
+ return
89
270
 
90
- Args:
91
- params: Pagination parameters
271
+ elapsed = time.time() - start_time
272
+ duration = self._format_duration(elapsed)
92
273
 
93
- Returns:
94
- Paginated list of web agent setup results
95
- """
96
- query_params: Dict[str, Any] = {}
97
- if params:
98
- query_params['page'] = params.page
99
- query_params['pageSize'] = params.page_size
100
-
101
- query_string = f'?{urlencode(query_params)}' if query_params else ''
102
- return self._http.get(
103
- f'{self._base_path}{query_string}',
104
- response_model=PaginatedResult[DynamicWebAgentSetupResult]
274
+ is_success = (
275
+ result.processing_state.status == 'completed' and result.success
105
276
  )
277
+ if is_success:
278
+ bar = self._create_progress_bar(100)
279
+ print(f'[Web Agent] {bar} 100% | Setup complete')
280
+ print(f'[Web Agent] Ready in {duration}')
281
+ if result.agent_configuration_id:
282
+ print(f' -> Agent ID: {result.agent_configuration_id}')
283
+ if result.instruction_configuration_id:
284
+ inst_id = result.instruction_configuration_id
285
+ print(f' -> Instruction ID: {inst_id}')
286
+ if result.integration_snippets:
287
+ count = len(result.integration_snippets)
288
+ print(f' -> Integration snippets: {count} available')
289
+ else:
290
+ print(f'[Web Agent] Setup failed after {duration}')
291
+ if result.error_message:
292
+ print(f' -> Error: {result.error_message}')
293
+
294
+ def _create_progress_bar(self, percentage: int) -> str:
295
+ """Create a visual progress bar."""
296
+ total = 20
297
+ filled = round((percentage / 100) * total)
298
+ empty = total - filled
299
+ return '█' * filled + '░' * empty
300
+
301
+ def _get_status_message(self, status: str) -> str:
302
+ """Get a human-readable status message."""
303
+ messages = {
304
+ 'pending': 'Initializing...',
305
+ 'in_progress': 'Processing...',
306
+ 'completed': 'Setup complete',
307
+ 'failed': 'Setup failed',
308
+ }
309
+ return messages.get(status, status)
310
+
311
+ def _format_duration(self, seconds: float) -> str:
312
+ """Format duration in human-readable form."""
313
+ if seconds < 1:
314
+ return f'{int(seconds * 1000)}ms'
315
+ return f'{seconds:.1f}s'
106
316
 
107
317
 
108
- __all__ = ['DynamicWebAgentResource']
318
+ __all__ = ['DynamicWebAgentResource', 'WebAgentCreateOptions']
@@ -1,30 +1,60 @@
1
- """Provisioning Configurations resource for managing provisioning configuration entities."""
1
+ """Provisioning Configurations resource for managing provisioning configs."""
2
2
 
3
- from typing import Any, Dict, Optional, Union
4
- from urllib.parse import urlencode
3
+ from typing import Optional, Union
5
4
 
6
5
  from wiil.client.http_client import HttpClient
6
+ from wiil.errors import WiilValidationError
7
7
  from wiil.models.service_mgt import (
8
8
  CreateProvisioningConfig,
9
+ CreateTranslationChainConfig,
10
+ DynamicModelConfiguration,
11
+ DynamicSTTModelConfiguration,
12
+ DynamicTTSModelConfiguration,
9
13
  ProvisioningConfigChain,
14
+ TranslationChainConfig,
10
15
  UpdateProvisioningConfig,
11
16
  )
12
17
  from wiil.types import PaginatedResult, PaginationRequest
13
18
 
14
19
 
15
20
  class ProvisioningConfigurationsResource:
16
- """Resource class for managing provisioning configurations in the WIIL Platform.
21
+ """Resource class for managing provisioning configurations.
17
22
 
18
23
  Provides methods for creating, retrieving, updating, deleting, and listing
19
24
  provisioning configurations. Provisioning configurations define processing
20
25
  chains and translation configurations for AI deployments.
26
+
27
+ Example:
28
+ >>> client = WiilClient(api_key='your-api-key')
29
+ >>>
30
+ >>> # Create a new provisioning configuration
31
+ >>> config = client.provisioning_configs.create(
32
+ ... CreateProvisioningConfig(
33
+ ... chain_name='customer-support-chain',
34
+ ... stt_config=DynamicSTTModelConfiguration(...),
35
+ ... processing_config=DynamicModelConfiguration(...),
36
+ ... tts_config=DynamicTTSModelConfiguration(...),
37
+ ... )
38
+ ... )
39
+ >>>
40
+ >>> # Get by chain name
41
+ >>> config = client.provisioning_configs.get_by_chain_name('my-chain')
42
+ >>>
43
+ >>> # List provisioning chains
44
+ >>> chains = client.provisioning_configs.list_provisioning_chains()
45
+ >>>
46
+ >>> # List translation chains
47
+ >>> trans = client.provisioning_configs.list_translation_chains()
21
48
  """
22
49
 
23
50
  def __init__(self, http: HttpClient):
24
51
  self._http = http
25
52
  self._base_path = '/provisioning-configurations'
26
53
 
27
- def create(self, data: CreateProvisioningConfig) -> ProvisioningConfigChain:
54
+ def create(
55
+ self,
56
+ data: CreateProvisioningConfig
57
+ ) -> ProvisioningConfigChain:
28
58
  """Create a new provisioning configuration chain.
29
59
 
30
60
  Args:
@@ -32,7 +62,17 @@ class ProvisioningConfigurationsResource:
32
62
 
33
63
  Returns:
34
64
  The created provisioning configuration chain
65
+
66
+ Raises:
67
+ WiilValidationError: When validation fails or model not supported
68
+ WiilAPIError: When the API returns an error
35
69
  """
70
+ self._validate_model_configurations(
71
+ data.stt_config,
72
+ data.processing_config,
73
+ data.tts_config
74
+ )
75
+
36
76
  return self._http.post(
37
77
  self._base_path,
38
78
  data.model_dump(by_alias=True, exclude_none=True),
@@ -40,21 +80,79 @@ class ProvisioningConfigurationsResource:
40
80
  response_model=ProvisioningConfigChain
41
81
  )
42
82
 
43
- def get(self, config_id: str) -> ProvisioningConfigChain:
44
- """Retrieve a provisioning configuration by ID."""
83
+ def create_translation(
84
+ self,
85
+ data: CreateTranslationChainConfig
86
+ ) -> TranslationChainConfig:
87
+ """Create a new translation configuration chain.
88
+
89
+ Args:
90
+ data: Translation configuration chain data
91
+
92
+ Returns:
93
+ The created translation configuration chain
94
+
95
+ Raises:
96
+ WiilValidationError: When validation fails or model not supported
97
+ WiilAPIError: When the API returns an error
98
+ """
99
+ self._validate_model_configurations(
100
+ data.stt_config,
101
+ data.processing_config,
102
+ data.tts_config
103
+ )
104
+
105
+ return self._http.post(
106
+ self._base_path,
107
+ data.model_dump(by_alias=True, exclude_none=True),
108
+ schema=CreateTranslationChainConfig,
109
+ response_model=TranslationChainConfig
110
+ )
111
+
112
+ def get(
113
+ self,
114
+ config_id: str
115
+ ) -> Union[ProvisioningConfigChain, TranslationChainConfig]:
116
+ """Retrieve a provisioning configuration by ID.
117
+
118
+ Args:
119
+ config_id: Provisioning configuration ID
120
+
121
+ Returns:
122
+ The provisioning configuration chain or translation chain
123
+
124
+ Raises:
125
+ WiilAPIError: When configuration is not found or API error
126
+ """
45
127
  return self._http.get(
46
128
  f'{self._base_path}/{config_id}',
47
129
  response_model=ProvisioningConfigChain
48
130
  )
49
131
 
50
- def get_by_chain_name(self, chain_name: str) -> ProvisioningConfigChain:
51
- """Retrieve a provisioning configuration by chain name."""
132
+ def get_by_chain_name(
133
+ self,
134
+ chain_name: str
135
+ ) -> Union[ProvisioningConfigChain, TranslationChainConfig]:
136
+ """Retrieve a provisioning configuration by chain name.
137
+
138
+ Args:
139
+ chain_name: Chain name
140
+
141
+ Returns:
142
+ The provisioning configuration chain or translation chain
143
+
144
+ Raises:
145
+ WiilAPIError: When configuration is not found or API error
146
+ """
52
147
  return self._http.get(
53
148
  f'{self._base_path}/by-chain-name/{chain_name}',
54
149
  response_model=ProvisioningConfigChain
55
150
  )
56
151
 
57
- def update(self, data: UpdateProvisioningConfig) -> ProvisioningConfigChain:
152
+ def update(
153
+ self,
154
+ data: UpdateProvisioningConfig
155
+ ) -> ProvisioningConfigChain:
58
156
  """Update an existing provisioning configuration.
59
157
 
60
158
  Args:
@@ -62,7 +160,17 @@ class ProvisioningConfigurationsResource:
62
160
 
63
161
  Returns:
64
162
  The updated provisioning configuration chain
163
+
164
+ Raises:
165
+ WiilValidationError: When validation fails or model not supported
166
+ WiilAPIError: When configuration is not found or API error
65
167
  """
168
+ self._validate_model_configurations(
169
+ data.stt_config,
170
+ data.processing_config,
171
+ data.tts_config
172
+ )
173
+
66
174
  return self._http.patch(
67
175
  self._base_path,
68
176
  data.model_dump(by_alias=True, exclude_none=True),
@@ -71,14 +179,24 @@ class ProvisioningConfigurationsResource:
71
179
  )
72
180
 
73
181
  def delete(self, config_id: str) -> bool:
74
- """Delete a provisioning configuration."""
182
+ """Delete a provisioning configuration.
183
+
184
+ Args:
185
+ config_id: Provisioning configuration ID
186
+
187
+ Returns:
188
+ True if deletion was successful
189
+
190
+ Raises:
191
+ WiilAPIError: When configuration is not found or API error
192
+ """
75
193
  return self._http.delete(f'{self._base_path}/{config_id}')
76
194
 
77
195
  def list(
78
196
  self,
79
197
  params: Optional[PaginationRequest] = None,
80
198
  include_deleted: Optional[bool] = None
81
- ) -> PaginatedResult[ProvisioningConfigChain]:
199
+ ) -> PaginatedResult[Union[ProvisioningConfigChain, TranslationChainConfig]]:
82
200
  """List all provisioning configurations with pagination.
83
201
 
84
202
  Args:
@@ -88,14 +206,16 @@ class ProvisioningConfigurationsResource:
88
206
  Returns:
89
207
  Paginated list of provisioning configurations
90
208
  """
91
- query_params: Dict[str, Any] = {}
209
+ query_parts = []
92
210
  if params:
93
- query_params['page'] = params.page
94
- query_params['pageSize'] = params.page_size
211
+ if params.page:
212
+ query_parts.append(f'page={params.page}')
213
+ if params.page_size:
214
+ query_parts.append(f'pageSize={params.page_size}')
95
215
  if include_deleted is not None:
96
- query_params['includeDeleted'] = str(include_deleted).lower()
216
+ query_parts.append(f'includeDeleted={str(include_deleted).lower()}')
97
217
 
98
- query_string = f'?{urlencode(query_params)}' if query_params else ''
218
+ query_string = '?' + '&'.join(query_parts) if query_parts else ''
99
219
  return self._http.get(
100
220
  f'{self._base_path}{query_string}',
101
221
  response_model=PaginatedResult[ProvisioningConfigChain]
@@ -113,16 +233,106 @@ class ProvisioningConfigurationsResource:
113
233
  Returns:
114
234
  Paginated list of provisioning configuration chains
115
235
  """
116
- query_params: Dict[str, Any] = {}
236
+ query_parts = []
117
237
  if params:
118
- query_params['page'] = params.page
119
- query_params['pageSize'] = params.page_size
238
+ if params.page:
239
+ query_parts.append(f'page={params.page}')
240
+ if params.page_size:
241
+ query_parts.append(f'pageSize={params.page_size}')
120
242
 
121
- query_string = f'?{urlencode(query_params)}' if query_params else ''
243
+ query_string = '?' + '&'.join(query_parts) if query_parts else ''
122
244
  return self._http.get(
123
245
  f'{self._base_path}/provisioning{query_string}',
124
246
  response_model=PaginatedResult[ProvisioningConfigChain]
125
247
  )
126
248
 
249
+ def list_translation_chains(
250
+ self,
251
+ params: Optional[PaginationRequest] = None
252
+ ) -> PaginatedResult[TranslationChainConfig]:
253
+ """List translation configuration chains with pagination.
254
+
255
+ Args:
256
+ params: Pagination parameters
257
+
258
+ Returns:
259
+ Paginated list of translation configuration chains
260
+ """
261
+ query_parts = []
262
+ if params:
263
+ if params.page:
264
+ query_parts.append(f'page={params.page}')
265
+ if params.page_size:
266
+ query_parts.append(f'pageSize={params.page_size}')
267
+
268
+ query_string = '?' + '&'.join(query_parts) if query_parts else ''
269
+ return self._http.get(
270
+ f'{self._base_path}/translations{query_string}',
271
+ response_model=PaginatedResult[TranslationChainConfig]
272
+ )
273
+
274
+ def _validate_model_configurations(
275
+ self,
276
+ stt_config: Optional[DynamicSTTModelConfiguration],
277
+ processing_config: Optional[DynamicModelConfiguration],
278
+ tts_config: Optional[DynamicTTSModelConfiguration]
279
+ ) -> None:
280
+ """Validate STT, Processing, and TTS model configs."""
281
+ has_stt = (
282
+ stt_config
283
+ and stt_config.provider_type
284
+ and stt_config.provider_model_id
285
+ )
286
+ if has_stt:
287
+ self._validate_model(
288
+ stt_config.provider_type,
289
+ stt_config.provider_model_id,
290
+ 'STT'
291
+ )
292
+
293
+ has_processing = (
294
+ processing_config
295
+ and processing_config.provider_type
296
+ and processing_config.provider_model_id
297
+ )
298
+ if has_processing:
299
+ self._validate_model(
300
+ processing_config.provider_type,
301
+ processing_config.provider_model_id,
302
+ 'Processing'
303
+ )
304
+
305
+ has_tts = (
306
+ tts_config
307
+ and tts_config.provider_type
308
+ and tts_config.provider_model_id
309
+ )
310
+ if has_tts:
311
+ self._validate_model(
312
+ tts_config.provider_type,
313
+ tts_config.provider_model_id,
314
+ 'TTS'
315
+ )
316
+
317
+ def _validate_model(
318
+ self,
319
+ provider_type: str,
320
+ provider_model_id: str,
321
+ model_type: str
322
+ ) -> None:
323
+ """Validate a single model against the support registry."""
324
+ is_supported = self._http.get(
325
+ f'/support-models/supports/{provider_type}/{provider_model_id}',
326
+ response_model=bool
327
+ )
328
+
329
+ if not is_supported:
330
+ msg = (
331
+ f'Unsupported {model_type} model: '
332
+ f'{provider_type}/{provider_model_id}. '
333
+ f'Verify the model is available in the support registry.'
334
+ )
335
+ raise WiilValidationError(msg)
336
+
127
337
 
128
338
  __all__ = ['ProvisioningConfigurationsResource']
@@ -295,5 +295,36 @@ class SupportModelsResource:
295
295
  response_model=WiilSupportModel
296
296
  )
297
297
 
298
+ def is_supported(
299
+ self,
300
+ proprietor: str,
301
+ provider_model_id: str
302
+ ) -> bool:
303
+ """Check if a model is supported by proprietor and provider model ID.
304
+
305
+ Args:
306
+ proprietor: Model proprietor (e.g., 'OpenAI', 'Anthropic', 'Deepgram')
307
+ provider_model_id: Provider-specific model identifier (e.g., 'gpt-4-turbo')
308
+
309
+ Returns:
310
+ True if the model is supported, False otherwise
311
+
312
+ Raises:
313
+ WiilAPIError: When the API returns an error
314
+ WiilNetworkError: When network communication fails
315
+
316
+ Example:
317
+ >>> # Check if a specific model is supported
318
+ >>> is_supported = client.support_models.is_supported('OpenAI', 'gpt-4-turbo')
319
+ >>> if is_supported:
320
+ ... print('Model is supported')
321
+ >>> else:
322
+ ... print('Model is not supported')
323
+ """
324
+ return self._http.get(
325
+ f'{self._base_path}/supports/{proprietor}/{provider_model_id}',
326
+ response_model=bool
327
+ )
328
+
298
329
 
299
330
  __all__ = ['SupportModelsResource']
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wiil-python
3
- Version: 0.0.3
3
+ Version: 0.0.4
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
@@ -32,7 +32,7 @@ wiil/models/business_mgt/property_config.py,sha256=8WEo15nrwZ5TuywwZhjHYFLCQFtm7
32
32
  wiil/models/business_mgt/property_inquiry.py,sha256=-b0TF_IkyGngz70c1J25BXTq38_XErWT_AT0ZIbkNKE,13424
33
33
  wiil/models/business_mgt/reservation.py,sha256=VB0K0H-t4Boxnc1llV0UlTVGF5tAM6mrLi-LGqxSKds,11243
34
34
  wiil/models/business_mgt/reservation_resource.py,sha256=zaM2kdcVUPnRFPfbKm3vgfRz96qdjCSX3wiYxuHZGAo,11207
35
- wiil/models/business_mgt/service_appointment.py,sha256=O9XtT0YbxwRyfl0JMO9XEK1irezrRAsXgtris2I6stc,8464
35
+ wiil/models/business_mgt/service_appointment.py,sha256=7H0bKx5utYa5SaT66ghr16WiiSJnwfY6ShbU8aNsdS0,7678
36
36
  wiil/models/business_mgt/service_config.py,sha256=XiOLJheAOvz8up2Mc5Dl0GYUwVn1IxI2JhLQSVmoqv4,6294
37
37
  wiil/models/business_mgt/service_person.py,sha256=QOGTjtUYhiWSitUGo_VdfvduQnOdukRP7h6Eg0wWuQc,3024
38
38
  wiil/models/conversation/__init__.py,sha256=J_JngMg-IBUDQL5a_s-7UKiGx0E4WoDr8fJkJod_-yI,2496
@@ -84,19 +84,19 @@ wiil/resources/business_mgt/property_inquiry.py,sha256=AxYqP9WWsQIVTneuWu0-TmkHS
84
84
  wiil/resources/business_mgt/reservation_resources.py,sha256=zcWCoFJvAX1tbFQCMIQAjJjKUsl1TBCeGedpq8rxjNk,5240
85
85
  wiil/resources/business_mgt/reservations.py,sha256=f4JoZDeusXUa9CTe2heY8jPkK-AZmCe0J-WaLl4hhsA,5927
86
86
  wiil/resources/business_mgt/service_appointments.py,sha256=w-75Y3xOt7bSGyiJsvTS5Mad13MPMblPtFBcY85KovM,4828
87
- wiil/resources/service_mgt/__init__.py,sha256=V3CnNm2DbWlyyp2bxvBzSe3GOtFMJuaa8VUlmvvr0f4,1876
87
+ wiil/resources/service_mgt/__init__.py,sha256=tmAhy3YrMwykNqzsAAWHlBHXhejv9QmsLBjB22XvZ8c,2077
88
88
  wiil/resources/service_mgt/agent_configs.py,sha256=1rGjV3-maYy0vbGKu4J5sWSrrXojgJ9gjFkDBPDQ3IU,3034
89
89
  wiil/resources/service_mgt/conversation_configs.py,sha256=Fhlqz0dRg0iiM5PVdfI7yLs4oRfgouo4_nQYk9DSfEM,1913
90
90
  wiil/resources/service_mgt/deployment_channels.py,sha256=rw7dMasphgyR8fTcqaPGfVnLLvMH0EB-MBVqhQE4Do8,4504
91
91
  wiil/resources/service_mgt/deployment_configs.py,sha256=OJynzPRNUbLBNzHgaRbUhaBN8ozENXBtS-yWzPILDvg,6153
92
- wiil/resources/service_mgt/dynamic_agent_status.py,sha256=vbubx8LAeLwmkN3rhW5YP5TTEkM7i1smFigKlvfAXJc,1072
93
- wiil/resources/service_mgt/dynamic_phone_agent.py,sha256=jUKOru7jtpOLkJd14U0y58ZQ3sLj0_IWGNKXniWsisQ,3476
94
- wiil/resources/service_mgt/dynamic_web_agent.py,sha256=RgEJ4qhUnbsj6Xg2gHlv1Tsp_dyOaCDUgSIZ6BdioS0,3355
92
+ wiil/resources/service_mgt/dynamic_agent_status.py,sha256=Ksx1RtiZB3zxV3KjygCqIdVSFSq0rJyq1XHTht-Z5q8,1381
93
+ wiil/resources/service_mgt/dynamic_phone_agent.py,sha256=_agPadUIFqKDRJ6SgV26d06OvGPfIIrdTLTk2XFBLJg,11002
94
+ wiil/resources/service_mgt/dynamic_web_agent.py,sha256=gwewZU1ColpLVZ0CGlnRUW_MZjCSLq6vTaG7E25hBFU,11290
95
95
  wiil/resources/service_mgt/instruction_configs.py,sha256=uTIiRiEkHXtfekbO8m9kYPbfcBk2LP4crAjFU4UANOE,3655
96
96
  wiil/resources/service_mgt/knowledge_sources.py,sha256=I7kTf7mf6bW59Sm4iq4HrQbVraASsnySVTP67qeCSGM,1754
97
97
  wiil/resources/service_mgt/phone_configs.py,sha256=8Vwq6C2HateV-w1jkxziyaXccL2xSKCxGc8aZCn9Mdg,3084
98
- wiil/resources/service_mgt/provisioning_configs.py,sha256=K5eXthNVCN-qKS5Qfx137eyLdd5e9MRiwfC9MfNMnxo,4618
99
- wiil/resources/service_mgt/support_models.py,sha256=J6l2m36E7wzAA2bPACv4vbYB-PEU8-v-o2Vm-zqlIXc,11311
98
+ wiil/resources/service_mgt/provisioning_configs.py,sha256=DnppwQ7Y7nBKiRukYJZ1o8OuYsX7dfckgyl_wFldmlE,11179
99
+ wiil/resources/service_mgt/support_models.py,sha256=itiiyEpkbAJw12XX6px8Q0fkwx2piBpI0GkxwiLaH7Y,12410
100
100
  wiil/resources/service_mgt/telephony_provider.py,sha256=VOqp7eXj9mee0YzIrWvdv8Dgwhc9jhcn7bRxtxvIzdE,8037
101
101
  wiil/resources/service_mgt/translation_sessions.py,sha256=GALso78qvQbMWI7mzc3BZ6FmPkb7k-jJfuguYws06e8,1809
102
102
  wiil/services/__init__.py,sha256=lZZQj2KpsExUrt4dKmSsBxH4_HMnaPkJBpT1txUZmNU,758
@@ -114,7 +114,7 @@ wiil/types/knowledge_types.py,sha256=DUVh8VbzUMljo0DQg1BjBdXReWHMX1yKmjoXIDWOLXM
114
114
  wiil/types/paginated_quest.py,sha256=SMnCvPbiWe0df13nxmQfEFa_bXeg7DzGuN-Ah1eNYO0,1785
115
115
  wiil/types/paginated_result.py,sha256=nCbHbPsjbnuwFjtLd7RBLezlKY0S3CfYVxASB2gTUl0,5311
116
116
  wiil/types/service_types.py,sha256=-F41Nb_95uuZf3Jau8IETpgcbzHzmC3M8ysy93UXMEI,5091
117
- wiil_python-0.0.3.dist-info/METADATA,sha256=fRUjxw7zONGJNeokROP6c1hgOmDvxqgLmJJePyMeUl8,19073
118
- wiil_python-0.0.3.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
119
- wiil_python-0.0.3.dist-info/top_level.txt,sha256=8CizIxlMF7XuxJQVlzf2UMy2JH4f0-hYO5fntuRQkx4,5
120
- wiil_python-0.0.3.dist-info/RECORD,,
117
+ wiil_python-0.0.4.dist-info/METADATA,sha256=O5Iv07egaTCVOR980LyiLW9qIB6kh1BI_dMorRKXO6U,19073
118
+ wiil_python-0.0.4.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
119
+ wiil_python-0.0.4.dist-info/top_level.txt,sha256=8CizIxlMF7XuxJQVlzf2UMy2JH4f0-hYO5fntuRQkx4,5
120
+ wiil_python-0.0.4.dist-info/RECORD,,