mirror of
https://github.com/AstrBotDevs/AstrBot
synced 2026-07-15 17:30:13 +08:00
fix: address neo skill review findings
This commit is contained in:
@@ -40,15 +40,19 @@ async def _sync_skills_to_sandbox(booter: ComputerBooter) -> None:
|
||||
upload_result = await booter.upload_file(zip_path, str(remote_zip))
|
||||
if not upload_result.get("success", False):
|
||||
raise RuntimeError("Failed to upload skills bundle to sandbox.")
|
||||
# Always overwrite with local source of truth to avoid stale skills in long-lived sandboxes.
|
||||
# Extract into a temp folder first, then replace skills atomically.
|
||||
tmp_extract_root = f"{SANDBOX_SKILLS_ROOT}_tmp_extract"
|
||||
await booter.shell.exec(
|
||||
f"mkdir -p {SANDBOX_SKILLS_ROOT} && "
|
||||
f"rm -rf {SANDBOX_SKILLS_ROOT}/* && "
|
||||
f"(unzip -o {remote_zip} -d {SANDBOX_SKILLS_ROOT} || "
|
||||
f"mkdir -p {SANDBOX_SKILLS_ROOT} {tmp_extract_root} && "
|
||||
f"rm -rf {tmp_extract_root}/* && "
|
||||
f"(unzip -o {remote_zip} -d {tmp_extract_root} || "
|
||||
f"python3 -c \"import zipfile; z=zipfile.ZipFile('{remote_zip}'); "
|
||||
f"z.extractall('{SANDBOX_SKILLS_ROOT}')\" || "
|
||||
f"z.extractall('{tmp_extract_root}')\" || "
|
||||
f"python -c \"import zipfile; z=zipfile.ZipFile('{remote_zip}'); "
|
||||
f"z.extractall('{SANDBOX_SKILLS_ROOT}')\"); "
|
||||
f"z.extractall('{tmp_extract_root}')\") && "
|
||||
f"find {SANDBOX_SKILLS_ROOT} -mindepth 1 -delete && "
|
||||
f"cp -a {tmp_extract_root}/. {SANDBOX_SKILLS_ROOT}/ && "
|
||||
f"rm -rf {tmp_extract_root} && "
|
||||
f"rm -f {remote_zip}"
|
||||
)
|
||||
finally:
|
||||
|
||||
@@ -250,9 +250,10 @@ class SkillsRoute(Route):
|
||||
endpoint, access_token = self._get_neo_client_config()
|
||||
data = await request.get_json()
|
||||
candidate_id = data.get("candidate_id")
|
||||
passed = data.get("passed")
|
||||
if not candidate_id or passed is None:
|
||||
passed_value = data.get("passed")
|
||||
if not candidate_id or passed_value is None:
|
||||
return Response().error("Missing candidate_id or passed").__dict__
|
||||
passed = _to_bool(passed_value, False)
|
||||
|
||||
from shipyard_neo import BayClient
|
||||
|
||||
@@ -262,7 +263,7 @@ class SkillsRoute(Route):
|
||||
) as client:
|
||||
result = await client.skills.evaluate_candidate(
|
||||
candidate_id,
|
||||
passed=bool(passed),
|
||||
passed=passed,
|
||||
score=data.get("score"),
|
||||
benchmark_id=data.get("benchmark_id"),
|
||||
report=data.get("report"),
|
||||
|
||||
@@ -311,6 +311,13 @@ export default {
|
||||
return payload.skills || [];
|
||||
};
|
||||
|
||||
const normalizeNeoItemsPayload = (res) => {
|
||||
const payload = res?.data?.data || [];
|
||||
if (Array.isArray(payload)) return payload;
|
||||
if (Array.isArray(payload.items)) return payload.items;
|
||||
return [];
|
||||
};
|
||||
|
||||
const fetchSkills = async () => {
|
||||
loading.value = true;
|
||||
try {
|
||||
@@ -406,8 +413,7 @@ export default {
|
||||
status: neoFilters.status || undefined,
|
||||
};
|
||||
const res = await axios.get("/api/skills/neo/candidates", { params });
|
||||
const payload = res?.data?.data || {};
|
||||
neoCandidates.value = payload.items || [];
|
||||
neoCandidates.value = normalizeNeoItemsPayload(res);
|
||||
};
|
||||
|
||||
const fetchNeoReleases = async () => {
|
||||
@@ -416,8 +422,15 @@ export default {
|
||||
stage: neoFilters.stage || undefined,
|
||||
};
|
||||
const res = await axios.get("/api/skills/neo/releases", { params });
|
||||
const payload = res?.data?.data || {};
|
||||
neoReleases.value = payload.items || [];
|
||||
neoReleases.value = normalizeNeoItemsPayload(res).map((item) => {
|
||||
if (!item || typeof item !== "object") {
|
||||
return item;
|
||||
}
|
||||
return {
|
||||
...item,
|
||||
is_active: item.is_active ?? item.active ?? false,
|
||||
};
|
||||
});
|
||||
};
|
||||
|
||||
const fetchNeoData = async () => {
|
||||
|
||||
@@ -385,6 +385,16 @@ async def test_neo_skills_routes(
|
||||
assert data["data"]["candidate_id"] == "cand-1"
|
||||
assert data["data"]["passed"] is True
|
||||
|
||||
response = await test_client.post(
|
||||
"/api/skills/neo/evaluate",
|
||||
json={"candidate_id": "cand-1", "passed": "false", "score": 0.0},
|
||||
headers=authenticated_header,
|
||||
)
|
||||
assert response.status_code == 200
|
||||
data = await response.get_json()
|
||||
assert data["status"] == "ok"
|
||||
assert data["data"]["passed"] is False
|
||||
|
||||
response = await test_client.post(
|
||||
"/api/skills/neo/promote",
|
||||
json={"candidate_id": "cand-1", "stage": "stable"},
|
||||
|
||||
Reference in New Issue
Block a user