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,66 @@
|
||||
"""Explicit per-role opt-in credential loaders; never source/eval an env file."""
|
||||
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
from .connections import Connection
|
||||
from .protocol import DecisionError
|
||||
|
||||
OPENROUTER_ENDPOINT = "https://openrouter.ai/api/alpha/decisions"
|
||||
OPENROUTER_JEV = "typesafe/jev-1.13"
|
||||
|
||||
|
||||
def _read_key(env_file: Path, variable: str):
|
||||
key = None
|
||||
try:
|
||||
if env_file.stat().st_size > 65536:
|
||||
raise DecisionError("credential_file_too_large")
|
||||
with env_file.open(encoding="utf-8") as stream:
|
||||
for line in stream:
|
||||
match = re.match(
|
||||
rf"^\s*(?:export\s+)?{re.escape(variable)}\s*=\s*(.*?)\s*$",
|
||||
line,
|
||||
flags=re.IGNORECASE,
|
||||
)
|
||||
if not match:
|
||||
continue
|
||||
if key is not None:
|
||||
raise DecisionError("duplicate_credential_variable")
|
||||
value = match.group(1)
|
||||
if value[:1] in ('"', "'"):
|
||||
quote = value[0]
|
||||
end = value.find(quote, 1)
|
||||
if end < 0 or (
|
||||
value[end + 1 :].strip() and not value[end + 1 :].lstrip().startswith("#")
|
||||
):
|
||||
raise DecisionError("invalid_credential_value")
|
||||
value = value[1:end]
|
||||
else:
|
||||
value = value.split(" #", 1)[0].strip()
|
||||
if not re.fullmatch(r"[A-Za-z0-9_-]{16,4096}", value):
|
||||
raise DecisionError("invalid_credential_value")
|
||||
key = value
|
||||
except (OSError, UnicodeError):
|
||||
raise DecisionError("credential_file_unreadable") from None
|
||||
if not key:
|
||||
raise DecisionError("credential_variable_missing")
|
||||
return key
|
||||
|
||||
|
||||
def openrouter_jev(env_file: Path):
|
||||
# No URL/model can be supplied by file content. This opt-in grants only Jev calls.
|
||||
return Connection(
|
||||
"openrouter-decisions",
|
||||
OPENROUTER_ENDPOINT,
|
||||
OPENROUTER_JEV,
|
||||
_read_key(env_file, "OPENROUTER_API_KEY"),
|
||||
)
|
||||
|
||||
|
||||
def deepseek_llm(env_file: Path):
|
||||
return Connection(
|
||||
"responses",
|
||||
"https://api.deepseek.com",
|
||||
"deepseek-flash",
|
||||
_read_key(env_file, "Deepseek_API_KEY"),
|
||||
)
|
||||
Reference in New Issue
Block a user