Skip to content

Commit ff5776a

Browse files
vertex-sdk-botcopybara-github
authored andcommitted
feat: Implement ListSkills and DeleteSkill methods in Vertex AI GenAI SDK
PiperOrigin-RevId: 911346796
1 parent 2db8698 commit ff5776a

9 files changed

Lines changed: 3212 additions & 9 deletions

File tree

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
"""Tests the skills.create() method against the Vertex AI endpoint using replays."""
16+
17+
import io
18+
import os
19+
import tempfile
20+
import zipfile
21+
22+
from tests.unit.vertexai.genai.replays import pytest_helper
23+
from vertexai._genai import types
24+
25+
# MANDATORY: Initialize the replay test framework for this module
26+
pytestmark = pytest_helper.setup(
27+
file=__file__,
28+
globals_for_file=globals(),
29+
)
30+
31+
32+
def test_create_skill(client):
33+
"""Tests the creation of a skill using `client.skills.create()`."""
34+
# Target the autopush sandbox endpoint for the Skill Registry API
35+
client._api_client._http_options.base_url = (
36+
"https://us-central1-autopush-aiplatform.sandbox.googleapis.com"
37+
)
38+
39+
with tempfile.TemporaryDirectory() as tmpdir:
40+
# Create a dummy skill structure (SKILL.md is required by the spec)
41+
with open(os.path.join(tmpdir, "SKILL.md"), "w") as f:
42+
f.write("# My Replay Skill\nThis is a test skill for replay tests.")
43+
44+
skill = client.skills.create(
45+
display_name="My Replay Skill",
46+
description="My Replay Skill Description",
47+
config=types.CreateSkillConfig(
48+
local_path=tmpdir, wait_for_completion=True
49+
),
50+
)
51+
52+
assert skill.name is not None
53+
assert skill.display_name == "My Replay Skill"
54+
assert skill.description == "My Replay Skill Description"
55+
56+
57+
def test_create_skill_with_prezipped_bytes(client):
58+
"""Tests the creation of a skill with pre-zipped bytes."""
59+
# Target the autopush sandbox endpoint for the Skill Registry API
60+
client._api_client._http_options.base_url = (
61+
"https://us-central1-autopush-aiplatform.sandbox.googleapis.com"
62+
)
63+
64+
zip_buffer = io.BytesIO()
65+
zinfo = zipfile.ZipInfo("SKILL.md", date_time=(1980, 1, 1, 0, 0, 0))
66+
with zipfile.ZipFile(zip_buffer, "w") as zip_file:
67+
zip_file.writestr(zinfo, "# My Zipped Replay Skill\nThis is a test.")
68+
zipped_bytes = zip_buffer.getvalue()
69+
70+
skill = client.skills.create(
71+
display_name="My Zipped Replay Skill",
72+
description="My Zipped Replay Skill Description",
73+
config=types.CreateSkillConfig(
74+
zipped_filesystem=zipped_bytes, wait_for_completion=True
75+
),
76+
)
77+
78+
assert skill.name is not None
79+
assert skill.display_name == "My Zipped Replay Skill"
80+
assert skill.description == "My Zipped Replay Skill Description"
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
"""Tests the skills.get() method against the autopush endpoint."""
2+
3+
from google.api_core import exceptions
4+
from tests.unit.vertexai.genai.replays import pytest_helper
5+
import pytest
6+
7+
PROJECT_ID = "demo-project"
8+
REGION = "us-central1"
9+
SKILL_ID = "7184367305562783744"
10+
# target the autopush sandbox endpoint for the Skill Registry API
11+
ENDPOINT = f"{REGION}-autopush-aiplatform.sandbox.googleapis.com"
12+
13+
14+
pytestmark = pytest_helper.setup(
15+
file=__file__,
16+
globals_for_file=globals(),
17+
)
18+
19+
20+
def test_get_skill(client): # client fixture is injected by pytest_helper.setup
21+
"""Tests the skills.get() method against the autopush endpoint."""
22+
23+
client._api_client._http_options.base_url = (
24+
"https://us-central1-autopush-aiplatform.sandbox.googleapis.com"
25+
)
26+
skill_name = f"projects/{PROJECT_ID}/locations/{REGION}/skills/{SKILL_ID}"
27+
28+
try:
29+
skill = client.skills.get(name=skill_name)
30+
assert skill.name == skill_name
31+
32+
except exceptions.GoogleAPIError as e:
33+
pytest.fail(f"Error calling client.skills.get(): {e}")
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
# Copyright 2026 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
#
15+
"""Tests the skills.update() method against the Vertex AI endpoint using replays."""
16+
17+
import io
18+
import os
19+
import random
20+
import tempfile
21+
import zipfile
22+
23+
from tests.unit.vertexai.genai.replays import pytest_helper
24+
from vertexai._genai import types
25+
26+
# MANDATORY: Initialize the replay test framework for this module
27+
pytestmark = pytest_helper.setup(
28+
file=__file__,
29+
globals_for_file=globals(),
30+
)
31+
32+
PROJECT_ID = os.environ.get("GOOGLE_CLOUD_PROJECT", "srbai-testing")
33+
REGION = "us-central1"
34+
35+
36+
def test_update_skill(client):
37+
"""Tests the update of a skill using `client.skills.update()` (metadata only)."""
38+
# Target the autopush sandbox endpoint for the Skill Registry API
39+
client._api_client._http_options.base_url = (
40+
"https://us-central1-autopush-aiplatform.sandbox.googleapis.com"
41+
)
42+
43+
# 1. Create a fresh unique skill first
44+
skill_id = f"update_meta_test_skill_{random.randint(10000, 99999)}"
45+
with tempfile.TemporaryDirectory() as tmpdir:
46+
with open(os.path.join(tmpdir, "SKILL.md"), "w") as f:
47+
f.write("# Test Skill\nInitial content.")
48+
49+
created_skill = client.skills.create(
50+
display_name="Original Skill",
51+
description="Original Description",
52+
config=types.CreateSkillConfig(
53+
local_path=tmpdir, skill_id=skill_id, wait_for_completion=True
54+
),
55+
)
56+
57+
# 2. Perform the metadata-only update on the new skill
58+
updated_skill = client.skills.update(
59+
name=created_skill.name,
60+
config=types.UpdateSkillConfig(
61+
display_name="My Updated Replay Skill",
62+
description="My Updated Replay Skill Description",
63+
wait_for_completion=True,
64+
),
65+
)
66+
67+
assert updated_skill.name == created_skill.name
68+
assert updated_skill.display_name == "My Updated Replay Skill"
69+
assert updated_skill.description == "My Updated Replay Skill Description"
70+
71+
72+
def test_update_skill_with_zipped_bytes(client):
73+
"""Tests the update of a skill with zipped bytes filesystem."""
74+
# Target the autopush sandbox endpoint for the Skill Registry API
75+
client._api_client._http_options.base_url = (
76+
"https://us-central1-autopush-aiplatform.sandbox.googleapis.com"
77+
)
78+
79+
# 1. Create a fresh unique skill first
80+
skill_id = f"update_zip_test_skill_{random.randint(10000, 99999)}"
81+
with tempfile.TemporaryDirectory() as tmpdir:
82+
with open(os.path.join(tmpdir, "SKILL.md"), "w") as f:
83+
f.write("# Test Skill\nInitial content.")
84+
85+
created_skill = client.skills.create(
86+
display_name="Original Skill",
87+
description="Original Description",
88+
config=types.CreateSkillConfig(
89+
local_path=tmpdir, skill_id=skill_id, wait_for_completion=True
90+
),
91+
)
92+
93+
# 2. Prepare zipped bytes for update
94+
zip_buffer = io.BytesIO()
95+
zinfo = zipfile.ZipInfo("SKILL.md", date_time=(1980, 1, 1, 0, 0, 0))
96+
with zipfile.ZipFile(zip_buffer, "w") as zip_file:
97+
zip_file.writestr(
98+
zinfo, "# My Updated Zipped Replay Skill\nThis is updated."
99+
)
100+
zipped_bytes = zip_buffer.getvalue()
101+
102+
# 3. Update the skill with new zipped bytes
103+
updated_skill = client.skills.update(
104+
name=created_skill.name,
105+
config=types.UpdateSkillConfig(
106+
zipped_filesystem=zipped_bytes, wait_for_completion=True
107+
),
108+
)
109+
110+
assert updated_skill.name == created_skill.name
111+
assert (
112+
updated_skill.display_name == "Original Skill"
113+
) # Display name remains unchanged

0 commit comments

Comments
 (0)