airbyte-agent-zendesk-support 0.18.18__py3-none-any.whl → 0.18.51__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.
Files changed (37) hide show
  1. airbyte_agent_zendesk_support/__init__.py +239 -18
  2. airbyte_agent_zendesk_support/_vendored/connector_sdk/auth_strategies.py +2 -5
  3. airbyte_agent_zendesk_support/_vendored/connector_sdk/auth_template.py +1 -1
  4. airbyte_agent_zendesk_support/_vendored/connector_sdk/cloud_utils/__init__.py +5 -0
  5. airbyte_agent_zendesk_support/_vendored/connector_sdk/cloud_utils/client.py +213 -0
  6. airbyte_agent_zendesk_support/_vendored/connector_sdk/connector_model_loader.py +35 -8
  7. airbyte_agent_zendesk_support/_vendored/connector_sdk/constants.py +1 -1
  8. airbyte_agent_zendesk_support/_vendored/connector_sdk/executor/hosted_executor.py +92 -84
  9. airbyte_agent_zendesk_support/_vendored/connector_sdk/executor/local_executor.py +274 -54
  10. airbyte_agent_zendesk_support/_vendored/connector_sdk/extensions.py +43 -5
  11. airbyte_agent_zendesk_support/_vendored/connector_sdk/http/response.py +2 -0
  12. airbyte_agent_zendesk_support/_vendored/connector_sdk/http_client.py +63 -49
  13. airbyte_agent_zendesk_support/_vendored/connector_sdk/introspection.py +262 -0
  14. airbyte_agent_zendesk_support/_vendored/connector_sdk/logging/logger.py +19 -10
  15. airbyte_agent_zendesk_support/_vendored/connector_sdk/logging/types.py +11 -10
  16. airbyte_agent_zendesk_support/_vendored/connector_sdk/observability/config.py +179 -0
  17. airbyte_agent_zendesk_support/_vendored/connector_sdk/observability/models.py +6 -6
  18. airbyte_agent_zendesk_support/_vendored/connector_sdk/observability/session.py +41 -32
  19. airbyte_agent_zendesk_support/_vendored/connector_sdk/performance/metrics.py +3 -3
  20. airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/base.py +22 -18
  21. airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/components.py +59 -58
  22. airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/connector.py +22 -33
  23. airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/extensions.py +131 -10
  24. airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/operations.py +32 -32
  25. airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/security.py +44 -34
  26. airbyte_agent_zendesk_support/_vendored/connector_sdk/secrets.py +2 -2
  27. airbyte_agent_zendesk_support/_vendored/connector_sdk/telemetry/events.py +9 -8
  28. airbyte_agent_zendesk_support/_vendored/connector_sdk/telemetry/tracker.py +9 -5
  29. airbyte_agent_zendesk_support/_vendored/connector_sdk/types.py +9 -3
  30. airbyte_agent_zendesk_support/_vendored/connector_sdk/validation.py +12 -6
  31. airbyte_agent_zendesk_support/connector.py +1170 -171
  32. airbyte_agent_zendesk_support/connector_model.py +7 -1
  33. airbyte_agent_zendesk_support/models.py +628 -69
  34. airbyte_agent_zendesk_support/types.py +3717 -1
  35. {airbyte_agent_zendesk_support-0.18.18.dist-info → airbyte_agent_zendesk_support-0.18.51.dist-info}/METADATA +55 -31
  36. {airbyte_agent_zendesk_support-0.18.18.dist-info → airbyte_agent_zendesk_support-0.18.51.dist-info}/RECORD +37 -33
  37. {airbyte_agent_zendesk_support-0.18.18.dist-info → airbyte_agent_zendesk_support-0.18.51.dist-info}/WHEEL +0 -0
@@ -1,17 +1,18 @@
1
1
  """
2
- zendesk-support connector.
2
+ Zendesk-Support connector.
3
3
  """
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
- from typing import TYPE_CHECKING, Any, AsyncIterator, overload
7
+ import logging
8
+ from typing import TYPE_CHECKING, Any, Callable, TypeVar, AsyncIterator, overload
8
9
  try:
9
10
  from typing import Literal
10
11
  except ImportError:
11
12
  from typing_extensions import Literal
12
13
 
13
14
  from .connector_model import ZendeskSupportConnectorModel
14
-
15
+ from ._vendored.connector_sdk.introspection import describe_entities, generate_tool_description
15
16
  from .types import (
16
17
  ArticleAttachmentsDownloadParams,
17
18
  ArticleAttachmentsGetParams,
@@ -52,8 +53,32 @@ from .types import (
52
53
  UsersListParams,
53
54
  ViewsGetParams,
54
55
  ViewsListParams,
56
+ AirbyteSearchParams,
57
+ BrandsSearchFilter,
58
+ BrandsSearchQuery,
59
+ GroupsSearchFilter,
60
+ GroupsSearchQuery,
61
+ OrganizationsSearchFilter,
62
+ OrganizationsSearchQuery,
63
+ SatisfactionRatingsSearchFilter,
64
+ SatisfactionRatingsSearchQuery,
65
+ TagsSearchFilter,
66
+ TagsSearchQuery,
67
+ TicketAuditsSearchFilter,
68
+ TicketAuditsSearchQuery,
69
+ TicketCommentsSearchFilter,
70
+ TicketCommentsSearchQuery,
71
+ TicketFieldsSearchFilter,
72
+ TicketFieldsSearchQuery,
73
+ TicketFormsSearchFilter,
74
+ TicketFormsSearchQuery,
75
+ TicketMetricsSearchFilter,
76
+ TicketMetricsSearchQuery,
77
+ TicketsSearchFilter,
78
+ TicketsSearchQuery,
79
+ UsersSearchFilter,
80
+ UsersSearchQuery,
55
81
  )
56
-
57
82
  if TYPE_CHECKING:
58
83
  from .models import ZendeskSupportAuthConfig
59
84
  # Import specific auth config classes for multi-auth isinstance checks
@@ -63,45 +88,81 @@ from .models import (
63
88
  ZendeskSupportExecuteResult,
64
89
  ZendeskSupportExecuteResultWithMeta,
65
90
  TicketsListResult,
66
- TicketsGetResult,
67
91
  UsersListResult,
68
- UsersGetResult,
69
92
  OrganizationsListResult,
70
- OrganizationsGetResult,
71
93
  GroupsListResult,
72
- GroupsGetResult,
73
94
  TicketCommentsListResult,
74
- AttachmentsGetResult,
75
95
  TicketAuditsListResult,
76
96
  TicketAuditsListResult,
77
97
  TicketMetricsListResult,
78
98
  TicketFieldsListResult,
79
- TicketFieldsGetResult,
80
99
  BrandsListResult,
81
- BrandsGetResult,
82
100
  ViewsListResult,
83
- ViewsGetResult,
84
101
  MacrosListResult,
85
- MacrosGetResult,
86
102
  TriggersListResult,
87
- TriggersGetResult,
88
103
  AutomationsListResult,
89
- AutomationsGetResult,
90
104
  TagsListResult,
91
105
  SatisfactionRatingsListResult,
92
- SatisfactionRatingsGetResult,
93
106
  GroupMembershipsListResult,
94
107
  OrganizationMembershipsListResult,
95
108
  SlaPoliciesListResult,
96
- SlaPoliciesGetResult,
97
109
  TicketFormsListResult,
98
- TicketFormsGetResult,
99
110
  ArticlesListResult,
100
- ArticlesGetResult,
101
111
  ArticleAttachmentsListResult,
102
- ArticleAttachmentsGetResult,
112
+ Article,
113
+ ArticleAttachment,
114
+ Attachment,
115
+ Automation,
116
+ Brand,
117
+ Group,
118
+ GroupMembership,
119
+ Macro,
120
+ Organization,
121
+ OrganizationMembership,
122
+ SLAPolicy,
123
+ SatisfactionRating,
124
+ Tag,
125
+ Ticket,
126
+ TicketAudit,
127
+ TicketComment,
128
+ TicketField,
129
+ TicketForm,
130
+ TicketMetric,
131
+ Trigger,
132
+ User,
133
+ View,
134
+ AirbyteSearchHit,
135
+ AirbyteSearchResult,
136
+ BrandsSearchData,
137
+ BrandsSearchResult,
138
+ GroupsSearchData,
139
+ GroupsSearchResult,
140
+ OrganizationsSearchData,
141
+ OrganizationsSearchResult,
142
+ SatisfactionRatingsSearchData,
143
+ SatisfactionRatingsSearchResult,
144
+ TagsSearchData,
145
+ TagsSearchResult,
146
+ TicketAuditsSearchData,
147
+ TicketAuditsSearchResult,
148
+ TicketCommentsSearchData,
149
+ TicketCommentsSearchResult,
150
+ TicketFieldsSearchData,
151
+ TicketFieldsSearchResult,
152
+ TicketFormsSearchData,
153
+ TicketFormsSearchResult,
154
+ TicketMetricsSearchData,
155
+ TicketMetricsSearchResult,
156
+ TicketsSearchData,
157
+ TicketsSearchResult,
158
+ UsersSearchData,
159
+ UsersSearchResult,
103
160
  )
104
161
 
162
+ # TypeVar for decorator type preservation
163
+ _F = TypeVar("_F", bound=Callable[..., Any])
164
+
165
+
105
166
 
106
167
  class ZendeskSupportConnector:
107
168
  """
@@ -111,51 +172,51 @@ class ZendeskSupportConnector:
111
172
  """
112
173
 
113
174
  connector_name = "zendesk-support"
114
- connector_version = "0.1.3"
175
+ connector_version = "0.1.6"
115
176
  vendored_sdk_version = "0.1.0" # Version of vendored connector-sdk
116
177
 
117
- # Map of (entity, action) -> has_extractors for envelope wrapping decision
118
- _EXTRACTOR_MAP = {
178
+ # Map of (entity, action) -> needs_envelope for envelope wrapping decision
179
+ _ENVELOPE_MAP = {
119
180
  ("tickets", "list"): True,
120
- ("tickets", "get"): True,
181
+ ("tickets", "get"): None,
121
182
  ("users", "list"): True,
122
- ("users", "get"): True,
183
+ ("users", "get"): None,
123
184
  ("organizations", "list"): True,
124
- ("organizations", "get"): True,
185
+ ("organizations", "get"): None,
125
186
  ("groups", "list"): True,
126
- ("groups", "get"): True,
187
+ ("groups", "get"): None,
127
188
  ("ticket_comments", "list"): True,
128
- ("attachments", "get"): True,
129
- ("attachments", "download"): False,
189
+ ("attachments", "get"): None,
190
+ ("attachments", "download"): None,
130
191
  ("ticket_audits", "list"): True,
131
192
  ("ticket_audits", "list"): True,
132
193
  ("ticket_metrics", "list"): True,
133
194
  ("ticket_fields", "list"): True,
134
- ("ticket_fields", "get"): True,
195
+ ("ticket_fields", "get"): None,
135
196
  ("brands", "list"): True,
136
- ("brands", "get"): True,
197
+ ("brands", "get"): None,
137
198
  ("views", "list"): True,
138
- ("views", "get"): True,
199
+ ("views", "get"): None,
139
200
  ("macros", "list"): True,
140
- ("macros", "get"): True,
201
+ ("macros", "get"): None,
141
202
  ("triggers", "list"): True,
142
- ("triggers", "get"): True,
203
+ ("triggers", "get"): None,
143
204
  ("automations", "list"): True,
144
- ("automations", "get"): True,
205
+ ("automations", "get"): None,
145
206
  ("tags", "list"): True,
146
207
  ("satisfaction_ratings", "list"): True,
147
- ("satisfaction_ratings", "get"): True,
208
+ ("satisfaction_ratings", "get"): None,
148
209
  ("group_memberships", "list"): True,
149
210
  ("organization_memberships", "list"): True,
150
211
  ("sla_policies", "list"): True,
151
- ("sla_policies", "get"): True,
212
+ ("sla_policies", "get"): None,
152
213
  ("ticket_forms", "list"): True,
153
- ("ticket_forms", "get"): True,
214
+ ("ticket_forms", "get"): None,
154
215
  ("articles", "list"): True,
155
- ("articles", "get"): True,
216
+ ("articles", "get"): None,
156
217
  ("article_attachments", "list"): True,
157
- ("article_attachments", "get"): True,
158
- ("article_attachments", "download"): False,
218
+ ("article_attachments", "get"): None,
219
+ ("article_attachments", "download"): None,
159
220
  }
160
221
 
161
222
  # Map of (entity, action) -> {python_param_name: api_param_name}
@@ -205,10 +266,9 @@ class ZendeskSupportConnector:
205
266
  def __init__(
206
267
  self,
207
268
  auth_config: ZendeskSupportAuthConfig | None = None,
208
- connector_id: str | None = None,
269
+ external_user_id: str | None = None,
209
270
  airbyte_client_id: str | None = None,
210
271
  airbyte_client_secret: str | None = None,
211
- airbyte_connector_api_url: str | None = None,
212
272
  on_token_refresh: Any | None = None,
213
273
  subdomain: str | None = None ):
214
274
  """
@@ -216,14 +276,13 @@ class ZendeskSupportConnector:
216
276
 
217
277
  Supports both local and hosted execution modes:
218
278
  - Local mode: Provide `auth_config` for direct API calls
219
- - Hosted mode: Provide `connector_id`, `airbyte_client_id`, and `airbyte_client_secret` for hosted execution
279
+ - Hosted mode: Provide `external_user_id`, `airbyte_client_id`, and `airbyte_client_secret` for hosted execution
220
280
 
221
281
  Args:
222
282
  auth_config: Typed authentication configuration (required for local mode)
223
- connector_id: Connector ID (required for hosted mode)
283
+ external_user_id: External user ID (required for hosted mode)
224
284
  airbyte_client_id: Airbyte OAuth client ID (required for hosted mode)
225
285
  airbyte_client_secret: Airbyte OAuth client secret (required for hosted mode)
226
- airbyte_connector_api_url: Airbyte connector API URL (defaults to Airbyte Cloud API URL)
227
286
  on_token_refresh: Optional callback for OAuth2 token refresh persistence.
228
287
  Called with new_tokens dict when tokens are refreshed. Can be sync or async.
229
288
  Example: lambda tokens: save_to_database(tokens) subdomain: Your Zendesk subdomain
@@ -232,7 +291,7 @@ class ZendeskSupportConnector:
232
291
  connector = ZendeskSupportConnector(auth_config=ZendeskSupportAuthConfig(access_token="...", refresh_token="..."))
233
292
  # Hosted mode (executed on Airbyte cloud)
234
293
  connector = ZendeskSupportConnector(
235
- connector_id="connector-456",
294
+ external_user_id="user-123",
236
295
  airbyte_client_id="client_abc123",
237
296
  airbyte_client_secret="secret_xyz789"
238
297
  )
@@ -248,20 +307,20 @@ class ZendeskSupportConnector:
248
307
  on_token_refresh=save_tokens
249
308
  )
250
309
  """
251
- # Hosted mode: connector_id, airbyte_client_id, and airbyte_client_secret provided
252
- if connector_id and airbyte_client_id and airbyte_client_secret:
310
+ # Hosted mode: external_user_id, airbyte_client_id, and airbyte_client_secret provided
311
+ if external_user_id and airbyte_client_id and airbyte_client_secret:
253
312
  from ._vendored.connector_sdk.executor import HostedExecutor
254
313
  self._executor = HostedExecutor(
255
- connector_id=connector_id,
314
+ external_user_id=external_user_id,
256
315
  airbyte_client_id=airbyte_client_id,
257
316
  airbyte_client_secret=airbyte_client_secret,
258
- api_url=airbyte_connector_api_url,
317
+ connector_definition_id=str(ZendeskSupportConnectorModel.id),
259
318
  )
260
319
  else:
261
320
  # Local mode: auth_config required
262
321
  if not auth_config:
263
322
  raise ValueError(
264
- "Either provide (connector_id, airbyte_client_id, airbyte_client_secret) for hosted mode "
323
+ "Either provide (external_user_id, airbyte_client_id, airbyte_client_secret) for hosted mode "
265
324
  "or auth_config for local mode"
266
325
  )
267
326
 
@@ -334,7 +393,7 @@ class ZendeskSupportConnector:
334
393
  entity: Literal["tickets"],
335
394
  action: Literal["get"],
336
395
  params: "TicketsGetParams"
337
- ) -> "TicketsGetResult": ...
396
+ ) -> "Ticket": ...
338
397
 
