Merge origin/master into fix/subagent-empty-terminal-message-output
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 docs/config-catalog.md
|
||||
config-catalog.md: 10078dea5221cfe76b1c028ef83216f5a4575940
|
||||
config-catalog.zh.md: 38ed9f94bee9b0c11f5ea4dad4ba48532cce6450
|
||||
config-catalog.md: 64c7722a3cc3788d110eab8d9be161129684b942
|
||||
config-catalog.zh.md: 4cc146a38b408d9f1a7e5067419fead48520ae11
|
||||
|
||||
@@ -1161,6 +1161,8 @@ export interface Config {
|
||||
* variables. Empty text drops the section at render, matching the registry.
|
||||
*/
|
||||
text: string
|
||||
/** Make this persona the complete system prompt, suppressing every other section. */
|
||||
complete?: boolean
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1987,7 +1989,7 @@ export interface Config {
|
||||
}
|
||||
```
|
||||
|
||||
Source: [`packages/core/system-prompt/src/index.ts:177`](../packages/core/system-prompt/src/index.ts)
|
||||
Source: [`packages/core/system-prompt/src/index.ts:186`](../packages/core/system-prompt/src/index.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-time-context`
|
||||
|
||||
|
||||
@@ -1163,6 +1163,8 @@ export interface Config {
|
||||
* variables. Empty text drops the section at render, matching the registry.
|
||||
*/
|
||||
text: string
|
||||
/** Make this persona the complete system prompt, suppressing every other section. */
|
||||
complete?: boolean
|
||||
}
|
||||
```
|
||||
|
||||
@@ -1989,7 +1991,7 @@ export interface Config {
|
||||
}
|
||||
```
|
||||
|
||||
来源:[`packages/core/system-prompt/src/index.ts:177`](../packages/core/system-prompt/src/index.ts)
|
||||
来源:[`packages/core/system-prompt/src/index.ts:186`](../packages/core/system-prompt/src/index.ts)
|
||||
|
||||
## `@deepseek-ai/dsh-time-context`
|
||||
|
||||
|
||||
@@ -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 docs/event-producer-consumer.md
|
||||
event-producer-consumer.md: 61d51677842c6e27dfa11bba56f6af145206c165
|
||||
event-producer-consumer.zh.md: 2f454cedc23f388d745fbb6c399d575681281afb
|
||||
event-producer-consumer.md: 19e2e660e58101b54054091b3d55b362d25d29dc
|
||||
event-producer-consumer.zh.md: d29cab8974d206b74b8869057b8efcf7542c1161
|
||||
|
||||
@@ -41,8 +41,8 @@ This matrix shows which packages dispatch each harness-owned event and which pac
|
||||
| `subagent/provider-added` | `emit` | [`packages/subagent/subagent/src/index.ts:139`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`emit`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) |
|
||||
| `subagent/provider-removed` | `emit` | [`packages/subagent/subagent/src/index.ts:145`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) |
|
||||
| `subagent/start` | `emit` | [`packages/subagent/subagent/src/index.ts:156`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude`](../packages/hooks/hooks-claude), [`subagent`](../packages/subagent/subagent) |
|
||||
| `system-prompt/assemble` | `waterfall` | [`packages/core/system-prompt/src/index.ts:29`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`waterfall`) | [`agent`](../packages/core/agent), [`system-prompt`](../packages/core/system-prompt) |
|
||||
| `system-prompt/change` | `emit` | [`packages/core/system-prompt/src/index.ts:35`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`emit`) | - |
|
||||
| `system-prompt/assemble` | `waterfall` | [`packages/core/system-prompt/src/index.ts:31`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`waterfall`) | [`agent`](../packages/core/agent), [`system-prompt`](../packages/core/system-prompt) |
|
||||
| `system-prompt/change` | `emit` | [`packages/core/system-prompt/src/index.ts:37`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`emit`) | - |
|
||||
| `telemetry/record` | `waterfall` | [`packages/session/session-telemetry/src/index.ts:43`](../packages/session/session-telemetry/src/index.ts) | [`session-telemetry`](../packages/session/session-telemetry) (`waterfall`) | - |
|
||||
| `tools/change` | `emit` | [`packages/core/tools/src/index.ts:193`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`emit`) | - |
|
||||
| `tools/code-dispatch-log` | `waterfall` | [`packages/core/tools/src/index.ts:175`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`spill-policy`](../packages/spill/spill-policy) |
|
||||
|
||||
@@ -43,8 +43,8 @@
|
||||
| `subagent/provider-added` | `emit` | [`packages/subagent/subagent/src/index.ts:139`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`emit`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) |
|
||||
| `subagent/provider-removed` | `emit` | [`packages/subagent/subagent/src/index.ts:145`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`subagent`](../packages/subagent/subagent), [`tool-subagent`](../packages/subagent/tool-subagent) |
|
||||
| `subagent/start` | `emit` | [`packages/subagent/subagent/src/index.ts:156`](../packages/subagent/subagent/src/index.ts) | [`subagent`](../packages/subagent/subagent) (`events.dispatch`) | [`hooks-claude`](../packages/hooks/hooks-claude), [`subagent`](../packages/subagent/subagent) |
|
||||
| `system-prompt/assemble` | `waterfall` | [`packages/core/system-prompt/src/index.ts:29`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`waterfall`) | [`agent`](../packages/core/agent), [`system-prompt`](../packages/core/system-prompt) |
|
||||
| `system-prompt/change` | `emit` | [`packages/core/system-prompt/src/index.ts:35`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`emit`) | - |
|
||||
| `system-prompt/assemble` | `waterfall` | [`packages/core/system-prompt/src/index.ts:31`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`waterfall`) | [`agent`](../packages/core/agent), [`system-prompt`](../packages/core/system-prompt) |
|
||||
| `system-prompt/change` | `emit` | [`packages/core/system-prompt/src/index.ts:37`](../packages/core/system-prompt/src/index.ts) | [`system-prompt`](../packages/core/system-prompt) (`emit`) | - |
|
||||
| `telemetry/record` | `waterfall` | [`packages/session/session-telemetry/src/index.ts:43`](../packages/session/session-telemetry/src/index.ts) | [`session-telemetry`](../packages/session/session-telemetry) (`waterfall`) | - |
|
||||
| `tools/change` | `emit` | [`packages/core/tools/src/index.ts:193`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`emit`) | - |
|
||||
| `tools/code-dispatch-log` | `waterfall` | [`packages/core/tools/src/index.ts:175`](../packages/core/tools/src/index.ts) | [`tools`](../packages/core/tools) (`waterfall`) | [`spill-policy`](../packages/spill/spill-policy) |
|
||||
|
||||
@@ -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 docs/subsystems/system-prompt.md
|
||||
system-prompt.md: bdc0e994fb8e784a19814574c405d8cc3dce2d11
|
||||
system-prompt.zh.md: db6932b18f4721020fed567d49727f863eb06608
|
||||
system-prompt.md: 56617ef9d3d8da89673a4624abcef73e58d72cab
|
||||
system-prompt.zh.md: cafea4f9689879b3fd8d0e1fff7249fcb02a7c12
|
||||
|
||||
@@ -39,7 +39,7 @@ interface ToolProviderResult {
|
||||
|
||||
## Prompt sections
|
||||
|
||||
`PromptSection` is a readonly same-process registration contract. Its text may be static or resolved from the current assembly context.
|
||||
`PromptSection` is a readonly same-process registration contract. Its text may be static or resolved from the current assembly context. One effective `complete` section becomes the sole prompt section after cooperative assembly.
|
||||
|
||||
```ts type-equiv
|
||||
/** One contributed section of the system prompt (registry input). */
|
||||
@@ -58,6 +58,13 @@ interface PromptSection {
|
||||
* interpolated later, by {@link renderPrompt}.
|
||||
*/
|
||||
readonly text: string | ((context: AssembleContext) => string)
|
||||
/**
|
||||
* Treat this contribution as the complete system prompt. Assembly still
|
||||
* runs the cooperative waterfall so tools, contexts, and variables can be
|
||||
* resolved, then restores this exact section as the sole prompt section.
|
||||
* More than one effective complete section makes assembly fail.
|
||||
*/
|
||||
readonly complete?: boolean
|
||||
}
|
||||
```
|
||||
|
||||
@@ -132,14 +139,16 @@ variable(name: string, provider: (context: AssembleContext) => string | undefine
|
||||
/**
|
||||
* Assemble global and scoped providers, detach tool parameters, apply
|
||||
* canonical ordering, then run the assembly waterfall. Scoped sections and
|
||||
* variables shadow globals; the returned waterfall value is authoritative.
|
||||
* variables shadow globals. The returned waterfall value is authoritative
|
||||
* except that an effective complete section is restored afterwards as the
|
||||
* sole prompt section.
|
||||
* @param context - the optional scope and plugin-defined assembly fields.
|
||||
* @returns the authoritative post-waterfall assembly.
|
||||
* @returns the post-waterfall assembly with any complete prompt enforced.
|
||||
*/
|
||||
async assemble(context: AssembleContext = {}): Promise<PromptAssembly>
|
||||
```
|
||||
|
||||
Source: [`packages/core/system-prompt/src/index.ts:325`](../../packages/core/system-prompt/src/index.ts)
|
||||
Source: [`packages/core/system-prompt/src/index.ts:334`](../../packages/core/system-prompt/src/index.ts)
|
||||
|
||||
<a id="system-prompt-events"></a>
|
||||
|
||||
@@ -149,7 +158,7 @@ Source: [`packages/core/system-prompt/src/index.ts:325`](../../packages/core/sys
|
||||
|
||||
#### `system-prompt/assemble` — waterfall
|
||||
|
||||
Expert waterfall over the assembled sections, contexts, tools, and variables. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): scoped listeners receive only that scope's assemblies. The returned value is authoritative. A supplied signal controls only this explicit assembly request and must not be retained to control later turns.
|
||||
Expert waterfall over the assembled sections, contexts, tools, and variables. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): scoped listeners receive only that scope's assemblies. The returned value is authoritative. A supplied signal controls only this explicit assembly request and must not be retained to control later turns. A registered complete section is restored after this waterfall, so listeners cannot add to or replace that scope's system prompt.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
@@ -157,7 +166,9 @@ Expert waterfall over the assembled sections, contexts, tools, and variables. Sc
|
||||
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): scoped listeners
|
||||
* receive only that scope's assemblies. The returned value is authoritative.
|
||||
* A supplied signal controls only this explicit assembly request and must not
|
||||
* be retained to control later turns.
|
||||
* be retained to control later turns. A registered complete section is
|
||||
* restored after this waterfall, so listeners cannot add to or replace
|
||||
* that scope's system prompt.
|
||||
* @param assembly - the mutable assembly built from registered providers.
|
||||
* @param context - the caller's per-assembly context.
|
||||
* @mode waterfall
|
||||
@@ -167,7 +178,7 @@ Expert waterfall over the assembled sections, contexts, tools, and variables. Sc
|
||||
|
||||
Types: [Scoped](scope.md)
|
||||
|
||||
Source: [`packages/core/system-prompt/src/index.ts:29`](../../packages/core/system-prompt/src/index.ts)
|
||||
Source: [`packages/core/system-prompt/src/index.ts:31`](../../packages/core/system-prompt/src/index.ts)
|
||||
|
||||
<a id="system-promptchange--emit"></a>
|
||||
|
||||
@@ -184,5 +195,5 @@ Emitted when any prompt provider changes. This registry notification is unfilter
|
||||
'system-prompt/change'(): void
|
||||
```
|
||||
|
||||
Source: [`packages/core/system-prompt/src/index.ts:35`](../../packages/core/system-prompt/src/index.ts)
|
||||
Source: [`packages/core/system-prompt/src/index.ts:37`](../../packages/core/system-prompt/src/index.ts)
|
||||
<!-- END GENERATED cordis-surface -->
|
||||
|
||||
@@ -39,7 +39,7 @@ interface ToolProviderResult {
|
||||
|
||||
## 提示词段落
|
||||
|
||||
`PromptSection` 是一份只读的同进程注册约定。其文本可以是静态的,也可以从当前组装上下文动态解析。
|
||||
`PromptSection` 是一份只读的同进程注册约定。其文本可以是静态的,也可以从当前组装上下文动态解析。协作式组装完成后,一个有效的 `complete` 段会成为唯一的提示词段落。
|
||||
|
||||
```ts type-equiv
|
||||
/** One contributed section of the system prompt (registry input). */
|
||||
@@ -58,6 +58,13 @@ interface PromptSection {
|
||||
* interpolated later, by {@link renderPrompt}.
|
||||
*/
|
||||
readonly text: string | ((context: AssembleContext) => string)
|
||||
/**
|
||||
* Treat this contribution as the complete system prompt. Assembly still
|
||||
* runs the cooperative waterfall so tools, contexts, and variables can be
|
||||
* resolved, then restores this exact section as the sole prompt section.
|
||||
* More than one effective complete section makes assembly fail.
|
||||
*/
|
||||
readonly complete?: boolean
|
||||
}
|
||||
```
|
||||
|
||||
@@ -132,14 +139,16 @@ variable(name: string, provider: (context: AssembleContext) => string | undefine
|
||||
/**
|
||||
* Assemble global and scoped providers, detach tool parameters, apply
|
||||
* canonical ordering, then run the assembly waterfall. Scoped sections and
|
||||
* variables shadow globals; the returned waterfall value is authoritative.
|
||||
* variables shadow globals. The returned waterfall value is authoritative
|
||||
* except that an effective complete section is restored afterwards as the
|
||||
* sole prompt section.
|
||||
* @param context - the optional scope and plugin-defined assembly fields.
|
||||
* @returns the authoritative post-waterfall assembly.
|
||||
* @returns the post-waterfall assembly with any complete prompt enforced.
|
||||
*/
|
||||
async assemble(context: AssembleContext = {}): Promise<PromptAssembly>
|
||||
```
|
||||
|
||||
Source: [`packages/core/system-prompt/src/index.ts:325`](../../packages/core/system-prompt/src/index.ts)
|
||||
Source: [`packages/core/system-prompt/src/index.ts:334`](../../packages/core/system-prompt/src/index.ts)
|
||||
|
||||
<a id="system-prompt-events"></a>
|
||||
|
||||
@@ -149,7 +158,7 @@ Source: [`packages/core/system-prompt/src/index.ts:325`](../../packages/core/sys
|
||||
|
||||
#### `system-prompt/assemble` — waterfall
|
||||
|
||||
Expert waterfall over the assembled sections, contexts, tools, and variables. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): scoped listeners receive only that scope's assemblies. The returned value is authoritative. A supplied signal controls only this explicit assembly request and must not be retained to control later turns.
|
||||
Expert waterfall over the assembled sections, contexts, tools, and variables. Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): scoped listeners receive only that scope's assemblies. The returned value is authoritative. A supplied signal controls only this explicit assembly request and must not be retained to control later turns. A registered complete section is restored after this waterfall, so listeners cannot add to or replace that scope's system prompt.
|
||||
|
||||
```ts cordis-catalog
|
||||
/**
|
||||
@@ -157,7 +166,9 @@ Expert waterfall over the assembled sections, contexts, tools, and variables. Sc
|
||||
* Scope-filtered dispatch (`@deepseek-ai/dsh-scope`): scoped listeners
|
||||
* receive only that scope's assemblies. The returned value is authoritative.
|
||||
* A supplied signal controls only this explicit assembly request and must not
|
||||
* be retained to control later turns.
|
||||
* be retained to control later turns. A registered complete section is
|
||||
* restored after this waterfall, so listeners cannot add to or replace
|
||||
* that scope's system prompt.
|
||||
* @param assembly - the mutable assembly built from registered providers.
|
||||
* @param context - the caller's per-assembly context.
|
||||
* @mode waterfall
|
||||
@@ -167,7 +178,7 @@ Expert waterfall over the assembled sections, contexts, tools, and variables. Sc
|
||||
|
||||
Types: [Scoped](scope.md)
|
||||
|
||||
Source: [`packages/core/system-prompt/src/index.ts:29`](../../packages/core/system-prompt/src/index.ts)
|
||||
Source: [`packages/core/system-prompt/src/index.ts:31`](../../packages/core/system-prompt/src/index.ts)
|
||||
|
||||
<a id="system-promptchange--emit"></a>
|
||||
|
||||
@@ -184,5 +195,5 @@ Emitted when any prompt provider changes. This registry notification is unfilter
|
||||
'system-prompt/change'(): void
|
||||
```
|
||||
|
||||
Source: [`packages/core/system-prompt/src/index.ts:35`](../../packages/core/system-prompt/src/index.ts)
|
||||
Source: [`packages/core/system-prompt/src/index.ts:37`](../../packages/core/system-prompt/src/index.ts)
|
||||
<!-- END GENERATED cordis-surface -->
|
||||
|
||||
6
docs/user/guide/python-sdk.i18n.yaml
Normal file
6
docs/user/guide/python-sdk.i18n.yaml
Normal file
@@ -0,0 +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 docs/user/guide/python-sdk.md
|
||||
python-sdk.md: c48bc95c9334cfd16a925d12726c20b2f968c753
|
||||
python-sdk.zh.md: dc31c391a180a742c7dc10807f6ed2ef8d11927d
|
||||
130
docs/user/guide/python-sdk.md
Normal file
130
docs/user/guide/python-sdk.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# Get started with the Python SDK
|
||||
|
||||
English | [中文](python-sdk.zh.md)
|
||||
|
||||
This tutorial installs the Python SDK, runs a checked-in Cordis composition without the Web UI, and uses the same API in your own program. It uses the compact [`minimal.cordis.yml`](../../../examples/jsonrpc-agent/minimal.cordis.yml) configuration as a complete example with a fixed system prompt, tool catalog, persistent-shell behavior, and compaction policy.
|
||||
|
||||
## Prerequisites
|
||||
|
||||
- Python 3.10 or newer
|
||||
- Linux x64, Linux arm64, or macOS arm64
|
||||
- A DeepSeek-compatible API endpoint and credential
|
||||
- An isolated workspace that the agent may modify
|
||||
|
||||
## Install the SDK
|
||||
|
||||
Choose either the public package or a source build. Both install the `deepseek-harness-sdk` distribution and expose the `deepseek_harness` Python module.
|
||||
|
||||
### Install from PyPI
|
||||
|
||||
Create a virtual environment and install the SDK with its same-version bundled runtime:
|
||||
|
||||
```sh
|
||||
python -m venv .venv
|
||||
. .venv/bin/activate
|
||||
python -m pip install deepseek-harness-sdk
|
||||
```
|
||||
|
||||
### Build from source
|
||||
|
||||
A source build additionally requires Git, Node.js ^22.19 or >= 24, Corepack-enabled pnpm 11, and `uv`. The following commands build the runtime for the current supported host platform, build both wheels, and install them into the active virtual environment:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/deepseek-ai/deepseek-harness-sdk.git deepseek-harness
|
||||
cd deepseek-harness
|
||||
python -m pip install uv==0.11.23
|
||||
corepack enable
|
||||
pnpm install
|
||||
|
||||
case "$(uname -s):$(uname -m)" in
|
||||
Linux:x86_64) runtime_platform=linux-x64 ;;
|
||||
Linux:aarch64|Linux:arm64) runtime_platform=linux-arm64 ;;
|
||||
Darwin:arm64) runtime_platform=macos-arm64 ;;
|
||||
*) echo "unsupported platform" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
pnpm exec tsx scripts/build-exe-for-python-sdk.ts --targets="node24-$runtime_platform"
|
||||
version="$(node -p "require('./package.json').version")"
|
||||
python scripts/build-python-release.py --package sdk --output-dir dist-python
|
||||
python scripts/build-python-release.py \
|
||||
--package runtime \
|
||||
--platform "$runtime_platform" \
|
||||
--runtime-exe "dist-exe/dsh-jsonrpc-agent-pkg-$runtime_platform" \
|
||||
--output-dir dist-python
|
||||
python -m pip install --find-links dist-python "deepseek-harness-sdk==$version"
|
||||
```
|
||||
|
||||
The runtime wheel contains the JSON-RPC executable and every plugin used by the complete [`minimal.cordis.yml`](../../../examples/jsonrpc-agent/minimal.cordis.yml), so neither installation path needs Node.js after installation.
|
||||
|
||||
## Run the checked-in example
|
||||
|
||||
Set the credential in the environment. Set `DEEPSEEK_BASE_URL` as well when the model is served by an OpenAI-compatible proxy rather than the default DeepSeek endpoint.
|
||||
|
||||
```sh
|
||||
export DEEPSEEK_API_KEY=sk-your-key-here
|
||||
# export DEEPSEEK_BASE_URL=http://127.0.0.1:8000/v1
|
||||
```
|
||||
|
||||
Run one task from the repository checkout:
|
||||
|
||||
```sh
|
||||
python examples/jsonrpc-agent/minimal.py \
|
||||
--workspace /absolute/path/to/workspace \
|
||||
--session-root /absolute/path/to/sessions \
|
||||
--session-id example-001 \
|
||||
"Inspect the repository and fix the failing tests."
|
||||
```
|
||||
|
||||
The script prints the final assistant response. The session root receives a JSONL session log containing the assembled model request and every tool call.
|
||||
|
||||
## Use the SDK in your own program
|
||||
|
||||
The example is a thin wrapper around this SDK call:
|
||||
|
||||
```python
|
||||
from pathlib import Path
|
||||
|
||||
from deepseek_harness import DeepSeekHarness
|
||||
|
||||
config = Path("examples/jsonrpc-agent/minimal.cordis.yml").resolve()
|
||||
workspace = Path("/absolute/path/to/workspace").resolve()
|
||||
sessions = Path("/absolute/path/to/sessions").resolve()
|
||||
|
||||
with DeepSeekHarness(
|
||||
provider="deepseek-official",
|
||||
model="deepseek-v4-flash",
|
||||
max_tokens=49_152,
|
||||
cwd=str(workspace),
|
||||
session_root=str(sessions),
|
||||
cordis=str(config),
|
||||
) as harness:
|
||||
result = harness.run(
|
||||
"Inspect the repository and fix the failing tests.",
|
||||
session_id="example-001",
|
||||
)
|
||||
|
||||
print(result.final_response)
|
||||
```
|
||||
|
||||
`DeepSeekHarness` starts the bundled JSON-RPC runtime lazily and reuses it until the context manager exits. Reusing the same harness and session id across calls also preserves the session-owned Bash process, including its working directory, exported variables, and shell functions.
|
||||
|
||||
## Understand the example configuration
|
||||
|
||||
| Surface | Fixed value |
|
||||
|---|---|
|
||||
| System prompt | `You are a helpful software engineer assistant.` |
|
||||
| Model-facing tools | Persistent `bash` and `str_replace_editor` only |
|
||||
| Bash timeout | 300 seconds |
|
||||
| Editor output limit | 16,000 characters |
|
||||
| Compaction | Trigger ratio `0.8`, retain `20,480` tokens, summary cap `8,192` tokens, one retry |
|
||||
| Session persistence | Uncompressed JSONL under `DSH_SESSION_ROOT` |
|
||||
|
||||
The configuration omits harness identity, workspace prompt text, skills, one-shot Bash, task tools, and every other model-facing plugin. Filesystem policy facts are logged as runtime user context rather than appended to the system prompt. The editor requires absolute paths as an unconditional current contract, so the obsolete `requireAbsolutePath` option is absent.
|
||||
|
||||
## Choose workspace and session IDs
|
||||
|
||||
`cwd` selects the workspace available to the agent, while `session_root` stores session logs and state. Use a fresh session id for an independent task; reuse an id only when the next call should continue the same conversation and persistent shell state.
|
||||
|
||||
The composition uses `danger-full-access`. Run it only inside a disposable checkout or container: Bash and the editor can modify any path allowed to the runtime process. The persistent PTY backend requires a POSIX terminal substrate and is not a Windows agent surface.
|
||||
|
||||
For the complete SDK lifecycle and result contract, see the [Python SDK reference](../../../python/sdk/README.md). For Cordis composition syntax, see [Configuration](./config.md).
|
||||
130
docs/user/guide/python-sdk.zh.md
Normal file
130
docs/user/guide/python-sdk.zh.md
Normal file
@@ -0,0 +1,130 @@
|
||||
# Python SDK 快速上手
|
||||
|
||||
[English](python-sdk.md) | 中文
|
||||
|
||||
本教程介绍如何安装 Python SDK、在不使用 Web UI 的情况下运行仓库内置 Cordis 组合,以及如何在自己的程序中调用同一套 API。教程使用精简且完整的 [`minimal.cordis.yml`](../../../examples/jsonrpc-agent/minimal.cordis.yml) 作为示例,其中固定了系统提示词、工具目录、持久 shell 行为和压缩(compaction)策略。
|
||||
|
||||
## 前置要求
|
||||
|
||||
- Python 3.10 或更高版本
|
||||
- Linux x64、Linux arm64 或 macOS arm64
|
||||
- DeepSeek 兼容的 API 端点与凭据
|
||||
- agent 可以修改的隔离 workspace
|
||||
|
||||
## 安装 SDK
|
||||
|
||||
可以选择安装公开包或从源码构建。两种方式都会安装 `deepseek-harness-sdk` 分发包,并提供 `deepseek_harness` Python 模块。
|
||||
|
||||
### 从 PyPI 安装
|
||||
|
||||
请创建虚拟环境,并安装 SDK 及其同版本内置运行时:
|
||||
|
||||
```sh
|
||||
python -m venv .venv
|
||||
. .venv/bin/activate
|
||||
python -m pip install deepseek-harness-sdk
|
||||
```
|
||||
|
||||
### 从源码构建
|
||||
|
||||
从源码构建还需要 Git、Node.js ^22.19 或 >= 24、通过 Corepack 启用的 pnpm 11,以及 `uv`。以下命令为当前受支持的宿主平台构建运行时和两个 wheel 包,并将它们安装进当前虚拟环境:
|
||||
|
||||
```sh
|
||||
git clone https://github.com/deepseek-ai/deepseek-harness-sdk.git deepseek-harness
|
||||
cd deepseek-harness
|
||||
python -m pip install uv==0.11.23
|
||||
corepack enable
|
||||
pnpm install
|
||||
|
||||
case "$(uname -s):$(uname -m)" in
|
||||
Linux:x86_64) runtime_platform=linux-x64 ;;
|
||||
Linux:aarch64|Linux:arm64) runtime_platform=linux-arm64 ;;
|
||||
Darwin:arm64) runtime_platform=macos-arm64 ;;
|
||||
*) echo "unsupported platform" >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
pnpm exec tsx scripts/build-exe-for-python-sdk.ts --targets="node24-$runtime_platform"
|
||||
version="$(node -p "require('./package.json').version")"
|
||||
python scripts/build-python-release.py --package sdk --output-dir dist-python
|
||||
python scripts/build-python-release.py \
|
||||
--package runtime \
|
||||
--platform "$runtime_platform" \
|
||||
--runtime-exe "dist-exe/dsh-jsonrpc-agent-pkg-$runtime_platform" \
|
||||
--output-dir dist-python
|
||||
python -m pip install --find-links dist-python "deepseek-harness-sdk==$version"
|
||||
```
|
||||
|
||||
运行时 wheel 包含 JSON-RPC 可执行文件,以及完整 [`minimal.cordis.yml`](../../../examples/jsonrpc-agent/minimal.cordis.yml) 使用的每个插件,因此两种安装方式完成后都不再需要 Node.js。
|
||||
|
||||
## 运行仓库内置示例
|
||||
|
||||
请在环境中设置凭据。如果模型不是由默认 DeepSeek 端点提供,而是通过 OpenAI 兼容代理提供,还需要设置 `DEEPSEEK_BASE_URL`。
|
||||
|
||||
```sh
|
||||
export DEEPSEEK_API_KEY=sk-your-key-here
|
||||
# export DEEPSEEK_BASE_URL=http://127.0.0.1:8000/v1
|
||||
```
|
||||
|
||||
从仓库 checkout 运行一个任务:
|
||||
|
||||
```sh
|
||||
python examples/jsonrpc-agent/minimal.py \
|
||||
--workspace /absolute/path/to/workspace \
|
||||
--session-root /absolute/path/to/sessions \
|
||||
--session-id example-001 \
|
||||
"Inspect the repository and fix the failing tests."
|
||||
```
|
||||
|
||||
脚本会打印 assistant 的最终回复。会话根目录会收到 JSONL 会话日志,其中包含组装后的模型请求与每次工具调用。
|
||||
|
||||
## 在自己的程序中使用 SDK
|
||||
|
||||
该示例是以下 SDK 调用的轻量包装层:
|
||||
|
||||
```python
|
||||
from pathlib import Path
|
||||
|
||||
from deepseek_harness import DeepSeekHarness
|
||||
|
||||
config = Path("examples/jsonrpc-agent/minimal.cordis.yml").resolve()
|
||||
workspace = Path("/absolute/path/to/workspace").resolve()
|
||||
sessions = Path("/absolute/path/to/sessions").resolve()
|
||||
|
||||
with DeepSeekHarness(
|
||||
provider="deepseek-official",
|
||||
model="deepseek-v4-flash",
|
||||
max_tokens=49_152,
|
||||
cwd=str(workspace),
|
||||
session_root=str(sessions),
|
||||
cordis=str(config),
|
||||
) as harness:
|
||||
result = harness.run(
|
||||
"Inspect the repository and fix the failing tests.",
|
||||
session_id="example-001",
|
||||
)
|
||||
|
||||
print(result.final_response)
|
||||
```
|
||||
|
||||
`DeepSeekHarness` 会延迟启动内置 JSON-RPC 运行时,并持续复用,直至退出上下文管理器。在多次调用中复用同一个 harness 和 session id,还会保留该会话拥有的 Bash 进程,包括其工作目录、已导出的变量与 shell 函数。
|
||||
|
||||
## 了解示例配置
|
||||
|
||||
| 方面 | 固定值 |
|
||||
|---|---|
|
||||
| 系统提示词 | `You are a helpful software engineer assistant.` |
|
||||
| 面向模型的工具 | 仅持久 `bash` 与 `str_replace_editor` |
|
||||
| Bash 超时 | 300 秒 |
|
||||
| 编辑器输出上限 | 16,000 个字符 |
|
||||
| 压缩 | 触发比例 `0.8`、保留 `20,480` 个 token、摘要上限 `8,192` 个 token、重试 1 次 |
|
||||
| 会话持久化 | `DSH_SESSION_ROOT` 下未压缩的 JSONL |
|
||||
|
||||
该配置省略了 harness 身份、workspace 提示词文本、skill(技能)、一次性 Bash、任务工具和其他所有面向模型的插件。文件系统策略事实记录为运行时用户上下文,而不会追加到系统提示词中。编辑器无条件要求绝对路径,因此配置中没有已经废弃的 `requireAbsolutePath` 选项。
|
||||
|
||||
## 选择 workspace 与 session id
|
||||
|
||||
`cwd` 用于选择 agent 可访问的 workspace,`session_root` 用于保存会话日志和状态。独立任务应使用新的 session id;只有下一次调用需要延续同一段对话和持久 shell 状态时,才复用原有 id。
|
||||
|
||||
该组合使用 `danger-full-access`。只能在可丢弃的 checkout 或容器内运行:Bash 与编辑器可以修改运行时进程有权访问的任何路径。持久 PTY 后端需要 POSIX 终端环境,因此该模式不适用于 Windows agent。
|
||||
|
||||
完整的 SDK 生命周期与结果约定见 [Python SDK 参考](../../../python/sdk/README.md)。Cordis 组合语法见[配置](./config.md)。
|
||||
@@ -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 docs/user/guide/quickstart.md
|
||||
quickstart.md: ce196641f205324334533c025b4ac1dc791f857d
|
||||
quickstart.zh.md: 3a5d6d0748ec0c7ec83c74570d0fad1e8d66a97c
|
||||
quickstart.md: 6a0b292ce12b32b7993b7de56b35f1df2e7a7153
|
||||
quickstart.zh.md: 008245f136e28630c7e8368eeec536e11112a885
|
||||
|
||||
@@ -57,6 +57,7 @@ Open `http://127.0.0.1:3080`. The agent can read and write files, run commands,
|
||||
|
||||
## Next steps
|
||||
|
||||
- [Get started with the Python SDK](./python-sdk.md) — install the SDK and run a complete Cordis configuration without the Web UI
|
||||
- [Configure models](./providers.md) — reach providers beyond DeepSeek, and custom gateways
|
||||
- [Configuration](./config.md) — understand the `cordis.yml` format
|
||||
- [Develop a plugin](../develop/basic/) — build your own tool or backend
|
||||
|
||||
@@ -57,6 +57,7 @@ pnpm run dsh web
|
||||
|
||||
## 下一步
|
||||
|
||||
- [Python SDK 快速上手](./python-sdk.md) — 安装 SDK,并在不使用 Web UI 的情况下运行完整 Cordis 配置
|
||||
- [配置模型](./providers.md) — 接入 DeepSeek 之外的提供方与自定义网关
|
||||
- [配置文件](./config.md) — 了解 `cordis.yml` 的格式
|
||||
- [开发插件](../develop/basic/) — 编写自己的工具或后端
|
||||
|
||||
Reference in New Issue
Block a user