fix(subagent): complete output selection contract
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 packages/subagent/subagent-dsh-sdk/README.md
|
||||
README.md: 80f5c40a2c949b7c2a638ec19c02950e8cd69f0b
|
||||
README.zh.md: b34421dbbf2d06b7c9236776aabf19ba8005204e
|
||||
README.md: 493bb187d45c7654958cfb3dbbe1dee6bb21b368
|
||||
README.zh.md: 2e1d9b1e602f2180d20d43fe8c358163ec4ec024
|
||||
|
||||
@@ -10,7 +10,7 @@ The SDK provider runs each subagent as a complete DeepSeek Harness runtime in a
|
||||
|
||||
The working directory resolves exactly like the ACP backend, through the seam's shared out-of-process helpers ([`dsh-subagent`](../subagent/README.md)): the configured `cwd` override when set (validated once at load), else the delegating parent session's cwd — never the server process's own cwd. The resolved path becomes the child process cwd and the workspace cwd of its SDK session.
|
||||
|
||||
The returned run id is minted in the parent namespace; the child runtime's session id exists only inside the child process. After publication the provider owns one SDK activity and reads the child's answer from its session events: the last complete NON-EMPTY `assistant/message` (an empty-content message hosts only usage and is skipped), or the `text-delta` stream accumulated before the activity was cut short — a partial answer survives cancel and error paths.
|
||||
The returned run id is minted in the parent namespace; the child runtime's session id exists only inside the child process. After publication the provider owns one SDK activity and reads the child's answer from its session events: the last complete non-empty `assistant/message` (an empty-content message that records usage is skipped), or the accumulated `text-delta` stream when no such message exists. Partial output remains available after cancellation or an error.
|
||||
|
||||
`dispose()` is idempotent: it settles the result locally as `aborted` (there is no wire-level prompt cancel), then closes the runtime — a bounded protocol `shutdown` request followed by the shared stdin-EOF → SIGTERM → SIGKILL ladder to actual exit.
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ SDK 提供方会在全新的子进程中把每个 subagent 作为完整的 DeepS
|
||||
|
||||
工作目录的解析与 ACP 后端完全一致,并使用 seam 共享的进程外辅助工具([`dsh-subagent`](../subagent/README.md)):设置了 `cwd` 覆盖值时使用该值(加载时校验一次),否则使用发起委派的父会话 cwd,绝不使用服务器进程自身的 cwd。解析出的路径同时成为子进程 cwd 和其 SDK 会话的工作区 cwd。
|
||||
|
||||
返回的 run id 在父级命名空间中生成;子运行时的会话 id 只存在于子进程内部。发布后,提供方拥有一段 SDK 活动,并从子会话事件中读取答案:最后一条完整且**非空**的 `assistant/message`(空内容消息仅承载 usage,会被跳过),或该活动中断前已经累积的 `text-delta` 流;部分答案在取消和错误路径上都得以保留。
|
||||
返回的 run id 在父级命名空间中生成;子运行时的会话 id 只存在于子进程内部。发布后,提供方拥有一段 SDK 活动,并从子会话事件中读取答案:最后一条完整且非空的 `assistant/message`(记录 usage 的空内容消息会被跳过);若没有这类消息,则取累积的 `text-delta` 流。取消或发生错误后,部分输出仍然可用。
|
||||
|
||||
`dispose()`(资源释放)是幂等的:先在本地把结果确定为 `aborted`(协议层面没有提示词取消机制),再关闭运行时,即先发出一次有界的协议 `shutdown` 请求,随后通过共享的 stdin-EOF → SIGTERM → SIGKILL 阶梯使进程实际退出。
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ describe('dsh-subagent-dsh-sdk provider', () => {
|
||||
await ctx.fiber.dispose()
|
||||
})
|
||||
|
||||
it('keeps streamed text when the terminal message is an EMPTY usage-only step', async () => {
|
||||
it('keeps streamed text when the terminal message is an empty usage-only step', async () => {
|
||||
// The child streams its answer, then emits an empty-content
|
||||
// assistant/message (the harness loop appends one to host usage on a
|
||||
// max-tokens step that assembled no text blocks). The empty message is
|
||||
|
||||
Reference in New Issue
Block a user