airbyte-agent-zendesk-support 0.18.28__tar.gz → 0.18.29__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (60) hide show
  1. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/CHANGELOG.md +5 -0
  2. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/PKG-INFO +3 -3
  3. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/README.md +2 -2
  4. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/__init__.py +3 -0
  5. airbyte_agent_zendesk_support-0.18.29/airbyte_agent_zendesk_support/_vendored/connector_sdk/decorators.py +128 -0
  6. airbyte_agent_zendesk_support-0.18.29/airbyte_agent_zendesk_support/_vendored/connector_sdk/introspection.py +262 -0
  7. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/connector.py +47 -0
  8. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/pyproject.toml +1 -1
  9. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/.gitignore +0 -0
  10. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/REFERENCE.md +0 -0
  11. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/__init__.py +0 -0
  12. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/__init__.py +0 -0
  13. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/auth_strategies.py +0 -0
  14. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/auth_template.py +0 -0
  15. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/cloud_utils/__init__.py +0 -0
  16. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/cloud_utils/client.py +0 -0
  17. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/connector_model_loader.py +0 -0
  18. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/constants.py +0 -0
  19. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/exceptions.py +0 -0
  20. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/executor/__init__.py +0 -0
  21. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/executor/hosted_executor.py +0 -0
  22. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/executor/local_executor.py +0 -0
  23. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/executor/models.py +0 -0
  24. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/extensions.py +0 -0
  25. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/http/__init__.py +0 -0
  26. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/http/adapters/__init__.py +0 -0
  27. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/http/adapters/httpx_adapter.py +0 -0
  28. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/http/config.py +0 -0
  29. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/http/exceptions.py +0 -0
  30. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/http/protocols.py +0 -0
  31. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/http/response.py +0 -0
  32. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/http_client.py +0 -0
  33. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/logging/__init__.py +0 -0
  34. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/logging/logger.py +0 -0
  35. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/logging/types.py +0 -0
  36. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/observability/__init__.py +0 -0
  37. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/observability/models.py +0 -0
  38. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/observability/redactor.py +0 -0
  39. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/observability/session.py +0 -0
  40. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/performance/__init__.py +0 -0
  41. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/performance/instrumentation.py +0 -0
  42. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/performance/metrics.py +0 -0
  43. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/__init__.py +0 -0
  44. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/base.py +0 -0
  45. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/components.py +0 -0
  46. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/connector.py +0 -0
  47. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/extensions.py +0 -0
  48. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/operations.py +0 -0
  49. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/schema/security.py +0 -0
  50. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/secrets.py +0 -0
  51. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/telemetry/__init__.py +0 -0
  52. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/telemetry/config.py +0 -0
  53. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/telemetry/events.py +0 -0
  54. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/telemetry/tracker.py +0 -0
  55. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/types.py +0 -0
  56. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/utils.py +0 -0
  57. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/_vendored/connector_sdk/validation.py +0 -0
  58. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/connector_model.py +0 -0
  59. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/models.py +0 -0
  60. {airbyte_agent_zendesk_support-0.18.28 → airbyte_agent_zendesk_support-0.18.29}/airbyte_agent_zendesk_support/types.py +0 -0
@@ -1,5 +1,10 @@
1
1
  # Zendesk Support changelog
2
2
 
3
+ ## [0.18.29] - 2026-01-07
4
+ - Updated connector definition (YAML version 0.1.4)
5
+ - Source commit: d023e05f
6
+ - SDK version: 0.1.0
7
+
3
8
  ## [0.18.28] - 2026-01-06
4
9
  - Updated connector definition (YAML version 0.1.4)
5
10
  - Source commit: 0580c727
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: airbyte-agent-zendesk-support
3
- Version: 0.18.28
3
+ Version: 0.18.29
4
4
  Summary: Airbyte Zendesk-Support Connector for AI platforms
5
5
  Project-URL: Homepage, https://github.com/airbytehq/airbyte-embedded
