From f002bbff76cda660abd0e30b39e3d6b3c4de6dde Mon Sep 17 00:00:00 2001 From: Tram Anh Date: Tue, 27 Oct 2026 00:17:45 +0700 Subject: [PATCH 1/2] fix(mcp): rename deploy_noop_destination_to_cloud name param to destination_name (#1416) Co-authored-by: anhdoox <206002858+anhdoox@users.noreply.github.com> --- airbyte/mcp/cloud.py | 9 +++-- tests/unit_tests/test_mcp_cloud.py | 55 ++++++++++++++++++++++++++++++ 2 files changed, 61 insertions(+), 3 deletions(-) diff --git a/airbyte/mcp/cloud.py b/airbyte/mcp/cloud.py index 1247d6785..225c825a4 100644 --- a/airbyte/mcp/cloud.py +++ b/airbyte/mcp/cloud.py @@ -943,7 +943,10 @@ def run_cloud_sync( ) def deploy_noop_destination_to_cloud( ctx: Context, - name: str = "No-op Destination", + destination_name: Annotated[ + str, + Field(description="The name to use when deploying the No-op destination."), + ] = "No-op Destination", *, workspace_id: Annotated[ str | None, @@ -952,13 +955,13 @@ def deploy_noop_destination_to_cloud( default=None, ), ], - unique: bool = True, + unique: Annotated[bool, Field(description="Whether to require a unique name.")] = True, ) -> str: """Deploy the No-op destination to Airbyte Cloud for testing purposes.""" destination = get_noop_destination() workspace: CloudWorkspace = _get_cloud_workspace(ctx, workspace_id) deployed_destination = workspace.deploy_destination( - name=name, + name=destination_name, destination=destination, unique=unique, ) diff --git a/tests/unit_tests/test_mcp_cloud.py b/tests/unit_tests/test_mcp_cloud.py index b26681110..90a749383 100644 --- a/tests/unit_tests/test_mcp_cloud.py +++ b/tests/unit_tests/test_mcp_cloud.py @@ -3,6 +3,7 @@ from __future__ import annotations +import inspect from dataclasses import dataclass from datetime import datetime, timezone from types import SimpleNamespace @@ -820,3 +821,57 @@ def fake_get_cloud_workspace( assert seen_workspace_ids == ["explicit-workspace-id"] assert "resource-id" in result + + +def test_deploy_noop_destination_to_cloud_uses_destination_name( + monkeypatch: pytest.MonkeyPatch, +) -> None: + """Verify the No-op deploy tool accepts `destination_name` and documents its params.""" + deployed: dict[str, object] = {} + + def fake_deploy_destination(**kwargs: object) -> SimpleNamespace: + deployed.update(kwargs) + return SimpleNamespace( + connector_id="noop-id", + connector_url="https://cloud.airbyte.com/noop-id", + ) + + workspace = SimpleNamespace(deploy_destination=fake_deploy_destination) + monkeypatch.setattr( + cloud_mcp, "_get_cloud_workspace", lambda ctx, workspace_id=None: workspace + ) + monkeypatch.setattr(cloud_mcp, "get_noop_destination", object) + monkeypatch.setattr(cloud_mcp, "register_guid_created_in_session", lambda _: None) + + result = cloud_mcp.deploy_noop_destination_to_cloud( + cast(Context, object()), + destination_name="my-noop", + workspace_id=None, + unique=False, + ) + + assert deployed["name"] == "my-noop" + assert deployed["unique"] is False + assert "noop-id" in result + + default_result = cloud_mcp.deploy_noop_destination_to_cloud( + cast(Context, object()), workspace_id=None + ) + assert deployed["name"] == "No-op Destination" + assert deployed["unique"] is True + assert "noop-id" in default_result + + +def test_deploy_noop_destination_to_cloud_params_have_descriptions() -> None: + """Verify every No-op deploy tool parameter exposes a schema description.""" + signature = inspect.signature(cloud_mcp.deploy_noop_destination_to_cloud) + for param_name in ("destination_name", "workspace_id", "unique"): + annotation = signature.parameters[param_name].annotation + field_infos = [ + meta + for meta in getattr(annotation, "__metadata__", ()) + if hasattr(meta, "description") + ] + assert field_infos, param_name + assert field_infos[0].description, param_name + assert "name" not in signature.parameters From cccec3598c7265cde19ff174521a02651f3c4557 Mon Sep 17 00:00:00 2001 From: Kayvan Zahiri <123409429+Kayvan-Zahiri@users.noreply.github.com> Date: Mon, 26 Oct 2026 10:20:22 -0700 Subject: [PATCH 2/2] fix: resolve document timestamp type at runtime (#1415) --- airbyte/documents.py | 7 ++--- tests/unit_tests/test_documents.py | 49 ++++++++++++++++++++++++++++++ 2 files changed, 51 insertions(+), 5 deletions(-) create mode 100644 tests/unit_tests/test_documents.py diff --git a/airbyte/documents.py b/airbyte/documents.py index d77264be3..bf260ecac 100644 --- a/airbyte/documents.py +++ b/airbyte/documents.py @@ -10,15 +10,12 @@ from __future__ import annotations -from typing import TYPE_CHECKING, Any +import datetime # noqa: TC003 # Pydantic resolves this annotation at runtime. +from typing import Any from pydantic import BaseModel, Field -if TYPE_CHECKING: - import datetime - - MAX_SINGLE_LINE_LENGTH = 60 AIRBYTE_DOCUMENT_RENDERING = "airbyte_document_rendering" TITLE_PROPERTY = "title_property" diff --git a/tests/unit_tests/test_documents.py b/tests/unit_tests/test_documents.py new file mode 100644 index 000000000..07414b7b0 --- /dev/null +++ b/tests/unit_tests/test_documents.py @@ -0,0 +1,49 @@ +# Copyright (c) 2026 Airbyte, Inc., all rights reserved. +"""Regression coverage for document model construction and rendering.""" + +from __future__ import annotations + +from datetime import datetime as DateTime +from typing import Any + +import pytest + +from airbyte._util.document_rendering import DocumentRenderer +from airbyte.documents import Document + + +@pytest.mark.parametrize( + "fields", + [ + {}, + {"last_modified": None}, + {"last_modified": "2026-10-20T12:00:00Z"}, + ], +) +def test_document_construction(fields: dict[str, Any]) -> None: + """Documents validate without callers rebuilding the model's forward references.""" + document = Document(content="Example", metadata={"source": "test"}, **fields) + assert document.page_content == "Example" + assert document.metadata == {"source": "test"} + if fields.get("last_modified"): + assert document.last_modified == DateTime.fromisoformat( + "2026-10-20T12:00:00+00:00" + ) + else: + assert document.last_modified is None + + +def test_document_rendering() -> None: + """The record-to-document path constructs the document model successfully.""" + renderer = DocumentRenderer(content_properties=["body"], metadata_properties=["id"]) + document = renderer.render_document({"body": "Example", "id": "record-1"}) + assert document.page_content == "Example" + assert document.metadata == {"id": "record-1"} + + +def test_document_schema() -> None: + """The model's JSON schema resolves the optional timestamp at runtime.""" + schema = Document.model_json_schema() + assert {"type": "string", "format": "date-time"} in schema["properties"][ + "last_modified" + ]["anyOf"]