- conftest.py: secrets 路径改为多位置查找 (QE_SECRETS_PATH env → ~/.openclaw/config/ → workspace-document-analyzer/config/) - conftest.py: IR 默认路径改为 output/final/ir_final.json (匹配 config.IR_FINAL_JSON) - conftest.py: parsed 默认路径改为项目相对路径 - agent_poller.py: 添加 --labels 过滤 (向后兼容) - 新增 agents/QE_AGENT.md + scripts/start_qe_agent.sh
This commit is contained in:
@@ -4,13 +4,16 @@ Usage::
|
||||
|
||||
pytest tests/acceptance/ -v --run-acceptance [--acceptance-runs=3]
|
||||
|
||||
LLM configuration is read from ``~/.openclaw/config/secrets.yaml``:
|
||||
LLM configuration is read from secrets.yaml (searched in order):
|
||||
1. QE_SECRETS_PATH env var
|
||||
2. ~/.openclaw/config/secrets.yaml
|
||||
3. ~/.openclaw/workspace-document-analyzer/config/secrets.yaml
|
||||
|
||||
deepseek.apiKey / deepseek.baseUrl → text model (deepseek-v4-flash)
|
||||
dashscope.apiKey / dashscope.baseUrl → vision model (qwen3-vl-plus)
|
||||
|
||||
Environment variables:
|
||||
TEST_IR_PATH — path to IR JSON to validate (default: ir_final.json sample)
|
||||
TEST_PARSED_PATH — path to _parsed.json or _updated.json for coverage analysis
|
||||
TEST_IR_PATH — path to IR JSON (default: output/final/ir_final.json)
|
||||
TEST_PARSED_PATH — path to _parsed.json or _updated.json (default: output/)
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -30,7 +33,14 @@ import yaml
|
||||
_PROJECT_ROOT = Path(__file__).resolve().parent.parent.parent
|
||||
sys.path.insert(0, str(_PROJECT_ROOT))
|
||||
|
||||
_SECRETS_PATH = Path.home() / ".openclaw" / "config" / "secrets.yaml"
|
||||
# Try multiple known secrets locations (no single hardcoded path)
|
||||
_SECRETS_CANDIDATES = [
|
||||
Path.home() / ".openclaw" / "config" / "secrets.yaml",
|
||||
Path.home() / ".openclaw" / "workspace-document-analyzer" / "config" / "secrets.yaml",
|
||||
]
|
||||
|
||||
# Allow override via environment variable
|
||||
_SECRETS_PATH = Path(os.environ.get("QE_SECRETS_PATH", ""))
|
||||
|
||||
|
||||
def _skill_path(skill_name: str) -> str:
|
||||
@@ -38,10 +48,16 @@ def _skill_path(skill_name: str) -> str:
|
||||
|
||||
|
||||
def _load_secrets() -> dict:
|
||||
"""Load LLM configuration from secrets.yaml."""
|
||||
if _SECRETS_PATH.exists():
|
||||
with open(_SECRETS_PATH, "r", encoding="utf-8") as f:
|
||||
return yaml.safe_load(f) or {}
|
||||
"""Load LLM configuration from secrets.yaml.
|
||||
|
||||
Tries paths in order: QE_SECRETS_PATH env var → ~/.openclaw/config/ →
|
||||
~/.openclaw/workspace-document-analyzer/config/.
|
||||
"""
|
||||
paths = [_SECRETS_PATH] + _SECRETS_CANDIDATES if _SECRETS_PATH.parts else _SECRETS_CANDIDATES
|
||||
for p in paths:
|
||||
if p.exists():
|
||||
with open(p, "r", encoding="utf-8") as f:
|
||||
return yaml.safe_load(f) or {}
|
||||
return {}
|
||||
|
||||
|
||||
@@ -178,9 +194,11 @@ class _AcceptanceLLM:
|
||||
ds_base = ds.get("baseUrl", "https://api.deepseek.com/v1")
|
||||
|
||||
if not ds_key:
|
||||
tried = [str(p) for p in ([_SECRETS_PATH] + _SECRETS_CANDIDATES if _SECRETS_PATH.parts else _SECRETS_CANDIDATES)]
|
||||
raise RuntimeError(
|
||||
"No DeepSeek API key found. Set deepseek.apiKey in "
|
||||
f"{_SECRETS_PATH} or DEEPSEEK_API_KEY env var."
|
||||
"No DeepSeek API key found. Tried:\n "
|
||||
+ "\n ".join(tried)
|
||||
+ "\nSet deepseek.apiKey in secrets.yaml or DEEPSEEK_API_KEY env var."
|
||||
)
|
||||
|
||||
self._api_key = ds_key
|
||||
|
||||
Reference in New Issue
Block a user