6
6
  Project-URL: Documentation, https://github.com/airbytehq/airbyte-embedded/tree/main/integrations
@@ -141,6 +141,6 @@ For the service's official API docs, see the [Zendesk-Support API reference](htt
141
141
 
142
142
  ## Version information
143
143
 
144
- - **Package version:** 0.18.28
144
+ - **Package version:** 0.18.29
145
145
  - **Connector version:** 0.1.4
146
- - **Generated with Connector SDK commit SHA:** 0580c7278394ff52ee3bec5d5192905ac3b15878
146
+ - **Generated with Connector SDK commit SHA:** d023e05f2b7a1ddabf81fab7640c64de1e0aa6a1
@@ -107,6 +107,6 @@ For the service's official API docs, see the [Zendesk-Support API reference](htt
107
107
 
108
108
  ## Version information
109
109
 
110
- - **Package version:** 0.18.28
110
+ - **Package version:** 0.18.29
111
111
  - **Connector version:** 0.1.4
112
- - **Generated with Connector SDK commit SHA:** 0580c7278394ff52ee3bec5d5192905ac3b15878
112
+ - **Generated with Connector SDK commit SHA:** d023e05f2b7a1ddabf81fab7640c64de1e0aa6a1
@@ -13,6 +13,7 @@ from __future__ import annotations
13
13
  from .auth_strategies import AuthStrategy
14
14
  from .connector_model_loader import load_connector_model
15
15
  from .constants import SDK_VERSION
