Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
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
1 change: 1 addition & 0 deletions docs/docs/tools/builtin.md
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ VeADK 集成了以下火山引擎工具:
- `AGENTKIT_TOOL_HOST`:用于调用火山引擎AgentKit Tools的EndPoint
- `AGENTKIT_TOOL_SERVICE_CODE`:用于调用AgentKit Tools的ServiceCode
- `AGENTKIT_TOOL_SCHEME`:用于切换调用 AgentKit Tools 的协议,允许 `http`/`https`,默认 `https`
- `AGENTKIT_TOP_SCHEME`:用于切换调用 AgentKit TOP 的协议,允许 `http`/`https`,默认 `https`

环境变量列表:

Expand Down
2 changes: 2 additions & 0 deletions veadk/skills/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ def load_skills_from_cloud(skill_space_ids: str) -> list[Skill]:
"InnerTags": {"source": "sandbox"},
}
logger.debug(f"ListSkillsBySpaceId request body: {request_body}")
scheme = os.getenv("AGENTKIT_TOP_SCHEME", "https").lower()

response = ve_request(
request_body=request_body,
Expand All @@ -185,6 +186,7 @@ def load_skills_from_cloud(skill_space_ids: str) -> list[Skill]:
region=region,
host=host,
header={"X-Security-Token": session_token},
scheme=scheme,
)

if isinstance(response, str):
Expand Down
116 changes: 110 additions & 6 deletions veadk/tools/skills_tools/download_skills_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,93 @@
logger = get_logger(__name__)


def _download_skill_via_vestack(
tos_path: str,
skill_name: str,
access_key: str,
secret_key: str,
session_token: str,
service: str,
region: str,
host: str,
scheme: str,
zip_path: Path,
) -> bool:
import json
import requests
from veadk.utils.volcengine_sign import ve_request

try:
path_parts = tos_path.split("/")
if len(path_parts) >= 3:
skill_id = path_parts[1]
skill_version = path_parts[2]
else:
logger.error(
f"Invalid TosPath format for skill '{skill_name}': {tos_path}"
)
return False
except Exception as e:
logger.error(
f"Failed to parse TosPath for skill '{skill_name}': {e}"
)
return False

# Call GenTempTosObjectDownloadUrl API
temp_url_request_body = {
"SkillId": skill_id,
"SkillVersion": skill_version,
}
logger.debug(
f"GenTempTosObjectDownloadUrl request body: {temp_url_request_body}"
)

temp_url_res = ve_request(
request_body=temp_url_request_body,
action="GenTempTosObjectDownloadUrl",
ak=access_key,
sk=secret_key,
service=service,
version="2025-10-30",
region=region,
host=host,
header={"X-Security-Token": session_token},
scheme=scheme,
)

if isinstance(temp_url_res, str):
temp_url_res = json.loads(temp_url_res)

if (
"ResponseMetadata" in temp_url_res
and "Error" in temp_url_res["ResponseMetadata"]
):
error_details = temp_url_res["ResponseMetadata"]["Error"]
logger.error(
f"Failed to get temporary download URL for '{skill_name}': {error_details}"
)
return False
else:
signed_url = temp_url_res.get("Result", {}).get("SignedUrl")
if not signed_url:
logger.error(
f"Failed to get SignedUrl from GenTempTosObjectDownloadUrl response: {temp_url_res}"
)
return False
else:
try:
response = requests.get(signed_url)
response.raise_for_status()
with open(zip_path, "wb") as f:
f.write(response.content)
return True
except Exception as e:
logger.warning(
f"Failed to download skill '{skill_name}' from minio: {e}"
)
return False


