mirror of
https://github.com/langgenius/dify.git
synced 2026-07-12 07:57:55 +08:00
Co-authored-by: yunlu.wen <yunlu.wen@dify.ai> Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com> Co-authored-by: Yunlu Wen <wylswz@163.com> Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: Joel <iamjoel007@gmail.com> Co-authored-by: Yanli 盐粒 <yanli@dify.ai> Co-authored-by: 盐粒 Yanli <beautyyuyanli@gmail.com> Co-authored-by: zyssyz123 <916125788@qq.com> Co-authored-by: 盐粒 Yanli <mail@yanli.one>
244 lines
8.4 KiB
Python
244 lines
8.4 KiB
Python
"""Inner API for Agent Soul-backed config assets.
|
|
|
|
These endpoints are called by the dify-agent server with the inner API key.
|
|
They resolve the requested Agent config version directly from Agent Soul JSON
|
|
and never expose signed download URLs or drive-owned metadata.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import io
|
|
|
|
from flask import request, send_file
|
|
from flask_restx import Resource
|
|
from pydantic import BaseModel, ValidationError
|
|
|
|
from controllers.console.wraps import setup_required
|
|
from controllers.inner_api import inner_api_ns
|
|
from controllers.inner_api.wraps import plugin_inner_api_only
|
|
from services.agent_config_service import (
|
|
AgentConfigService,
|
|
AgentConfigServiceError,
|
|
AgentConfigVersionKind,
|
|
ConfigPushPayload,
|
|
)
|
|
|
|
|
|
class _ConfigTargetQuery(BaseModel):
|
|
tenant_id: str
|
|
user_id: str | None = None
|
|
config_version_id: str
|
|
config_version_kind: AgentConfigVersionKind
|
|
|
|
|
|
class _ConfigMutationRequest(BaseModel):
|
|
tenant_id: str
|
|
user_id: str
|
|
config_version_id: str
|
|
config_version_kind: AgentConfigVersionKind
|
|
|
|
|
|
class _ConfigPushRequest(_ConfigMutationRequest):
|
|
files: list[dict] = []
|
|
skills: list[dict] = []
|
|
env_text: str | None = None
|
|
note: str | None = None
|
|
|
|
def to_payload(self) -> ConfigPushPayload:
|
|
return ConfigPushPayload.model_validate(
|
|
{
|
|
"files": self.files,
|
|
"skills": self.skills,
|
|
"env_text": self.env_text,
|
|
"note": self.note,
|
|
}
|
|
)
|
|
|
|
|
|
class _ConfigEnvUpdateRequest(_ConfigMutationRequest):
|
|
env_text: str
|
|
|
|
|
|
class _ConfigNoteUpdateRequest(_ConfigMutationRequest):
|
|
note: str
|
|
|
|
|
|
def _target_query_from_request() -> _ConfigTargetQuery:
|
|
return _ConfigTargetQuery.model_validate(
|
|
{
|
|
"tenant_id": request.args.get("tenant_id"),
|
|
"user_id": request.args.get("user_id"),
|
|
"config_version_id": request.args.get("config_version_id"),
|
|
"config_version_kind": request.args.get("config_version_kind"),
|
|
}
|
|
)
|
|
|
|
|
|
def _error_response(exc: AgentConfigServiceError) -> tuple[dict[str, str], int]:
|
|
return {"code": exc.code, "message": exc.message}, exc.status_code
|
|
|
|
|
|
@inner_api_ns.route("/agent-config/<string:agent_id>/manifest")
|
|
class AgentConfigManifestApi(Resource):
|
|
@setup_required
|
|
@plugin_inner_api_only
|
|
@inner_api_ns.doc("agent_config_manifest")
|
|
def get(self, agent_id: str):
|
|
try:
|
|
query = _target_query_from_request()
|
|
return AgentConfigService().manifest(
|
|
tenant_id=query.tenant_id,
|
|
agent_id=agent_id,
|
|
user_id=query.user_id,
|
|
config_version_id=query.config_version_id,
|
|
config_version_kind=query.config_version_kind,
|
|
)
|
|
except ValidationError as exc:
|
|
return {"code": "invalid_request", "message": str(exc)}, 400
|
|
except AgentConfigServiceError as exc:
|
|
return _error_response(exc)
|
|
|
|
|
|
@inner_api_ns.route("/agent-config/<string:agent_id>/skills/<string:name>/pull")
|
|
class AgentConfigSkillPullApi(Resource):
|
|
@setup_required
|
|
@plugin_inner_api_only
|
|
@inner_api_ns.doc("agent_config_skill_pull")
|
|
def get(self, agent_id: str, name: str):
|
|
try:
|
|
query = _target_query_from_request()
|
|
result = AgentConfigService().pull_skill(
|
|
tenant_id=query.tenant_id,
|
|
agent_id=agent_id,
|
|
user_id=query.user_id,
|
|
config_version_id=query.config_version_id,
|
|
config_version_kind=query.config_version_kind,
|
|
name=name,
|
|
)
|
|
return send_file(
|
|
io.BytesIO(result.payload),
|
|
mimetype=result.mime_type,
|
|
as_attachment=True,
|
|
download_name=result.filename,
|
|
)
|
|
except ValidationError as exc:
|
|
return {"code": "invalid_request", "message": str(exc)}, 400
|
|
except AgentConfigServiceError as exc:
|
|
return _error_response(exc)
|
|
|
|
|
|
@inner_api_ns.route("/agent-config/<string:agent_id>/skills/<string:name>/inspect")
|
|
class AgentConfigSkillInspectApi(Resource):
|
|
@setup_required
|
|
@plugin_inner_api_only
|
|
@inner_api_ns.doc("agent_config_skill_inspect")
|
|
def get(self, agent_id: str, name: str):
|
|
try:
|
|
query = _target_query_from_request()
|
|
return AgentConfigService().inspect_skill(
|
|
tenant_id=query.tenant_id,
|
|
agent_id=agent_id,
|
|
user_id=query.user_id,
|
|
config_version_id=query.config_version_id,
|
|
config_version_kind=query.config_version_kind,
|
|
name=name,
|
|
)
|
|
except ValidationError as exc:
|
|
return {"code": "invalid_request", "message": str(exc)}, 400
|
|
except AgentConfigServiceError as exc:
|
|
return _error_response(exc)
|
|
|
|
|
|
@inner_api_ns.route("/agent-config/<string:agent_id>/files/<string:name>/pull")
|
|
class AgentConfigFilePullApi(Resource):
|
|
@setup_required
|
|
@plugin_inner_api_only
|
|
@inner_api_ns.doc("agent_config_file_pull")
|
|
def get(self, agent_id: str, name: str):
|
|
try:
|
|
query = _target_query_from_request()
|
|
result = AgentConfigService().pull_file(
|
|
tenant_id=query.tenant_id,
|
|
agent_id=agent_id,
|
|
user_id=query.user_id,
|
|
config_version_id=query.config_version_id,
|
|
config_version_kind=query.config_version_kind,
|
|
name=name,
|
|
)
|
|
return send_file(
|
|
io.BytesIO(result.payload),
|
|
mimetype=result.mime_type,
|
|
as_attachment=True,
|
|
download_name=result.filename,
|
|
)
|
|
except ValidationError as exc:
|
|
return {"code": "invalid_request", "message": str(exc)}, 400
|
|
except AgentConfigServiceError as exc:
|
|
return _error_response(exc)
|
|
|
|
|
|
@inner_api_ns.route("/agent-config/<string:agent_id>/push")
|
|
class AgentConfigPushApi(Resource):
|
|
@setup_required
|
|
@plugin_inner_api_only
|
|
@inner_api_ns.doc("agent_config_push")
|
|
def post(self, agent_id: str):
|
|
try:
|
|
body = _ConfigPushRequest.model_validate(request.get_json(silent=True) or {})
|
|
return AgentConfigService().push(
|
|
tenant_id=body.tenant_id,
|
|
agent_id=agent_id,
|
|
user_id=body.user_id,
|
|
config_version_id=body.config_version_id,
|
|
config_version_kind=body.config_version_kind,
|
|
payload=body.to_payload(),
|
|
)
|
|
except ValidationError as exc:
|
|
return {"code": "invalid_request", "message": str(exc)}, 400
|
|
except AgentConfigServiceError as exc:
|
|
return _error_response(exc)
|
|
|
|
|
|
@inner_api_ns.route("/agent-config/<string:agent_id>/env")
|
|
class AgentConfigEnvApi(Resource):
|
|
@setup_required
|
|
@plugin_inner_api_only
|
|
@inner_api_ns.doc("agent_config_env")
|
|
def patch(self, agent_id: str):
|
|
try:
|
|
body = _ConfigEnvUpdateRequest.model_validate(request.get_json(silent=True) or {})
|
|
return AgentConfigService().update_env(
|
|
tenant_id=body.tenant_id,
|
|
agent_id=agent_id,
|
|
user_id=body.user_id,
|
|
config_version_id=body.config_version_id,
|
|
config_version_kind=body.config_version_kind,
|
|
env_text=body.env_text,
|
|
)
|
|
except ValidationError as exc:
|
|
return {"code": "invalid_request", "message": str(exc)}, 400
|
|
except AgentConfigServiceError as exc:
|
|
return _error_response(exc)
|
|
|
|
|
|
@inner_api_ns.route("/agent-config/<string:agent_id>/note")
|
|
class AgentConfigNoteApi(Resource):
|
|
@setup_required
|
|
@plugin_inner_api_only
|
|
@inner_api_ns.doc("agent_config_note")
|
|
def put(self, agent_id: str):
|
|
try:
|
|
body = _ConfigNoteUpdateRequest.model_validate(request.get_json(silent=True) or {})
|
|
return AgentConfigService().update_note(
|
|
tenant_id=body.tenant_id,
|
|
agent_id=agent_id,
|
|
user_id=body.user_id,
|
|
config_version_id=body.config_version_id,
|
|
config_version_kind=body.config_version_kind,
|
|
note=body.note,
|
|
)
|
|
except ValidationError as exc:
|
|
return {"code": "invalid_request", "message": str(exc)}, 400
|
|
except AgentConfigServiceError as exc:
|
|
return _error_response(exc)
|