@deepseek-ai/dsh-sdk-client 0.2.0-rc.2 → 0.2.1-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.i18n.yaml +6 -6
- package/README.md +4 -1
- package/README.zh.md +4 -1
- package/lib/index.js +49 -3
- package/lib/types/api.d.ts +18 -1
- package/lib/types/client.d.ts +14 -0
- package/lib/types/index.d.ts +1 -1
- package/package.json +11 -10
package/README.i18n.yaml
CHANGED
|
@@ -15,14 +15,14 @@
|
|
|
15
15
|
en: d152484eb41ac6b4
|
|
16
16
|
zh: 09388d293f9be9cb
|
|
17
17
|
/deepseek-ai-dsh-sdk-client/use-this-package:
|
|
18
|
-
en:
|
|
19
|
-
zh:
|
|
18
|
+
en: 316b142489dd050f
|
|
19
|
+
zh: 2b37ae57b2a52b5e
|
|
20
20
|
/deepseek-ai-dsh-sdk-client/use-this-package/running-agent-turns-with-deepseekharness:
|
|
21
21
|
en: 01c58dddd7e62de2
|
|
22
22
|
zh: 6dbd46e244f3f135
|
|
23
23
|
/deepseek-ai-dsh-sdk-client/use-this-package/lower-level-control-with-harnessclient:
|
|
24
|
-
en:
|
|
25
|
-
zh:
|
|
24
|
+
en: 8778901987da6e59
|
|
25
|
+
zh: 3d09fe4b0b393a15
|
|
26
26
|
/deepseek-ai-dsh-sdk-client/understand-the-implementation:
|
|
27
27
|
en: 8773f50c51da85f0
|
|
28
28
|
zh: 4649ebc69357deb0
|
|
@@ -30,8 +30,8 @@
|
|
|
30
30
|
en: 6632c06d819233cc
|
|
31
31
|
zh: 207d55d8217ec6b1
|
|
32
32
|
/deepseek-ai-dsh-sdk-client/understand-the-implementation/source-map:
|
|
33
|
-
en:
|
|
34
|
-
zh:
|
|
33
|
+
en: a3c7978a80f5aba3
|
|
34
|
+
zh: fdc4dfdafd2eccfa
|
|
35
35
|
/deepseek-ai-dsh-sdk-client/understand-the-implementation/owned-activity-flow:
|
|
36
36
|
en: 94a42babac5f1c7d
|
|
37
37
|
zh: df9e42ed02f7d002
|
package/README.md
CHANGED
|
@@ -25,6 +25,8 @@ English | [中文](README.zh.md)
|
|
|
25
25
|
<a id="use-this-package"></a>
|
|
26
26
|
## Use this package
|
|
27
27
|
|
|
28
|
+
`HarnessSession.getWorkingDirectory()` reads the effective directory; `setWorkingDirectory(path)` changes it and returns the validated absolute path. Either method creates an unknown Session without starting a model turn. Relative paths use the Session's current directory. Origin metadata, permissions, and existing processes remain unchanged. `HarnessClient` exposes the same methods with a leading `sessionId` argument.
|
|
29
|
+
|
|
28
30
|
Use this client when TypeScript code must drive a complete Harness runtime from another process and you can name the runtime executable explicitly. The common path is minimal: construct a `DeepSeekHarness` with a launch spec, run prompts, and close it so the child process is always reaped.
|
|
29
31
|
|
|
30
32
|
### Running agent turns with DeepSeekHarness
|
|
@@ -51,6 +53,8 @@ The subprocess starts lazily on first use and stays owned by the instance across
|
|
|
51
53
|
|
|
52
54
|
`HarnessClient` is the protocol client under the run API: explicit `start()`, `initialize()`, `prompt()`, `request()`, and `close()`, plus notification subscriptions. `prompt()` returns the queued message id as soon as the runtime accepts it and never waits for agent activity. `subscribe(filter?)` returns a `NotificationSubscription` (awaitable `next()`, non-blocking `tryNext()`, async iteration); `subscribeSessionTree(id)` scopes to one session and the descendants discovered from `subagent.started` lineage edges — the runtime notifies for every session in its context, and scoping is client-side, exactly like the Python SDK.
|
|
53
55
|
|
|
56
|
+
Task-owning consumers can subscribe before `prompt()`, then call `request('session/wait', { sessionId })` and drain queued notifications with `tryNext()`. This waits for managed descendants and their root summary turns; `HarnessSession.run()` retains its next-idle interval. `validatedSessionEvent()` validates the event envelope and the assistant/turn fields consumed by SDK readers before they enter an output fold.
|
|
57
|
+
|
|
54
58
|
The client exports typed errors for every failure mode: `JsonRpcResponseError` (a wire error response, code and data preserved), `RequestTimeoutError` (a configured bound elapsed), `SdkProtocolError` (a response outside the documented protocol), and `TransportClosedError` (the runtime is gone — the message carries the exit code and a bounded stderr tail). `close()` requests protocol `shutdown` (bounded by `shutdownTimeoutMs`, default 1000 ms), then walks a stdin-EOF → SIGTERM → SIGKILL ladder until the process has exited; it is idempotent, and a closed client refuses reuse. `HarnessClientOptions.env` replaces the child environment entirely when given (`undefined` inherits the parent's); callers own credential policy — `scrubbedParentEnv` from `dsh-subprocess` is the shared scrub base for isolation-minded launches.
|
|
55
59
|
|
|
56
60
|
-----
|
|
@@ -76,7 +80,6 @@ The client is two layers over one wire: `DeepSeekHarness` (owned runs) over `Har
|
|
|
76
80
|
| [`src/dispose.ts`](src/dispose.ts) | Private teardown ladder: stdin EOF → SIGTERM → SIGKILL to actual exit |
|
|
77
81
|
| [`src/types.ts`](src/types.ts) | Launch and timeout options, notification shapes, `RunResult` |
|
|
78
82
|
| [`src/index.ts`](src/index.ts) | Consumer interface: the two client layers and caller-facing types |
|
|
79
|
-
| — | No runtime invariant companion is published; this client library runs outside any harness context (its peer is a separate runtime process); the runtime's own packages own the event-stream relations. |
|
|
80
83
|
|
|
81
84
|
### Owned activity flow
|
|
82
85
|
|
package/README.zh.md
CHANGED
|
@@ -25,6 +25,8 @@ kind: "package-library"
|
|
|
25
25
|
<a id="use-this-package"></a>
|
|
26
26
|
## 使用本包
|
|
27
27
|
|
|
28
|
+
`HarnessSession.getWorkingDirectory()` 读取有效目录;`setWorkingDirectory(path)` 修改目录并返回校验后的绝对路径。两个方法都可创建未知 Session,而不启动模型轮次。相对路径以 Session 当前目录解析。起始目录元数据、权限与已有进程保持不变。`HarnessClient` 提供同名方法,并以 `sessionId` 作为首个参数。
|
|
29
|
+
|
|
28
30
|
当 TypeScript 代码需要从另一进程驱动完整 Harness 运行时、且你能显式指名运行时可执行文件时,使用本客户端。常用路径极简:用启动规格构造 `DeepSeekHarness`,运行提示词,然后关闭它,使子进程总能被回收。
|
|
29
31
|
|
|
30
32
|
### 用 DeepSeekHarness 运行 agent 轮次
|
|
@@ -51,6 +53,8 @@ console.log(result.finalResponse)
|
|
|
51
53
|
|
|
52
54
|
`HarnessClient` 是运行 API 之下的协议客户端:显式 `start()`、`initialize()`、`prompt()`、`request()` 与 `close()`,外加通知订阅。`prompt()` 在运行时接受排队消息后立即返回该消息的 id,绝不等待 agent 活动。`subscribe(filter?)` 返回 `NotificationSubscription`(可等待的 `next()`、非阻塞 `tryNext()`、异步迭代);`subscribeSessionTree(id)` 把范围限定到一个会话及从 `subagent.started` 血缘边发现的后代——运行时对上下文内每个会话都发通知,范围限定在客户端完成,与 Python SDK 完全一致。
|
|
53
55
|
|
|
56
|
+
拥有完整任务的消费者可以先订阅,再调用 `prompt()`,随后调用 `request('session/wait', { sessionId })`,并通过 `tryNext()` 取完已排队的通知。这会等待受管理后代及其触发的根 Agent 摘要轮次;`HarnessSession.run()` 仍以首次空闲作为活动区间终点。`validatedSessionEvent()` 在事件进入输出折叠前,校验事件封装及 SDK 读取方使用的 assistant/turn 字段。
|
|
57
|
+
|
|
54
58
|
本客户端为每种失败模式导出类型化错误:`JsonRpcResponseError`(协议错误响应,保留 code 与 data)、`RequestTimeoutError`(配置的时限已到)、`SdkProtocolError`(响应超出文档化协议)、`TransportClosedError`(运行时已消失——消息携带退出码与有界 stderr 尾部)。`close()` 先请求协议 `shutdown`(受 `shutdownTimeoutMs` 约束,默认 1000 毫秒),然后走 stdin-EOF → SIGTERM → SIGKILL 阶梯直到进程退出;幂等,已关闭的客户端拒绝复用。`HarnessClientOptions.env` 给定时整体替换子进程环境(`undefined` 原样继承父进程环境);凭据策略归调用方——`dsh-subprocess` 的 `scrubbedParentEnv` 是面向隔离启动的共享擦除基底。
|
|
55
59
|
|
|
56
60
|
-----
|
|
@@ -76,7 +80,6 @@ console.log(result.finalResponse)
|
|
|
76
80
|
| [`src/dispose.ts`](src/dispose.ts) | 私有关闭阶梯:stdin EOF → SIGTERM → SIGKILL 直到真正退出 |
|
|
77
81
|
| [`src/types.ts`](src/types.ts) | 启动与超时选项、通知结构、`RunResult` |
|
|
78
82
|
| [`src/index.ts`](src/index.ts) | 消费方接口:两层客户端与面向调用方的类型 |
|
|
79
|
-
| — | 不发布运行时不变式伴生入口;本客户端库运行在任何 harness 上下文之外(其对端是独立运行时进程);运行时自身的包负责维护事件流关系。 |
|
|
80
83
|
|
|
81
84
|
### 自有活动流程
|
|
82
85
|
|
package/lib/index.js
CHANGED
|
@@ -441,6 +441,31 @@ var HarnessClient = class {
|
|
|
441
441
|
return result.messageId;
|
|
442
442
|
}
|
|
443
443
|
/**
|
|
444
|
+
* Read a Session's effective working directory, recovering it if missing.
|
|
445
|
+
* @param sessionId - target Session; an unknown id creates it.
|
|
446
|
+
* @returns the absolute effective directory.
|
|
447
|
+
*/
|
|
448
|
+
getWorkingDirectory(sessionId) {
|
|
449
|
+
return this.workingDirectoryRequest("session/working-directory/get", { sessionId });
|
|
450
|
+
}
|
|
451
|
+
/**
|
|
452
|
+
* Change a Session's effective directory without changing origin or permissions.
|
|
453
|
+
* @param sessionId - target Session; an unknown id creates it.
|
|
454
|
+
* @param path - absolute or Session-current-directory-relative path.
|
|
455
|
+
* @returns the validated absolute directory.
|
|
456
|
+
*/
|
|
457
|
+
setWorkingDirectory(sessionId, path) {
|
|
458
|
+
return this.workingDirectoryRequest("session/working-directory/set", {
|
|
459
|
+
sessionId,
|
|
460
|
+
path
|
|
461
|
+
});
|
|
462
|
+
}
|
|
463
|
+
async workingDirectoryRequest(method, params) {
|
|
464
|
+
const result = await this.request(method, params);
|
|
465
|
+
if (!isRecord(result) || typeof result.cwd !== "string") throw new SdkProtocolError(`${method} returned no working directory: ${JSON.stringify(result)}`);
|
|
466
|
+
return result.cwd;
|
|
467
|
+
}
|
|
468
|
+
/**
|
|
444
469
|
* Send one JSON-RPC request and await its result.
|
|
445
470
|
* @param method - the wire method name.
|
|
446
471
|
* @param params - the params object; omitted params send `{}`.
|
|
@@ -682,7 +707,7 @@ var DeepSeekHarness = class {
|
|
|
682
707
|
}
|
|
683
708
|
/**
|
|
684
709
|
* Open a session handle (no wire traffic; the runtime creates the session
|
|
685
|
-
* on its first prompt).
|
|
710
|
+
* on its first prompt or working-directory operation).
|
|
686
711
|
* @param sessionId - explicit id to reuse; omitted mints a fresh one.
|
|
687
712
|
* @returns the session handle.
|
|
688
713
|
*/
|
|
@@ -730,6 +755,23 @@ var HarnessSession = class {
|
|
|
730
755
|
this.id = id;
|
|
731
756
|
}
|
|
732
757
|
/**
|
|
758
|
+
* Read the effective directory and recover a missing directory to the Session origin.
|
|
759
|
+
* @returns the absolute directory used by new independent operations.
|
|
760
|
+
*/
|
|
761
|
+
async getWorkingDirectory() {
|
|
762
|
+
await this.harness.start();
|
|
763
|
+
return this.harness.client.getWorkingDirectory(this.id);
|
|
764
|
+
}
|
|
765
|
+
/**
|
|
766
|
+
* Change the effective directory without moving existing processes or changing permissions.
|
|
767
|
+
* @param path - absolute or Session-current-directory-relative directory.
|
|
768
|
+
* @returns the validated absolute directory.
|
|
769
|
+
*/
|
|
770
|
+
async setWorkingDirectory(path) {
|
|
771
|
+
await this.harness.start();
|
|
772
|
+
return this.harness.client.setWorkingDirectory(this.id, path);
|
|
773
|
+
}
|
|
774
|
+
/**
|
|
733
775
|
* Queue one prompt, then observe the whole session through its next idle.
|
|
734
776
|
* @param input - prompt text, or content blocks sent verbatim.
|
|
735
777
|
* @param options - optional per-notification observer.
|
|
@@ -806,7 +848,11 @@ function validatedTurnEndReason(value) {
|
|
|
806
848
|
}
|
|
807
849
|
return value;
|
|
808
850
|
}
|
|
809
|
-
/**
|
|
851
|
+
/**
|
|
852
|
+
* Validate the event envelope and assistant/turn fields consumed by SDK readers.
|
|
853
|
+
* @param value - the raw `session.event` event payload.
|
|
854
|
+
* @returns the event, or throws a protocol error for malformed consumed fields.
|
|
855
|
+
*/
|
|
810
856
|
function validatedSessionEvent(value) {
|
|
811
857
|
if (!isRecord(value) || typeof value.type !== "string") throw new SdkProtocolError(`session.event carried no event envelope: ${JSON.stringify(value)}`);
|
|
812
858
|
if (value.type === "assistant/message") {
|
|
@@ -841,4 +887,4 @@ function finalResponse(events) {
|
|
|
841
887
|
return "";
|
|
842
888
|
}
|
|
843
889
|
//#endregion
|
|
844
|
-
export { DeepSeekHarness, HarnessClient, HarnessSession, JsonRpcResponseError, RequestTimeoutError, SdkProtocolError, TransportClosedError };
|
|
890
|
+
export { DeepSeekHarness, HarnessClient, HarnessSession, JsonRpcResponseError, RequestTimeoutError, SdkProtocolError, TransportClosedError, validatedSessionEvent };
|
package/lib/types/api.d.ts
CHANGED
|
@@ -48,7 +48,7 @@ export declare class DeepSeekHarness implements AsyncDisposable {
|
|
|
48
48
|
start(): Promise<void>;
|
|
49
49
|
/**
|
|
50
50
|
* Open a session handle (no wire traffic; the runtime creates the session
|
|
51
|
-
* on its first prompt).
|
|
51
|
+
* on its first prompt or working-directory operation).
|
|
52
52
|
* @param sessionId - explicit id to reuse; omitted mints a fresh one.
|
|
53
53
|
* @returns the session handle.
|
|
54
54
|
*/
|
|
@@ -92,6 +92,17 @@ export declare class HarnessSession {
|
|
|
92
92
|
* @param id - the wire session id this handle runs on.
|
|
93
93
|
*/
|
|
94
94
|
constructor(harness: DeepSeekHarness, id: string);
|
|
95
|
+
/**
|
|
96
|
+
* Read the effective directory and recover a missing directory to the Session origin.
|
|
97
|
+
* @returns the absolute directory used by new independent operations.
|
|
98
|
+
*/
|
|
99
|
+
getWorkingDirectory(): Promise<string>;
|
|
100
|
+
/**
|
|
101
|
+
* Change the effective directory without moving existing processes or changing permissions.
|
|
102
|
+
* @param path - absolute or Session-current-directory-relative directory.
|
|
103
|
+
* @returns the validated absolute directory.
|
|
104
|
+
*/
|
|
105
|
+
setWorkingDirectory(path: string): Promise<string>;
|
|
95
106
|
/**
|
|
96
107
|
* Queue one prompt, then observe the whole session through its next idle.
|
|
97
108
|
* @param input - prompt text, or content blocks sent verbatim.
|
|
@@ -107,6 +118,12 @@ export declare class HarnessSession {
|
|
|
107
118
|
* @returns the content blocks to send.
|
|
108
119
|
*/
|
|
109
120
|
export declare function normalizeInput(input: string | SdkPromptContentBlock[]): SdkPromptContentBlock[];
|
|
121
|
+
/**
|
|
122
|
+
* Validate the event envelope and assistant/turn fields consumed by SDK readers.
|
|
123
|
+
* @param value - the raw `session.event` event payload.
|
|
124
|
+
* @returns the event, or throws a protocol error for malformed consumed fields.
|
|
125
|
+
*/
|
|
126
|
+
export declare function validatedSessionEvent(value: unknown): SessionEvent;
|
|
110
127
|
/**
|
|
111
128
|
* Extract the concatenated text of the last assistant message.
|
|
112
129
|
* @param events - the activity interval's `session.event` payloads in wire order.
|
package/lib/types/client.d.ts
CHANGED
|
@@ -96,6 +96,20 @@ export declare class HarnessClient {
|
|
|
96
96
|
* @returns the queued message id.
|
|
97
97
|
*/
|
|
98
98
|
prompt(sessionId: string, contentBlocks: SdkPromptContentBlock[]): Promise<string>;
|
|
99
|
+
/**
|
|
100
|
+
* Read a Session's effective working directory, recovering it if missing.
|
|
101
|
+
* @param sessionId - target Session; an unknown id creates it.
|
|
102
|
+
* @returns the absolute effective directory.
|
|
103
|
+
*/
|
|
104
|
+
getWorkingDirectory(sessionId: string): Promise<string>;
|
|
105
|
+
/**
|
|
106
|
+
* Change a Session's effective directory without changing origin or permissions.
|
|
107
|
+
* @param sessionId - target Session; an unknown id creates it.
|
|
108
|
+
* @param path - absolute or Session-current-directory-relative path.
|
|
109
|
+
* @returns the validated absolute directory.
|
|
110
|
+
*/
|
|
111
|
+
setWorkingDirectory(sessionId: string, path: string): Promise<string>;
|
|
112
|
+
private workingDirectoryRequest;
|
|
99
113
|
/**
|
|
100
114
|
* Send one JSON-RPC request and await its result.
|
|
101
115
|
* @param method - the wire method name.
|
package/lib/types/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @module @deepseek-ai/dsh-sdk-client
|
|
10
10
|
*/
|
|
11
|
-
export { DeepSeekHarness, HarnessSession } from './api.ts';
|
|
11
|
+
export { DeepSeekHarness, HarnessSession, validatedSessionEvent } from './api.ts';
|
|
12
12
|
export type { RunOptions } from './api.ts';
|
|
13
13
|
export { HarnessClient, RequestTimeoutError, SdkProtocolError, TransportClosedError, } from './client.ts';
|
|
14
14
|
export type { NotificationSubscription } from './client.ts';
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-sdk-client",
|
|
3
3
|
"description": "TypeScript client SDK for driving a DeepSeek Harness runtime subprocess over stdio JSON-RPC: the DeepSeekHarness high-level turns API and the lower-level HarnessClient",
|
|
4
|
-
"version": "0.2.
|
|
4
|
+
"version": "0.2.1-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -26,18 +26,19 @@
|
|
|
26
26
|
],
|
|
27
27
|
"license": "MIT",
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@deepseek-ai/dsh": "0.2.
|
|
29
|
+
"@deepseek-ai/dsh": "0.2.1-alpha.2"
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
|
-
"@deepseek-ai/dsh-llm": "0.2.
|
|
33
|
-
"@deepseek-ai/dsh-sdk-protocol": "0.2.
|
|
34
|
-
"@deepseek-ai/dsh-session": "0.2.
|
|
35
|
-
"@deepseek-ai/cordis": "~4.0.
|
|
32
|
+
"@deepseek-ai/dsh-llm": "0.2.1-alpha.2",
|
|
33
|
+
"@deepseek-ai/dsh-sdk-protocol": "0.2.1-alpha.2",
|
|
34
|
+
"@deepseek-ai/dsh-session": "0.2.1-alpha.2",
|
|
35
|
+
"@deepseek-ai/cordis": "~4.0.5-alpha.1"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
|
-
"@deepseek-ai/dsh-llm": "0.2.
|
|
39
|
-
"@deepseek-ai/dsh-sdk-protocol": "0.2.
|
|
40
|
-
"@deepseek-ai/dsh-session": "0.2.
|
|
41
|
-
"@deepseek-ai/cordis": "~4.0.
|
|
38
|
+
"@deepseek-ai/dsh-llm": "0.2.1-alpha.2",
|
|
39
|
+
"@deepseek-ai/dsh-sdk-protocol": "0.2.1-alpha.2",
|
|
40
|
+
"@deepseek-ai/dsh-session": "0.2.1-alpha.2",
|
|
41
|
+
"@deepseek-ai/cordis": "~4.0.5-alpha.1",
|
|
42
|
+
"@deepseek-ai/dsh-experimental-translator": "0.2.1-alpha.2"
|
|
42
43
|
}
|
|
43
44
|
}
|