airbyte.agents.skills
Airbyte Agents skills: reusable documentation served by the Agents API.
⚠️ Experimental Interface
The Airbyte Agents Python interfaces are experimental. Class names, method signatures, and result models may change or be removed without notice between minor versions of PyAirbyte. Pin an exact PyAirbyte version if you depend on them.
1# Copyright (c) 2026 Airbyte, Inc., all rights reserved. 2"""Airbyte Agents skills: reusable documentation served by the Agents API. 3 4> ## ⚠️ Experimental Interface 5> 6> **The Airbyte Agents Python interfaces are experimental.** Class names, method signatures, 7> and result models may change or be removed without notice between minor versions of 8> PyAirbyte. Pin an exact PyAirbyte version if you depend on them. 9""" 10 11from __future__ import annotations 12 13from typing import TYPE_CHECKING 14 15from airbyte.agents import _api_util 16from airbyte.agents.models import AgentSkillDocs, AgentSkillInfo, AgentSkillList 17 18 19if TYPE_CHECKING: 20 from collections.abc import Callable, Iterator 21 22 from airbyte.cloud._credentials import _AirbyteCredentials 23 24 25class AgentSkill: 26 """A skill on the Airbyte Agents platform. 27 28 Get one from `AgentWorkspace.get_skill()` or `AgentWorkspace.list_skills()` rather than 29 constructing it directly. 30 """ 31 32 def __init__( 33 self, 34 skill_id: str, 35 *, 36 credentials: _AirbyteCredentials, 37 workspace_id: str | None = None, 38 info: AgentSkillInfo | None = None, 39 ) -> None: 40 """Initialize an `AgentSkill`. Prefer `AgentWorkspace.get_skill()`.""" 41 self.skill_id = skill_id 42 """The skill ID.""" 43 44 self._credentials = credentials 45 self._workspace_id = workspace_id 46 self._info = info 47 48 @property 49 def info(self) -> AgentSkillInfo: 50 """The skill's metadata, fetched from the Agents API if not already known.""" 51 if self._info is None: 52 self._info = self.read_docs().metadata 53 return self._info 54 55 @property 56 def title(self) -> str | None: 57 """The human-readable skill title.""" 58 return self.info.title 59 60 @property 61 def kind(self) -> str | None: 62 """The skill category, for example `static` or `connector_source`.""" 63 return self.info.kind 64 65 def read_docs(self, *, section: str | None = None) -> AgentSkillDocs: 66 """Read this skill's docs, optionally scoped to a single section. 67 68 Omit `section` for metadata, guidance, and the outline of available sections, or 69 pass an exact section `id` from the outline to read that section. 70 """ 71 docs = AgentSkillDocs.model_validate( 72 _api_util.read_agent_skill_docs( 73 skill_id=self.skill_id, 74 credentials=self._credentials, 75 organization_id=self._credentials.organization_id, 76 workspace_id=self._workspace_id, 77 section=section, 78 ) 79 ) 80 if self._info is None: 81 self._info = docs.metadata 82 return docs 83 84 85def list_skills( 86 *, 87 credentials: _AirbyteCredentials, 88 workspace_id: str | None = None, 89 limit: int | None = None, 90 cursor: str | None = None, 91) -> AgentSkillList: 92 """List the skills available to a workspace or organization. 93 94 Pass `limit` to cap the page size and the `next_cursor` of a previous result as 95 `cursor` to fetch the next page. 96 """ 97 return AgentSkillList.model_validate( 98 _api_util.list_agent_skills( 99 credentials=credentials, 100 organization_id=credentials.organization_id, 101 workspace_id=workspace_id, 102 limit=limit, 103 cursor=cursor, 104 ) 105 ) 106 107 108def _iter_skill_pages( 109 fetch_page: Callable[[str | None], AgentSkillList], 110) -> Iterator[AgentSkillInfo]: 111 """Yield skills across pages, following `next_cursor` until it is `None`. 112 113 Stops early if the server returns a blank cursor or one already seen, rather than 114 requesting the same page forever. 115 """ 116 cursor: str | None = None 117 seen_cursors: set[str] = set() 118 while True: 119 page = fetch_page(cursor) 120 yield from page.data 121 cursor = page.next_cursor 122 if cursor is None or not cursor.strip() or cursor in seen_cursors: 123 return 124 seen_cursors.add(cursor) 125 126 127def iter_skills( 128 *, 129 credentials: _AirbyteCredentials, 130 workspace_id: str | None = None, 131) -> Iterator[AgentSkillInfo]: 132 """Yield all available skills, following the API's pagination cursor. 133 134 This is the pagination-free way to list skills: each page is fetched lazily as the 135 caller iterates, so no cursor bookkeeping is needed. 136 """ 137 return _iter_skill_pages( 138 lambda cursor: list_skills( 139 credentials=credentials, 140 workspace_id=workspace_id, 141 cursor=cursor, 142 ) 143 )
26class AgentSkill: 27 """A skill on the Airbyte Agents platform. 28 29 Get one from `AgentWorkspace.get_skill()` or `AgentWorkspace.list_skills()` rather than 30 constructing it directly. 31 """ 32 33 def __init__( 34 self, 35 skill_id: str, 36 *, 37 credentials: _AirbyteCredentials, 38 workspace_id: str | None = None, 39 info: AgentSkillInfo | None = None, 40 ) -> None: 41 """Initialize an `AgentSkill`. Prefer `AgentWorkspace.get_skill()`.""" 42 self.skill_id = skill_id 43 """The skill ID.""" 44 45 self._credentials = credentials 46 self._workspace_id = workspace_id 47 self._info = info 48 49 @property 50 def info(self) -> AgentSkillInfo: 51 """The skill's metadata, fetched from the Agents API if not already known.""" 52 if self._info is None: 53 self._info = self.read_docs().metadata 54 return self._info 55 56 @property 57 def title(self) -> str | None: 58 """The human-readable skill title.""" 59 return self.info.title 60 61 @property 62 def kind(self) -> str | None: 63 """The skill category, for example `static` or `connector_source`.""" 64 return self.info.kind 65 66 def read_docs(self, *, section: str | None = None) -> AgentSkillDocs: 67 """Read this skill's docs, optionally scoped to a single section. 68 69 Omit `section` for metadata, guidance, and the outline of available sections, or 70 pass an exact section `id` from the outline to read that section. 71 """ 72 docs = AgentSkillDocs.model_validate( 73 _api_util.read_agent_skill_docs( 74 skill_id=self.skill_id, 75 credentials=self._credentials, 76 organization_id=self._credentials.organization_id, 77 workspace_id=self._workspace_id, 78 section=section, 79 ) 80 ) 81 if self._info is None: 82 self._info = docs.metadata 83 return docs
A skill on the Airbyte Agents platform.
Get one from AgentWorkspace.get_skill() or AgentWorkspace.list_skills() rather than
constructing it directly.
33 def __init__( 34 self, 35 skill_id: str, 36 *, 37 credentials: _AirbyteCredentials, 38 workspace_id: str | None = None, 39 info: AgentSkillInfo | None = None, 40 ) -> None: 41 """Initialize an `AgentSkill`. Prefer `AgentWorkspace.get_skill()`.""" 42 self.skill_id = skill_id 43 """The skill ID.""" 44 45 self._credentials = credentials 46 self._workspace_id = workspace_id 47 self._info = info
Initialize an AgentSkill. Prefer AgentWorkspace.get_skill().
49 @property 50 def info(self) -> AgentSkillInfo: 51 """The skill's metadata, fetched from the Agents API if not already known.""" 52 if self._info is None: 53 self._info = self.read_docs().metadata 54 return self._info
The skill's metadata, fetched from the Agents API if not already known.
56 @property 57 def title(self) -> str | None: 58 """The human-readable skill title.""" 59 return self.info.title
The human-readable skill title.
61 @property 62 def kind(self) -> str | None: 63 """The skill category, for example `static` or `connector_source`.""" 64 return self.info.kind
The skill category, for example static or connector_source.
66 def read_docs(self, *, section: str | None = None) -> AgentSkillDocs: 67 """Read this skill's docs, optionally scoped to a single section. 68 69 Omit `section` for metadata, guidance, and the outline of available sections, or 70 pass an exact section `id` from the outline to read that section. 71 """ 72 docs = AgentSkillDocs.model_validate( 73 _api_util.read_agent_skill_docs( 74 skill_id=self.skill_id, 75 credentials=self._credentials, 76 organization_id=self._credentials.organization_id, 77 workspace_id=self._workspace_id, 78 section=section, 79 ) 80 ) 81 if self._info is None: 82 self._info = docs.metadata 83 return docs
Read this skill's docs, optionally scoped to a single section.
Omit section for metadata, guidance, and the outline of available sections, or
pass an exact section id from the outline to read that section.
86def list_skills( 87 *, 88 credentials: _AirbyteCredentials, 89 workspace_id: str | None = None, 90 limit: int | None = None, 91 cursor: str | None = None, 92) -> AgentSkillList: 93 """List the skills available to a workspace or organization. 94 95 Pass `limit` to cap the page size and the `next_cursor` of a previous result as 96 `cursor` to fetch the next page. 97 """ 98 return AgentSkillList.model_validate( 99 _api_util.list_agent_skills( 100 credentials=credentials, 101 organization_id=credentials.organization_id, 102 workspace_id=workspace_id, 103 limit=limit, 104 cursor=cursor, 105 ) 106 )
List the skills available to a workspace or organization.
Pass limit to cap the page size and the next_cursor of a previous result as
cursor to fetch the next page.
128def iter_skills( 129 *, 130 credentials: _AirbyteCredentials, 131 workspace_id: str | None = None, 132) -> Iterator[AgentSkillInfo]: 133 """Yield all available skills, following the API's pagination cursor. 134 135 This is the pagination-free way to list skills: each page is fetched lazily as the 136 caller iterates, so no cursor bookkeeping is needed. 137 """ 138 return _iter_skill_pages( 139 lambda cursor: list_skills( 140 credentials=credentials, 141 workspace_id=workspace_id, 142 cursor=cursor, 143 ) 144 )
Yield all available skills, following the API's pagination cursor.
This is the pagination-free way to list skills: each page is fetched lazily as the caller iterates, so no cursor bookkeeping is needed.