f3a8a38acd
web-platform-ci / Standalone decision service (no cloud credentials) (push) Waiting to run
web-platform-ci / TypeScript, lint, unit, build (push) Waiting to run
web-platform-ci / Playwright E2E (push) Waiting to run
lekiwi-compatibility / cpu-compatibility (push) Waiting to run
web-platform-ci / Standalone decision service (no cloud credentials) (pull_request) Waiting to run
web-platform-ci / TypeScript, lint, unit, build (pull_request) Waiting to run
web-platform-ci / Playwright E2E (pull_request) Waiting to run
lekiwi-compatibility / cpu-compatibility (pull_request) Waiting to run
集成同源 BYOK 会话隔离、精简模型设置、官方订阅入口和 HTTPS 发布运维;保留本地训练/调参与控制能力。同步 npm 版本及 CHANGELOG,记录公网真实 API 验收仍待用户凭据。
67 lines
2.2 KiB
Python
67 lines
2.2 KiB
Python
"""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"),
|
|
)
|