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

集成服务器托管模型、自然语言移动与有界抓放、内置 LeKiwi URL 导入和双摄像头;同步部署契约与指定域名 iframe 白名单,保留原有物理安全、会话及调用预算防护。

更新 npm 包及锁文件版本、CHANGELOG 与发布文档。提交前 typecheck、120 项定向前端测试和 44 项后端测试通过(3 项可选跳过);真实 v2 云模型抓放仍待单独验收,不包含运行密钥或构建产物。
This commit is contained in:
2026-09-24 15:29:49 +08:00
parent f3a8a38acd
commit 0d986f60bd
93 changed files with 5166 additions and 1094 deletions
+18 -5
View File
@@ -12,12 +12,14 @@ from aiohttp import web
from .connections import Connections
from .protocol import (
SCHEMA,
LANGUAGE_VERSION,
VERSION,
DecisionError,
candidates,
fields,
loads,
remaining_skills,
schema_for,
validate,
)
from .providers import jev, openai
@@ -101,21 +103,25 @@ class Service:
[] if role == "llm" else ["failure"],
)
data = self.connections.redact(data)
obs = validate("Observation", data["observation"])
raw = data["observation"]
version = raw.get("version") if isinstance(raw, dict) else VERSION
obs = validate("Observation", raw, version)
if role == "llm":
instruction = data["instruction"]
if not isinstance(instruction, str) or not 1 <= len(instruction) <= 2000:
raise DecisionError("invalid_instruction")
remaining_skills(data["remaining"])
remaining_skills(data["remaining"], version)
else:
candidates(data["candidates"])
codes = SCHEMA["$defs"]["SkillResult"]["properties"]["code"]["enum"]
candidates(data["candidates"], version)
codes = schema_for(version)["$defs"]["SkillResult"]["properties"]["code"]["enum"]
if data.get("failure", "none") not in codes:
raise DecisionError("invalid_failure_code")
conn = self.connections.get(role)
async def invoke():
if conn.protocol == "codex":
if version == LANGUAGE_VERSION:
raise DecisionError("language_requires_configured_api", 409)
return await self.codex.plan(data, conn.model)
if role == "llm":
return await openai.plan(self.session, conn, data)
@@ -363,6 +369,13 @@ def create_app(directory=None, token=None, origins=None, port=8768):
app.router.add_get(PREFIX + "/status", status)
app.router.add_put(PREFIX + "/connections", configure)
app.router.add_post(PREFIX + "/test", test_connection)
async def command(request):
from .commands import command as run_command
return web.json_response(await run_command(service_for(request), await body(request)))
app.router.add_post(PREFIX + "/command", command)
app.router.add_post(PREFIX + "/plan", plan)
app.router.add_post(PREFIX + "/decide", decide)
app.router.add_post(PREFIX + "/cancel", cancel)