339
398
  @overload
340
399
  async def execute(
@@ -350,7 +409,7 @@ class ZendeskSupportConnector:
350
409
  entity: Literal["users"],
351
410
  action: Literal["get"],
352
411
  params: "UsersGetParams"
353
- ) -> "UsersGetResult": ...
412
+ ) -> "User": ...
354
413
 
355
414
  @overload
356
415
  async def execute(
@@ -366,7 +425,7 @@ class ZendeskSupportConnector:
366
425
  entity: Literal["organizations"],
367
426
  action: Literal["get"],
368
427
  params: "OrganizationsGetParams"
369
- ) -> "OrganizationsGetResult": ...
428
+ ) -> "Organization": ...
370
429
 
371
430
  @overload
372
431
  async def execute(
@@ -382,7 +441,7 @@ class ZendeskSupportConnector:
382
441
  entity: Literal["groups"],
383
442
  action: Literal["get"],
384
443
  params: "GroupsGetParams"
385
- ) -> "GroupsGetResult": ...
444
+ ) -> "Group": ...
386
445
 
387
446
  @overload
388
447
  async def execute(
@@ -398,7 +457,7 @@ class ZendeskSupportConnector:
398
457
  entity: Literal["attachments"],
399
458
  action: Literal["get"],
400
459
  params: "AttachmentsGetParams"
401
- ) -> "AttachmentsGetResult": ...
460
+ ) -> "Attachment": ...
402
461
 
403
462
  @overload
404
463
  async def execute(
@@ -446,7 +505,7 @@ class ZendeskSupportConnector:
446
505
  entity: Literal["ticket_fields"],
447
506
  action: Literal["get"],
448
507
  params: "TicketFieldsGetParams"
449
- ) -> "TicketFieldsGetResult": ...
508
+ ) -> "TicketField": ...
450
509
 
451
510
  @overload
452
511
  async def execute(
@@ -462,7 +521,7 @@ class ZendeskSupportConnector:
462
521
  entity: Literal["brands"],
463
522
  action: Literal["get"],
464
523
  params: "BrandsGetParams"
465
- ) -> "BrandsGetResult": ...
524
+ ) -> "Brand": ...
466
525
 
467
526
  @overload
468
527
  async def execute(
@@ -478,7 +537,7 @@ class ZendeskSupportConnector:
478
537
  entity: Literal["views"],
479
538
  action: Literal["get"],
480
539
  params: "ViewsGetParams"
481
- ) -> "ViewsGetResult": ...
540
+ ) -> "View": ...
482
541
 
483
542
  @overload
484
543
  async def execute(
@@ -494,7 +553,7 @@ class ZendeskSupportConnector:
494
553
  entity: Literal["macros"],
495
554
  action: Literal["get"],
496
555
  params: "MacrosGetParams"
497
- ) -> "MacrosGetResult": ...
556
+ ) -> "Macro": ...
498
557
 
499
558
  @overload
500
559
  async def execute(
@@ -510,7 +569,7 @@ class ZendeskSupportConnector:
510
569
  entity: Literal["triggers"],
511
570
  action: Literal["get"],
512
571
  params: "TriggersGetParams"
513
- ) -> "TriggersGetResult": ...
572
+ ) -> "Trigger": ...
514
573
 
515
574
  @overload
516
575
  async def execute(
@@ -526,7 +585,7 @@ class ZendeskSupportConnector:
526
585
  entity: Literal["automations"],
527
586
  action: Literal["get"],
528
587
  params: "AutomationsGetParams"
529
- ) -> "AutomationsGetResult": ...
588
+ ) -> "Automation": ...
530
589
 
531
590
  @overload
532
591
  async def execute(
@@ -550,7 +609,7 @@ class ZendeskSupportConnector:
550
609
  entity: Literal["satisfaction_ratings"],
551
610
  action: Literal["get"],
552
611
  params: "SatisfactionRatingsGetParams"
553
- ) -> "SatisfactionRatingsGetResult": ...
612
+ ) -> "SatisfactionRating": ...
554
613
 
555
614
  @overload
556
615
  async def execute(
@@ -582,7 +641,7 @@ class ZendeskSupportConnector:
582
641
  entity: Literal["sla_policies"],
583
642
  action: Literal["get"],
584
643
  params: "SlaPoliciesGetParams"
585
- ) -> "SlaPoliciesGetResult": ...
644
+ ) -> "SLAPolicy": ...
586
645
 
587
646
  @overload
588
647
  async def execute(
@@ -598,7 +657,7 @@ class ZendeskSupportConnector:
598
657
  entity: Literal["ticket_forms"],
599
658
  action: Literal["get"],
600
659
  params: "TicketFormsGetParams"
601
- ) -> "TicketFormsGetResult": ...
660
+ ) -> "TicketForm": ...
602
661
 
603
662
  @overload
604
663
  async def execute(
@@ -614,7 +673,7 @@ class ZendeskSupportConnector:
614
673
  entity: Literal["articles"],
615
674
  action: Literal["get"],
616
675
  params: "ArticlesGetParams"
617
- ) -> "ArticlesGetResult": ...
676
+ ) -> "Article": ...
618
677
 
619
678
  @overload
620
679
  async def execute(
@@ -630,7 +689,7 @@ class ZendeskSupportConnector:
630
689
  entity: Literal["article_attachments"],
631
690
  action: Literal["get"],
632
691
  params: "ArticleAttachmentsGetParams"
633
- ) -> "ArticleAttachmentsGetResult": ...
692
+ ) -> "ArticleAttachment": ...
634
693
 
635
694
  @overload
