mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-08-29 04:26:38 +00:00
feat(subagent): carry model routing through DSH SDK
This commit is contained in:
@@ -2,5 +2,5 @@
|
||||
# side as of the last confirmed-consistent state. Both languages carry equal authority;
|
||||
# after editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write python/sdk/README.md
|
||||
README.md: 1b03fe5553f25da3bc62f8a7eec2a274b0afb66a
|
||||
README.zh.md: c0bfa8bdd9e2ecbaad0a019a274b94516e219ac6
|
||||
README.md: faef82996077bbb7bf3fc3aeaf0e99af9219d36d
|
||||
README.zh.md: b9e028c596ad0ece5acd4fe31fbd697c6f50c20a
|
||||
|
||||
@@ -20,13 +20,17 @@ from deepseek_harness import DeepSeekHarness
|
||||
with DeepSeekHarness(
|
||||
dsh_home="/absolute/path/to/isolated-dsh-home",
|
||||
cwd="/absolute/path/to/workspace",
|
||||
provider="deepseek-official",
|
||||
model="deepseek-v4-flash",
|
||||
reasoning_effort="max",
|
||||
max_tokens=49_152,
|
||||
) as harness:
|
||||
result = harness.run("Say hi.", session_id="example-001")
|
||||
|
||||
print(result.final_response)
|
||||
```
|
||||
|
||||
`DeepSeekHarness` starts lazily and reuses its runtime until `close()` or context-manager exit. The initial profile handshake has an independent 30-second default bound through `initialize_timeout_seconds`; ordinary turns remain unbounded unless `request_timeout_seconds` is set. A timeout names the selected profile and includes retained runtime diagnostics. `cwd` is the agent workspace; `runtime_cwd` independently selects the subprocess working directory. Both become absolute before launch. `provider`, `model`, and optional positive `max_tokens` are sent during JSON-RPC initialization. `base_url` and `api_key` explicitly override `DEEPSEEK_BASE_URL` and `DEEPSEEK_API_KEY` in the child environment.
|
||||
`DeepSeekHarness` starts lazily and reuses its runtime until `close()` or context-manager exit. The initial profile handshake has an independent 30-second default bound through `initialize_timeout_seconds`; ordinary turns remain unbounded unless `request_timeout_seconds` is set. A timeout names the selected profile and includes retained runtime diagnostics. `cwd` is the agent workspace; `runtime_cwd` independently selects the subprocess working directory. Both become absolute before launch. `provider`, `model`, optional `reasoning_effort`, and optional positive `max_tokens` are sent during JSON-RPC initialization. `base_url` and `api_key` explicitly override `DEEPSEEK_BASE_URL` and `DEEPSEEK_API_KEY` in the child environment.
|
||||
|
||||
## Customize plugins
|
||||
|
||||
@@ -53,6 +57,8 @@ with DeepSeekHarness(
|
||||
|
||||
`profile` may select another existing profile, but that composition must retain `@deepseek-ai/dsh-sdk-app` or another `@deepseek-ai/dsh-sdk-jsonrpc-server` row. Misconfiguration fails during CLI boot or SDK initialization; there is no complete-config fallback. `dsh_bin` may select another `dsh` executable while preserving the same profile grammar. Arbitrary argv replacement remains an internal fake-runtime test adapter, not public API.
|
||||
|
||||
`provider` selects a provider route registered by the chosen Cordis composition; `model` is the model id resolved by that adapter. `reasoning_effort` is an optional non-empty adapter-owned identifier for that exact route; omission preserves the model's own default. `max_tokens` is an optional positive per-request output-token cap for the root agent and its in-process descendants; omission leaves the provider default in control. Initialization rejects a missing adapter, unavailable model, or unsupported effort before a prompt runs. Compaction summaries keep the separate limit configured by their compaction plugin. The bundled default composition registers `deepseek-official`. A custom composition can mount `llm-pi-ai`, configure provider-specific credentials/endpoints there, and select any provider/model present in pi-ai's installed catalog.
|
||||
|
||||
The shipped `sdk-minimal` profile is a standalone explicit tree rather than an overlay on `dsh-base`. Select it with `profile="sdk-minimal"`; the ordinary `model` argument is the sole runtime model selection, including for model ids outside the adapter's advisory catalog. It provides persistent Bash, the string-replace editor, local execution, and JSONL sessions; settings, managed credentials, telemetry, Web tools, and the full default tool roster remain available through the separate full `sdk` and `web` profiles.
|
||||
|
||||
## Results and notifications
|
||||
|
||||
@@ -20,13 +20,17 @@ from deepseek_harness import DeepSeekHarness
|
||||
with DeepSeekHarness(
|
||||
dsh_home="/absolute/path/to/isolated-dsh-home",
|
||||
cwd="/absolute/path/to/workspace",
|
||||
provider="deepseek-official",
|
||||
model="deepseek-v4-flash",
|
||||
reasoning_effort="max",
|
||||
max_tokens=49_152,
|
||||
) as harness:
|
||||
result = harness.run("Say hi.", session_id="example-001")
|
||||
|
||||
print(result.final_response)
|
||||
```
|
||||
|
||||
`DeepSeekHarness` 延迟启动运行时,并在调用 `close()` 或退出上下文管理器前复用该进程。首次 profile 握手通过 `initialize_timeout_seconds` 使用独立的 30 秒默认上限;普通轮次在未设置 `request_timeout_seconds` 时仍不设上限。超时诊断会指明所选 profile,并包含保留的运行时诊断。`cwd` 是 agent workspace;`runtime_cwd` 独立选择子进程工作目录。两者都会在启动前转成绝对路径。`provider`、`model` 和可选的正整数 `max_tokens` 通过 JSON-RPC 初始化发送。`base_url` 与 `api_key` 会显式覆盖子进程环境中的 `DEEPSEEK_BASE_URL` 与 `DEEPSEEK_API_KEY`。
|
||||
`DeepSeekHarness` 延迟启动运行时,并在调用 `close()` 或退出上下文管理器前复用该进程。首次 profile 握手通过 `initialize_timeout_seconds` 使用独立的 30 秒默认上限;普通轮次在未设置 `request_timeout_seconds` 时仍不设上限。超时诊断会指明所选 profile,并包含保留的运行时诊断。`cwd` 是 agent workspace;`runtime_cwd` 独立选择子进程工作目录。两者都会在启动前转成绝对路径。`provider`、`model`、可选的 `reasoning_effort` 和可选的正整数 `max_tokens` 通过 JSON-RPC 初始化发送。`base_url` 与 `api_key` 会显式覆盖子进程环境中的 `DEEPSEEK_BASE_URL` 与 `DEEPSEEK_API_KEY`。
|
||||
|
||||
## 自定义插件
|
||||
|
||||
@@ -53,6 +57,8 @@ with DeepSeekHarness(
|
||||
|
||||
`profile` 可以选择另一个已存在的 profile,但该组合必须保留 `@deepseek-ai/dsh-sdk-app` 或另一个 `@deepseek-ai/dsh-sdk-jsonrpc-server` 配置项。配置错误会在 CLI 启动或 SDK 初始化时失败;不存在完整配置回退。`dsh_bin` 可以选择另一个 `dsh` 可执行程序,同时保持相同的 profile 语法。任意 argv 替换仅是内部 fake-runtime 测试适配器,不属于公开 API。
|
||||
|
||||
`provider` 选择指定 Cordis 组合所注册的提供方路由;`model` 是该适配器解析出的模型 ID。`reasoning_effort` 是该确切路由可选的非空适配器自有标识符;省略时保留模型自身的默认值。`max_tokens` 是一个可选的正整数,用于限制根 agent 及其进程内后代在每次请求中输出的 token 数量;省略该参数时,由提供方的默认行为决定输出上限。缺少适配器、模型不可用或推理强度不受支持时,初始化会在提示词运行前拒绝。压缩摘要继续使用压缩插件单独配置的上限。内置默认组合注册 `deepseek-official`。自定义组合可以挂载 `llm-pi-ai`,在其中配置各提供方专属的凭据和端点,并选择 pi-ai 已安装 catalog 中存在的任意提供方/模型组合。
|
||||
|
||||
随附的 `sdk-minimal` profile 是独立显式配置树,而不是 `dsh-base` 上的 overlay。使用 `profile="sdk-minimal"` 选择它;普通 `model` 参数是唯一运行时模型选择,也适用于不在适配器建议目录中的模型 id。它提供持久 Bash、字符串替换 editor、本地执行与 JSONL 会话;settings、托管凭据、遥测、Web 工具与完整默认工具清单仍由独立的完整 `sdk` 与 `web` profile 提供。
|
||||
|
||||
## 结果与通知
|
||||
|
||||
@@ -21,6 +21,7 @@ class DeepSeekHarnessConfig:
|
||||
|
||||
provider: str = "deepseek-official"
|
||||
model: str = "deepseek-v4-flash"
|
||||
reasoning_effort: str | None = None
|
||||
max_tokens: int | None = None
|
||||
cwd: str | None = None
|
||||
runtime_cwd: str | None = None
|
||||
@@ -107,6 +108,7 @@ class DeepSeekHarness:
|
||||
cwd=self._cwd,
|
||||
provider=self.config.provider,
|
||||
model=self.config.model,
|
||||
reasoning_effort=self.config.reasoning_effort,
|
||||
max_tokens=self.config.max_tokens,
|
||||
)
|
||||
self._initialized = True
|
||||
|
||||
@@ -137,6 +137,7 @@ class HarnessClient:
|
||||
cwd: str,
|
||||
provider: str,
|
||||
model: str,
|
||||
reasoning_effort: str | None = None,
|
||||
max_tokens: int | None = None,
|
||||
) -> InitializeResponse:
|
||||
payload: JsonObject = {
|
||||
@@ -144,6 +145,8 @@ class HarnessClient:
|
||||
"provider": provider,
|
||||
"model": model,
|
||||
}
|
||||
if reasoning_effort is not None:
|
||||
payload["reasoningEffort"] = reasoning_effort
|
||||
if max_tokens is not None:
|
||||
payload["maxTokens"] = max_tokens
|
||||
try:
|
||||
|
||||
@@ -94,6 +94,7 @@ for line in sys.stdin:
|
||||
|
||||
with DeepSeekHarness(
|
||||
model="deepseek-v4-flash",
|
||||
reasoning_effort="max",
|
||||
max_tokens=4096,
|
||||
cwd=str(tmp_path),
|
||||
_launch_args=(sys.executable, str(script)),
|
||||
@@ -119,6 +120,7 @@ for line in sys.stdin:
|
||||
"cwd": str(tmp_path),
|
||||
"provider": "deepseek-official",
|
||||
"model": "deepseek-v4-flash",
|
||||
"reasoningEffort": "max",
|
||||
"maxTokens": 4096,
|
||||
}
|
||||
|
||||
@@ -862,7 +864,9 @@ def test_public_signatures_omit_unsupported_wire_parameters() -> None:
|
||||
assert "profile" not in inspect.signature(Session.run).parameters
|
||||
assert "system_prompt" not in DeepSeekHarnessConfig.__dataclass_fields__
|
||||
assert "max_tokens" in DeepSeekHarnessConfig.__dataclass_fields__
|
||||
assert "reasoning_effort" in DeepSeekHarnessConfig.__dataclass_fields__
|
||||
assert "max_tokens" in inspect.signature(HarnessClient.initialize).parameters
|
||||
assert "reasoning_effort" in inspect.signature(HarnessClient.initialize).parameters
|
||||
assert "client_name" not in HarnessConfig.__dataclass_fields__
|
||||
assert "client_version" not in HarnessConfig.__dataclass_fields__
|
||||
assert {"dsh_bin", "profile", "patches", "dsh_home"} <= set(
|
||||
|
||||
Reference in New Issue
Block a user