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:
@@ -6,7 +6,7 @@ Protocol shape informed by MIT-licensed jev-libero / embodied-jev; see THIRD_PAR
|
||||
import json
|
||||
import math
|
||||
|
||||
from ..protocol import SCHEMA, VERSION, DecisionError, validate_jev
|
||||
from ..protocol import LANGUAGE_VERSION, DecisionError, schema_for, validate_jev
|
||||
from .http import post, usage
|
||||
|
||||
|
||||
@@ -38,7 +38,8 @@ def answer(result, name, options):
|
||||
|
||||
|
||||
async def decide(session, conn, request):
|
||||
props = SCHEMA["$defs"]["JevDecision"]["properties"]
|
||||
version = request["observation"]["version"]
|
||||
props = schema_for(version)["$defs"]["JevDecision"]["properties"]
|
||||
options = {name: props[name]["enum"] for name in ("grasp", "diagnosis", "recovery")}
|
||||
options["choice"] = request["candidates"]
|
||||
prompts = {
|
||||
@@ -62,6 +63,26 @@ async def decide(session, conn, request):
|
||||
"stop for hard safety faults or unsafe uncertainty."
|
||||
),
|
||||
}
|
||||
if version == LANGUAGE_VERSION:
|
||||
options.update({name: props[name]["enum"] for name in ("noul", "score", "reason")})
|
||||
prompts.update(
|
||||
{
|
||||
"noul": (
|
||||
"Veto unsafe actions: allow only with fresh sufficient evidence and no hard "
|
||||
"safety fault; deny on danger, uncertain on missing evidence. "
|
||||
"This is not physical authorization."
|
||||
),
|
||||
"score": (
|
||||
"Grade progress at this skill boundary: poor, partial, good, excellent, "
|
||||
"or unavailable. This is a discrete quality grade, NOT probability or "
|
||||
"final success. Empty fingers before grasp/after release are expected."
|
||||
),
|
||||
"reason": (
|
||||
"Select the main reason for safety/quality: none, unsafe, "
|
||||
"insufficient_evidence, tracking_error, verified_progress."
|
||||
),
|
||||
}
|
||||
)
|
||||
result = await post(
|
||||
session,
|
||||
conn,
|
||||
@@ -83,7 +104,7 @@ async def decide(session, conn, request):
|
||||
},
|
||||
)
|
||||
value = {
|
||||
"version": VERSION,
|
||||
"version": version,
|
||||
**{name: answer(result, name, values) for name, values in options.items()},
|
||||
}
|
||||
return validate_jev(value, request["candidates"]), usage(result)
|
||||
return validate_jev(value, request["candidates"], version), usage(result)
|
||||
|
||||
@@ -2,7 +2,15 @@
|
||||
|
||||
import json
|
||||
|
||||
from ..protocol import PRECONDITIONS, DecisionError, loads, output_schema, validate_plan
|
||||
from ..protocol import (
|
||||
LANGUAGE_PRECONDITIONS,
|
||||
LANGUAGE_VERSION,
|
||||
PRECONDITIONS,
|
||||
DecisionError,
|
||||
loads,
|
||||
output_schema,
|
||||
validate_plan,
|
||||
)
|
||||
from .http import post, usage
|
||||
|
||||
INSTRUCTIONS = (
|
||||
@@ -20,14 +28,16 @@ def context(request):
|
||||
"instruction": request["instruction"],
|
||||
"observation": request["observation"],
|
||||
"remaining": request["remaining"],
|
||||
"preconditions": PRECONDITIONS,
|
||||
"preconditions": LANGUAGE_PRECONDITIONS
|
||||
if request["observation"]["version"] == LANGUAGE_VERSION
|
||||
else PRECONDITIONS,
|
||||
},
|
||||
ensure_ascii=False,
|
||||
allow_nan=False,
|
||||
)
|
||||
|
||||
|
||||
async def structured(session, conn, text, schema):
|
||||
async def structured(session, conn, text, schema, *, instructions=INSTRUCTIONS, max_tokens=4096):
|
||||
fmt = {"name": "lekiwi_plan", "schema": schema, "strict": True}
|
||||
if conn.protocol == "responses":
|
||||
result = await post(
|
||||
@@ -36,12 +46,12 @@ async def structured(session, conn, text, schema):
|
||||
"/responses",
|
||||
{
|
||||
"model": conn.model,
|
||||
"instructions": INSTRUCTIONS,
|
||||
"instructions": instructions,
|
||||
"input": text,
|
||||
"text": {"format": {"type": "json_schema", **fmt}},
|
||||
"tools": [],
|
||||
"tool_choice": "none",
|
||||
"max_output_tokens": 4096,
|
||||
"max_output_tokens": max_tokens,
|
||||
"store": False,
|
||||
},
|
||||
)
|
||||
@@ -72,11 +82,11 @@ async def structured(session, conn, text, schema):
|
||||
else {}
|
||||
),
|
||||
"messages": [
|
||||
{"role": "system", "content": INSTRUCTIONS},
|
||||
{"role": "system", "content": instructions},
|
||||
{"role": "user", "content": text},
|
||||
],
|
||||
"response_format": {"type": "json_schema", "json_schema": fmt},
|
||||
"max_tokens": 4096,
|
||||
"max_tokens": max_tokens,
|
||||
"stream": False,
|
||||
},
|
||||
)
|
||||
@@ -103,5 +113,8 @@ async def structured(session, conn, text, schema):
|
||||
|
||||
|
||||
async def plan(session, conn, request):
|
||||
value, metrics = await structured(session, conn, context(request), output_schema("Plan"))
|
||||
return validate_plan(value, request["remaining"]), metrics
|
||||
version = request["observation"]["version"]
|
||||
value, metrics = await structured(
|
||||
session, conn, context(request), output_schema("Plan", version)
|
||||
)
|
||||
return validate_plan(value, request["remaining"], version), metrics
|
||||
|
||||
Reference in New Issue
Block a user