feat: release v1.0.2 LeKiwi 语言控制与网站嵌入
web-platform-ci / Standalone decision service (no cloud credentials) (push) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (push) Has been cancelled
web-platform-ci / Playwright E2E (push) Has been cancelled
lekiwi-compatibility / cpu-compatibility (push) Has been cancelled
web-platform-ci / Standalone decision service (no cloud credentials) (push) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (push) Has been cancelled
web-platform-ci / Playwright E2E (push) Has been cancelled
lekiwi-compatibility / cpu-compatibility (push) Has been cancelled
集成服务器托管模型、自然语言移动与有界抓放、内置 LeKiwi URL 导入和双摄像头;同步部署契约与指定域名 iframe 白名单,保留原有物理安全、会话及调用预算防护。 更新 npm 包及锁文件版本、CHANGELOG 与发布文档。提交前 typecheck、120 项定向前端测试和 44 项后端测试通过(3 项可选跳过);真实 v2 云模型抓放仍待单独验收,不包含运行密钥或构建产物。
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
import unittest
|
||||
|
||||
from decision_server.commands import checked as motion_checked
|
||||
from decision_server.language_tasks import checked, resolve_target
|
||||
from decision_server.protocol import (
|
||||
LANGUAGE_PRECONDITIONS,
|
||||
LANGUAGE_SKILLS,
|
||||
VERSION,
|
||||
DecisionError,
|
||||
validate_jev,
|
||||
validate_plan,
|
||||
)
|
||||
from decision_server.protocol import (
|
||||
LANGUAGE_VERSION as V,
|
||||
)
|
||||
|
||||
|
||||
def command(**changes):
|
||||
return (
|
||||
dict(
|
||||
version=V,
|
||||
action="pick_place",
|
||||
value=0,
|
||||
summary="搬运方块",
|
||||
objectId="block",
|
||||
targetId="B",
|
||||
position=[],
|
||||
supportId="table",
|
||||
)
|
||||
| changes
|
||||
)
|
||||
|
||||
|
||||
class LanguageTests(unittest.TestCase):
|
||||
def test_named_and_coordinates(self):
|
||||
self.assertEqual(
|
||||
checked(command(), "抓起方块并搬到B区放下", motion_checked)["targetId"], "B"
|
||||
)
|
||||
for text, values in [
|
||||
("搬到(25,50)厘米", [0.25, 0.5]),
|
||||
("搬到 X=0.25 Y=0.50 Z=0.128", [0.25, 0.5, 0.128]),
|
||||
]:
|
||||
result = checked(command(targetId="coordinates", position=values), text, motion_checked)
|
||||
self.assertEqual(
|
||||
resolve_target(result["targetId"], result["position"]),
|
||||
([0.25, 0.5, 0.128], "table"),
|
||||
)
|
||||
|
||||
def test_bad_targets_and_mismatch(self):
|
||||
for pos in ([0.8, 0.5], [0.25, 0.5, 0.5], [float("nan"), 0.5]):
|
||||
with self.assertRaises(DecisionError):
|
||||
resolve_target("coordinates", pos)
|
||||
with self.assertRaisesRegex(DecisionError, "command_mismatch"):
|
||||
checked(
|
||||
command(targetId="coordinates", position=[0.25, 0.6]),
|
||||
"搬到(0.25,0.50)",
|
||||
motion_checked,
|
||||
)
|
||||
for text in [
|
||||
"不要搬到 B 区",
|
||||
"搬到指定位置",
|
||||
"前进0.5米然后搬到 B 区",
|
||||
"搬到 A 区或者 B 区",
|
||||
]:
|
||||
self.assertEqual(checked(command(), text, motion_checked)["action"], "clarify")
|
||||
|
||||
def test_multiple_or_contradictory_coordinates_rejected(self):
|
||||
for instruction in ["搬到(0.25,0.5)然后到(0.25,0.6)", "搬到 B 区 (0.25,0.5)"]:
|
||||
with self.assertRaises(DecisionError):
|
||||
checked(command(), instruction, motion_checked)
|
||||
|
||||
def test_v2_does_not_weaken_v1(self):
|
||||
plan = dict(
|
||||
version=V,
|
||||
objectId="block",
|
||||
goalId="placement",
|
||||
summary="计划",
|
||||
steps=[
|
||||
dict(skill=s, precondition=LANGUAGE_PRECONDITIONS[s], onFailure="stop")
|
||||
for s in LANGUAGE_SKILLS
|
||||
],
|
||||
)
|
||||
validate_plan(plan, LANGUAGE_SKILLS, V)
|
||||
with self.assertRaises(DecisionError):
|
||||
validate_plan(plan, LANGUAGE_SKILLS, VERSION)
|
||||
d = dict(
|
||||
version=V,
|
||||
choice="stow",
|
||||
grasp="empty",
|
||||
diagnosis="none",
|
||||
recovery="continue",
|
||||
noul="allow",
|
||||
score="good",
|
||||
reason="verified_progress",
|
||||
)
|
||||
validate_jev(d, ["stow", "stop"], V)
|
||||
for field, value in [("noul", "yes"), ("score", 100), ("choice", "carry")]:
|
||||
with self.assertRaises(DecisionError):
|
||||
validate_jev(d | {field: value}, ["stow", "stop"], V)
|
||||
Reference in New Issue
Block a user