mirror of
https://github.com/bytedance/deer-flow.git
synced 2026-11-15 07:41:20 +00:00
fix(doctor): reject placeholder model credentials (#8184)
* fix(doctor): reject placeholder model credentials * fix(doctor): reject whitespace-only model keys * docs: drop changelog edit from doctor PR
This commit is contained in:
parent
ba4e60dec4
commit
5f6d7c06e0
@ -76,6 +76,10 @@ make install
|
||||
make dev
|
||||
```
|
||||
|
||||
Run `make doctor` after setting model credentials. It reports obvious placeholder
|
||||
API keys as incomplete configuration; replace them with real keys before testing
|
||||
model calls.
|
||||
|
||||
Open http://localhost:2026.
|
||||
|
||||
- All configuration options, providers and manual setup: [Configuration](docs/guide/configuration.md)
|
||||
|
||||
@ -357,6 +357,24 @@ class TestCheckLLMApiKey:
|
||||
assert all(r.fix is not None for r in failed)
|
||||
assert any("OPENAI_API_KEY" in (r.fix or "") for r in failed)
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"placeholder",
|
||||
["your-openai-api-key", "replace-with-your-totokens-api-key", " "],
|
||||
)
|
||||
def test_placeholder_key_is_not_reported_as_ready(self, tmp_path, monkeypatch, placeholder):
|
||||
cfg = tmp_path / "config.yaml"
|
||||
cfg.write_text(
|
||||
"models:\n - name: relay\n use: langchain_openai:ChatOpenAI\n model: gpt-6-luna\n api_key: $RELAY_API_KEY\n",
|
||||
encoding="utf-8",
|
||||
)
|
||||
monkeypatch.setenv("RELAY_API_KEY", placeholder)
|
||||
|
||||
results = doctor.check_llm_api_key(cfg)
|
||||
|
||||
assert len(results) == 1
|
||||
assert results[0].status == "fail"
|
||||
assert "RELAY_API_KEY" in (results[0].fix or "")
|
||||
|
||||
def test_missing_config_returns_empty(self, tmp_path):
|
||||
results = doctor.check_llm_api_key(tmp_path / "config.yaml")
|
||||
assert results == []
|
||||
|
||||
@ -57,6 +57,8 @@ Cases marked for real Compose run only when a `docker` CLI is installed.
|
||||
files mark the env files optional so a fresh checkout still starts and stops.
|
||||
- **Support bundles export no secrets** and show an external runtime home as
|
||||
`{DEER_FLOW_HOME}`.
|
||||
- **Doctor does not echo model credentials.** Obvious sample key values fail the
|
||||
model readiness check even when the environment variable is nonempty.
|
||||
|
||||
## Start, stop, clean
|
||||
|
||||
|
||||
@ -497,6 +497,12 @@ def _memory_backend_config_fix(detail: str) -> str | None:
|
||||
return None
|
||||
|
||||
|
||||
def _looks_like_key_placeholder(value: str) -> bool:
|
||||
"""Recognize sample key values without logging or transmitting them."""
|
||||
normalized = value.strip().lower()
|
||||
return normalized.startswith(("your-", "replace-with-", "sk-your-", "sk-replace-with-"))
|
||||
|
||||
|
||||
def check_llm_api_key(config_path: Path) -> list[CheckResult]:
|
||||
"""Check that each model's env var is set in the environment."""
|
||||
if not config_path.exists():
|
||||
@ -532,14 +538,15 @@ def check_llm_api_key(config_path: Path) -> list[CheckResult]:
|
||||
model_name = model.get("name", "default")
|
||||
for var in env_refs:
|
||||
label = f"{var} set (model: {model_name})"
|
||||
if os.environ.get(var):
|
||||
value = os.environ.get(var)
|
||||
if value and value.strip() and not _looks_like_key_placeholder(value):
|
||||
results.append(CheckResult(label, "ok"))
|
||||
else:
|
||||
results.append(
|
||||
CheckResult(
|
||||
label,
|
||||
"fail",
|
||||
fix=f"Add {var}=<your-key> to your .env file",
|
||||
fix=f"Set {var} to a real key in your .env file",
|
||||
)
|
||||
)
|
||||
except Exception as exc:
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user