16
+ from .decorators import airbyte_description
16
17
  from .exceptions import (
17
18
  AuthenticationError,
18
19
  HTTPClientError,
@@ -79,4 +80,6 @@ __all__ = [
79
80
  "instrument",
80
81
  # Utilities
81
82
  "save_download",
83
+ # Decorators for AI integration
84
+ "airbyte_description",
82
85
  ]
@@ -0,0 +1,128 @@
1
+ """
2
+ Decorators for AI agent tool integration.
3
+
4
+ Provides utilities to auto-generate comprehensive tool descriptions
5
+ from connector metadata, enabling easy integration with AI frameworks.
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import importlib
11
+ from typing import Any, Callable, TypeVar
12
+
13
+ from .introspection import (
14
+ MAX_EXAMPLE_QUESTIONS,
15
+ ConnectorModelProtocol,
16
+ EndpointProtocol,
17
+ generate_tool_description,
18
+ )
19
+
20
+ F = TypeVar("F", bound=Callable[..., Any])
21
+
22
+ __all__ = [
23
+ "airbyte_description",
24
+ "EndpointProtocol",
25
+ "ConnectorModelProtocol",
26
+ "MAX_EXAMPLE_QUESTIONS",
27
+ # Private function exposed for testing
28
+ "_load_connector_model",
29
+ ]
30
+
31
+
32
+ def airbyte_description(connector_name: str) -> Callable[[F], F]:
33
+ """
34
+ Decorator that generates comprehensive tool descriptions from connector metadata.
35
+
36
+ Automatically populates the function's docstring with:
37
+ - Connector description
38
+ - Available entities and their actions
39
+ - Example questions the connector can answer
40
+
41
+ Args:
42
+ connector_name: Name of the connector (e.g., "hubspot", "stripe")
43
+ Must match the generated package name pattern:
44
+ airbyte_agent_{connector_name}
45
+
46
+ Returns:
47
+ Decorator that updates the function's __doc__ attribute
48
+
49
+ Example:
50
+ from airbyte_agent_hubspot import HubspotConnector
51
+
52
+ connector = HubspotConnector(
53
+ external_user_id=external_user_id,
54
+ airbyte_client_id=airbyte_client_id,
55
+ airbyte_client_secret=airbyte_client_secret
56
+ )
57
+
58
+ # IMPORTANT: @airbyte_description must be the INNER decorator (closest to function)
59
+ # This ensures __doc__ is expanded BEFORE frameworks like FastMCP capture it
60
+ @agent.tool_plain # or @mcp.tool() for FastMCP
61
+ @airbyte_description("hubspot")
62
+ async def hubspot_exec(entity: str, action: str, params: dict | None = None):
63
+ '''Execute HubSpot operations.'''
64
+ return await connector.execute(entity, action, params or {})
65
+
66
+ The decorator will update hubspot_exec.__doc__ with a comprehensive
67
+ description including all available entities, actions, and example questions.
68
+ """
69
+
70
+ def decorator(func: F) -> F:
71
+ # Load connector model from generated package
72
+ model = _load_connector_model(connector_name)
73
+
74
+ # Generate description using shared introspection module
75
+ description = generate_tool_description(model)
76
+
77
+ # Preserve original docstring if present, append to it
78
+ original_doc = func.__doc__ or ""
79
+ if original_doc.strip():
80
+ func.__doc__ = f"{original_doc.strip()}\n\n{description}"
81
+ else:
82
+ func.__doc__ = description
83
+
84
+ return func
85
+
86
+ return decorator
87
+
88
+
89
+ def _load_connector_model(connector_name: str) -> Any:
90
+ """
91
+ Load connector model from generated package.
92
+
93
+ Args:
94
+ connector_name: Connector name (e.g., "hubspot")
95
+
96
+ Returns:
97
+ ConnectorModel instance from the generated package
98
+
99
+ Raises:
100
+ ImportError: If connector package is not installed
101
+ AttributeError: If connector model constant not found
102
+ """
103
+ # Normalize connector name to package name
104
+ package_name = f"airbyte_agent_{connector_name.replace('-', '_')}"
105
+
106
+ try:
107
+ # Import the connector_model module from the generated package
108
+ module = importlib.import_module(f"{package_name}.connector_model")
109
+ except ImportError as e:
110
+ raise ImportError(f"Could not import connector package '{package_name}'. " f"Ensure the package is installed. Error: {e}") from e
111
+
112
+ # Find the ConnectorModel constant (named like HubspotConnectorModel)
113
+ # Convention: {PascalCase connector name}ConnectorModel
114
+ pascal_name = "".join(word.capitalize() for word in connector_name.replace("-", "_").split("_"))
115
+ model_name = f"{pascal_name}ConnectorModel"
116
+
117
+ model = getattr(module, model_name, None)
118
+ if model is None:
119
+ # Fallback: look for any ConnectorModel attribute
120
+ for attr_name in dir(module):
121
+ if attr_name.endswith("ConnectorModel"):
122
+ model = getattr(module, attr_name)
123
+ break
124
+
125
+ if model is None:
126
+ raise AttributeError(f"Could not find ConnectorModel in {package_name}.connector_model. " f"Expected constant named '{model_name}'")
127
+
128
+ return model
@@ -0,0 +1,262 @@
1
+ """
2
+ Shared introspection utilities for connector metadata.
3
+
4
+ This module provides utilities for introspecting connector metadata,
5
+ generating descriptions, and formatting parameter signatures. These
6
+ functions are used by both the runtime decorators and the generated
7
+ connector code.
8
+
9
+ The module is designed to work with any object conforming to the
10
+ ConnectorModel and EndpointDefinition interfaces from connector_sdk.types.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ from typing import Any, Protocol
16
+
17
+ # Constants
18
+ MAX_EXAMPLE_QUESTIONS = 5 # Maximum number of example questions to include in description
19
+
20
+
21
+ class EndpointProtocol(Protocol):
22
+ """Protocol defining the expected interface for endpoint parameters.
23
+
24
+ This allows functions to work with any endpoint-like object
25
+ that has these attributes, including EndpointDefinition and mock objects.
26
+ """
27
+
28
+ path_params: list[str]
29
+ path_params_schema: dict[str, dict[str, Any]]
30
+ query_params: list[str]
31
+ query_params_schema: dict[str, dict[str, Any]]
32
+ body_fields: list[str]
33
+ request_schema: dict[str, Any] | None
34
+
35
+
36
+ class EntityProtocol(Protocol):
37
+ """Protocol defining the expected interface for entity definitions."""
38
+
39
+ name: str
40
+ actions: list[Any]
41
+ endpoints: dict[Any, EndpointProtocol]
42
+
43
+
44
+ class ConnectorModelProtocol(Protocol):
45
+ """Protocol defining the expected interface for connector model parameters.
46
+
47
+ This allows functions to work with any connector-like object
48
+ that has these attributes, including ConnectorModel and mock objects.
49
+ """
50
+
51
+ @property
52
+ def entities(self) -> list[EntityProtocol]: ...
53
+
54
+ @property
55
+ def openapi_spec(self) -> Any: ...
56
+
57
+
58
+ def format_param_signature(endpoint: EndpointProtocol) -> str:
59
+ """Format parameter signature for an endpoint action.
60
+
61
+ Returns a string like: (id*) or (limit?, starting_after?, email?)
62
+ where * = required, ? = optional
63
+
64
+ Args:
65
+ endpoint: Object conforming to EndpointProtocol (e.g., EndpointDefinition)
66
+
67
+ Returns:
68
+ Formatted parameter signature string
69
+ """
70
+ params = []
71
+
72
+ # Defensive: safely access attributes with defaults for malformed endpoints
73
+ path_params = getattr(endpoint, "path_params", []) or []
74
+ query_params = getattr(endpoint, "query_params", []) or []
75
+ query_params_schema = getattr(endpoint, "query_params_schema", {}) or {}
76
+ body_fields = getattr(endpoint, "body_fields", []) or []
77
+ request_schema = getattr(endpoint, "request_schema", None)
78
+
79
+ # Path params (always required)
80
+ for name in path_params:
81
+ params.append(f"{name}*")
82
+
83
+ # Query params
84
+ for name in query_params:
85
+ schema = query_params_schema.get(name, {})
86
+ required = schema.get("required", False)
87
+ params.append(f"{name}{'*' if required else '?'}")
88
+
89
+ # Body fields
90
+ if request_schema:
91
+ required_fields = set(request_schema.get("required", []))
92
+ for name in body_fields:
93
+ params.append(f"{name}{'*' if name in required_fields else '?'}")
94
+
95
+ return f"({', '.join(params)})" if params else "()"
96
+
97
+
98
+ def describe_entities(model: ConnectorModelProtocol) -> list[dict[str, Any]]:
99
+ """Generate entity descriptions from ConnectorModel.
100
+
101
+ Returns a list of entity descriptions with detailed parameter information
102
+ for each action. This is used by generated connectors' describe() method.
103
+
104
+ Args:
105
+ model: Object conforming to ConnectorModelProtocol (e.g., ConnectorModel)
106
+
107
+ Returns:
108
+ List of entity description dicts with keys:
109
+ - entity_name: Name of the entity (e.g., "contacts", "deals")
110
+ - description: Entity description from the first endpoint
111
+ - available_actions: List of actions (e.g., ["list", "get", "create"])
112
+ - parameters: Dict mapping action -> list of parameter dicts
113
+ """
114
+ entities = []
115
+ for entity_def in model.entities:
116
+ description = ""
117
+ parameters: dict[str, list[dict[str, Any]]] = {}
118
+
119
+ endpoints = getattr(entity_def, "endpoints", {}) or {}
120
+ if endpoints:
121
+ for action, endpoint in endpoints.items():
122
+ # Get description from first endpoint that has one
123
+ if not description:
124
+ endpoint_desc = getattr(endpoint, "description", None)
125
+ if endpoint_desc:
126
+ description = endpoint_desc
127
+
128
+ action_params: list[dict[str, Any]] = []
129
+
130
+ # Defensive: safely access endpoint attributes
131
+ path_params = getattr(endpoint, "path_params", []) or []
132
+ path_params_schema = getattr(endpoint, "path_params_schema", {}) or {}
133
+ query_params = getattr(endpoint, "query_params", []) or []
134
+ query_params_schema = getattr(endpoint, "query_params_schema", {}) or {}
135
+ body_fields = getattr(endpoint, "body_fields", []) or []
136
+ request_schema = getattr(endpoint, "request_schema", None)
137
+
138
+ # Path params (always required)
139
+ for param_name in path_params:
140
+ schema = path_params_schema.get(param_name, {})
141
+ action_params.append(
142
+ {
143
+ "name": param_name,
144
+ "in": "path",
145
+ "required": True,
146
+ "type": schema.get("type", "string"),
147
+ "description": schema.get("description", ""),
148
+ }
149
+ )
150
+
151
+ # Query params
152
+ for param_name in query_params:
153
+ schema = query_params_schema.get(param_name, {})
154
+ action_params.append(
155
+ {
156
+ "name": param_name,
157
+ "in": "query",
158
+ "required": schema.get("required", False),
159
+ "type": schema.get("type", "string"),
160
+ "description": schema.get("description", ""),
161
+ }
162
+ )
163
+
164
+ # Body fields
165
+ if request_schema:
166
+ required_fields = request_schema.get("required", [])
167
+ properties = request_schema.get("properties", {})
168
+ for param_name in body_fields:
169
+ prop = properties.get(param_name, {})
170
+ action_params.append(
171
+ {
172
+ "name": param_name,
173
+ "in": "body",
174
+ "required": param_name in required_fields,
175
+ "type": prop.get("type", "string"),
176
+ "description": prop.get("description", ""),
177
+ }
178
+ )
179
+
180
+ if action_params:
181
+ # Action is an enum, use .value to get string
182
+ action_key = action.value if hasattr(action, "value") else str(action)
183
+ parameters[action_key] = action_params
184
+
185
+ actions = getattr(entity_def, "actions", []) or []
186
+ entities.append(
187
+ {
188
+ "entity_name": entity_def.name,
189
+ "description": description,
190
+ "available_actions": [a.value if hasattr(a, "value") else str(a) for a in actions],
191
+ "parameters": parameters,
192
+ }
193
+ )
194
+
195
+ return entities
196
+
197
+
198
+ def generate_tool_description(model: ConnectorModelProtocol) -> str:
199
+ """Generate AI tool description from connector metadata.
200
+
201
+ Produces a detailed description that includes:
202
+ - Per-entity/action parameter signatures with required (*) and optional (?) markers
203
+ - Response structure documentation with pagination hints
204
+ - Example questions if available in the OpenAPI spec
205
+
206
+ This is used by the @airbyte_description decorator to populate
207
+ function docstrings for AI framework integration.
208
+
209
+ Args:
210
+ model: Object conforming to ConnectorModelProtocol (e.g., ConnectorModel)
211
+
212
+ Returns:
213
+ Formatted description string suitable for AI tool documentation
214
+ """
215
+ lines = []
216
+
217
+ # Entity/action parameter details (including pagination params like limit, starting_after)
218
+ lines.append("ENTITIES AND PARAMETERS:")
219
+ for entity in model.entities:
220
+ lines.append(f" {entity.name}:")
221
+ actions = getattr(entity, "actions", []) or []
222
+ endpoints = getattr(entity, "endpoints", {}) or {}
223
+ for action in actions:
224
+ action_str = action.value if hasattr(action, "value") else str(action)
225
+ endpoint = endpoints.get(action)
226
+ if endpoint:
227
+ param_sig = format_param_signature(endpoint)
228
+ lines.append(f" - {action_str}{param_sig}")
229
+ else:
230
+ lines.append(f" - {action_str}()")
231
+
232
+ # Response structure (brief, includes pagination hint)
233
+ lines.append("")
234
+ lines.append("RESPONSE STRUCTURE:")
235
+ lines.append(" - list/search: {data: [...], meta: {has_more: bool}}")
236
+ lines.append(" - get: Returns entity directly (no envelope)")
237
+ lines.append(" To paginate: pass starting_after=<last_id> while has_more is true")
238
+
239
+ # Add example questions if available in openapi_spec
240
+ openapi_spec = getattr(model, "openapi_spec", None)
241
+ if openapi_spec:
242
+ info = getattr(openapi_spec, "info", None)
243
+ if info:
244
+ example_questions = getattr(info, "x_airbyte_example_questions", None)
245
+ if example_questions:
246
+ supported = getattr(example_questions, "supported", None)
247
+ if supported:
248
+ lines.append("")
249
+ lines.append("EXAMPLE QUESTIONS:")
250
+ for q in supported[:MAX_EXAMPLE_QUESTIONS]:
251
+ lines.append(f" - {q}")
252
+
253
+ # Generic parameter description for function signature
254
+ lines.append("")
255
+ lines.append("FUNCTION PARAMETERS:")
256
+ lines.append(" - entity: Entity name (string)")
257
+ lines.append(" - action: Operation to perform (string)")
258
+ lines.append(" - params: Operation parameters (dict) - see entity details above")
259
+ lines.append("")
260
+ lines.append("Parameter markers: * = required, ? = optional")
261
+
262
+ return "\n".join(lines)
@@ -4,6 +4,7 @@ zendesk-support connector.
4
4
 
5
5
  from __future__ import annotations
6
6
 
7
+ import logging
7
8
  from typing import TYPE_CHECKING, Any, AsyncIterator, overload
8
9
  try:
9
10
  from typing import Literal
@@ -11,6 +12,7 @@ except ImportError:
11
12
  from typing_extensions import Literal
12
13
 
13
14
  from .connector_model import ZendeskSupportConnectorModel
15
+ from ._vendored.connector_sdk.introspection import describe_entities
14
16
 
15
17
  from .types import (
16
18
  ArticleAttachmentsDownloadParams,
@@ -712,6 +714,51 @@ class ZendeskSupportConnector:
712
714
  # No extractors - return raw response data
713
715
  return result.data
714
716
 
717
+ # ===== INTROSPECTION METHODS =====
718
+
719
+ def describe(self) -> list[dict[str, Any]]:
720
+ """
721
+ Describe available entities, actions, and parameters.
722
+
723
+ Returns a list of entity descriptions with:
724
+ - entity_name: Name of the entity (e.g., "contacts", "deals")
725
+ - description: Entity description from the first endpoint
726
+ - available_actions: List of actions (e.g., ["list", "get", "create"])
727
+ - parameters: Dict mapping action -> list of parameter dicts
728
+
729
+ Example:
730
+ entities = connector.describe()
731
+ for entity in entities:
732
+ print(f"{entity['entity_name']}: {entity['available_actions']}")
733
+ """
734
+ return describe_entities(ZendeskSupportConnectorModel)
735
+
736
+ def entity_schema(self, entity: str) -> dict[str, Any] | None:
737
+ """
738
+ Get the JSON schema for an entity.
739
+
740
+ Args:
741
+ entity: Entity name (e.g., "contacts", "companies")
742
+
743
+ Returns:
744
+ JSON schema dict describing the entity structure, or None if not found.
745
+
746
+ Example:
747
+ schema = connector.entity_schema("contacts")
748
+ if schema:
749
+ print(f"Contact properties: {list(schema.get('properties', {}).keys())}")
750
+ """
751
+ entity_def = next(
752
+ (e for e in ZendeskSupportConnectorModel.entities if e.name == entity),
753
+ None
754
+ )
755
+ if entity_def is None:
756
+ logging.getLogger(__name__).warning(
757
+ f"Entity '{entity}' not found. Available entities: "
758
+ f"{[e.name for e in ZendeskSupportConnectorModel.entities]}"
759
+ )
760
+ return entity_def.entity_schema if entity_def else None
761
+
715
762
 
716
763
 
717
764
  class TicketsQuery:
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "airbyte-agent-zendesk-support"
3
- version = "0.18.28"
3
+ version = "0.18.29"
4
4
  description = "Airbyte Zendesk-Support Connector for AI platforms"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.9"