From 04f1771e16f54a0627ecac1266764ca77f833694 Mon Sep 17 00:00:00 2001 From: Shawn Yang Date: Thu, 18 Dec 2025 11:31:00 -0800 Subject: [PATCH] feat: Support Developer Connect in AE PiperOrigin-RevId: 846350835 --- .../genai/replays/test_create_agent_engine.py | 37 ++ .../unit/vertexai/genai/test_agent_engines.py | 78 +++- vertexai/_genai/agent_engines.py | 368 +++++++++++------- vertexai/_genai/types/__init__.py | 12 + vertexai/_genai/types/common.py | 112 ++++++ 5 files changed, 459 insertions(+), 148 deletions(-) diff --git a/tests/unit/vertexai/genai/replays/test_create_agent_engine.py b/tests/unit/vertexai/genai/replays/test_create_agent_engine.py index e3181a9ce7..103b0df19d 100644 --- a/tests/unit/vertexai/genai/replays/test_create_agent_engine.py +++ b/tests/unit/vertexai/genai/replays/test_create_agent_engine.py @@ -170,6 +170,43 @@ def test_create_with_identity_type(client): client.agent_engines.delete(name=agent_engine.api_resource.name, force=True) +def test_create_with_developer_connect_source(client): + """Tests creating an agent engine with developer connect source.""" + developer_connect_source_config = types.ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfig( + git_repository_link="projects/reasoning-engine-test-1/locations/europe-west3/connections/shawn-develop-connect/gitRepositoryLinks/shawn-yang-google-adk-samples", + revision="main", + dir="test", + ) + agent_engine = client.agent_engines.create( + config={ + "display_name": "test-agent-engine-dev-connect", + "developer_connect_source": developer_connect_source_config, + "entrypoint_module": "my_agent", + "entrypoint_object": "agent", + "class_methods": _TEST_CLASS_METHODS, + "http_options": { + "base_url": "https://europe-west3-aiplatform.googleapis.com", + "api_version": "v1beta1", + }, + }, + ) + assert agent_engine.api_resource.display_name == "test-agent-engine-dev-connect" + assert ( + agent_engine.api_resource.spec.source_code_spec.developer_connect_source.config.git_repository_link + == developer_connect_source_config.git_repository_link + ) + assert ( + agent_engine.api_resource.spec.source_code_spec.developer_connect_source.config.revision + == developer_connect_source_config.revision + ) + assert ( + agent_engine.api_resource.spec.source_code_spec.developer_connect_source.config.dir + == developer_connect_source_config.dir + ) + # Clean up resources. + client.agent_engines.delete(name=agent_engine.api_resource.name, force=True) + + pytestmark = pytest_helper.setup( file=__file__, globals_for_file=globals(), diff --git a/tests/unit/vertexai/genai/test_agent_engines.py b/tests/unit/vertexai/genai/test_agent_engines.py index d51edce6ec..38e8303cb2 100644 --- a/tests/unit/vertexai/genai/test_agent_engines.py +++ b/tests/unit/vertexai/genai/test_agent_engines.py @@ -904,6 +904,11 @@ def test_agent_engine_adk_telemetry_enablement( {"name": key, "value": value} for key, value in expected_env_vars.items() ] + @mock.patch.object( + _agent_engines_utils, + "_create_base64_encoded_tarball", + return_value="test_tarball", + ) @mock.patch.object(_agent_engines_utils, "_prepare") @pytest.mark.parametrize( "env_vars,expected_env_vars", @@ -930,20 +935,25 @@ def test_agent_engine_adk_telemetry_enablement( def test_agent_engine_adk_telemetry_enablement_through_source_packages( self, mock_prepare: mock.Mock, + mock_create_base64_encoded_tarball: mock.Mock, env_vars: dict[str, str], expected_env_vars: dict[str, str], ): - config = self.client.agent_engines._create_config( - mode="create", - display_name=_TEST_AGENT_ENGINE_DISPLAY_NAME, - description=_TEST_AGENT_ENGINE_DESCRIPTION, - source_packages=[], - class_methods=[], - entrypoint_module=".", - entrypoint_object=".", - env_vars=env_vars, - agent_framework="google-adk", - ) + with tempfile.TemporaryDirectory() as tmpdir: + test_file_path = os.path.join(tmpdir, "test_file.txt") + with open(test_file_path, "w") as f: + f.write("test content") + config = self.client.agent_engines._create_config( + mode="create", + display_name=_TEST_AGENT_ENGINE_DISPLAY_NAME, + description=_TEST_AGENT_ENGINE_DESCRIPTION, + source_packages=[test_file_path], + class_methods=[], + entrypoint_module=".", + entrypoint_object=".", + env_vars=env_vars, + agent_framework="google-adk", + ) assert config["display_name"] == _TEST_AGENT_ENGINE_DISPLAY_NAME assert config["description"] == _TEST_AGENT_ENGINE_DESCRIPTION assert config["spec"]["deployment_spec"]["env"] == [ @@ -1062,6 +1072,47 @@ def test_create_agent_engine_config_with_source_packages( == _TEST_AGENT_ENGINE_IDENTITY_TYPE_SERVICE_ACCOUNT ) + def test_create_agent_engine_config_with_developer_connect_source(self): + with tempfile.TemporaryDirectory() as tmpdir: + requirements_file_path = os.path.join(tmpdir, "requirements.txt") + with open(requirements_file_path, "w") as f: + f.write("requests==2.0.0") + developer_connect_source = { + "git_repository_link": "projects/test-project/locations/us-central1/connections/test-connection/gitRepositoryLinks/test-repo", + "revision": "main", + "dir": "agent", + } + config = self.client.agent_engines._create_config( + mode="create", + display_name=_TEST_AGENT_ENGINE_DISPLAY_NAME, + description=_TEST_AGENT_ENGINE_DESCRIPTION, + developer_connect_source=developer_connect_source, + entrypoint_module="main", + entrypoint_object="app", + requirements_file=requirements_file_path, + class_methods=_TEST_AGENT_ENGINE_CLASS_METHODS, + agent_framework=_TEST_AGENT_FRAMEWORK, + identity_type=_TEST_AGENT_ENGINE_IDENTITY_TYPE_SERVICE_ACCOUNT, + python_version=_TEST_PYTHON_VERSION_OVERRIDE, + ) + assert config["display_name"] == _TEST_AGENT_ENGINE_DISPLAY_NAME + assert config["description"] == _TEST_AGENT_ENGINE_DESCRIPTION + assert config["spec"]["agent_framework"] == _TEST_AGENT_FRAMEWORK + assert config["spec"]["source_code_spec"] == { + "developer_connect_source": {"config": developer_connect_source}, + "python_spec": { + "version": _TEST_PYTHON_VERSION_OVERRIDE, + "entrypoint_module": "main", + "entrypoint_object": "app", + "requirements_file": requirements_file_path, + }, + } + assert config["spec"]["class_methods"] == _TEST_AGENT_ENGINE_CLASS_METHODS + assert ( + config["spec"]["identity_type"] + == _TEST_AGENT_ENGINE_IDENTITY_TYPE_SERVICE_ACCOUNT + ) + @mock.patch.object( _agent_engines_utils, "_create_base64_encoded_tarball", @@ -1824,6 +1875,7 @@ def test_create_agent_engine_with_env_vars_dict( labels=None, class_methods=None, source_packages=None, + developer_connect_source=None, entrypoint_module=None, entrypoint_object=None, requirements_file=None, @@ -1924,6 +1976,7 @@ def test_create_agent_engine_with_custom_service_account( agent_server_mode=None, class_methods=None, source_packages=None, + developer_connect_source=None, entrypoint_module=None, entrypoint_object=None, requirements_file=None, @@ -2023,6 +2076,7 @@ def test_create_agent_engine_with_experimental_mode( agent_server_mode=_genai_types.AgentServerMode.EXPERIMENTAL, class_methods=None, source_packages=None, + developer_connect_source=None, entrypoint_module=None, entrypoint_object=None, requirements_file=None, @@ -2191,6 +2245,7 @@ def test_create_agent_engine_with_class_methods( agent_server_mode=None, class_methods=_TEST_AGENT_ENGINE_CLASS_METHODS, source_packages=None, + developer_connect_source=None, entrypoint_module=None, entrypoint_object=None, requirements_file=None, @@ -2284,6 +2339,7 @@ def test_create_agent_engine_with_agent_framework( agent_server_mode=None, class_methods=None, source_packages=None, + developer_connect_source=None, entrypoint_module=None, entrypoint_object=None, requirements_file=None, diff --git a/vertexai/_genai/agent_engines.py b/vertexai/_genai/agent_engines.py index 258ab4c516..77c7701606 100644 --- a/vertexai/_genai/agent_engines.py +++ b/vertexai/_genai/agent_engines.py @@ -761,6 +761,13 @@ def _list_pager( config, ) + def _is_lightweight_creation( + self, agent: Any, config: types.AgentEngineConfig + ) -> bool: + if agent or config.source_packages or config.developer_connect_source: + return False + return True + def get( self, *, @@ -902,7 +909,12 @@ def create( context_spec = config.context_spec if context_spec is not None: # Conversion to a dict for _create_config - context_spec = context_spec.model_dump() + context_spec = json.loads(context_spec.model_dump_json()) + developer_connect_source = config.developer_connect_source + if developer_connect_source is not None: + developer_connect_source = json.loads( + developer_connect_source.model_dump_json() + ) if agent and agent_engine: raise ValueError("Please specify only one of `agent` or `agent_engine`.") elif agent_engine: @@ -933,6 +945,7 @@ def create( labels=config.labels, class_methods=config.class_methods, source_packages=config.source_packages, + developer_connect_source=developer_connect_source, entrypoint_module=config.entrypoint_module, entrypoint_object=config.entrypoint_object, requirements_file=config.requirements_file, @@ -950,7 +963,7 @@ def create( "&query=resource.type%3D%22aiplatform.googleapis.com%2FReasoningEngine%22%0A" f"resource.labels.reasoning_engine_id%3D%22{reasoning_engine_id}%22." ) - if agent is not None or config.source_packages is not None: + if not self._is_lightweight_creation(agent, config): poll_interval_seconds = 10 else: poll_interval_seconds = 1 # Lightweight agent engine resource creation. @@ -974,12 +987,182 @@ def create( raise RuntimeError(f"Failed to create Agent Engine: {operation.error}") else: logger.warning("The operation returned an empty response.") - if agent is not None or config.source_packages is not None: + if not self._is_lightweight_creation(agent, config): # If the user did not provide an agent_engine (e.g. lightweight # provisioning), it will not have any API methods registered. agent_engine = self._register_api_methods(agent_engine=agent_engine) return agent_engine + def _set_source_code_spec( + self, + *, + spec: types.ReasoningEngineSpecDict, + update_masks: list[str], + source_packages: Optional[Sequence[str]] = None, + developer_connect_source: Optional[ + types.ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfigDict + ] = None, + class_methods: Optional[Sequence[dict[str, Any]]] = None, + entrypoint_module: Optional[str] = None, + entrypoint_object: Optional[str] = None, + requirements_file: Optional[str] = None, + sys_version: str, + build_options: Optional[dict[str, list[str]]] = None, + ): + """Sets source_code_spec for agent engine inside the `spec`.""" + source_code_spec = {} + if source_packages: + source_packages = _agent_engines_utils._validate_packages_or_raise( + packages=source_packages, + build_options=build_options, + ) + update_masks.append("spec.source_code_spec.inline_source.source_archive") + source_code_spec["inline_source"] = { + "source_archive": _agent_engines_utils._create_base64_encoded_tarball( + source_packages=source_packages + ) + } + elif developer_connect_source: + update_masks.append("spec.source_code_spec.developer_connect_source") + source_code_spec["developer_connect_source"] = { + "config": developer_connect_source + } + else: + raise ValueError( + "Please specify one of `source_packages` or `developer_connect_source`." + ) + return + + update_masks.append("spec.source_code_spec.python_spec.version") + python_spec = { + "version": sys_version, + } + if not entrypoint_module: + raise ValueError( + "`entrypoint_module` must be specified if `source_packages` or `developer_connect_source` is specified." + ) + update_masks.append("spec.source_code_spec.python_spec.entrypoint_module") + python_spec["entrypoint_module"] = entrypoint_module + if not entrypoint_object: + raise ValueError( + "`entrypoint_object` must be specified if `source_packages` or `developer_connect_source` is specified." + ) + update_masks.append("spec.source_code_spec.python_spec.entrypoint_object") + python_spec["entrypoint_object"] = entrypoint_object + if requirements_file is not None: + update_masks.append("spec.source_code_spec.python_spec.requirements_file") + python_spec["requirements_file"] = requirements_file + source_code_spec["python_spec"] = python_spec + spec["source_code_spec"] = source_code_spec + + if class_methods is None: + raise ValueError( + "`class_methods` must be specified if `source_packages` or `developer_connect_source` is specified." + ) + update_masks.append("spec.class_methods") + class_methods_spec_list = ( + _agent_engines_utils._class_methods_to_class_methods_spec( + class_methods=class_methods + ) + ) + spec["class_methods"] = [ + _agent_engines_utils._to_dict(class_method_spec) + for class_method_spec in class_methods_spec_list + ] + + def _set_package_spec( + self, + *, + spec: types.ReasoningEngineSpecDict, + update_masks: list[str], + agent: Any, + staging_bucket: Optional[str] = None, + requirements: Optional[Union[str, Sequence[str]]] = None, + gcs_dir_name: Optional[str] = None, + extra_packages: Optional[Sequence[str]] = None, + class_methods: Optional[Sequence[dict[str, Any]]] = None, + sys_version: str, + build_options: Optional[dict[str, list[str]]] = None, + ): + """Sets package spec for agent engine.""" + project = self._api_client.project + if project is None: + raise ValueError("project must be set using `vertexai.Client`.") + location = self._api_client.location + if location is None: + raise ValueError("location must be set using `vertexai.Client`.") + gcs_dir_name = gcs_dir_name or _agent_engines_utils._DEFAULT_GCS_DIR_NAME + staging_bucket = _agent_engines_utils._validate_staging_bucket_or_raise( + staging_bucket=staging_bucket, + ) + requirements = _agent_engines_utils._validate_requirements_or_raise( + agent=agent, + requirements=requirements, + ) + extra_packages = _agent_engines_utils._validate_packages_or_raise( + packages=extra_packages, + build_options=build_options, + ) + # Prepares the Agent Engine for creation/update in Vertex AI. This + # involves packaging and uploading the artifacts for agent_engine, + # requirements and extra_packages to `staging_bucket/gcs_dir_name`. + _agent_engines_utils._prepare( + agent=agent, + requirements=requirements, + project=project, + location=location, + staging_bucket=staging_bucket, + gcs_dir_name=gcs_dir_name, + extra_packages=extra_packages, + credentials=self._api_client._credentials, + ) + # Update the package spec. + update_masks.append("spec.package_spec.pickle_object_gcs_uri") + package_spec = { + "python_version": sys_version, + "pickle_object_gcs_uri": "{}/{}/{}".format( + staging_bucket, + gcs_dir_name, + _agent_engines_utils._BLOB_FILENAME, + ), + } + if extra_packages: + update_masks.append("spec.package_spec.dependency_files_gcs_uri") + package_spec["dependency_files_gcs_uri"] = "{}/{}/{}".format( + staging_bucket, + gcs_dir_name, + _agent_engines_utils._EXTRA_PACKAGES_FILE, + ) + if requirements: + update_masks.append("spec.package_spec.requirements_gcs_uri") + package_spec["requirements_gcs_uri"] = "{}/{}/{}".format( + staging_bucket, + gcs_dir_name, + _agent_engines_utils._REQUIREMENTS_FILE, + ) + spec["package_spec"] = package_spec + + update_masks.append("spec.class_methods") + if class_methods is not None: + class_methods_spec_list = ( + _agent_engines_utils._class_methods_to_class_methods_spec( + class_methods=class_methods + ) + ) + else: + class_methods_spec_list = ( + _agent_engines_utils._generate_class_methods_spec_or_raise( + agent=agent, + operations=_agent_engines_utils._get_registered_operations( + agent=agent + ), + ) + ) + spec["class_methods"] = [ + _agent_engines_utils._to_dict(class_method_spec) + for class_method_spec in class_methods_spec_list + ] + def _create_config( self, *, @@ -1005,6 +1188,9 @@ def _create_config( agent_server_mode: Optional[types.AgentServerMode] = None, class_methods: Optional[Sequence[dict[str, Any]]] = None, source_packages: Optional[Sequence[str]] = None, + developer_connect_source: Optional[ + types.ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfigDict + ] = None, entrypoint_module: Optional[str] = None, entrypoint_object: Optional[str] = None, requirements_file: Optional[str] = None, @@ -1046,156 +1232,58 @@ def _create_config( sys_version = python_version else: sys_version = f"{sys.version_info.major}.{sys.version_info.minor}" - agent_engine_spec: Any = None - if agent is not None: - if source_packages is not None: + + if agent: + if source_packages: raise ValueError( "If you have provided `source_packages` in `config`, please " "do not specify `agent` in `agent_engines.create()` or " "`agent_engines.update()`." ) + if developer_connect_source: + raise ValueError( + "If you have provided `developer_connect_source` in `config`, please " + "do not specify `agent` in `agent_engines.create()` or " + "`agent_engines.update()`." + ) + elif source_packages and developer_connect_source: + raise ValueError( + "Please specify only one of `source_packages` or `developer_connect_source` in `config`." + ) - project = self._api_client.project - if project is None: - raise ValueError("project must be set using `vertexai.Client`.") - location = self._api_client.location - if location is None: - raise ValueError("location must be set using `vertexai.Client`.") - gcs_dir_name = gcs_dir_name or _agent_engines_utils._DEFAULT_GCS_DIR_NAME + agent_engine_spec: Any = None + if agent: + agent_engine_spec = {} agent = _agent_engines_utils._validate_agent_or_raise(agent=agent) if _agent_engines_utils._is_adk_agent(agent): env_vars = _agent_engines_utils._add_telemetry_enablement_env(env_vars) - staging_bucket = _agent_engines_utils._validate_staging_bucket_or_raise( - staging_bucket=staging_bucket, - ) - requirements = _agent_engines_utils._validate_requirements_or_raise( + self._set_package_spec( + spec=agent_engine_spec, + update_masks=update_masks, agent=agent, - requirements=requirements, - ) - extra_packages = _agent_engines_utils._validate_packages_or_raise( - packages=extra_packages, - build_options=build_options, - ) - # Prepares the Agent Engine for creation/update in Vertex AI. This - # involves packaging and uploading the artifacts for agent_engine, - # requirements and extra_packages to `staging_bucket/gcs_dir_name`. - _agent_engines_utils._prepare( - agent=agent, - requirements=requirements, - project=project, - location=location, staging_bucket=staging_bucket, + requirements=requirements, gcs_dir_name=gcs_dir_name, extra_packages=extra_packages, - credentials=self._api_client._credentials, - ) - # Update the package spec. - update_masks.append("spec.package_spec.pickle_object_gcs_uri") - package_spec = { - "python_version": sys_version, - "pickle_object_gcs_uri": "{}/{}/{}".format( - staging_bucket, - gcs_dir_name, - _agent_engines_utils._BLOB_FILENAME, - ), - } - if extra_packages: - update_masks.append("spec.package_spec.dependency_files_gcs_uri") - package_spec["dependency_files_gcs_uri"] = "{}/{}/{}".format( - staging_bucket, - gcs_dir_name, - _agent_engines_utils._EXTRA_PACKAGES_FILE, - ) - if requirements: - update_masks.append("spec.package_spec.requirements_gcs_uri") - package_spec["requirements_gcs_uri"] = "{}/{}/{}".format( - staging_bucket, - gcs_dir_name, - _agent_engines_utils._REQUIREMENTS_FILE, - ) - - update_masks.append("spec.class_methods") - class_methods_spec = [] - if class_methods is not None: - class_methods_spec = ( - _agent_engines_utils._class_methods_to_class_methods_spec( - class_methods=class_methods - ) - ) - else: - class_methods_spec = ( - _agent_engines_utils._generate_class_methods_spec_or_raise( - agent=agent, - operations=_agent_engines_utils._get_registered_operations( - agent=agent - ), - ) - ) - - agent_engine_spec: types.ReasoningEngineSpecDict = { - "package_spec": package_spec, - "class_methods": [ - _agent_engines_utils._to_dict(class_method_spec) - for class_method_spec in class_methods_spec - ], - } - - if source_packages is not None: - source_packages = _agent_engines_utils._validate_packages_or_raise( - packages=source_packages, + class_methods=class_methods, + sys_version=sys_version, build_options=build_options, ) - update_masks.append("spec.source_code_spec.inline_source.source_archive") - source_code_spec = { - "inline_source": { - "source_archive": _agent_engines_utils._create_base64_encoded_tarball( - source_packages=source_packages - ) - } - } - - update_masks.append("spec.source_code_spec.python_spec.version") - python_spec = { - "version": sys_version, - } - if not entrypoint_module: - raise ValueError( - "entrypoint_module must be specified if source_packages is specified." - ) - update_masks.append("spec.source_code_spec.python_spec.entrypoint_module") - python_spec["entrypoint_module"] = entrypoint_module - if not entrypoint_object: - raise ValueError( - "entrypoint_object must be specified if source_packages is specified." - ) - update_masks.append("spec.source_code_spec.python_spec.entrypoint_object") - python_spec["entrypoint_object"] = entrypoint_object - if requirements_file is not None: - update_masks.append( - "spec.source_code_spec.python_spec.requirements_file" - ) - python_spec["requirements_file"] = requirements_file - source_code_spec["python_spec"] = python_spec - - if class_methods is None: - raise ValueError( - "class_methods must be specified if source_packages is specified." - ) - update_masks.append("spec.class_methods") - class_methods_spec = ( - _agent_engines_utils._class_methods_to_class_methods_spec( - class_methods=class_methods - ) + elif source_packages or developer_connect_source: + agent_engine_spec = {} + self._set_source_code_spec( + spec=agent_engine_spec, + update_masks=update_masks, + source_packages=source_packages, + developer_connect_source=developer_connect_source, + class_methods=class_methods, + entrypoint_module=entrypoint_module, + entrypoint_object=entrypoint_object, + requirements_file=requirements_file, + sys_version=sys_version, + build_options=build_options, ) - agent_engine_spec: types.ReasoningEngineSpecDict = { - "source_code_spec": source_code_spec, - "class_methods": [ - _agent_engines_utils._to_dict(class_method_spec) - for class_method_spec in class_methods_spec - ], - } - if agent_engine_spec is not None: if ( env_vars is not None @@ -1444,7 +1532,12 @@ def update( context_spec = config.context_spec if context_spec is not None: # Conversion to a dict for _create_config - context_spec = context_spec.model_dump() + context_spec = json.loads(context_spec.model_dump_json()) + developer_connect_source = config.developer_connect_source + if developer_connect_source is not None: + developer_connect_source = json.loads( + developer_connect_source.model_dump_json() + ) if agent and agent_engine: raise ValueError("Please specify only one of `agent` or `agent_engine`.") elif agent_engine: @@ -1473,6 +1566,7 @@ def update( labels=config.labels, class_methods=config.class_methods, source_packages=config.source_packages, + developer_connect_source=developer_connect_source, entrypoint_module=config.entrypoint_module, entrypoint_object=config.entrypoint_object, requirements_file=config.requirements_file, diff --git a/vertexai/_genai/types/__init__.py b/vertexai/_genai/types/__init__.py index a1f8da0079..86b88b8994 100644 --- a/vertexai/_genai/types/__init__.py +++ b/vertexai/_genai/types/__init__.py @@ -730,6 +730,12 @@ from .common import ReasoningEngineSpecPackageSpecDict from .common import ReasoningEngineSpecPackageSpecOrDict from .common import ReasoningEngineSpecSourceCodeSpec +from .common import ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfig +from .common import ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfigDict +from .common import ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfigOrDict +from .common import ReasoningEngineSpecSourceCodeSpecDeveloperConnectSource +from .common import ReasoningEngineSpecSourceCodeSpecDeveloperConnectSourceDict +from .common import ReasoningEngineSpecSourceCodeSpecDeveloperConnectSourceOrDict from .common import ReasoningEngineSpecSourceCodeSpecDict from .common import ReasoningEngineSpecSourceCodeSpecInlineSource from .common import ReasoningEngineSpecSourceCodeSpecInlineSourceDict @@ -1365,6 +1371,12 @@ "ReasoningEngineSpecPackageSpec", "ReasoningEngineSpecPackageSpecDict", "ReasoningEngineSpecPackageSpecOrDict", + "ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfig", + "ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfigDict", + "ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfigOrDict", + "ReasoningEngineSpecSourceCodeSpecDeveloperConnectSource", + "ReasoningEngineSpecSourceCodeSpecDeveloperConnectSourceDict", + "ReasoningEngineSpecSourceCodeSpecDeveloperConnectSourceOrDict", "ReasoningEngineSpecSourceCodeSpecInlineSource", "ReasoningEngineSpecSourceCodeSpecInlineSourceDict", "ReasoningEngineSpecSourceCodeSpecInlineSourceOrDict", diff --git a/vertexai/_genai/types/common.py b/vertexai/_genai/types/common.py index e8efba4216..fd54f5a8ff 100644 --- a/vertexai/_genai/types/common.py +++ b/vertexai/_genai/types/common.py @@ -4747,6 +4747,74 @@ class ReasoningEngineSpecPackageSpecDict(TypedDict, total=False): ] +class ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfig(_common.BaseModel): + """Specifies the configuration for fetching source code from a Git repository that is managed by Developer Connect. + + This includes the repository, revision, and directory to use. + """ + + dir: Optional[str] = Field( + default=None, + description="""Required. Directory, relative to the source root, in which to run the build.""", + ) + git_repository_link: Optional[str] = Field( + default=None, + description="""Required. The Developer Connect Git repository link, formatted as `projects/*/locations/*/connections/*/gitRepositoryLink/*`.""", + ) + revision: Optional[str] = Field( + default=None, + description="""Required. The revision to fetch from the Git repository such as a branch, a tag, a commit SHA, or any Git ref.""", + ) + + +class ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfigDict( + TypedDict, total=False +): + """Specifies the configuration for fetching source code from a Git repository that is managed by Developer Connect. + + This includes the repository, revision, and directory to use. + """ + + dir: Optional[str] + """Required. Directory, relative to the source root, in which to run the build.""" + + git_repository_link: Optional[str] + """Required. The Developer Connect Git repository link, formatted as `projects/*/locations/*/connections/*/gitRepositoryLink/*`.""" + + revision: Optional[str] + """Required. The revision to fetch from the Git repository such as a branch, a tag, a commit SHA, or any Git ref.""" + + +ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfigOrDict = Union[ + ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfig, + ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfigDict, +] + + +class ReasoningEngineSpecSourceCodeSpecDeveloperConnectSource(_common.BaseModel): + """Specifies source code to be fetched from a Git repository managed through the Developer Connect service.""" + + config: Optional[ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfig] = Field( + default=None, + description="""Required. The Developer Connect configuration thats defines the specific repository, revision, and directory to use as the source code root.""", + ) + + +class ReasoningEngineSpecSourceCodeSpecDeveloperConnectSourceDict( + TypedDict, total=False +): + """Specifies source code to be fetched from a Git repository managed through the Developer Connect service.""" + + config: Optional[ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfigDict] + """Required. The Developer Connect configuration thats defines the specific repository, revision, and directory to use as the source code root.""" + + +ReasoningEngineSpecSourceCodeSpecDeveloperConnectSourceOrDict = Union[ + ReasoningEngineSpecSourceCodeSpecDeveloperConnectSource, + ReasoningEngineSpecSourceCodeSpecDeveloperConnectSourceDict, +] + + class ReasoningEngineSpecSourceCodeSpecInlineSource(_common.BaseModel): """Specifies source code provided as a byte stream.""" @@ -4815,6 +4883,12 @@ class ReasoningEngineSpecSourceCodeSpecPythonSpecDict(TypedDict, total=False): class ReasoningEngineSpecSourceCodeSpec(_common.BaseModel): """Specification for deploying from source code.""" + developer_connect_source: Optional[ + ReasoningEngineSpecSourceCodeSpecDeveloperConnectSource + ] = Field( + default=None, + description="""Source code is in a Git repository managed by Developer Connect.""", + ) inline_source: Optional[ReasoningEngineSpecSourceCodeSpecInlineSource] = Field( default=None, description="""Source code is provided directly in the request.""" ) @@ -4826,6 +4900,11 @@ class ReasoningEngineSpecSourceCodeSpec(_common.BaseModel): class ReasoningEngineSpecSourceCodeSpecDict(TypedDict, total=False): """Specification for deploying from source code.""" + developer_connect_source: Optional[ + ReasoningEngineSpecSourceCodeSpecDeveloperConnectSourceDict + ] + """Source code is in a Git repository managed by Developer Connect.""" + inline_source: Optional[ReasoningEngineSpecSourceCodeSpecInlineSourceDict] """Source code is provided directly in the request.""" @@ -5484,6 +5563,12 @@ class CreateAgentEngineConfig(_common.BaseModel): - class_methods (required) """, ) + developer_connect_source: Optional[ + ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfig + ] = Field( + default=None, + description="""Specifies the configuration for fetching source code from a Git repository that is managed by Developer Connect. This includes the repository, revision, and directory to use.""", + ) entrypoint_module: Optional[str] = Field( default=None, description="""The entrypoint module to be used for the Agent Engine @@ -5616,6 +5701,11 @@ class CreateAgentEngineConfigDict(TypedDict, total=False): - class_methods (required) """ + developer_connect_source: Optional[ + ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfigDict + ] + """Specifies the configuration for fetching source code from a Git repository that is managed by Developer Connect. This includes the repository, revision, and directory to use.""" + entrypoint_module: Optional[str] """The entrypoint module to be used for the Agent Engine This field only used when source_packages is specified.""" @@ -6244,6 +6334,12 @@ class UpdateAgentEngineConfig(_common.BaseModel): - class_methods (required) """, ) + developer_connect_source: Optional[ + ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfig + ] = Field( + default=None, + description="""Specifies the configuration for fetching source code from a Git repository that is managed by Developer Connect. This includes the repository, revision, and directory to use.""", + ) entrypoint_module: Optional[str] = Field( default=None, description="""The entrypoint module to be used for the Agent Engine @@ -6381,6 +6477,11 @@ class UpdateAgentEngineConfigDict(TypedDict, total=False): - class_methods (required) """ + developer_connect_source: Optional[ + ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfigDict + ] + """Specifies the configuration for fetching source code from a Git repository that is managed by Developer Connect. This includes the repository, revision, and directory to use.""" + entrypoint_module: Optional[str] """The entrypoint module to be used for the Agent Engine This field only used when source_packages is specified.""" @@ -13626,6 +13727,12 @@ class AgentEngineConfig(_common.BaseModel): - class_methods (required) """, ) + developer_connect_source: Optional[ + ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfig + ] = Field( + default=None, + description="""Specifies the configuration for fetching source code from a Git repository that is managed by Developer Connect. This includes the repository, revision, and directory to use.""", + ) entrypoint_module: Optional[str] = Field( default=None, description="""The entrypoint module to be used for the Agent Engine @@ -13790,6 +13897,11 @@ class AgentEngineConfigDict(TypedDict, total=False): - class_methods (required) """ + developer_connect_source: Optional[ + ReasoningEngineSpecSourceCodeSpecDeveloperConnectConfigDict + ] + """Specifies the configuration for fetching source code from a Git repository that is managed by Developer Connect. This includes the repository, revision, and directory to use.""" + entrypoint_module: Optional[str] """The entrypoint module to be used for the Agent Engine This field only used when source_packages is specified."""