636
695
  async def execute(
@@ -699,7 +758,7 @@ class ZendeskSupportConnector:
699
758
  raise RuntimeError(f"Execution failed: {result.error}")
700
759
 
701
760
  # Check if this operation has extractors configured
702
- has_extractors = self._EXTRACTOR_MAP.get((entity, action), False)
761
+ has_extractors = self._ENVELOPE_MAP.get((entity, action), False)
703
762
 
704
763
  if has_extractors:
705
764
  # With extractors - return Pydantic envelope with data and meta
@@ -714,6 +773,88 @@ class ZendeskSupportConnector:
714
773
  # No extractors - return raw response data
715
774
  return result.data
716
775
 
776
+ # ===== INTROSPECTION METHODS =====
777
+
778
+ @classmethod
779
+ def describe(cls, func: _F) -> _F:
780
+ """
781
+ Decorator that populates a function's docstring with connector capabilities.
782
+
783
+ This class method can be used as a decorator to automatically generate
784
+ comprehensive documentation for AI tool functions.
785
+
786
+ Usage:
787
+ @mcp.tool()
788
+ @ZendeskSupportConnector.describe
789
+ async def execute(entity: str, action: str, params: dict):
790
+ '''Execute operations.'''
791
+ ...
792
+
793
+ The decorated function's __doc__ will be updated with:
794
+ - Available entities and their actions
795
+ - Parameter signatures with required (*) and optional (?) markers
796
+ - Response structure documentation
797
+ - Example questions (if available in OpenAPI spec)
798
+
799
+ Args:
800
+ func: The function to decorate
801
+
802
+ Returns:
803
+ The same function with updated __doc__
804
+ """
805
+ description = generate_tool_description(ZendeskSupportConnectorModel)
806
+
807
+ original_doc = func.__doc__ or ""
808
+ if original_doc.strip():
809
+ func.__doc__ = f"{original_doc.strip()}\n{description}"
810
+ else:
811
+ func.__doc__ = description
812
+
813
+ return func
814
+
815
+ def list_entities(self) -> list[dict[str, Any]]:
816
+ """
817
+ Get structured data about available entities, actions, and parameters.
818
+
819
+ Returns a list of entity descriptions with:
820
+ - entity_name: Name of the entity (e.g., "contacts", "deals")
821
+ - description: Entity description from the first endpoint
822
+ - available_actions: List of actions (e.g., ["list", "get", "create"])
823
+ - parameters: Dict mapping action -> list of parameter dicts
824
+
825
+ Example:
826
+ entities = connector.list_entities()
827
+ for entity in entities:
828
+ print(f"{entity['entity_name']}: {entity['available_actions']}")
829
+ """
830
+ return describe_entities(ZendeskSupportConnectorModel)
831
+
832
+ def entity_schema(self, entity: str) -> dict[str, Any] | None:
833
+ """
834
+ Get the JSON schema for an entity.
835
+
836
+ Args:
837
+ entity: Entity name (e.g., "contacts", "companies")
838
+
839
+ Returns:
840
+ JSON schema dict describing the entity structure, or None if not found.
841
+
842
+ Example:
843
+ schema = connector.entity_schema("contacts")
844
+ if schema:
845
+ print(f"Contact properties: {list(schema.get('properties', {}).keys())}")
846
+ """
847
+ entity_def = next(
848
+ (e for e in ZendeskSupportConnectorModel.entities if e.name == entity),
849
+ None
850
+ )
851
+ if entity_def is None:
852
+ logging.getLogger(__name__).warning(
853
+ f"Entity '{entity}' not found. Available entities: "
854
+ f"{[e.name for e in ZendeskSupportConnectorModel.entities]}"
855
+ )
856
+ return entity_def.entity_schema if entity_def else None
857
+
717
858
 
718
859
 
719
860
  class TicketsQuery:
@@ -755,7 +896,8 @@ class TicketsQuery:
755
896
  # Cast generic envelope to concrete typed result
756
897
  return TicketsListResult(
757
898
  data=result.data,
758
- meta=result.meta )
899
+ meta=result.meta
900
+ )
759
901
 
760
902
 
761
903
 
@@ -763,7 +905,7 @@ class TicketsQuery:
763
905
  self,
764
906
  ticket_id: str,
765
907
  **kwargs
766
- ) -> TicketsGetResult:
908
+ ) -> Ticket:
767
909
  """
768
910
  Returns a ticket by its ID
769
911
 
@@ -772,7 +914,7 @@ class TicketsQuery:
772
914
  **kwargs: Additional parameters
773
915
 
774
916
  Returns:
775
- TicketsGetResult
917
+ Ticket
776
918
  """
777
919
  params = {k: v for k, v in {
778
920
  "ticket_id": ticket_id,
@@ -780,11 +922,102 @@ class TicketsQuery:
780
922
  }.items() if v is not None}
781
923
 
782
924
  result = await self._connector.execute("tickets", "get", params)
783
- # Cast generic envelope to concrete typed result
784
- return TicketsGetResult(
785
- data=result.data )
925
+ return result
926
+
786
927
 
787
928
 
929
+ async def search(
930
+ self,
931
+ query: TicketsSearchQuery,
932
+ limit: int | None = None,
933
+ cursor: str | None = None,
934
+ fields: list[list[str]] | None = None,
935
+ ) -> TicketsSearchResult:
936
+ """
937
+ Search tickets records from Airbyte cache.
938
+
939
+ This operation searches cached data from Airbyte syncs.
940
+ Only available in hosted execution mode.
941
+
942
+ Available filter fields (TicketsSearchFilter):
943
+ - allow_attachments: Boolean indicating whether attachments are allowed on the ticket
944
+ - allow_channelback: Boolean indicating whether agents can reply to the ticket through the original channel
945
+ - assignee_id: Unique identifier of the agent currently assigned to the ticket
946
+ - brand_id: Unique identifier of the brand associated with the ticket in multi-brand accounts
947
+ - collaborator_ids: Array of user identifiers who are collaborating on the ticket
948
+ - created_at: Timestamp indicating when the ticket was created
949
+ - custom_fields: Array of custom field values specific to the account's ticket configuration
950
+ - custom_status_id: Unique identifier of the custom status applied to the ticket
951
+ - deleted_ticket_form_id: Unique identifier of the ticket form if it was deleted after the ticket was created
952
+ - description: Initial description or content of the ticket when it was created
953
+ - due_at: Timestamp indicating when the ticket is due for completion or resolution
954
+ - email_cc_ids: Array of user identifiers who are CC'd on ticket email notifications
955
+ - external_id: External identifier for the ticket, used for integrations with other systems
956
+ - fields: Array of ticket field values including both system and custom fields
957
+ - follower_ids: Array of user identifiers who are following the ticket for updates
958
+ - followup_ids: Array of identifiers for follow-up tickets related to this ticket
959
+ - forum_topic_id: Unique identifier linking the ticket to a forum topic if applicable
960
+ - from_messaging_channel: Boolean indicating whether the ticket originated from a messaging channel
961
+ - generated_timestamp: Timestamp updated for all ticket updates including system changes, used for incremental export co...
962
+ - group_id: Unique identifier of the agent group assigned to handle the ticket
963
+ - has_incidents: Boolean indicating whether this problem ticket has related incident tickets
964
+ - id: Unique identifier for the ticket
965
+ - is_public: Boolean indicating whether the ticket is publicly visible
966
+ - organization_id: Unique identifier of the organization associated with the ticket
967
+ - priority: Priority level assigned to the ticket (e.g., urgent, high, normal, low)
968
+ - problem_id: Unique identifier of the problem ticket if this is an incident ticket
969
+ - raw_subject: Original unprocessed subject line before any system modifications
970
+ - recipient: Email address or identifier of the ticket recipient
971
+ - requester_id: Unique identifier of the user who requested or created the ticket
972
+ - satisfaction_rating: Object containing customer satisfaction rating data for the ticket
973
+ - sharing_agreement_ids: Array of sharing agreement identifiers if the ticket is shared across Zendesk instances
974
+ - status: Current status of the ticket (e.g., new, open, pending, solved, closed)
975
+ - subject: Subject line of the ticket describing the issue or request
976
+ - submitter_id: Unique identifier of the user who submitted the ticket on behalf of the requester
977
+ - tags: Array of tags applied to the ticket for categorization and filtering
978
+ - ticket_form_id: Unique identifier of the ticket form used when creating the ticket
979
+ - type: Type of ticket (e.g., problem, incident, question, task)
980
+ - updated_at: Timestamp indicating when the ticket was last updated with a ticket event
981
+ - url: API URL to access the full ticket resource
982
+ - via: Object describing the channel and method through which the ticket was created
983
+
984
+ Args:
985
+ query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
986
+ in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
987
+ limit: Maximum results to return (default 1000)
988
+ cursor: Pagination cursor from previous response's next_cursor
989
+ fields: Field paths to include in results. Each path is a list of keys for nested access.
990
+ Example: [["id"], ["user", "name"]] returns id and user.name fields.
991
+
992
+ Returns:
993
+ TicketsSearchResult with hits (list of AirbyteSearchHit[TicketsSearchData]) and pagination info
994
+
995
+ Raises:
996
+ NotImplementedError: If called in local execution mode
997
+ """
998
+ params: dict[str, Any] = {"query": query}
999
+ if limit is not None:
1000
+ params["limit"] = limit
1001
+ if cursor is not None:
1002
+ params["cursor"] = cursor
1003
+ if fields is not None:
1004
+ params["fields"] = fields
1005
+
1006
+ result = await self._connector.execute("tickets", "search", params)
1007
+
1008
+ # Parse response into typed result
1009
+ return TicketsSearchResult(
1010
+ hits=[
1011
+ AirbyteSearchHit[TicketsSearchData](
1012
+ id=hit.get("id"),
1013
+ score=hit.get("score"),
1014
+ data=TicketsSearchData(**hit.get("data", {}))
1015
+ )
1016
+ for hit in result.get("hits", [])
1017
+ ],
1018
+ next_cursor=result.get("next_cursor"),
1019
+ took_ms=result.get("took_ms")
1020
+ )
788
1021
 
789
1022
  class UsersQuery:
790
1023
  """
@@ -825,7 +1058,8 @@ class UsersQuery:
825
1058
  # Cast generic envelope to concrete typed result
826
1059
  return UsersListResult(
827
1060
  data=result.data,
828
- meta=result.meta )
1061
+ meta=result.meta
1062
+ )
829
1063
 
830
1064
 
831
1065
 
@@ -833,7 +1067,7 @@ class UsersQuery:
833
1067
  self,
834
1068
  user_id: str,
835
1069
  **kwargs
836
- ) -> UsersGetResult:
1070
+ ) -> User:
837
1071
  """
838
1072
  Returns a user by their ID
839
1073
 
@@ -842,7 +1076,7 @@ class UsersQuery:
842
1076
  **kwargs: Additional parameters
843
1077
 
844
1078
  Returns:
