mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
The native adapter's route was named deepseek, colliding with pi-ai's catalog provider of the same name, so the two DeepSeek paths could never be mounted side by side. The web settings page needs both configurable at once. Compositions, fixtures, goldens, scaffolding defaults, and docs all move together (pre-release, no shim); TUI/session-query-spill/ missing-credential goldens re-recorded through their keyless refresh modes because provider-name length shifts box padding and spill truncation points.
121 lines
3.9 KiB
Python
121 lines
3.9 KiB
Python
"""Keyless boot tests for the production exe and development node carrier.
|
|
|
|
Each carrier skips independently when absent. The dummy API key only satisfies
|
|
adapter loading; initialize and shutdown do not call a model.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
|
|
import pytest
|
|
|
|
from deepseek_harness import DeepSeekHarness, HarnessClient, HarnessConfig
|
|
from deepseek_harness.errors import TransportClosedError
|
|
from deepseek_harness_runtime import resolve_bundled_launch_args
|
|
|
|
_MODES = ("exe", "node")
|
|
|
|
# The config must include the JSON-RPC serving plugin.
|
|
_CORDIS_YML = """\
|
|
- id: jsonrpc
|
|
name: '@deepseek-ai/dsh-jsonrpc'
|
|
- id: agent-core
|
|
name: '@deepseek-ai/dsh-agent-spine-demo'
|
|
config:
|
|
workspaceContext: false
|
|
- id: sessions
|
|
name: '@deepseek-ai/dsh-session-persistence-jsonl'
|
|
config:
|
|
root: './sessions'
|
|
- id: session-checkpoints
|
|
name: '@deepseek-ai/dsh-session-checkpoint-policy'
|
|
- id: subprocess
|
|
name: '@deepseek-ai/dsh-subprocess-local'
|
|
- id: bash
|
|
name: '@deepseek-ai/dsh-bash-local'
|
|
config:
|
|
cwd: '.'
|
|
- id: todo
|
|
name: '@deepseek-ai/dsh-tool-todo'
|
|
"""
|
|
|
|
|
|
def _launch_args(mode: str) -> tuple[str, ...]:
|
|
try:
|
|
return resolve_bundled_launch_args(mode)
|
|
except FileNotFoundError as exc:
|
|
pytest.skip(f"bundled {mode}-mode runtime unavailable on this machine: {exc}")
|
|
|
|
|
|
def _client(tmp_path: Path, launch_args: tuple[str, ...]) -> HarnessClient:
|
|
return HarnessClient(
|
|
HarnessConfig(
|
|
launch_args_override=launch_args,
|
|
cwd=str(tmp_path),
|
|
env={
|
|
"DSH_CORDIS_CONFIG": "./cordis.yml",
|
|
"DSH_SESSION_ROOT": str(tmp_path / "sessions"),
|
|
"DSH_CWD": str(tmp_path),
|
|
# The lazily mounted adapter requires a key even without a model call.
|
|
"DEEPSEEK_API_KEY": "sk-dummy-for-boot",
|
|
"DEEPSEEK_BASE_URL": "http://127.0.0.1:9",
|
|
},
|
|
request_timeout_seconds=120,
|
|
)
|
|
)
|
|
|
|
|
|
@pytest.mark.parametrize("mode", _MODES)
|
|
def test_bundled_runtime_boots_a_cordis_config(tmp_path: Path, mode: str) -> None:
|
|
launch_args = _launch_args(mode)
|
|
(tmp_path / "cordis.yml").write_text(_CORDIS_YML)
|
|
|
|
with _client(tmp_path, launch_args) as client:
|
|
init = client.initialize(provider="deepseek-official", cwd=str(tmp_path), model="deepseek-v4-pro")
|
|
|
|
assert init.serverInfo is not None
|
|
assert init.serverInfo.name == "deepseek-harness-sdk-runtime"
|
|
|
|
|
|
@pytest.mark.parametrize("mode", _MODES)
|
|
def test_bundled_runtime_surfaces_unbundled_plugin_failure(tmp_path: Path, mode: str) -> None:
|
|
launch_args = _launch_args(mode)
|
|
(tmp_path / "cordis.yml").write_text(
|
|
"- id: missing\n name: '@deepseek-ai/dsh-does-not-exist'\n"
|
|
)
|
|
|
|
client = _client(tmp_path, launch_args)
|
|
client.start()
|
|
try:
|
|
with pytest.raises((TransportClosedError, TimeoutError)) as excinfo:
|
|
client.initialize(provider="deepseek-official", cwd=str(tmp_path), model="deepseek-v4-pro")
|
|
finally:
|
|
client.close()
|
|
|
|
assert "@deepseek-ai/dsh-does-not-exist" in str(excinfo.value)
|
|
|
|
|
|
@pytest.mark.parametrize("mode", _MODES)
|
|
@pytest.mark.parametrize("ambient_config", [None, ""], ids=["unset", "empty-counts-as-absent"])
|
|
def test_zero_config_run_injects_bundled_default_cordis_config(
|
|
tmp_path: Path, mode: str, ambient_config: str | None, monkeypatch: pytest.MonkeyPatch
|
|
) -> None:
|
|
_launch_args(mode) # skip early when this carrier is unavailable
|
|
monkeypatch.setenv("DSH_RUNTIME_MODE", mode)
|
|
if ambient_config is None:
|
|
monkeypatch.delenv("DSH_CORDIS_CONFIG", raising=False)
|
|
else:
|
|
monkeypatch.setenv("DSH_CORDIS_CONFIG", ambient_config)
|
|
|
|
harness = DeepSeekHarness(
|
|
model="deepseek-v4-pro",
|
|
cwd=str(tmp_path),
|
|
session_root=str(tmp_path / "sessions"),
|
|
api_key="sk-dummy-for-boot",
|
|
base_url="http://127.0.0.1:9",
|
|
request_timeout_seconds=120,
|
|
)
|
|
with harness:
|
|
pass
|