feat(skill): pin run revision bindings

This commit is contained in:
huanghuoguoguo
2026-09-28 10:22:01 +08:00
parent 1ab1a29b53
commit 9b8d1b4034
16 changed files with 657 additions and 274 deletions
@@ -5,6 +5,7 @@ import quart
from ...authz import Permission
from ...context import RequestContext
from .....operation_trace import service as settings_service
from .....skill.repository import SkillRevisionConflictError
from .. import group
@@ -76,6 +77,8 @@ class SkillsRouterGroup(group.RouterGroup):
previous = None
try:
skill = await self.ap.skill_service.update_skill(request_context, skill_name, data)
except SkillRevisionConflictError as exc:
return self.http_status(409, -1, str(exc))
except ValueError as exc:
return self.http_status(400, -1, str(exc))
@@ -115,6 +118,8 @@ class SkillsRouterGroup(group.RouterGroup):
include_hidden=include_hidden,
)
return self.success(data=result)
except SkillRevisionConflictError as exc:
return self.http_status(409, -1, str(exc))
except ValueError as exc:
return self.http_status(400, -1, str(exc))
@@ -140,11 +145,18 @@ class SkillsRouterGroup(group.RouterGroup):
async def write_skill_file(skill_name: str, path: str, request_context: RequestContext) -> quart.Response:
data = await quart.request.json
content = data.get('content', '')
base_revision = str(data.get('base_revision', '') or '').strip() or None
if content is None:
return self.http_status(400, -1, 'Missing required field: content')
try:
result = await self.ap.skill_service.write_skill_file(request_context, skill_name, path, content)
result = await self.ap.skill_service.write_skill_file(
request_context,
skill_name,
path,
content,
base_revision=base_revision,
)
return self.success(data=result)
except ValueError as exc:
return self.http_status(400, -1, str(exc))
+38 -5
View File
@@ -103,15 +103,34 @@ class SkillService:
await self._reload_skills(execution_context)
return self._serialize_skill(created)
async def import_skill_directory(self, context: TenantContext, path: str, data: dict) -> dict:
async def import_skill_directory(
self,
context: TenantContext,
path: str,
data: dict,
*,
base_revision: str | None = None,
) -> dict:
execution_context = await self._execution_context(context)
created = await self._repository().import_skill_directory(execution_context, path, data)
created = await self._repository().import_skill_directory(
execution_context,
path,
data,
base_revision=base_revision,
)
await self._reload_skills(execution_context)
return self._serialize_skill(created)
async def update_skill(self, context: TenantContext, skill_name: str, data: dict) -> dict:
execution_context = await self._execution_context(context)
updated = await self._repository().update_skill(execution_context, skill_name, data)
payload = dict(data)
base_revision = str(payload.pop('base_revision', '') or '').strip() or None
updated = await self._repository().update_skill(
execution_context,
skill_name,
payload,
base_revision=base_revision,
)
await self._reload_skills(execution_context)
return self._serialize_skill(updated)
@@ -142,9 +161,23 @@ class SkillService:
execution_context = await self._execution_context(context)
return await self._repository().read_skill_file(execution_context, skill_name, path)
async def write_skill_file(self, context: TenantContext, skill_name: str, path: str, content: str) -> dict:
async def write_skill_file(
self,
context: TenantContext,
skill_name: str,
path: str,
content: str,
*,
base_revision: str | None,
) -> dict:
execution_context = await self._execution_context(context)
result = await self._repository().write_skill_file(execution_context, skill_name, path, content)
result = await self._repository().write_skill_file(
execution_context,
skill_name,
path,
content,
base_revision=base_revision,
)
await self._reload_skills(execution_context)
return result