845
- UsersGetResult
1079
+ User
846
1080
  """
847
1081
  params = {k: v for k, v in {
848
1082
  "user_id": user_id,
@@ -850,11 +1084,101 @@ class UsersQuery:
850
1084
  }.items() if v is not None}
851
1085
 
852
1086
  result = await self._connector.execute("users", "get", params)
853
- # Cast generic envelope to concrete typed result
854
- return UsersGetResult(
855
- data=result.data )
1087
+ return result
1088
+
856
1089
 
857
1090
 
1091
+ async def search(
1092
+ self,
1093
+ query: UsersSearchQuery,
1094
+ limit: int | None = None,
1095
+ cursor: str | None = None,
1096
+ fields: list[list[str]] | None = None,
1097
+ ) -> UsersSearchResult:
1098
+ """
1099
+ Search users records from Airbyte cache.
1100
+
1101
+ This operation searches cached data from Airbyte syncs.
1102
+ Only available in hosted execution mode.
1103
+
1104
+ Available filter fields (UsersSearchFilter):
1105
+ - active: Indicates if the user account is currently active
1106
+ - alias: Alternative name or nickname for the user
1107
+ - chat_only: Indicates if the user can only interact via chat
1108
+ - created_at: Timestamp indicating when the user was created
1109
+ - custom_role_id: Identifier for a custom role assigned to the user
1110
+ - default_group_id: Identifier of the default group assigned to the user
1111
+ - details: Additional descriptive information about the user
1112
+ - email: Email address of the user
1113
+ - external_id: External system identifier for the user, used for integrations
1114
+ - iana_time_zone: IANA standard time zone identifier for the user
1115
+ - id: Unique identifier for the user
1116
+ - last_login_at: Timestamp of the user's most recent login
1117
+ - locale: Locale setting determining language and regional format preferences
1118
+ - locale_id: Identifier for the user's locale preference
1119
+ - moderator: Indicates if the user has moderator privileges
1120
+ - name: Display name of the user
1121
+ - notes: Internal notes about the user, visible only to agents
1122
+ - only_private_comments: Indicates if the user can only make private comments on tickets
1123
+ - organization_id: Identifier of the organization the user belongs to
1124
+ - permanently_deleted: Indicates if the user has been permanently deleted from the system
1125
+ - phone: Phone number of the user
1126
+ - photo: Profile photo or avatar of the user
1127
+ - report_csv: Indicates if the user receives reports in CSV format
1128
+ - restricted_agent: Indicates if the agent has restricted access permissions
1129
+ - role: Role assigned to the user defining their permissions level
1130
+ - role_type: Type classification of the user's role
1131
+ - shared: Indicates if the user is shared across multiple accounts
1132
+ - shared_agent: Indicates if the user is a shared agent across multiple brands or accounts
1133
+ - shared_phone_number: Indicates if the phone number is shared with other users
1134
+ - signature: Email signature text for the user
1135
+ - suspended: Indicates if the user account is suspended
1136
+ - tags: Labels or tags associated with the user for categorization
1137
+ - ticket_restriction: Defines which tickets the user can access based on restrictions
1138
+ - time_zone: Time zone setting for the user
1139
+ - two_factor_auth_enabled: Indicates if two-factor authentication is enabled for the user
1140
+ - updated_at: Timestamp indicating when the user was last updated
1141
+ - url: API endpoint URL for accessing the user's detailed information
1142
+ - user_fields: Custom field values specific to the user, stored as key-value pairs
1143
+ - verified: Indicates if the user's identity has been verified
1144
+
1145
+ Args:
1146
+ query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
1147
+ in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
1148
+ limit: Maximum results to return (default 1000)
1149
+ cursor: Pagination cursor from previous response's next_cursor
1150
+ fields: Field paths to include in results. Each path is a list of keys for nested access.
1151
+ Example: [["id"], ["user", "name"]] returns id and user.name fields.
1152
+
1153
+ Returns:
1154
+ UsersSearchResult with hits (list of AirbyteSearchHit[UsersSearchData]) and pagination info
1155
+
1156
+ Raises:
1157
+ NotImplementedError: If called in local execution mode
1158
+ """
1159
+ params: dict[str, Any] = {"query": query}
1160
+ if limit is not None:
1161
+ params["limit"] = limit
1162
+ if cursor is not None:
1163
+ params["cursor"] = cursor
1164
+ if fields is not None:
1165
+ params["fields"] = fields
1166
+
1167
+ result = await self._connector.execute("users", "search", params)
1168
+
1169
+ # Parse response into typed result
1170
+ return UsersSearchResult(
1171
+ hits=[
1172
+ AirbyteSearchHit[UsersSearchData](
1173
+ id=hit.get("id"),
1174
+ score=hit.get("score"),
1175
+ data=UsersSearchData(**hit.get("data", {}))
1176
+ )
1177
+ for hit in result.get("hits", [])
1178
+ ],
1179
+ next_cursor=result.get("next_cursor"),
1180
+ took_ms=result.get("took_ms")
1181
+ )
858
1182
 
859
1183
  class OrganizationsQuery:
860
1184
  """
@@ -889,7 +1213,8 @@ class OrganizationsQuery:
889
1213
  # Cast generic envelope to concrete typed result
890
1214
  return OrganizationsListResult(
891
1215
  data=result.data,
892
- meta=result.meta )
1216
+ meta=result.meta
1217
+ )
893
1218
 
894
1219
 
895
1220
 
@@ -897,7 +1222,7 @@ class OrganizationsQuery:
897
1222
  self,
898
1223
  organization_id: str,
899
1224
  **kwargs
900
- ) -> OrganizationsGetResult:
1225
+ ) -> Organization:
901
1226
  """
902
1227
  Returns an organization by its ID
903
1228
 
@@ -906,7 +1231,7 @@ class OrganizationsQuery:
906
1231
  **kwargs: Additional parameters
907
1232
 
908
1233
  Returns:
909
- OrganizationsGetResult
1234
+ Organization
910
1235
  """
911
1236
  params = {k: v for k, v in {
912
1237
  "organization_id": organization_id,
@@ -914,11 +1239,77 @@ class OrganizationsQuery:
914
1239
  }.items() if v is not None}
915
1240
 
916
1241
  result = await self._connector.execute("organizations", "get", params)
917
- # Cast generic envelope to concrete typed result
918
- return OrganizationsGetResult(
919
- data=result.data )
1242
+ return result
1243
+
1244
+
1245
+
1246
+ async def search(
1247
+ self,
1248
+ query: OrganizationsSearchQuery,
1249
+ limit: int | None = None,
1250
+ cursor: str | None = None,
1251
+ fields: list[list[str]] | None = None,
1252
+ ) -> OrganizationsSearchResult:
1253
+ """
1254
+ Search organizations records from Airbyte cache.
1255
+
1256
+ This operation searches cached data from Airbyte syncs.
1257
+ Only available in hosted execution mode.
1258
+
1259
+ Available filter fields (OrganizationsSearchFilter):
1260
+ - created_at: Timestamp when the organization was created
1261
+ - deleted_at: Timestamp when the organization was deleted
1262
+ - details: Details about the organization, such as the address
1263
+ - domain_names: Array of domain names associated with this organization for automatic user assignment
1264
+ - external_id: Unique external identifier to associate the organization to an external record (case-insensitive)
1265
+ - group_id: ID of the group where new tickets from users in this organization are automatically assigned
1266
+ - id: Unique identifier automatically assigned when the organization is created
1267
+ - name: Unique name for the organization (mandatory field)
1268
+ - notes: Notes about the organization
1269
+ - organization_fields: Key-value object for custom organization fields
1270
+ - shared_comments: Boolean indicating whether end users in this organization can comment on each other's tickets
1271
+ - shared_tickets: Boolean indicating whether end users in this organization can see each other's tickets
1272
+ - tags: Array of tags associated with the organization
1273
+ - updated_at: Timestamp of the last update to the organization
1274
+ - url: The API URL of this organization
920
1275
 
1276
+ Args:
1277
+ query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
1278
+ in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
1279
+ limit: Maximum results to return (default 1000)
1280
+ cursor: Pagination cursor from previous response's next_cursor
1281
+ fields: Field paths to include in results. Each path is a list of keys for nested access.
1282
+ Example: [["id"], ["user", "name"]] returns id and user.name fields.
921
1283
 
1284
+ Returns:
1285
+ OrganizationsSearchResult with hits (list of AirbyteSearchHit[OrganizationsSearchData]) and pagination info
1286
+
1287
+ Raises:
1288
+ NotImplementedError: If called in local execution mode
1289
+ """
1290
+ params: dict[str, Any] = {"query": query}
1291
+ if limit is not None:
1292
+ params["limit"] = limit
1293
+ if cursor is not None:
1294
+ params["cursor"] = cursor
1295
+ if fields is not None:
1296
+ params["fields"] = fields
1297
+
1298
+ result = await self._connector.execute("organizations", "search", params)
1299
+
1300
+ # Parse response into typed result
1301
+ return OrganizationsSearchResult(
1302
+ hits=[
1303
+ AirbyteSearchHit[OrganizationsSearchData](
1304
+ id=hit.get("id"),
1305
+ score=hit.get("score"),
1306
+ data=OrganizationsSearchData(**hit.get("data", {}))
1307
+ )
1308
+ for hit in result.get("hits", [])
1309
+ ],
1310
+ next_cursor=result.get("next_cursor"),
1311
+ took_ms=result.get("took_ms")
1312
+ )
922
1313
 
923
1314
  class GroupsQuery:
924
1315
  """
@@ -956,7 +1347,8 @@ class GroupsQuery:
956
1347
  # Cast generic envelope to concrete typed result
957
1348
  return GroupsListResult(
958
1349
  data=result.data,
959
- meta=result.meta )
1350
+ meta=result.meta
1351
+ )
960
1352
 
961
1353
 
962
1354
 
@@ -964,7 +1356,7 @@ class GroupsQuery:
964
1356
  self,
965
1357
  group_id: str,
966
1358
  **kwargs
967
- ) -> GroupsGetResult:
1359
+ ) -> Group:
968
1360
  """
969
1361
  Returns a group by its ID
970
1362
 
@@ -973,7 +1365,7 @@ class GroupsQuery:
973
1365
  **kwargs: Additional parameters
974
1366
 
975
1367
  Returns:
976
- GroupsGetResult
1368
+ Group
977
1369
  """
978
1370
  params = {k: v for k, v in {
979
1371
  "group_id": group_id,
@@ -981,12 +1373,72 @@ class GroupsQuery:
981
1373
  }.items() if v is not None}
982
1374
 
983
1375
  result = await self._connector.execute("groups", "get", params)
984
- # Cast generic envelope to concrete typed result
985
- return GroupsGetResult(
986
- data=result.data )
1376
+ return result
987
1377
 
988
1378
 
989
1379
 
1380
+ async def search(
1381
+ self,
1382
+ query: GroupsSearchQuery,
1383
+ limit: int | None = None,
1384
+ cursor: str | None = None,
1385
+ fields: list[list[str]] | None = None,
1386
+ ) -> GroupsSearchResult:
1387
+ """
1388
+ Search groups records from Airbyte cache.
1389
+
1390
+ This operation searches cached data from Airbyte syncs.
1391
+ Only available in hosted execution mode.
1392
+
1393
+ Available filter fields (GroupsSearchFilter):
1394
+ - created_at: Timestamp indicating when the group was created
1395
+ - default: Indicates if the group is the default one for the account
1396
+ - deleted: Indicates whether the group has been deleted
1397
+ - description: The description of the group
1398
+ - id: Unique identifier automatically assigned when creating groups
1399
+ - is_public: Indicates if the group is public (true) or private (false)
1400
+ - name: The name of the group
1401
+ - updated_at: Timestamp indicating when the group was last updated
1402
+ - url: The API URL of the group
1403
+
1404
+ Args:
1405
+ query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
1406
+ in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
1407
+ limit: Maximum results to return (default 1000)
1408
+ cursor: Pagination cursor from previous response's next_cursor
1409
+ fields: Field paths to include in results. Each path is a list of keys for nested access.
1410
+ Example: [["id"], ["user", "name"]] returns id and user.name fields.
1411
+
1412
+ Returns:
1413
+ GroupsSearchResult with hits (list of AirbyteSearchHit[GroupsSearchData]) and pagination info
1414
+
1415
+ Raises:
1416
+ NotImplementedError: If called in local execution mode
1417
+ """
1418
+ params: dict[str, Any] = {"query": query}
1419
+ if limit is not None:
1420
+ params["limit"] = limit
1421
+ if cursor is not None:
1422
+ params["cursor"] = cursor
1423
+ if fields is not None:
1424
+ params["fields"] = fields
1425
+
1426
+ result = await self._connector.execute("groups", "search", params)
1427
+
1428
+ # Parse response into typed result
1429
+ return GroupsSearchResult(
1430
+ hits=[
1431
+ AirbyteSearchHit[GroupsSearchData](
1432
+ id=hit.get("id"),
1433
+ score=hit.get("score"),
1434
+ data=GroupsSearchData(**hit.get("data", {}))
1435
+ )
1436
+ for hit in result.get("hits", [])
1437
+ ],
1438
+ next_cursor=result.get("next_cursor"),
1439
+ took_ms=result.get("took_ms")
1440
+ )
1441
+
990
1442
  class TicketCommentsQuery:
991
1443
  """
992
1444
  Query class for TicketComments entity operations.
@@ -1029,9 +1481,80 @@ class TicketCommentsQuery:
1029
1481
  # Cast generic envelope to concrete typed result
