feat: release v1.0.1 CADWorld 网站与 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) (pull_request) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (pull_request) Has been cancelled
web-platform-ci / Playwright E2E (pull_request) Has been cancelled
lekiwi-compatibility / cpu-compatibility (pull_request) 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
web-platform-ci / Standalone decision service (no cloud credentials) (pull_request) Has been cancelled
web-platform-ci / TypeScript, lint, unit, build (pull_request) Has been cancelled
web-platform-ci / Playwright E2E (pull_request) Has been cancelled
lekiwi-compatibility / cpu-compatibility (pull_request) Has been cancelled
集成同源 BYOK 会话隔离、精简模型设置、官方订阅入口和 HTTPS 发布运维;保留本地训练/调参与控制能力。同步 npm 版本及 CHANGELOG,记录公网真实 API 验收仍待用户凭据。
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
"""TypeSafe System One / OpenRouter Decisions protocol, not a chat endpoint.
|
||||
|
||||
Protocol shape informed by MIT-licensed jev-libero / embodied-jev; see THIRD_PARTY_NOTICES.
|
||||
"""
|
||||
|
||||
import json
|
||||
import math
|
||||
|
||||
from ..protocol import SCHEMA, VERSION, DecisionError, validate_jev
|
||||
from .http import post, usage
|
||||
|
||||
|
||||
def question(options, instruction):
|
||||
return {
|
||||
"type": "choice",
|
||||
"instructions": instruction,
|
||||
"criteria": {option: option for option in options},
|
||||
}
|
||||
|
||||
|
||||
def answer(result, name, options):
|
||||
answers = result.get("answers")
|
||||
item = answers.get(name) if isinstance(answers, dict) else None
|
||||
if not isinstance(item, dict) or item.get("choice") not in options:
|
||||
raise DecisionError("jev_invalid_choice", 502)
|
||||
probabilities = item.get("probabilities", {})
|
||||
if (
|
||||
not isinstance(probabilities, dict)
|
||||
or probabilities.keys() - set(options)
|
||||
or any(
|
||||
type(p) not in (int, float) or not math.isfinite(p) or not 0 <= p <= 1
|
||||
for p in probabilities.values()
|
||||
)
|
||||
):
|
||||
raise DecisionError("jev_invalid_probabilities", 502)
|
||||
# Keep official choice even when probabilities do not rank it highest.
|
||||
return item["choice"]
|
||||
|
||||
|
||||
async def decide(session, conn, request):
|
||||
props = SCHEMA["$defs"]["JevDecision"]["properties"]
|
||||
options = {name: props[name]["enum"] for name in ("grasp", "diagnosis", "recovery")}
|
||||
options["choice"] = request["candidates"]
|
||||
prompts = {
|
||||
"choice": (
|
||||
"Choose an offered next skill if safe. Stop for hard safety faults. "
|
||||
"Only the local controller can determine success or permit actuation."
|
||||
),
|
||||
"grasp": (
|
||||
"secure requires two finger forces >=0.2 N, verified lift and stable grasp evidence. "
|
||||
"empty means no held object. slipping means a previously secure grasp is being lost. "
|
||||
"Use uncertain if evidence is insufficient. An open gripper is not a secure grasp."
|
||||
),
|
||||
"diagnosis": (
|
||||
"Report none when failure=none and there are no safety flags. "
|
||||
"An empty gripper before closing or after release is expected, not a fault. "
|
||||
"Otherwise diagnose empty, slipping, misaligned, unreachable, stalled or uncertain."
|
||||
),
|
||||
"recovery": (
|
||||
"Continue with a safe next skill if failure=none; retry only recoverable alignment "
|
||||
"or empty grasp failures before transport; replan when retries are insufficient; "
|
||||
"stop for hard safety faults or unsafe uncertainty."
|
||||
),
|
||||
}
|
||||
result = await post(
|
||||
session,
|
||||
conn,
|
||||
"",
|
||||
{
|
||||
"model": conn.model,
|
||||
**(
|
||||
{"provider": {"allow_fallbacks": False}}
|
||||
if conn.protocol == "openrouter-decisions"
|
||||
else {}
|
||||
),
|
||||
"state": json.dumps(
|
||||
{"observation": request["observation"], "failure": request.get("failure", "none")},
|
||||
ensure_ascii=False,
|
||||
),
|
||||
"questions": {
|
||||
name: question(values, prompts[name]) for name, values in options.items()
|
||||
},
|
||||
},
|
||||
)
|
||||
value = {
|
||||
"version": VERSION,
|
||||
**{name: answer(result, name, values) for name, values in options.items()},
|
||||
}
|
||||
return validate_jev(value, request["candidates"]), usage(result)
|
||||
Reference in New Issue
Block a user