def download_skills_tool(
download_path: str, skill_names: Optional[list[str]] = None
) -> str:
Expand Down Expand Up @@ -92,6 +179,7 @@ def download_skills_tool(

all_downloaded_skills = []

scheme = os.getenv("AGENTKIT_TOP_SCHEME", "https").lower()
# Iterate through each skill space
for skill_space_id in skill_space_ids_list:
try:
Expand All @@ -101,7 +189,7 @@ def download_skills_tool(
"InnerTags": {"source": "sandbox"},
}
logger.info(f"ListSkillsBySpaceId request body: {request_body}")

response = ve_request(
request_body=request_body,
action="ListSkillsBySpaceId",
Expand All @@ -112,6 +200,7 @@ def download_skills_tool(
region=region,
host=host,
header={"X-Security-Token": session_token},
scheme=scheme,
)

if isinstance(response, str):
Expand Down Expand Up @@ -161,11 +250,26 @@ def download_skills_tool(

# Download zip file
zip_path = download_dir / f"{skill_name}.zip"
success = tos_client.download(
bucket_name=tos_bucket,
object_key=tos_path,
save_path=str(zip_path),
)

if cloud_provider == "vestack":
success = _download_skill_via_vestack(
tos_path=tos_path,
skill_name=skill_name,
access_key=access_key,
secret_key=secret_key,
session_token=session_token,
service=service,
region=region,
host=host,
scheme=scheme,
zip_path=zip_path,
)
else:
success = tos_client.download(
bucket_name=tos_bucket,
object_key=tos_path,
save_path=str(zip_path),
)

if not success:
logger.warning(f"Failed to download skill '{skill_name}'")
Expand Down
125 changes: 90 additions & 35 deletions veadk/tools/skills_tools/register_skills_tool.py
Original file line number Diff line number Diff line change
Expand Up @@ -111,46 +111,100 @@ def register_skills_tool(
secret_key = cred.secret_access_key
session_token = cred.session_token

res = ve_request(
request_body={},
action="GetCallerIdentity",
ak=access_key,
sk=secret_key,
service="sts",
version="2018-01-01",
region=region,
host="sts.volcengineapi.com"
if cloud_provider != "byteplus"
else "open.byteplusapi.com",
header={"X-Security-Token": session_token},
)
try:
account_id = res["Result"]["AccountId"]
except KeyError as e:
logger.error(
f"Error occurred while getting account id: {e}, response is {res}"
account_id = ""
if cloud_provider != "vestack":
res = ve_request(
request_body={},
action="GetCallerIdentity",
ak=access_key,
sk=secret_key,
service="sts",
version="2018-01-01",
region=region,
host="sts.volcengineapi.com"
if cloud_provider != "byteplus"
else "open.byteplusapi.com",
header={"X-Security-Token": session_token},
)
return f"Error: Failed to get account id when registering skill '{skill_name}'."
try:
account_id = res["Result"]["AccountId"]
except KeyError as e:
logger.error(
f"Error occurred while getting account id: {e}, response is {res}"
)
return f"Error: Failed to get account id when registering skill '{skill_name}'."

tos_bucket = f"agentkit-platform-{region}-{account_id}-skill"
scheme = os.getenv("AGENTKIT_TOP_SCHEME", "https").lower()
if cloud_provider == "vestack":
import requests

# Call GenTempTosObjectUrl API
temp_url_request_body = {
"SkillName": skill_name,
}
logger.debug(f"GenTempTosObjectUrl request body: {temp_url_request_body}")

temp_url_res = ve_request(
request_body=temp_url_request_body,
action="GenTempTosObjectUrl",
ak=access_key,
sk=secret_key,
service=agentkit_tool_service,
version="2025-10-30",
region=region,
host=agentkit_skill_host,
header={"X-Security-Token": session_token},
scheme=scheme,
)

tos_client = VeTOS(
ak=access_key,
sk=secret_key,
session_token=session_token,
bucket_name=tos_bucket,
region=region,
)
if isinstance(temp_url_res, str):
temp_url_res = json.loads(temp_url_res)

if (
"ResponseMetadata" in temp_url_res
and "Error" in temp_url_res["ResponseMetadata"]
):
error_details = temp_url_res["ResponseMetadata"]["Error"]
logger.error(
f"Failed to get temporary upload URL for '{skill_name}': {error_details}"
)
return f"Failed to get temporary upload URL for '{skill_name}': {error_details}"

signed_url = temp_url_res.get("Result", {}).get("SignedUrl")
tos_url = temp_url_res.get("Result", {}).get("TosUrl")

if not signed_url or not tos_url:
logger.error(
f"Failed to get SignedUrl or TosUrl from GenTempTosObjectUrl response: {temp_url_res}"
)
return f"Failed to get temporary upload URL for '{skill_name}'."

try:
with open(zip_file_path, "rb") as f:
response = requests.put(signed_url, data=f)
response.raise_for_status()
except Exception as e:
logger.error(f"Failed to upload skill '{skill_name}' to minio: {e}")
return f"Failed to upload skill '{skill_name}' to minio: {e}"
else:
tos_client = VeTOS(
ak=access_key,
sk=secret_key,
session_token=session_token,
bucket_name=tos_bucket,
region=region,
)

object_key = (
f"uploads/{datetime.now().strftime('%Y%m%d_%H%M%S')}/{skill_name}.zip"
)
tos_client.upload_file(
file_path=zip_file_path, bucket_name=tos_bucket, object_key=object_key
)
tos_url = tos_client.build_tos_url(
bucket_name=tos_bucket, object_key=object_key
)
object_key = (
f"uploads/{datetime.now().strftime('%Y%m%d_%H%M%S')}/{skill_name}.zip"
)
tos_client.upload_file(
file_path=zip_file_path, bucket_name=tos_bucket, object_key=object_key
)
tos_url = tos_client.build_tos_url(
bucket_name=tos_bucket, object_key=object_key
)

skill_space_ids = os.getenv("SKILL_SPACE_ID", "")
skill_space_ids_list = [
Expand All @@ -173,6 +227,7 @@ def register_skills_tool(
region=region,
host=agentkit_skill_host,
header={"X-Security-Token": session_token},
scheme=scheme,
)

if isinstance(response, str):
Expand Down
Loading
Loading