1030
1482
  return TicketCommentsListResult(
1031
1483
  data=result.data,
1032
- meta=result.meta )
1484
+ meta=result.meta
1485
+ )
1486
+
1033
1487
 
1034
1488
 
1489
+ async def search(
1490
+ self,
1491
+ query: TicketCommentsSearchQuery,
1492
+ limit: int | None = None,
1493
+ cursor: str | None = None,
1494
+ fields: list[list[str]] | None = None,
1495
+ ) -> TicketCommentsSearchResult:
1496
+ """
1497
+ Search ticket_comments records from Airbyte cache.
1498
+
1499
+ This operation searches cached data from Airbyte syncs.
1500
+ Only available in hosted execution mode.
1501
+
1502
+ Available filter fields (TicketCommentsSearchFilter):
1503
+ - attachments: List of files or media attached to the comment
1504
+ - audit_id: Identifier of the audit record associated with this comment event
1505
+ - author_id: Identifier of the user who created the comment
1506
+ - body: Content of the comment in its original format
1507
+ - created_at: Timestamp when the comment was created
1508
+ - event_type: Specific classification of the event within the ticket event stream
1509
+ - html_body: HTML-formatted content of the comment
1510
+ - id: Unique identifier for the comment event
1511
+ - metadata: Additional structured information about the comment not covered by standard fields
1512
+ - plain_body: Plain text content of the comment without formatting
1513
+ - public: Boolean indicating whether the comment is visible to end users or is an internal note
1514
+ - ticket_id: Identifier of the ticket to which this comment belongs
1515
+ - timestamp: Timestamp of when the event occurred in the incremental export stream
1516
+ - type: Type of event, typically indicating this is a comment event
1517
+ - uploads: Array of upload tokens or identifiers for files being attached to the comment
1518
+ - via: Channel or method through which the comment was submitted
1519
+ - via_reference_id: Reference identifier for the channel through which the comment was created
1520
+
1521
+ Args:
1522
+ query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
1523
+ in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
1524
+ limit: Maximum results to return (default 1000)
1525
+ cursor: Pagination cursor from previous response's next_cursor
1526
+ fields: Field paths to include in results. Each path is a list of keys for nested access.
1527
+ Example: [["id"], ["user", "name"]] returns id and user.name fields.
1528
+
1529
+ Returns:
1530
+ TicketCommentsSearchResult with hits (list of AirbyteSearchHit[TicketCommentsSearchData]) and pagination info
1531
+
1532
+ Raises:
1533
+ NotImplementedError: If called in local execution mode
1534
+ """
1535
+ params: dict[str, Any] = {"query": query}
1536
+ if limit is not None:
1537
+ params["limit"] = limit
1538
+ if cursor is not None:
1539
+ params["cursor"] = cursor
1540
+ if fields is not None:
1541
+ params["fields"] = fields
1542
+
1543
+ result = await self._connector.execute("ticket_comments", "search", params)
1544
+
1545
+ # Parse response into typed result
1546
+ return TicketCommentsSearchResult(
1547
+ hits=[
1548
+ AirbyteSearchHit[TicketCommentsSearchData](
1549
+ id=hit.get("id"),
1550
+ score=hit.get("score"),
1551
+ data=TicketCommentsSearchData(**hit.get("data", {}))
1552
+ )
1553
+ for hit in result.get("hits", [])
1554
+ ],
1555
+ next_cursor=result.get("next_cursor"),
1556
+ took_ms=result.get("took_ms")
1557
+ )
1035
1558
 
1036
1559
  class AttachmentsQuery:
1037
1560
  """
@@ -1046,7 +1569,7 @@ class AttachmentsQuery:
1046
1569
  self,
1047
1570
  attachment_id: str,
1048
1571
  **kwargs
1049
- ) -> AttachmentsGetResult:
1572
+ ) -> Attachment:
1050
1573
  """
1051
1574
  Returns an attachment by its ID
1052
1575
 
@@ -1055,7 +1578,7 @@ class AttachmentsQuery:
1055
1578
  **kwargs: Additional parameters
1056
1579
 
1057
1580
  Returns:
1058
- AttachmentsGetResult
1581
+ Attachment
1059
1582
  """
1060
1583
  params = {k: v for k, v in {
1061
1584
  "attachment_id": attachment_id,
@@ -1063,9 +1586,7 @@ class AttachmentsQuery:
1063
1586
  }.items() if v is not None}
1064
1587
 
1065
1588
  result = await self._connector.execute("attachments", "get", params)
1066
- # Cast generic envelope to concrete typed result
1067
- return AttachmentsGetResult(
1068
- data=result.data )
1589
+ return result
1069
1590
 
1070
1591
 
1071
1592
 
@@ -1160,7 +1681,8 @@ class TicketAuditsQuery:
1160
1681
  # Cast generic envelope to concrete typed result
1161
1682
  return TicketAuditsListResult(
1162
1683
  data=result.data,
1163
- meta=result.meta )
1684
+ meta=result.meta
1685
+ )
1164
1686
 
1165
1687
 
1166
1688
 
@@ -1191,9 +1713,71 @@ class TicketAuditsQuery:
1191
1713
  # Cast generic envelope to concrete typed result
1192
1714
  return TicketAuditsListResult(
1193
1715
  data=result.data,
1194
- meta=result.meta )
1716
+ meta=result.meta
1717
+ )
1718
+
1195
1719
 
1196
1720
 
1721
+ async def search(
1722
+ self,
1723
+ query: TicketAuditsSearchQuery,
1724
+ limit: int | None = None,
1725
+ cursor: str | None = None,
1726
+ fields: list[list[str]] | None = None,
1727
+ ) -> TicketAuditsSearchResult:
1728
+ """
1729
+ Search ticket_audits records from Airbyte cache.
1730
+
1731
+ This operation searches cached data from Airbyte syncs.
1732
+ Only available in hosted execution mode.
1733
+
1734
+ Available filter fields (TicketAuditsSearchFilter):
1735
+ - attachments: Files or documents attached to the audit
1736
+ - author_id: The unique identifier of the user who created the audit
1737
+ - created_at: Timestamp indicating when the audit was created
1738
+ - events: Array of events that occurred in this audit, such as field changes, comments, or tag updates
1739
+ - id: Unique identifier for the audit record, automatically assigned when the audit is created
1740
+ - metadata: Custom and system data associated with the audit
1741
+ - ticket_id: The unique identifier of the ticket associated with this audit
1742
+ - via: Describes how the audit was created, providing context about the creation source
1743
+
1744
+ Args:
1745
+ query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
1746
+ in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
1747
+ limit: Maximum results to return (default 1000)
1748
+ cursor: Pagination cursor from previous response's next_cursor
1749
+ fields: Field paths to include in results. Each path is a list of keys for nested access.
1750
+ Example: [["id"], ["user", "name"]] returns id and user.name fields.
1751
+
1752
+ Returns:
1753
+ TicketAuditsSearchResult with hits (list of AirbyteSearchHit[TicketAuditsSearchData]) and pagination info
1754
+
1755
+ Raises:
1756
+ NotImplementedError: If called in local execution mode
1757
+ """
1758
+ params: dict[str, Any] = {"query": query}
1759
+ if limit is not None:
1760
+ params["limit"] = limit
1761
+ if cursor is not None:
1762
+ params["cursor"] = cursor
1763
+ if fields is not None:
1764
+ params["fields"] = fields
1765
+
1766
+ result = await self._connector.execute("ticket_audits", "search", params)
1767
+
1768
+ # Parse response into typed result
1769
+ return TicketAuditsSearchResult(
1770
+ hits=[
1771
+ AirbyteSearchHit[TicketAuditsSearchData](
1772
+ id=hit.get("id"),
1773
+ score=hit.get("score"),
1774
+ data=TicketAuditsSearchData(**hit.get("data", {}))
1775
+ )
1776
+ for hit in result.get("hits", [])
1777
+ ],
1778
+ next_cursor=result.get("next_cursor"),
1779
+ took_ms=result.get("took_ms")
1780
+ )
1197
1781
 
1198
1782
  class TicketMetricsQuery:
1199
1783
  """
@@ -1228,9 +1812,93 @@ class TicketMetricsQuery:
1228
1812
  # Cast generic envelope to concrete typed result
1229
1813
  return TicketMetricsListResult(
1230
1814
  data=result.data,
1231
- meta=result.meta )
1815
+ meta=result.meta
1816
+ )
1817
+
1818
+
1232
1819
 
1820
+ async def search(
1821
+ self,
1822
+ query: TicketMetricsSearchQuery,
1823
+ limit: int | None = None,
1824
+ cursor: str | None = None,
1825
+ fields: list[list[str]] | None = None,
1826
+ ) -> TicketMetricsSearchResult:
1827
+ """
1828
+ Search ticket_metrics records from Airbyte cache.
1829
+
1830
+ This operation searches cached data from Airbyte syncs.
1831
+ Only available in hosted execution mode.
1832
+
1833
+ Available filter fields (TicketMetricsSearchFilter):
1834
+ - agent_wait_time_in_minutes: Number of minutes the agent spent waiting during calendar and business hours
1835
+ - assigned_at: Timestamp when the ticket was assigned
1836
+ - assignee_stations: Number of assignees the ticket had
1837
+ - assignee_updated_at: Timestamp when the assignee last updated the ticket
1838
+ - created_at: Timestamp when the metric record was created
1839
+ - custom_status_updated_at: Timestamp when the ticket's custom status was last updated
1840
+ - first_resolution_time_in_minutes: Number of minutes to the first resolution time during calendar and business hours
1841
+ - full_resolution_time_in_minutes: Number of minutes to the full resolution during calendar and business hours
1842
+ - generated_timestamp: Timestamp of when record was last updated
1843
+ - group_stations: Number of groups the ticket passed through
1844
+ - id: Unique identifier for the ticket metric record
1845
+ - initially_assigned_at: Timestamp when the ticket was initially assigned
1846
+ - instance_id: ID of the Zendesk instance associated with the ticket
1847
+ - latest_comment_added_at: Timestamp when the latest comment was added
1848
+ - metric: Ticket metrics data
1849
+ - on_hold_time_in_minutes: Number of minutes on hold
1850
+ - reopens: Total number of times the ticket was reopened
1851
+ - replies: The number of public replies added to a ticket by an agent
1852
+ - reply_time_in_minutes: Number of minutes to the first reply during calendar and business hours
1853
+ - reply_time_in_seconds: Number of seconds to the first reply during calendar hours, only available for Messaging tickets
1854
+ - requester_updated_at: Timestamp when the requester last updated the ticket
1855
+ - requester_wait_time_in_minutes: Number of minutes the requester spent waiting during calendar and business hours
1856
+ - solved_at: Timestamp when the ticket was solved
1857
+ - status: The current status of the ticket (open, pending, solved, etc.).
1858
+ - status_updated_at: Timestamp when the status of the ticket was last updated
1859
+ - ticket_id: Identifier of the associated ticket
1860
+ - time: Time related to the ticket
1861
+ - type: Type of ticket
1862
+ - updated_at: Timestamp when the metric record was last updated
1863
+ - url: The API url of the ticket metric
1233
1864
 
1865
+ Args:
1866
+ query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
1867
+ in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
1868
+ limit: Maximum results to return (default 1000)
1869
+ cursor: Pagination cursor from previous response's next_cursor
1870
+ fields: Field paths to include in results. Each path is a list of keys for nested access.
1871
+ Example: [["id"], ["user", "name"]] returns id and user.name fields.
1872
+
1873
+ Returns:
1874
+ TicketMetricsSearchResult with hits (list of AirbyteSearchHit[TicketMetricsSearchData]) and pagination info
1875
+
1876
+ Raises:
1877
+ NotImplementedError: If called in local execution mode
1878
+ """
1879
+ params: dict[str, Any] = {"query": query}
1880
+ if limit is not None:
1881
+ params["limit"] = limit
1882
+ if cursor is not None:
1883
+ params["cursor"] = cursor
1884
+ if fields is not None:
1885
+ params["fields"] = fields
1886
+
1887
+ result = await self._connector.execute("ticket_metrics", "search", params)
1888
+
1889
+ # Parse response into typed result
1890
+ return TicketMetricsSearchResult(
1891
+ hits=[
1892
+ AirbyteSearchHit[TicketMetricsSearchData](
1893
+ id=hit.get("id"),
1894
+ score=hit.get("score"),
1895
+ data=TicketMetricsSearchData(**hit.get("data", {}))
1896
+ )
1897
+ for hit in result.get("hits", [])
1898
+ ],
1899
+ next_cursor=result.get("next_cursor"),
1900
+ took_ms=result.get("took_ms")
1901
+ )
1234
1902
 
