docs: translate remaining READMEs
This commit is contained in:
6
packages/util/README.i18n.yaml
Normal file
6
packages/util/README.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
|
||||
README.md: 140df90571d84320fb4eb888508c67e60aa29a22
|
||||
README.zh.md: 4c16df2a56476c0a7c965a037389fa5ba231e273
|
||||
@@ -1,5 +1,7 @@
|
||||
# util/ — low-level shared utilities
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
Zero-dependency primitives shared across the other groups. A package lands here when it owns a tiny, foundational type or helper that several capability families need but that belongs to none of them — keeping it out of any one group avoids a capability package depending on an unrelated one just to reach a shared primitive. These are **support** packages: small, stable, and free of harness dependencies.
|
||||
|
||||
| Package | Role |
|
||||
|
||||
20
packages/util/README.zh.md
Normal file
20
packages/util/README.zh.md
Normal file
@@ -0,0 +1,20 @@
|
||||
# util/:底层共享工具
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
其他分组共享的零依赖原语。当某个微小的基础类型或辅助工具被多个功能家族所需,但又不属于任何一个家族时,它就位于此处。这样可避免一个功能包仅为使用共享原语而依赖不相关的功能包。这些都是**支持** 包:规模小、稳定,且不依赖 harness。
|
||||
|
||||
| 包 | 职责 |
|
||||
|---|---|
|
||||
| `brand/` | 仅包含类型的 `Branded<B>` 名义类型原语(无运行时代码,无 harness 依赖) |
|
||||
| `paths/` | 规范的单根 `DSH_HOME` 解析,以及 harness 用户数据的共享文件系统路径常量和辅助工具(无 harness 依赖) |
|
||||
| `timeout/` | 超时的时序/分类部分:`clampTimeout`/`deadline`/`timeoutOf`/`TimeoutReason`(纯函数,无 harness 依赖);终止机制保留在各个功能中 |
|
||||
| `retention/` | 有界的面向模型输出:`ItemRetainer`/`TextRetainer` 加上中性通知辅助工具(纯工具,无 harness 依赖);业务语义保留在各个工具中 |
|
||||
|
||||
`dsh-brand` 是规范示例:它只负责 `Branded<B>` 辅助工具,因此功能包可以为自己拥有的 id 添加品牌(`dsh-tasks` 的 `TaskId`、`dsh-session` 的 `SessionId` 等),而只需依赖 `dsh-brand`,无需仅为使用 `Branded` 而引入不相关的包。
|
||||
|
||||
`dsh-paths` 为每个包提供同一个可配置的 Harness 主目录,而不将这项横切事实归属给 bash、skill、telemetry 或组合 bundle。它优先解析显式值,其次是 `$DSH_HOME`,最后回退到 `~/.dsh`;返回绝对路径,但不缓存、创建或修改任何内容。harness 将所有用户数据保存在同一根目录下。
|
||||
|
||||
`dsh-timeout` 对超时家族采用相同结构:`dsh-bash` 和 `dsh-web-fetch-local` 都只依赖 `dsh-timeout`,便可将调用方的取消与 deadline 融合,然后区分「已超时」和「已取消」。它刻意只负责时序/分类部分,*终止*机制(对进程组发送 SIGKILL、拆除 fetch socket)保留在各个功能中,因为没有任何共享层可以负责每个功能的终止操作(见[超时库 Agent Note](../../.agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.md))。
|
||||
|
||||
`dsh-retention` 对有界工具输出采用同样的拆分方式:工具(`glob`/`grep`/`bash`/`web_fetch`/`web_search`)将项或文本送入 retainer,取回保留的内容以及被省略的精确内容;分组、退出码、提供方错误和恢复文案则仍由工具负责。它刻意只负责保留机制;`truncated` 是预算事实,绝不表示「检查不完整」状态(见[保留库 Agent Note](../../.agents/notes/implemented/architecture/2026-07-06-tool-result-retention-library.md))。
|
||||
6
packages/util/brand/README.i18n.yaml
Normal file
6
packages/util/brand/README.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
|
||||
README.md: 68401d95a31ed2122386794ad5256a5cd93bb2a6
|
||||
README.zh.md: c8b773937426487e67001bc133cf7fae3aea2c6e
|
||||
@@ -1,5 +1,7 @@
|
||||
# dsh-brand
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
The `Branded<B>` nominal-typing primitive — a tiny, **type-only** package (no runtime code, no harness-package dependency) shared by every package that owns a cross-boundary id.
|
||||
|
||||
## What `Branded` is
|
||||
|
||||
28
packages/util/brand/README.zh.md
Normal file
28
packages/util/brand/README.zh.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# dsh-brand
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
`Branded<B>` 名义类型原语:一个微小的**仅类型** 包(无运行时代码,无 harness 包依赖),由每个拥有跨边界 id 的包共享。
|
||||
|
||||
## `Branded` 是什么
|
||||
|
||||
品牌使 `SessionId` 和 `CallId` 这样结构相同的字符串在类型层面不可互换,尽管两者在运行时都是普通 `string`。
|
||||
|
||||
```ts
|
||||
import type { Branded } from '@deepseek-ai/dsh-brand'
|
||||
|
||||
export type SessionId = Branded<'SessionId'>
|
||||
|
||||
/** Brand a string as a SessionId (a plain cast — zero runtime cost). */
|
||||
export function SessionId(id: string): SessionId {
|
||||
return id as SessionId
|
||||
}
|
||||
```
|
||||
|
||||
构造操作通过所属包中针对每个 id 的工厂完成。比较、日志记录、JSON 序列化和协议格式与普通字符串表现相同;品牌会在编译时被擦除。
|
||||
|
||||
## 策略:为跨包边界的 id 添加品牌
|
||||
|
||||
包为自己拥有的 id 添加品牌:`CallId` 位于 `dsh-llm`,共享的 agent/会话 `SessionId` 位于 `dsh-session`,`TaskId` 位于 `dsh-tasks`。为可能被混淆的跨包 id 添加品牌,但无需为每个字符串都添加。
|
||||
|
||||
该包只负责原语。保持无依赖意味着,例如 `dsh-tasks` 可以为 `TaskId` 添加品牌,而无需仅为使用 `Branded` 而导入不相关的功能包。
|
||||
6
packages/util/paths/README.i18n.yaml
Normal file
6
packages/util/paths/README.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
|
||||
README.md: b28e684f3183d739c8e229a9b341801dbf345d86
|
||||
README.zh.md: 20cc033e4d0ee22d75c7ca315c462a7846146444
|
||||
@@ -1,5 +1,7 @@
|
||||
# dsh-paths
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
Shared filesystem path helpers for DeepSeek Harness user data.
|
||||
|
||||
## DSH home
|
||||
|
||||
24
packages/util/paths/README.zh.md
Normal file
24
packages/util/paths/README.zh.md
Normal file
@@ -0,0 +1,24 @@
|
||||
# dsh-paths
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
DeepSeek Harness 用户数据的共享文件系统路径辅助工具。
|
||||
|
||||
## DSH 主目录
|
||||
|
||||
`resolveDshHome()` 解析 DeepSeek Harness 的单根主目录。优先级从高到低为:显式配置的路径、`$DSH_HOME`、`~/.dsh`。harness 将所有用户数据保存在同一根目录下。
|
||||
|
||||
`dshHomeDisplay()` 以符号方式表示当前根目录,用于面向用户的路径:默认主目录表示为 `~/.dsh`,任何已配置的主目录表示为 `$DSH_HOME`。它绝不会泄露机器的绝对路径。
|
||||
|
||||
`DSH_HOME_DIR_NAME` 定义默认用户数据目录名:`.dsh`。
|
||||
|
||||
`defaultDshHome()` 使用 Node 的平台路径规则,将操作系统主目录与 `.dsh` 拼接,并返回默认 DeepSeek Harness 主目录。
|
||||
|
||||
`expandHomePath()` 使用操作系统主目录展开 `~`、`~/...` 和 Windows 风格的 `~\...` 前缀。它会保留非波浪号路径和 `~user/...` 原样不变。
|
||||
|
||||
该包刻意保持规模小且不依赖 harness,以便产品包共享用户数据路径约定,而不必彼此依赖。
|
||||
|
||||
## 已知限制与待完成工作
|
||||
|
||||
- **展开范围刻意保持狭窄**:只有单独的 `~`、`~/...` 和 `~\...` 使用当前操作系统主目录;`~alice/...` 等指定用户的形式、环境变量和 shell 表达式保持不变。
|
||||
- **辅助工具不会操作文件系统**:调用方仍负责目录创建、存在性检查、权限,以及对结果路径应用信任策略。
|
||||
6
packages/util/retention/README.i18n.yaml
Normal file
6
packages/util/retention/README.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
|
||||
README.md: d257075a67b35e92bce53a88fc6d002f4f4d5d9b
|
||||
README.zh.md: 433d512144612137fbfccf107cfe0987cec091fa
|
||||
@@ -1,5 +1,7 @@
|
||||
# dsh-retention
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
A dependency-light **retention** library: bounded model-facing output for tools that must cap how much context they return. A caller feeds items or text chunks into a bounded object, then gets the retained content plus exact omission metadata.
|
||||
|
||||
The library owns **only** the mechanical question *"what did we keep, and what did we omit?"*. Tool-specific code keeps its business semantics: file grouping, line numbering, exit codes, provider error states, per-line preview truncation, spill files, and the model-facing prose. This is the boundary the [Agent Note](../../../.agents/notes/implemented/architecture/2026-07-06-tool-result-retention-library.md) draws.
|
||||
|
||||
97
packages/util/retention/README.zh.md
Normal file
97
packages/util/retention/README.zh.md
Normal file
@@ -0,0 +1,97 @@
|
||||
# dsh-retention
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
一个轻依赖的**保留** 库:为必须限制返回上下文量的工具提供有界的面向模型输出。调用方将项或文本分片送入有界对象,然后取回保留的内容和精确的省略元数据。
|
||||
|
||||
该库**只** 负责这个机制问题:*「我们保留了什么,又省略了什么?」*。工具专用代码保留其业务语义:文件分组、行号、退出码、提供方错误状态、每行预览截断、spill 文件以及面向模型的文案。这就是 [Agent Note](../../../.agents/notes/implemented/architecture/2026-07-06-tool-result-retention-library.md) 划定的边界。
|
||||
|
||||
它是**库,而非服务或插件**:没有 `ctx`,不注册任何内容,不发出任何事件。状态只存在于每个 retainer(一次累积)中,绝不跨调用。工具包直接导入它。
|
||||
|
||||
## 对外接口
|
||||
|
||||
```ts
|
||||
import {
|
||||
ItemRetainer, TextRetainer,
|
||||
describeOmitted, formatRetentionNotice,
|
||||
} from '@deepseek-ai/dsh-retention'
|
||||
import type {
|
||||
Omitted, PushDecision, RetainedItems, RetainedText,
|
||||
ItemRetentionStrategy, TextRetentionStrategy, RetentionNotice,
|
||||
} from '@deepseek-ai/dsh-retention'
|
||||
```
|
||||
|
||||
| 导出项 | 职责 |
|
||||
|---|---|
|
||||
| `ItemRetainer<T>` | 限制有序逻辑单元(路径、grep 匹配项、来源)。v1 只支持 `head`。`push()` → `PushDecision`;`finish()` → `RetainedItems<T>`。 |
|
||||
| `TextRetainer` | 限制面向字节的文本流。`head` / `tail` / `headTail`,并在 `finish()` 时保留 UTF-8 边界。`push()` → `PushDecision`;`finish()` → `RetainedText`。 |
|
||||
| `describeOmitted(omitted, unit)` | 标准化的省略子句(`exact` 输出数量;`unknown` 不输出)。 |
|
||||
| `formatRetentionNotice(notice, recovery)` | 将标准化的省略子句与工具自有的恢复指引连接起来。 |
|
||||
| `Omitted` | `none` / `exact` / `unknown`:省略了多少内容。 |
|
||||
| `PushDecision` | `{ kept, truncated }`:每次 push 的保留结果。 |
|
||||
|
||||
## 资源模式
|
||||
|
||||
两个 retainer 使用独立名称,而不是同一个通用收集器,因为它们的**资源模型** 不同。
|
||||
|
||||
- **`ItemRetainer` 限制有序逻辑单元**。搜索工具可收集完整结果集用于 spill 文件恢复,同时只为面向模型的预览保留前 `maxItems` 项。因为调用方会继续送入每个已观察到的项,所以省略数量是精确的。
|
||||
- **`TextRetainer` 限制面向字节的文本**。`head`、`tail` 和 `headTail` 在 `finish()` 时保留 UTF-8 边界;`headTail` 是 `dsh-spill-policy` 用于围绕 spill 文件通知构建有界预览的形态。
|
||||
|
||||
## `truncated` 是预算事实,绝不表示「不完整」
|
||||
|
||||
`truncated` 表示*因为预算限制,retainer 省略了本可获得的内容*。它**不** 表示上游不完整。权限失败、跳过二进制文件、提供方部分失败、不可读候选项和无效 UTF-8 保留在工具领域字段中,绝不合并到 `truncated`。将两者混为一谈是该库命名最容易诱发的缺陷;务必保持分离。
|
||||
|
||||
## 字节,而非字符
|
||||
|
||||
文本上限和 `omittedBytes` 按**字节** 计数,以保证进程/正文安全(子进程 pipe 和 HTTP 正文都是字节流)。跨越码点的分片会被正确处理:`finish()` 会修剪每个切割位置的不完整码点,使返回文本绝不在边界引入替换字符;首尾两侧会分开解码,因此绝不会跨越被省略的中间部分重建码点。按字符或行限制的预览预算属于独立的工具职责。
|
||||
|
||||
## 工具映射
|
||||
|
||||
当前每个保留消费方都按下表映射到该库。广泛迁移不属于该库首次落地的范围;下表是预期形态。
|
||||
|
||||
| 工具 | Retainer 与策略 | 说明 |
|
||||
|---|---|---|
|
||||
| `glob` | `ItemRetainer<FsGlobEntry>`, `head` | 收集完整的已排序路径列表用于 spill 文件,同时在内联位置保留第一页。路径映射、已跳过候选项和 `incomplete` 保留在外部。 |
|
||||
| `grep` | `ItemRetainer<FlatGrepMatch>`, `head` | 收集匹配项用于 spill 文件,同时在内联位置保留第一页。每个匹配项的预览截断、分组、排序和 `incomplete` 保留在外部。 |
|
||||
| `bash` | `TextRetainer`, `tail` or `headTail` | 执行器仍负责 spill 文件、退出状态、信号、超时和后台任务。 |
|
||||
| `web_fetch` | `TextRetainer`, `head` or `headTail` | 提供方/资源上限保留为提供方事实;retainer 只提供保留文本和省略元数据。 |
|
||||
| `web_search` | `ItemRetainer<WebSearchSource>`, `head` | 当提供方返回的来源超过面向模型的结果应包含的数量时,标准化「来源已达上限」通知。 |
|
||||
|
||||
`read` **刻意不在 v1 范围内**。其 `read-render` 辅助工具负责文件专用的分页契约:`offset`/`limit`、行号、`totalLines`、偏移越界错误、每行预览截断、针对已选窗口的字节上限。这是行窗口渲染器,而非通用保留机制。单个 `Omitted` 数量无法表示行窗口两侧。
|
||||
|
||||
## 使用形态
|
||||
|
||||
```ts ignore-check
|
||||
// glob: keep the first page inline while still collecting the full list for spill.
|
||||
const retainer = new ItemRetainer<FsGlobEntry>({ kind: 'head', maxItems: globMaxResults })
|
||||
const allEntries: FsGlobEntry[] = []
|
||||
for await (const entry of candidates) {
|
||||
allEntries.push(entry)
|
||||
retainer.push(entry)
|
||||
}
|
||||
const { items, truncated, omitted } = retainer.finish()
|
||||
|
||||
// bash: keep a head + tail, read to process exit.
|
||||
const out = new TextRetainer({ kind: 'headTail', headBytes: headCap, tailBytes: tailCap })
|
||||
child.stdout.on('data', (chunk: Buffer) => { out.push(chunk) })
|
||||
const { text, omittedBytes } = out.finish()
|
||||
|
||||
// A footer: the library standardizes the omission clause; the tool owns recovery words.
|
||||
const footer = formatRetentionNotice(
|
||||
{ scope: 'grep', strategy: 'head', unit: 'items', limit: grepMaxMatches, kept: items.length, omitted },
|
||||
({ kept }) => `Results capped at ${kept}. Narrow the pattern, path, or include to see more.`,
|
||||
)
|
||||
```
|
||||
|
||||
## 模型体验
|
||||
|
||||
通过渲染保留内容和省略元数据的工具消费方间接影响模型。
|
||||
|
||||
#### KV 缓存影响
|
||||
|
||||
不直接导致失效;指定的消费方负责其引起的任何请求前缀变更。
|
||||
|
||||
## 已知限制与待完成工作
|
||||
|
||||
- **项保留只支持 `head`**:tail、head/tail、分页、分组和提供方完整性语义仍由工具负责。
|
||||
- **文本保留面向字节**:`read` 分页等行窗口和字符窗口需要单独的渲染器;切割可能会丢弃部分 UTF-8 边界字节,以保持返回文本有效。
|
||||
6
packages/util/timeout/README.i18n.yaml
Normal file
6
packages/util/timeout/README.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
|
||||
README.md: 11c55a45a1255e14fb551e42ba3965453dbd94ae
|
||||
README.zh.md: 699fb62a4fa19f97d234f83b21f639f61a9f0777
|
||||
@@ -1,5 +1,7 @@
|
||||
# dsh-timeout
|
||||
|
||||
English | [中文](README.zh.md)
|
||||
|
||||
The **timing-and-classification** half of a timeout — a zero-dependency library of pure functions (no runtime harness deps) shared by every capability that clamps a caller's timeout hint, arms a deadline, and later has to tell "timed out" apart from "cancelled".
|
||||
|
||||
It owns **no termination**. The signal it hands out only *notifies*; actually stopping the work stays in each capability, because that mechanism differs — bash SIGKILLs an OS process group, web tears down a `fetch` socket — and no shared layer can own all of them. This is the boundary the [Agent Note](../../../.agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.md) draws: share the timing/classification, keep the hard kill local.
|
||||
|
||||
70
packages/util/timeout/README.zh.md
Normal file
70
packages/util/timeout/README.zh.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# dsh-timeout
|
||||
|
||||
[English](README.md) | 中文
|
||||
|
||||
超时的**时序与分类** 部分:一个零依赖纯函数库(无运行时 harness 依赖),由每个需要限制调用方超时提示、启动 deadline,并在之后区分「已超时」与「已取消」的功能共享。
|
||||
|
||||
它**不负责终止**。它发出的信号只会*通知*;真正停止工作仍由各功能负责,因为机制各不相同:bash 对操作系统进程组发送 SIGKILL,web 拆除 `fetch` socket,没有任何共享层能够承担全部终止机制。[Agent Note](../../../.agents/notes/implemented/architecture/2026-07-06-timeout-deadline-library.md) 将边界划定为:共享时序/分类,将强制终止保留在本地。
|
||||
|
||||
它是**库,而非服务或插件**:没有 `ctx`,不注册任何内容,不持有状态,也不发出事件。「超时服务」必须了解如何停止每项功能的工作,这正是微内核要排除在共享层之外的知识。
|
||||
|
||||
## 对外接口
|
||||
|
||||
```ts
|
||||
import { clampTimeout, deadline, idleWatchdog, MAX_TIMER_DELAY_MS, timeoutOf, TimeoutReason } from '@deepseek-ai/dsh-timeout'
|
||||
```
|
||||
|
||||
| 导出项 | 职责 |
|
||||
|---|---|
|
||||
| `clampTimeout(requested, def, max, name?)` | 验证调用方可选的正有限提示,从 `def` 填充,并限制在 `max` 以内。如果提示不为正数或有限数,则抛出错误(包含 `name`)。 |
|
||||
| `deadline(upstream, timeoutMs, code)` | 将 `upstream` 取消与超时融合为一个 `AbortSignal`(`AbortSignal.any`);超时携带 `TimeoutReason`。`[Symbol.dispose]` 清除 timer。 |
|
||||
| `idleWatchdog(upstream, timeoutMs, code)` | 保持一个稳定的融合信号,并且只在受保护的异步迭代器 `next()` 尚未完成时启动。解析后取消启动;后续需求重新启动;dispose 清除;并发需求被拒绝。 |
|
||||
| `MAX_TIMER_DELAY_MS` | Node 在不将延迟限制为 1 毫秒时可调度的最大延迟(`2_147_483_647`)。拥有 timer 的配置不得超过该值。 |
|
||||
| `timeoutOf(signal \| { reason }, code?)` | 从已中止的信号/错误中恢复 `TimeoutReason`,否则返回 `undefined`,即超时与取消的分类器。传入 `code` 可仅匹配这个 deadline 的 timer(见下文的嵌套)。 |
|
||||
| `TimeoutReason` | 印在超时中止上的内部原因(`code` + `timeoutMs`)。它不是公开错误;提供方将其转换为自己的错误/字段。 |
|
||||
|
||||
## `timeoutMs <= 0` 哨兵值
|
||||
|
||||
`0` 是后端自有后台工作(bash `start()`)使用的「无超时」值,其可见范围为:**内部**。`deadline()` 不启动 timer,只转发 `upstream`;如果也没有 upstream,它将返回永不中止的信号和无操作 disposer,因此每个调用方都能保持同一种调用形态。外部请求提示会通过 `clampTimeout` 验证为**正有限数**,之后才进入 `deadline`,因此 `0` 绝不是面向模型/插件的「禁用超时」值。
|
||||
|
||||
## 使用形态
|
||||
|
||||
```ts
|
||||
import { deadline, timeoutOf } from '@deepseek-ai/dsh-timeout'
|
||||
|
||||
declare function runWork(options: { signal: AbortSignal }): Promise<unknown>
|
||||
|
||||
// Scope-lifetime consumer (foreground bash, one fetch): `using` disposes the timer.
|
||||
export async function runWithDeadline(upstream: AbortSignal | undefined, timeoutMs: number): Promise<unknown> {
|
||||
using d = deadline(upstream, timeoutMs, 'BASH_TIMEOUT')
|
||||
const outcome = await runWork({ signal: d.signal }) // work listens on d.signal and terminates itself
|
||||
const timedOut = timeoutOf(d.signal, 'BASH_TIMEOUT') !== undefined // classify the first abort, scoped to OUR code
|
||||
const aborted = d.signal.aborted && !timedOut // mutually exclusive: timeout won, or cancel did
|
||||
return { outcome, timedOut, aborted }
|
||||
}
|
||||
```
|
||||
|
||||
该信号只会*通知*;调用方必须连接自己的终止机制(`d.signal.addEventListener('abort', kill)`,或将 `d.signal` 传给 `fetch`)。让 promise 与 timer 竞速,会在子进程或 socket 泄漏的情况下就解析工具调用;发出信号则会强制要求存在真正的终止路径。
|
||||
|
||||
将你自己的 `code` 传给 `timeoutOf`,以便分类可在嵌套中组合:当你收到的 `upstream` *本身*就是 deadline 信号时(未来启动每次调用 deadline 的 `tools/execute` 中间件),如果外层 timer 首先触发,`AbortSignal.any` 会保留外层 `TimeoutReason`。将范围限定为你的 `code`,可将外部超时视为普通 upstream 取消,这才是你所属功能视角下的正确分类,而不会在本地 timer 尚未到期时就声称自己超时。
|
||||
|
||||
对于流式传输,创建一个 `idleWatchdog`,将其稳定的 `signal` 传入传输,并为每次提供方读取调用 `watchdog.next(iterator)`。间隔必须为正有限数,且不得超过 `MAX_TIMER_DELAY_MS`;否则 Node 会将其限制为 1 毫秒。它只测量尚未完成的需求,因此当下游代码进行渲染或在请求下一个分片前以其他方式等待时,timer 不会运行。该原语仍然只会通知,因此传输必须观察稳定信号;DeepSeek 和 pi-ai 适配器证明,超时会关闭它们的真实响应正文或 SDK 请求。
|
||||
|
||||
## 哪些操作不设置超时
|
||||
|
||||
本地文件 `read`/`write`/`edit` 不接受 `timeoutMs`:系统调用最多只能尽力中止,超时无法强制 `fsync`/`rename` 停止,而添加超时将成为违反显式优于隐式的默认值。详见 [`fs/`](../../fs/README.md)。
|
||||
|
||||
## 模型体验
|
||||
|
||||
通过 `dsh-timeout-policy` 等消费方间接影响模型;消费方可能会将提供方结果替换为已保留的超时错误,或抑制延迟结果。
|
||||
|
||||
#### KV 缓存影响
|
||||
|
||||
不直接导致失效;指定的消费方负责其引起的任何请求前缀变更。
|
||||
|
||||
## 已知限制与待完成工作
|
||||
|
||||
- **只发出通知**:deadline 无法停止忽略其信号的工作;每项功能仍需要自己的 socket/进程/任务终止路径。
|
||||
- **`timeoutMs <= 0` 是内部词汇**:只有在所属后端已解析策略后,它才会禁用本地 timer;绝不会作为面向模型/插件的公开开关。
|
||||
- **第一个中止原因决定分类**:当 upstream 取消早于本地 timer 发生时,即使自己的超时之后也会到期,该层也无法再报告。
|
||||
- **空闲 watchdog 不是总 deadline**:它针对每个尚未完成的迭代器需求重新启动,并刻意排除消费方的思考时间。
|
||||
Reference in New Issue
Block a user