Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
a2ba515
feat(mcp): add tools to refresh catalog and set stream sync mode on C…
devin-ai-integration[bot] Oct 16, 2026
ce6518b
fix(mcp): update trace fixture and default cursor
devin-ai-integration[bot] Oct 16, 2026
5acdc20
refactor: move set_stream_sync_mode to a stacked PR
devin-ai-integration[bot] Oct 16, 2026
fb45501
feat(mcp): add tool to set stream sync mode on Cloud connections
devin-ai-integration[bot] Oct 16, 2026
a4fd77d
feat(mcp): fold catalog refresh into update_cloud_connection as force…
devin-ai-integration[bot] Oct 16, 2026
4f9687c
Merge branch 'devin/1792117913-rc-stream-sync-mode-refresh-catalog' i…
devin-ai-integration[bot] Oct 16, 2026
de9ad7f
Merge remote-tracking branch 'origin/release-candidate/v1' into devin…
devin-ai-integration[bot] Oct 16, 2026
9ae4b3b
Merge branch 'devin/1792117913-rc-stream-sync-mode-refresh-catalog' i…
devin-ai-integration[bot] Oct 16, 2026
6e8144b
feat(mcp): add safe batch stream config updates
devin-ai-integration[bot] Oct 16, 2026
b3deff4
refactor(mcp): remove catalog refresh from stream config updates
devin-ai-integration[bot] Oct 16, 2026
7e72381
refactor(cloud): make stream config planning private and flatten conn…
devin-ai-integration[bot] Oct 16, 2026
50e4faf
ci: retrigger checks
devin-ai-integration[bot] Oct 16, 2026
df615ae
Merge remote-tracking branch 'origin/release-candidate/v1' into devin…
devin-ai-integration[bot] Oct 16, 2026
17245d5
refactor(cloud): validate stream overrides with protocol models
devin-ai-integration[bot] Oct 16, 2026
6b18a21
style: put each argument on its own line in multi-arg signatures
devin-ai-integration[bot] Oct 20, 2026
0552371
style(mcp): define tool param defaults only in Field()
devin-ai-integration[bot] Oct 20, 2026
585268d
Merge remote-tracking branch 'origin/release-candidate/v1' into HEAD
devin-ai-integration[bot] Oct 20, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion airbyte/_util/api_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -3937,6 +3937,7 @@ def replace_connection_catalog(
client_id: SecretString | None,
client_secret: SecretString | None,
bearer_token: SecretString | None,
skip_reset: bool = True,
) -> dict[str, Any]:
"""Replace the configured catalog for a connection.

Expand All @@ -3953,6 +3954,7 @@ def replace_connection_catalog(
client_secret: OAuth client secret.
bearer_token: Bearer token for authentication (alternative to client credentials).
config_api_root: Optional explicit Config API root URL.
skip_reset: Whether to skip the platform reset of changed streams.

Returns:
Dictionary containing the updated WebBackendConnectionRead response.
Expand All @@ -3964,7 +3966,7 @@ def replace_connection_catalog(
"syncCatalog": configured_catalog_dict,
# Resets are destructive and cause customer-side data outage.
# If a reset is desired, caller will need to decide & manage.
"skipReset": True,
"skipReset": skip_reset,
},
api_root=api_root,
config_api_root=config_api_root,
Expand Down
6 changes: 6 additions & 0 deletions airbyte/cloud/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,9 @@
ConnectionStatus,
JobStatusEnum,
JobTypeEnum,
StreamConfigChange,
StreamConfigOverride,
StreamConfigUpdateResult,
WorkspacePrivilegeScope,
)
from airbyte.cloud.organizations import CloudOrganization
Expand Down Expand Up @@ -138,6 +141,9 @@
"CloudClientConfig",
"CloudDefaultContextInfo",
"CloudWorkspaceInfo",
"StreamConfigOverride",
"StreamConfigChange",
"StreamConfigUpdateResult",
"SyncResult",
# Enums
"ExternalApiReadOnlyAction",
Expand Down
71 changes: 71 additions & 0 deletions airbyte/cloud/_connection_settings.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Copyright (c) 2026 Airbyte, Inc., all rights reserved.
"""Private helpers for validating and updating Cloud connection settings."""

from __future__ import annotations

from typing import TYPE_CHECKING

from airbyte._util import api_util
from airbyte.exceptions import AirbyteLibInputError


if TYPE_CHECKING:
from airbyte.cloud.connections import CloudConnection
from airbyte.cloud.models import StreamConfigOverride


def _validate_update_connection_args(
*,
enabled: bool | None,
cron_expression: str | None,
interval_hours: int | None,
manual_schedule: bool | None,
override_stream_configs: list[StreamConfigOverride] | None,
) -> None:
"""Validate the connection settings before any API writes."""
if not any(
(
enabled is not None,
cron_expression is not None,
interval_hours is not None,
manual_schedule is not None,
bool(override_stream_configs),
)
):
raise AirbyteLibInputError(
message=(
"At least one setting must be provided: 'enabled', 'interval_hours', "
"'cron_expression', 'manual_schedule', or 'override_stream_configs'."
),
)

if sum((interval_hours is not None, cron_expression is not None, manual_schedule is True)) > 1:
raise AirbyteLibInputError(
message=(
"Cannot specify more than one of 'interval_hours', 'cron_expression', "
"and 'manual_schedule=True'."
),
)

if interval_hours is not None:
api_util.validate_interval_hours(interval_hours)


def _set_connection_schedule(
connection: CloudConnection,
*,
cron_expression: str | None,
interval_hours: int | None,
manual_schedule: bool | None,
) -> str | None:
"""Set the requested connection schedule and return its summary."""
if cron_expression is not None:
connection.set_schedule(cron_expression=cron_expression)
return f"schedule set to '{cron_expression}'"
if interval_hours is not None:
connection.set_schedule(interval_hours=interval_hours)
return f"schedule set to 'every {interval_hours} hours'"
if manual_schedule is True:
connection.set_manual_schedule()
return "schedule set to 'manual'"
return None
Loading
Loading