1235
1903
  class TicketFieldsQuery:
1236
1904
  """
@@ -1268,7 +1936,8 @@ class TicketFieldsQuery:
1268
1936
  # Cast generic envelope to concrete typed result
1269
1937
  return TicketFieldsListResult(
1270
1938
  data=result.data,
1271
- meta=result.meta )
1939
+ meta=result.meta
1940
+ )
1272
1941
 
1273
1942
 
1274
1943
 
@@ -1276,7 +1945,7 @@ class TicketFieldsQuery:
1276
1945
  self,
1277
1946
  ticket_field_id: str,
1278
1947
  **kwargs
1279
- ) -> TicketFieldsGetResult:
1948
+ ) -> TicketField:
1280
1949
  """
1281
1950
  Returns a ticket field by its ID
1282
1951
 
@@ -1285,7 +1954,7 @@ class TicketFieldsQuery:
1285
1954
  **kwargs: Additional parameters
1286
1955
 
1287
1956
  Returns:
1288
- TicketFieldsGetResult
1957
+ TicketField
1289
1958
  """
1290
1959
  params = {k: v for k, v in {
1291
1960
  "ticket_field_id": ticket_field_id,
@@ -1293,11 +1962,89 @@ class TicketFieldsQuery:
1293
1962
  }.items() if v is not None}
1294
1963
 
1295
1964
  result = await self._connector.execute("ticket_fields", "get", params)
1296
- # Cast generic envelope to concrete typed result
1297
- return TicketFieldsGetResult(
1298
- data=result.data )
1965
+ return result
1966
+
1299
1967
 
1300
1968
 
1969
+ async def search(
1970
+ self,
1971
+ query: TicketFieldsSearchQuery,
1972
+ limit: int | None = None,
1973
+ cursor: str | None = None,
1974
+ fields: list[list[str]] | None = None,
1975
+ ) -> TicketFieldsSearchResult:
1976
+ """
1977
+ Search ticket_fields records from Airbyte cache.
1978
+
1979
+ This operation searches cached data from Airbyte syncs.
1980
+ Only available in hosted execution mode.
1981
+
1982
+ Available filter fields (TicketFieldsSearchFilter):
1983
+ - active: Whether this field is currently available for use
1984
+ - agent_description: A description of the ticket field that only agents can see
1985
+ - collapsed_for_agents: If true, the field is shown to agents by default; if false, it is hidden alongside infrequently u...
1986
+ - created_at: Timestamp when the custom ticket field was created
1987
+ - custom_field_options: Array of option objects for custom ticket fields of type multiselect or tagger, containing name a...
1988
+ - custom_statuses: List of customized ticket statuses, only present for system ticket fields of type custom_status
1989
+ - description: Text describing the purpose of the ticket field to users
1990
+ - editable_in_portal: Whether this field is editable by end users in Help Center
1991
+ - id: Unique identifier for the ticket field, automatically assigned when created
1992
+ - key: Internal identifier or reference key for the field
1993
+ - position: The relative position of the ticket field on a ticket, controlling display order
1994
+ - raw_description: The dynamic content placeholder if present, or the description value if not
1995
+ - raw_title: The dynamic content placeholder if present, or the title value if not
1996
+ - raw_title_in_portal: The dynamic content placeholder if present, or the title_in_portal value if not
1997
+ - regexp_for_validation: For regexp fields only, the validation pattern for a field value to be deemed valid
1998
+ - removable: If false, this field is a system field that must be present on all tickets
1999
+ - required: If true, agents must enter a value in the field to change the ticket status to solved
2000
+ - required_in_portal: If true, end users must enter a value in the field to create a request
2001
+ - sub_type_id: For system ticket fields of type priority and status, controlling available options
2002
+ - system_field_options: Array of options for system ticket fields of type tickettype, priority, or status
2003
+ - tag: For checkbox fields only, a tag added to tickets when the checkbox field is selected
2004
+ - title: The title of the ticket field displayed to agents
2005
+ - title_in_portal: The title of the ticket field displayed to end users in Help Center
2006
+ - type: Field type such as text, textarea, checkbox, date, integer, decimal, regexp, multiselect, tagger,...
2007
+ - updated_at: Timestamp when the custom ticket field was last updated
2008
+ - url: The API URL for this ticket field resource
2009
+ - visible_in_portal: Whether this field is visible to end users in Help Center
2010
+
2011
+ Args:
2012
+ query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
2013
+ in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
2014
+ limit: Maximum results to return (default 1000)
2015
+ cursor: Pagination cursor from previous response's next_cursor
2016
+ fields: Field paths to include in results. Each path is a list of keys for nested access.
2017
+ Example: [["id"], ["user", "name"]] returns id and user.name fields.
2018
+
2019
+ Returns:
2020
+ TicketFieldsSearchResult with hits (list of AirbyteSearchHit[TicketFieldsSearchData]) and pagination info
2021
+
2022
+ Raises:
2023
+ NotImplementedError: If called in local execution mode
2024
+ """
2025
+ params: dict[str, Any] = {"query": query}
2026
+ if limit is not None:
2027
+ params["limit"] = limit
2028
+ if cursor is not None:
2029
+ params["cursor"] = cursor
2030
+ if fields is not None:
2031
+ params["fields"] = fields
2032
+
2033
+ result = await self._connector.execute("ticket_fields", "search", params)
2034
+
2035
+ # Parse response into typed result
2036
+ return TicketFieldsSearchResult(
2037
+ hits=[
2038
+ AirbyteSearchHit[TicketFieldsSearchData](
2039
+ id=hit.get("id"),
2040
+ score=hit.get("score"),
2041
+ data=TicketFieldsSearchData(**hit.get("data", {}))
2042
+ )
2043
+ for hit in result.get("hits", [])
2044
+ ],
2045
+ next_cursor=result.get("next_cursor"),
2046
+ took_ms=result.get("took_ms")
2047
+ )
1301
2048
 
1302
2049
  class BrandsQuery:
1303
2050
  """
@@ -1332,7 +2079,8 @@ class BrandsQuery:
1332
2079
  # Cast generic envelope to concrete typed result
1333
2080
  return BrandsListResult(
1334
2081
  data=result.data,
1335
- meta=result.meta )
2082
+ meta=result.meta
2083
+ )
1336
2084
 
1337
2085
 
1338
2086
 
@@ -1340,7 +2088,7 @@ class BrandsQuery:
1340
2088
  self,
1341
2089
  brand_id: str,
1342
2090
  **kwargs
1343
- ) -> BrandsGetResult:
2091
+ ) -> Brand:
1344
2092
  """
1345
2093
  Returns a brand by its ID
1346
2094
 
@@ -1349,7 +2097,7 @@ class BrandsQuery:
1349
2097
  **kwargs: Additional parameters
1350
2098
 
1351
2099
  Returns:
1352
- BrandsGetResult
2100
+ Brand
1353
2101
  """
1354
2102
  params = {k: v for k, v in {
1355
2103
  "brand_id": brand_id,
@@ -1357,11 +2105,78 @@ class BrandsQuery:
1357
2105
  }.items() if v is not None}
1358
2106
 
1359
2107
  result = await self._connector.execute("brands", "get", params)
1360
- # Cast generic envelope to concrete typed result
1361
- return BrandsGetResult(
1362
- data=result.data )
2108
+ return result
2109
+
2110
+
2111
+
2112
+ async def search(
2113
+ self,
2114
+ query: BrandsSearchQuery,
2115
+ limit: int | None = None,
2116
+ cursor: str | None = None,
2117
+ fields: list[list[str]] | None = None,
2118
+ ) -> BrandsSearchResult:
2119
+ """
2120
+ Search brands records from Airbyte cache.
1363
2121
 
2122
+ This operation searches cached data from Airbyte syncs.
2123
+ Only available in hosted execution mode.
1364
2124
 
2125
+ Available filter fields (BrandsSearchFilter):
2126
+ - active: Indicates whether the brand is set as active
2127
+ - brand_url: The public URL of the brand
2128
+ - created_at: Timestamp when the brand was created
2129
+ - default: Indicates whether the brand is the default brand for tickets generated from non-branded channels
2130
+ - has_help_center: Indicates whether the brand has a Help Center enabled
2131
+ - help_center_state: The state of the Help Center, with allowed values of enabled, disabled, or restricted
2132
+ - host_mapping: The host mapping configuration for the brand, visible only to administrators
2133
+ - id: Unique identifier automatically assigned when the brand is created
2134
+ - is_deleted: Indicates whether the brand has been deleted
2135
+ - logo: Brand logo image file represented as an Attachment object
2136
+ - name: The name of the brand
2137
+ - signature_template: The signature template used for the brand
2138
+ - subdomain: The subdomain associated with the brand
2139
+ - ticket_form_ids: Array of ticket form IDs that are available for use by this brand
2140
+ - updated_at: Timestamp when the brand was last updated
2141
+ - url: The API URL for accessing this brand resource
2142
+
2143
+ Args:
2144
+ query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
2145
+ in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
2146
+ limit: Maximum results to return (default 1000)
2147
+ cursor: Pagination cursor from previous response's next_cursor
2148
+ fields: Field paths to include in results. Each path is a list of keys for nested access.
2149
+ Example: [["id"], ["user", "name"]] returns id and user.name fields.
2150
+
2151
+ Returns:
2152
+ BrandsSearchResult with hits (list of AirbyteSearchHit[BrandsSearchData]) and pagination info
2153
+
2154
+ Raises:
2155
+ NotImplementedError: If called in local execution mode
2156
+ """
2157
+ params: dict[str, Any] = {"query": query}
2158
+ if limit is not None:
2159
+ params["limit"] = limit
2160
+ if cursor is not None:
2161
+ params["cursor"] = cursor
2162
+ if fields is not None:
2163
+ params["fields"] = fields
2164
+
2165
+ result = await self._connector.execute("brands", "search", params)
2166
+
2167
+ # Parse response into typed result
2168
+ return BrandsSearchResult(
2169
+ hits=[
2170
+ AirbyteSearchHit[BrandsSearchData](
2171
+ id=hit.get("id"),
2172
+ score=hit.get("score"),
2173
+ data=BrandsSearchData(**hit.get("data", {}))
2174
+ )
2175
+ for hit in result.get("hits", [])
2176
+ ],
2177
+ next_cursor=result.get("next_cursor"),
2178
+ took_ms=result.get("took_ms")
2179
+ )
1365
2180
 
1366
2181
  class ViewsQuery:
