feat(sdk): support max output tokens
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Bilingual-pair consistency record (docs/i18n/README.md): the git blob hash of each
|
||||
# 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
|
||||
README.md: bfa31a712acd6fccf1458a0a80fc2ff80dfe114e
|
||||
README.zh.md: 11ebcdd133b2fd839b73f50ef2be2e531e8bbc2a
|
||||
# pnpm run verify-translation-pairing --write python/sdk/README.md
|
||||
README.md: f1e16e724efd6f71f63e475e47d7e4d704b8ceac
|
||||
README.zh.md: e56ae31020d1068e009056c20d8f11bab145dc8a
|
||||
@@ -27,12 +27,13 @@ from deepseek_harness import DeepSeekHarness
|
||||
with DeepSeekHarness(
|
||||
provider="deepseek",
|
||||
model="deepseek-v4-flash",
|
||||
max_tokens=49_152,
|
||||
cordis="examples/jsonrpc-agent/cordis.yml",
|
||||
) as harness:
|
||||
result = harness.run("Make the requested code change.")
|
||||
```
|
||||
|
||||
`provider` selects a provider route registered by the chosen Cordis composition; `model` is the model id resolved by that adapter. The bundled default composition registers `deepseek`. 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.
|
||||
`provider` selects a provider route registered by the chosen Cordis composition; `model` is the model id resolved by that adapter. `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. Compaction summaries keep the separate limit configured by their compaction plugin. The bundled default composition registers `deepseek`. 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.
|
||||
|
||||
`HarnessClient` retains discovered subagent ancestry for the lifetime of the runtime process. During each `Session.run()`, `TurnResult.notifications` and `on_notification` receive the root session and all known descendant notifications in wire order, including nested subagent lifecycle and session events. `TurnResult.events` remains the root session's complete event stream, and `TurnResult.final_response` is the text content from its last `assistant/message`; descendant messages therefore cannot replace the root response.
|
||||
|
||||
|
||||
@@ -23,12 +23,13 @@ from deepseek_harness import DeepSeekHarness
|
||||
with DeepSeekHarness(
|
||||
provider="deepseek",
|
||||
model="deepseek-v4-flash",
|
||||
max_tokens=49_152,
|
||||
cordis="examples/jsonrpc-agent/cordis.yml",
|
||||
) as harness:
|
||||
result = harness.run("Make the requested code change.")
|
||||
```
|
||||
|
||||
`provider` 用于选择当前 Cordis 组合已注册的提供方路由;`model` 是该适配器解析的模型 ID。内置默认组合注册 `deepseek`。自定义组合可以挂载 `llm-pi-ai`,在其中配置各提供方的凭据与端点,再选择 pi-ai 已安装目录中的任意提供方/模型组合。
|
||||
`provider` 用于选择当前 Cordis 组合已注册的提供方路由;`model` 是该适配器解析的模型 ID。`max_tokens` 是可选的正整数,用于限制根 agent 及其进程内后代每次请求的输出 token;省略时由提供方默认值控制。压缩摘要继续使用压缩插件单独配置的上限。内置默认组合注册 `deepseek`。自定义组合可以挂载 `llm-pi-ai`,在其中配置各提供方的凭据与端点,再选择 pi-ai 已安装目录中的任意提供方/模型组合。
|
||||
|
||||
`HarnessClient` 会在运行时进程的生命周期内保留已发现的 subagent(子 agent)祖先关系。每次执行 `Session.run()` 时,`TurnResult.notifications` 与 `on_notification` 会按线上的原始顺序收到根会话及所有已知后代的通知,其中包括嵌套 subagent 的生命周期与会话事件。`TurnResult.events` 仍只保存根会话的完整事件流,`TurnResult.final_response` 则取该会话最后一个 `assistant/message` 的文本内容,因此后代消息不会覆盖根会话回复。
|
||||
|
||||
|
||||
@@ -20,6 +20,7 @@ class DeepSeekHarnessConfig:
|
||||
|
||||
provider: str = "deepseek"
|
||||
model: str = "deepseek-v4-flash"
|
||||
max_tokens: int | None = None
|
||||
cwd: str | None = None
|
||||
runtime_cwd: str | None = None
|
||||
session_root: str | None = None
|
||||
@@ -100,6 +101,7 @@ class DeepSeekHarness:
|
||||
cwd=self._cwd,
|
||||
provider=self.config.provider,
|
||||
model=self.config.model,
|
||||
max_tokens=self.config.max_tokens,
|
||||
)
|
||||
self._initialized = True
|
||||
|
||||
|
||||
@@ -120,12 +120,15 @@ class HarnessClient:
|
||||
cwd: str,
|
||||
provider: str,
|
||||
model: str,
|
||||
max_tokens: int | None = None,
|
||||
) -> InitializeResponse:
|
||||
payload: JsonObject = {
|
||||
"cwd": str(Path(cwd).resolve()),
|
||||
"provider": provider,
|
||||
"model": model,
|
||||
}
|
||||
if max_tokens is not None:
|
||||
payload["maxTokens"] = max_tokens
|
||||
try:
|
||||
return self.request("initialize", payload, response_model=InitializeResponse)
|
||||
except BaseException:
|
||||
|
||||
@@ -15,6 +15,7 @@ from deepseek_harness import DeepSeekHarness, HarnessClient, HarnessConfig, Noti
|
||||
def test_high_level_sdk_runs_turn_and_collects_final_response(tmp_path: Path) -> None:
|
||||
script = tmp_path / "fake_runtime.py"
|
||||
env_dump = tmp_path / "env.json"
|
||||
init_dump = tmp_path / "init.json"
|
||||
script.write_text(
|
||||
"""
|
||||
import json
|
||||
@@ -34,6 +35,7 @@ for line in sys.stdin:
|
||||
msg = json.loads(line)
|
||||
method = msg.get("method")
|
||||
if method == "initialize":
|
||||
json.dump(msg.get("params"), open(os.environ["INIT_DUMP"], "w"))
|
||||
print(json.dumps({"jsonrpc": "2.0", "id": msg["id"], "result": {"serverInfo": {"name": "fake-runtime"}}}), flush=True)
|
||||
elif method == "session/prompt":
|
||||
params = msg.get("params") or {}
|
||||
@@ -62,12 +64,14 @@ for line in sys.stdin:
|
||||
|
||||
with DeepSeekHarness(
|
||||
model="deepseek-v4-flash",
|
||||
max_tokens=4096,
|
||||
cwd=str(tmp_path),
|
||||
cordis=str(tmp_path / "cordis.yml"),
|
||||
session_root=str(tmp_path / "sessions"),
|
||||
launch_args_override=(sys.executable, str(script)),
|
||||
env={
|
||||
"ENV_DUMP": str(env_dump),
|
||||
"INIT_DUMP": str(init_dump),
|
||||
"DEEPSEEK_API_KEY": "env-key",
|
||||
"DEEPSEEK_BASE_URL": "http://127.0.0.1:4321",
|
||||
},
|
||||
@@ -83,6 +87,12 @@ for line in sys.stdin:
|
||||
assert dumped_env["DSH_CWD"] == str(tmp_path)
|
||||
assert dumped_env["DSH_SESSION_ROOT"] == str(tmp_path / "sessions")
|
||||
assert dumped_env["DSH_CORDIS_CONFIG"] == str(tmp_path / "cordis.yml")
|
||||
assert json.loads(init_dump.read_text()) == {
|
||||
"cwd": str(tmp_path),
|
||||
"provider": "deepseek",
|
||||
"model": "deepseek-v4-flash",
|
||||
"maxTokens": 4096,
|
||||
}
|
||||
|
||||
|
||||
def test_session_run_invokes_notification_callback_before_returning(tmp_path: Path) -> None:
|
||||
@@ -731,6 +741,8 @@ def test_public_signatures_omit_unsupported_wire_parameters() -> None:
|
||||
assert "profile" not in inspect.signature(DeepSeekHarness.run).parameters
|
||||
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 "max_tokens" in inspect.signature(HarnessClient.initialize).parameters
|
||||
assert "client_name" not in HarnessConfig.__dataclass_fields__
|
||||
assert "client_version" not in HarnessConfig.__dataclass_fields__
|
||||
|
||||
|
||||
Reference in New Issue
Block a user