1367
2182
  """
@@ -1411,7 +2226,8 @@ class ViewsQuery:
1411
2226
  # Cast generic envelope to concrete typed result
1412
2227
  return ViewsListResult(
1413
2228
  data=result.data,
1414
- meta=result.meta )
2229
+ meta=result.meta
2230
+ )
1415
2231
 
1416
2232
 
1417
2233
 
@@ -1419,7 +2235,7 @@ class ViewsQuery:
1419
2235
  self,
1420
2236
  view_id: str,
1421
2237
  **kwargs
1422
- ) -> ViewsGetResult:
2238
+ ) -> View:
1423
2239
  """
1424
2240
  Returns a view by its ID
1425
2241
 
@@ -1428,7 +2244,7 @@ class ViewsQuery:
1428
2244
  **kwargs: Additional parameters
1429
2245
 
1430
2246
  Returns:
1431
- ViewsGetResult
2247
+ View
1432
2248
  """
1433
2249
  params = {k: v for k, v in {
1434
2250
  "view_id": view_id,
@@ -1436,9 +2252,7 @@ class ViewsQuery:
1436
2252
  }.items() if v is not None}
1437
2253
 
1438
2254
  result = await self._connector.execute("views", "get", params)
1439
- # Cast generic envelope to concrete typed result
1440
- return ViewsGetResult(
1441
- data=result.data )
2255
+ return result
1442
2256
 
1443
2257
 
1444
2258
 
@@ -1496,7 +2310,8 @@ class MacrosQuery:
1496
2310
  # Cast generic envelope to concrete typed result
1497
2311
  return MacrosListResult(
1498
2312
  data=result.data,
1499
- meta=result.meta )
2313
+ meta=result.meta
2314
+ )
1500
2315
 
1501
2316
 
1502
2317
 
@@ -1504,7 +2319,7 @@ class MacrosQuery:
1504
2319
  self,
1505
2320
  macro_id: str,
1506
2321
  **kwargs
1507
- ) -> MacrosGetResult:
2322
+ ) -> Macro:
1508
2323
  """
1509
2324
  Returns a macro by its ID
1510
2325
 
@@ -1513,7 +2328,7 @@ class MacrosQuery:
1513
2328
  **kwargs: Additional parameters
1514
2329
 
1515
2330
  Returns:
1516
- MacrosGetResult
2331
+ Macro
1517
2332
  """
1518
2333
  params = {k: v for k, v in {
1519
2334
  "macro_id": macro_id,
@@ -1521,9 +2336,7 @@ class MacrosQuery:
1521
2336
  }.items() if v is not None}
1522
2337
 
1523
2338
  result = await self._connector.execute("macros", "get", params)
1524
- # Cast generic envelope to concrete typed result
1525
- return MacrosGetResult(
1526
- data=result.data )
2339
+ return result
1527
2340
 
1528
2341
 
1529
2342
 
@@ -1569,7 +2382,8 @@ class TriggersQuery:
1569
2382
  # Cast generic envelope to concrete typed result
1570
2383
  return TriggersListResult(
1571
2384
  data=result.data,
1572
- meta=result.meta )
2385
+ meta=result.meta
2386
+ )
1573
2387
 
1574
2388
 
1575
2389
 
@@ -1577,7 +2391,7 @@ class TriggersQuery:
1577
2391
  self,
1578
2392
  trigger_id: str,
1579
2393
  **kwargs
1580
- ) -> TriggersGetResult:
2394
+ ) -> Trigger:
1581
2395
  """
1582
2396
  Returns a trigger by its ID
1583
2397
 
@@ -1586,7 +2400,7 @@ class TriggersQuery:
1586
2400
  **kwargs: Additional parameters
1587
2401
 
1588
2402
  Returns:
1589
- TriggersGetResult
2403
+ Trigger
1590
2404
  """
1591
2405
  params = {k: v for k, v in {
1592
2406
  "trigger_id": trigger_id,
@@ -1594,9 +2408,7 @@ class TriggersQuery:
1594
2408
  }.items() if v is not None}
1595
2409
 
1596
2410
  result = await self._connector.execute("triggers", "get", params)
1597
- # Cast generic envelope to concrete typed result
1598
- return TriggersGetResult(
1599
- data=result.data )
2411
+ return result
1600
2412
 
1601
2413
 
1602
2414
 
@@ -1639,7 +2451,8 @@ class AutomationsQuery:
1639
2451
  # Cast generic envelope to concrete typed result
1640
2452
  return AutomationsListResult(
1641
2453
  data=result.data,
1642
- meta=result.meta )
2454
+ meta=result.meta
2455
+ )
1643
2456
 
1644
2457
 
1645
2458
 
@@ -1647,7 +2460,7 @@ class AutomationsQuery:
1647
2460
  self,
1648
2461
  automation_id: str,
1649
2462
  **kwargs
1650
- ) -> AutomationsGetResult:
2463
+ ) -> Automation:
1651
2464
  """
1652
2465
  Returns an automation by its ID
1653
2466
 
@@ -1656,7 +2469,7 @@ class AutomationsQuery:
1656
2469
  **kwargs: Additional parameters
1657
2470
 
1658
2471
  Returns:
1659
- AutomationsGetResult
2472
+ Automation
1660
2473
  """
1661
2474
  params = {k: v for k, v in {
1662
2475
  "automation_id": automation_id,
@@ -1664,9 +2477,7 @@ class AutomationsQuery:
1664
2477
  }.items() if v is not None}
1665
2478
 
1666
2479
  result = await self._connector.execute("automations", "get", params)
1667
- # Cast generic envelope to concrete typed result
1668
- return AutomationsGetResult(
1669
- data=result.data )
2480
+ return result
1670
2481
 
1671
2482
 
1672
2483
 
@@ -1703,9 +2514,65 @@ class TagsQuery:
1703
2514
  # Cast generic envelope to concrete typed result
1704
2515
  return TagsListResult(
1705
2516
  data=result.data,
1706
- meta=result.meta )
2517
+ meta=result.meta
2518
+ )
2519
+
1707
2520
 
1708
2521
 
2522
+ async def search(
2523
+ self,
2524
+ query: TagsSearchQuery,
2525
+ limit: int | None = None,
2526
+ cursor: str | None = None,
2527
+ fields: list[list[str]] | None = None,
2528
+ ) -> TagsSearchResult:
2529
+ """
2530
+ Search tags records from Airbyte cache.
2531
+
2532
+ This operation searches cached data from Airbyte syncs.
2533
+ Only available in hosted execution mode.
2534
+
2535
+ Available filter fields (TagsSearchFilter):
2536
+ - count: The number of times this tag has been used across resources
2537
+ - name: The tag name string used to label and categorize resources
2538
+
2539
+ Args:
2540
+ query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
2541
+ in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
2542
+ limit: Maximum results to return (default 1000)
2543
+ cursor: Pagination cursor from previous response's next_cursor
2544
+ fields: Field paths to include in results. Each path is a list of keys for nested access.
2545
+ Example: [["id"], ["user", "name"]] returns id and user.name fields.
2546
+
2547
+ Returns:
2548
+ TagsSearchResult with hits (list of AirbyteSearchHit[TagsSearchData]) and pagination info
2549
+
2550
+ Raises:
2551
+ NotImplementedError: If called in local execution mode
2552
+ """
2553
+ params: dict[str, Any] = {"query": query}
2554
+ if limit is not None:
2555
+ params["limit"] = limit
2556
+ if cursor is not None:
2557
+ params["cursor"] = cursor
2558
+ if fields is not None:
2559
+ params["fields"] = fields
2560
+
2561
+ result = await self._connector.execute("tags", "search", params)
2562
+
2563
+ # Parse response into typed result
2564
+ return TagsSearchResult(
2565
+ hits=[
2566
+ AirbyteSearchHit[TagsSearchData](
2567
+ id=hit.get("id"),
2568
+ score=hit.get("score"),
2569
+ data=TagsSearchData(**hit.get("data", {}))
2570
+ )
2571
+ for hit in result.get("hits", [])
2572
+ ],
2573
+ next_cursor=result.get("next_cursor"),
2574
+ took_ms=result.get("took_ms")
2575
+ )
1709
2576
 
1710
2577
  class SatisfactionRatingsQuery:
1711
2578
  """
@@ -1749,7 +2616,8 @@ class SatisfactionRatingsQuery:
1749
2616
  # Cast generic envelope to concrete typed result
1750
2617
  return SatisfactionRatingsListResult(
1751
2618
  data=result.data,
1752
- meta=result.meta )
2619
+ meta=result.meta
2620
+ )
1753
2621
 
1754
2622
 
1755
2623
 
@@ -1757,7 +2625,7 @@ class SatisfactionRatingsQuery:
1757
2625
  self,
1758
2626
  satisfaction_rating_id: str,
1759
2627
  **kwargs
1760
- ) -> SatisfactionRatingsGetResult:
2628
+ ) -> SatisfactionRating:
1761
2629
  """
1762
2630
  Returns a satisfaction rating by its ID
1763
2631
 
@@ -1766,7 +2634,7 @@ class SatisfactionRatingsQuery:
1766
2634
  **kwargs: Additional parameters
1767
2635
 
1768
2636
  Returns:
1769
- SatisfactionRatingsGetResult
2637
+ SatisfactionRating
1770
2638
  """
1771
2639
  params = {k: v for k, v in {
1772
2640
  "satisfaction_rating_id": satisfaction_rating_id,
@@ -1774,11 +2642,74 @@ class SatisfactionRatingsQuery:
1774
2642
  }.items() if v is not None}
1775
2643
 
1776
2644
  result = await self._connector.execute("satisfaction_ratings", "get", params)
1777
- # Cast generic envelope to concrete typed result
1778
- return SatisfactionRatingsGetResult(
1779
- data=result.data )
2645
+ return result
2646
+
2647
+
2648
+
2649
+ async def search(
2650
+ self,
2651
+ query: SatisfactionRatingsSearchQuery,
2652
+ limit: int | None = None,
2653
+ cursor: str | None = None,
2654
+ fields: list[list[str]] | None = None,
2655
+ ) -> SatisfactionRatingsSearchResult:
2656
+ """
2657
+ Search satisfaction_ratings records from Airbyte cache.
1780
2658
 
2659
+ This operation searches cached data from Airbyte syncs.
2660
+ Only available in hosted execution mode.
1781
2661
 
2662
+ Available filter fields (SatisfactionRatingsSearchFilter):
2663
+ - assignee_id: The identifier of the agent assigned to the ticket at the time the rating was submitted
2664
+ - comment: Optional comment provided by the requester with the rating
2665
+ - created_at: Timestamp indicating when the satisfaction rating was created
2666
+ - group_id: The identifier of the group assigned to the ticket at the time the rating was submitted
2667
+ - id: Unique identifier for the satisfaction rating, automatically assigned upon creation
2668
+ - reason: Free-text reason for a bad rating provided by the requester in a follow-up question
2669
+ - reason_id: Identifier for the predefined reason given for a negative rating, only applicable when score is '...
2670
+ - requester_id: The identifier of the ticket requester who submitted the satisfaction rating
2671
+ - score: The satisfaction rating value: 'offered', 'unoffered', 'good', or 'bad'
2672
+ - ticket_id: The identifier of the ticket being rated
2673
+ - updated_at: Timestamp indicating when the satisfaction rating was last updated
2674
+ - url: The API URL of this satisfaction rating resource
2675
+
2676
+ Args:
2677
+ query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
2678
+ in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
2679
+ limit: Maximum results to return (default 1000)
2680
+ cursor: Pagination cursor from previous response's next_cursor
2681
+ fields: Field paths to include in results. Each path is a list of keys for nested access.
2682
+ Example: [["id"], ["user", "name"]] returns id and user.name fields.
2683
+
2684
+ Returns:
2685
+ SatisfactionRatingsSearchResult with hits (list of AirbyteSearchHit[SatisfactionRatingsSearchData]) and pagination info
2686
+
2687
+ Raises:
2688
+ NotImplementedError: If called in local execution mode
2689
+ """
2690
+ params: dict[str, Any] = {"query": query}
2691
+ if limit is not None:
2692
+ params["limit"] = limit
2693
+ if cursor is not None:
2694
+ params["cursor"] = cursor
2695
+ if fields is not None:
2696
+ params["fields"] = fields
2697
+
2698
+ result = await self._connector.execute("satisfaction_ratings", "search", params)
2699
+
2700
+ # Parse response into typed result
2701
+ return SatisfactionRatingsSearchResult(
2702
+ hits=[
2703
+ AirbyteSearchHit[SatisfactionRatingsSearchData](
2704
+ id=hit.get("id"),
2705
+ score=hit.get("score"),
2706
+ data=SatisfactionRatingsSearchData(**hit.get("data", {}))
2707
+ )
2708
+ for hit in result.get("hits", [])
2709
+ ],
2710
+ next_cursor=result.get("next_cursor"),
2711
+ took_ms=result.get("took_ms")
2712
+ )
1782
2713
 
1783
2714
  class GroupMembershipsQuery:
1784
2715
  """
@@ -1813,7 +2744,8 @@ class GroupMembershipsQuery:
1813
2744
  # Cast generic envelope to concrete typed result
1814
2745
  return GroupMembershipsListResult(
1815
2746
  data=result.data,
1816
- meta=result.meta )
2747
+ meta=result.meta
2748
+ )
1817
2749
 
1818
2750
 
1819
2751
 
@@ -1850,7 +2782,8 @@ class OrganizationMembershipsQuery:
1850
2782
  # Cast generic envelope to concrete typed result
1851
2783
  return OrganizationMembershipsListResult(
1852
2784
  data=result.data,
1853
- meta=result.meta )
2785
+ meta=result.meta
2786
+ )
1854
2787
 
1855
2788
 
1856
2789
 
@@ -1887,7 +2820,8 @@ class SlaPoliciesQuery:
1887
2820
  # Cast generic envelope to concrete typed result
1888
2821
  return SlaPoliciesListResult(
1889
2822
  data=result.data,
1890
- meta=result.meta )
2823
+ meta=result.meta
2824
+ )
1891
2825
 
1892
2826
 
1893
2827
 
@@ -1895,7 +2829,7 @@ class SlaPoliciesQuery:
1895
2829
  self,
1896
2830
  sla_policy_id: str,
1897
2831
  **kwargs
1898
- ) -> SlaPoliciesGetResult:
2832
+ ) -> SLAPolicy:
1899
2833
  """
1900
2834
  Returns an SLA policy by its ID
1901
2835
 
@@ -1904,7 +2838,7 @@ class SlaPoliciesQuery:
1904
2838
  **kwargs: Additional parameters
1905
2839
 
1906
2840
  Returns:
1907
- SlaPoliciesGetResult
2841
+ SLAPolicy
1908
2842
  """
1909
2843
  params = {k: v for k, v in {
1910
2844
  "sla_policy_id": sla_policy_id,
@@ -1912,9 +2846,7 @@ class SlaPoliciesQuery:
1912
2846
  }.items() if v is not None}
1913
2847
 
1914
2848
  result = await self._connector.execute("sla_policies", "get", params)
1915
- # Cast generic envelope to concrete typed result
1916
- return SlaPoliciesGetResult(
1917
- data=result.data )
2849
+ return result
1918
2850
 
1919
2851
 
1920
2852
 
@@ -1957,7 +2889,8 @@ class TicketFormsQuery:
1957
2889
  # Cast generic envelope to concrete typed result
1958
2890
  return TicketFormsListResult(
1959
2891
  data=result.data,
1960
- meta=result.meta )
2892
+ meta=result.meta
2893
+ )
1961
2894
 
1962
2895
 
1963
2896
 
@@ -1965,7 +2898,7 @@ class TicketFormsQuery:
1965
2898
  self,
1966
2899
  ticket_form_id: str,
1967
2900
  **kwargs
1968
- ) -> TicketFormsGetResult:
2901
+ ) -> TicketForm:
1969
2902
  """
1970
2903
  Returns a ticket form by its ID
1971
2904
 
@@ -1974,7 +2907,7 @@ class TicketFormsQuery:
1974
2907
  **kwargs: Additional parameters
1975
2908
 
1976
2909
  Returns:
1977
- TicketFormsGetResult
2910
+ TicketForm
1978
2911
  """
1979
2912
  params = {k: v for k, v in {
1980
2913
  "ticket_form_id": ticket_form_id,
@@ -1982,11 +2915,79 @@ class TicketFormsQuery:
1982
2915
  }.items() if v is not None}
1983
2916
 
1984
2917
  result = await self._connector.execute("ticket_forms", "get", params)
1985
- # Cast generic envelope to concrete typed result
1986
- return TicketFormsGetResult(
1987
- data=result.data )
2918
+ return result
2919
+
2920
+
2921
+
2922
+ async def search(
2923
+ self,
2924
+ query: TicketFormsSearchQuery,
2925
+ limit: int | None = None,
2926
+ cursor: str | None = None,
2927
+ fields: list[list[str]] | None = None,
2928
+ ) -> TicketFormsSearchResult:
2929
+ """
2930
+ Search ticket_forms records from Airbyte cache.
1988
2931
 
2932
+ This operation searches cached data from Airbyte syncs.
2933
+ Only available in hosted execution mode.
1989
2934
 
2935
+ Available filter fields (TicketFormsSearchFilter):
2936
+ - active: Indicates if the form is set as active
2937
+ - agent_conditions: Array of condition sets for agent workspaces
2938
+ - created_at: Timestamp when the ticket form was created
2939
+ - default: Indicates if the form is the default form for this account
2940
+ - display_name: The name of the form that is displayed to an end user
2941
+ - end_user_conditions: Array of condition sets for end user products
2942
+ - end_user_visible: Indicates if the form is visible to the end user
2943
+ - id: Unique identifier for the ticket form, automatically assigned when creating the form
2944
+ - in_all_brands: Indicates if the form is available for use in all brands on this account
2945
+ - name: The name of the ticket form
2946
+ - position: The position of this form among other forms in the account, such as in a dropdown
2947
+ - raw_display_name: The dynamic content placeholder if present, or the display_name value if not
2948
+ - raw_name: The dynamic content placeholder if present, or the name value if not
2949
+ - restricted_brand_ids: IDs of all brands that this ticket form is restricted to
2950
+ - ticket_field_ids: IDs of all ticket fields included in this ticket form, ordered to determine field display sequenc...
2951
+ - updated_at: Timestamp of the last update to the ticket form
2952
+ - url: URL of the ticket form
2953
+
2954
+ Args:
2955
+ query: Filter and sort conditions. Supports operators like eq, neq, gt, gte, lt, lte,
2956
+ in, like, fuzzy, keyword, not, and, or. Example: {"filter": {"eq": {"status": "active"}}}
2957
+ limit: Maximum results to return (default 1000)
2958
+ cursor: Pagination cursor from previous response's next_cursor
2959
+ fields: Field paths to include in results. Each path is a list of keys for nested access.
2960
+ Example: [["id"], ["user", "name"]] returns id and user.name fields.
2961
+
2962
+ Returns:
2963
+ TicketFormsSearchResult with hits (list of AirbyteSearchHit[TicketFormsSearchData]) and pagination info
2964
+
2965
+ Raises:
2966
+ NotImplementedError: If called in local execution mode
2967
+ """
2968
+ params: dict[str, Any] = {"query": query}
2969
+ if limit is not None:
2970
+ params["limit"] = limit
2971
+ if cursor is not None:
2972
+ params["cursor"] = cursor
2973
+ if fields is not None:
2974
+ params["fields"] = fields
2975
+
2976
+ result = await self._connector.execute("ticket_forms", "search", params)
2977
+
2978
+ # Parse response into typed result
2979
+ return TicketFormsSearchResult(
2980
+ hits=[
2981
+ AirbyteSearchHit[TicketFormsSearchData](
2982
+ id=hit.get("id"),
2983
+ score=hit.get("score"),
2984
+ data=TicketFormsSearchData(**hit.get("data", {}))
2985
+ )
2986
+ for hit in result.get("hits", [])
2987
+ ],
2988
+ next_cursor=result.get("next_cursor"),
2989
+ took_ms=result.get("took_ms")
2990
+ )
1990
2991
 
1991
2992
  class ArticlesQuery:
1992
2993
  """
@@ -2027,7 +3028,8 @@ class ArticlesQuery:
2027
3028
  # Cast generic envelope to concrete typed result
2028
3029
  return ArticlesListResult(
2029
3030
  data=result.data,
2030
- meta=result.meta )
3031
+ meta=result.meta
3032
+ )
2031
3033
 
2032
3034
 
2033
3035
 
@@ -2035,7 +3037,7 @@ class ArticlesQuery:
2035
3037
  self,
2036
3038
  id: str | None = None,
2037
3039
  **kwargs
2038
- ) -> ArticlesGetResult:
3040
+ ) -> Article:
2039
3041
  """
2040
3042
  Retrieves the details of a specific article
2041
3043
 
@@ -2044,7 +3046,7 @@ class ArticlesQuery:
2044
3046
  **kwargs: Additional parameters
2045
3047
 
2046
3048
  Returns:
2047
- ArticlesGetResult
3049
+ Article
2048
3050
  """
2049
3051
  params = {k: v for k, v in {
2050
3052
  "id": id,
@@ -2052,9 +3054,7 @@ class ArticlesQuery:
2052
3054
  }.items() if v is not None}
2053
3055
 
2054
3056
  result = await self._connector.execute("articles", "get", params)
2055
- # Cast generic envelope to concrete typed result
2056
- return ArticlesGetResult(
2057
- data=result.data )
3057
+ return result
2058
3058
 
2059
3059
 
2060
3060
 
@@ -2094,7 +3094,8 @@ class ArticleAttachmentsQuery:
2094
3094
  # Cast generic envelope to concrete typed result
2095
3095
  return ArticleAttachmentsListResult(
2096
3096
  data=result.data,
2097
- meta=result.meta )
3097
+ meta=result.meta
3098
+ )
2098
3099
 
2099
3100
 
2100
3101
 
@@ -2103,7 +3104,7 @@ class ArticleAttachmentsQuery:
2103
3104
  article_id: str,
2104
3105
  attachment_id: str,
2105
3106
  **kwargs
2106
- ) -> ArticleAttachmentsGetResult:
3107
+ ) -> ArticleAttachment:
2107
3108
  """
2108
3109
  Retrieves the metadata of a specific attachment for a specific article
2109
3110
 
@@ -2113,7 +3114,7 @@ class ArticleAttachmentsQuery:
2113
3114
  **kwargs: Additional parameters
2114
3115
 
2115
3116
  Returns:
2116
- ArticleAttachmentsGetResult
3117
+ ArticleAttachment
2117
3118
  """
2118
3119
  params = {k: v for k, v in {
2119
3120
  "article_id": article_id,
@@ -2122,9 +3123,7 @@ class ArticleAttachmentsQuery:
2122
3123
  }.items() if v is not None}
2123
3124
 
2124
3125
  result = await self._connector.execute("article_attachments", "get", params)
2125
- # Cast generic envelope to concrete typed result
2126
- return ArticleAttachmentsGetResult(
2127
- data=result.data )
3126
+ return result
2128
3127
 
2129
3128
 
2130
3129