docs: reserve seam for complete capabilities

This commit is contained in:
Turtle
2026-08-09 15:34:32 +08:00
parent 27ac49e687
commit dda02250f5
966 changed files with 2166 additions and 2159 deletions

View File

@@ -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/llm/README.md
README.md: 077ae600c89cff80cd71830e37bda00707c1d837
README.zh.md: 46d4aa8a6088b3d5f40718f0c2626783e6c05c4b
README.md: 15f90024abf3256560d67099af79be7d4e0ee310
README.zh.md: 5f733808ddd591f10e4f2ed437a3f59db3bfb679

View File

@@ -2,7 +2,7 @@
English | [中文](README.zh.md)
The LLM seam and its provider adapters. The interface package (`llm`) owns the abstract service, the content-block vocabulary, and the stream-chunk assembler; the adapters are concrete implementations that register on `ctx.llm`. All **product** packages.
The LLM seam and its provider adapters. The `llm` package owns both the Service Definition and Consumer roles: the abstract service, content-block vocabulary, and stream-chunk assembler. Provider adapters register on `ctx.llm`. All **product** packages.
| Package | Role | ctx key |
|---|---|---|

View File

@@ -1,8 +1,8 @@
# llm/ — LLM(大语言模型)能力家族
# llm/ — LLM 能力家族
[English](README.md) | 中文
LLM seam 及其提供方适配器。接口包(`llm`)负责抽象服务、内容块词汇和流式分片组装器适配器注册到 `ctx.llm` 的具体实现。这些全是**产品**包。
LLM(大语言模型)seam 及其提供方适配器。`llm` 包同时承担 Service Definition 和 Consumer 角色:抽象服务、内容块词汇和流式分片组装器。提供方适配器注册到 `ctx.llm`。这些全是**产品**包。
| 包 | 职责 | ctx key |
|---|---|---|
@@ -14,4 +14,4 @@ LLM seam 及其提供方适配器。接口包(`llm`)负责抽象服务、内
适配器在 seam 上注册提供方路由;重试与 token 测量仍是独立消费方。子 README 负责路由、元数据、回放和提供方协议细节;[LLM 架构决策](../../.agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.md)负责设计原理。
子系统参考——消息与内容块、模型请求、`StreamChunk` 协议、适配器约定adapter contract——见 [docs/subsystems/llm-streaming.md](../../docs/subsystems/llm-streaming.md)token 计量:[token-meter.md](../../docs/subsystems/token-meter.md));另见[孪生适配器](../../.agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.md)、[回放 token 计量](../../.agents/notes/implemented/architecture/2026-07-15-replay-token-meter-service.md)与[按路由模型上下文](../../.agents/notes/implemented/architecture/2026-07-20-routed-model-context-and-compaction-policy.md) Agent Note。
子系统参考——消息与内容块、模型请求、`StreamChunk` 协议、适配器约定——见 [docs/subsystems/llm-streaming.md](../../docs/subsystems/llm-streaming.md)token 计量:[token-meter.md](../../docs/subsystems/token-meter.md));另见[孪生适配器](../../.agents/notes/implemented/architecture/2026-06-13-twin-llm-adapters.md)、[回放 token 计量](../../.agents/notes/implemented/architecture/2026-07-15-replay-token-meter-service.md)与[按路由模型上下文](../../.agents/notes/implemented/architecture/2026-07-20-routed-model-context-and-compaction-policy.md) Agent Note。

View File

@@ -69,7 +69,7 @@ export interface DeepSeekConnectionOptions {
retryPolicy: ResolvedRetryPolicy
}
/** Constructor options for {@link DeepSeekAdapter}: the two resolution seams the plugin owns. */
/** Constructor options for {@link DeepSeekAdapter}: the two resolution hooks the plugin owns. */
export interface DeepSeekAdapterOptions {
/** Current validated connection facts; called once per operation. */
options: () => DeepSeekConnectionOptions
@@ -298,7 +298,7 @@ export class DeepSeekAdapter extends LlmAdapter {
// fetch wraps every transport failure (DNS, refused connection, TLS,
// proxy) in a bare `TypeError: fetch failed` whose actionable detail
// lives on `cause`. Wrapping with the endpoint and chaining the cause
// lets `errorChain` render the full diagnosis at every reporting seam.
// lets `errorChain` render the full diagnosis at every reporting boundary.
throw new LlmError(
`DeepSeek API request to ${connection.baseURL} failed`,
'TRANSPORT',

View File

@@ -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/llm/llm-pi-ai/README.md
README.md: 4ad669344056a8290057cd39cbde56b0a2d80ba4
README.zh.md: 96e1ef2dd3219e8b1fe0d5afbf5c784d9c3e42d5
README.md: 7151fdf5b63f48e625d00a92dc42aa24b7de2f31
README.zh.md: 0bfd5c706e01dd4448edb9cf0eec812831f68093

View File

@@ -194,4 +194,4 @@ Recorded response content appends to the next request and does not invalidate it
- **`GenerateOptions.stop` is unsupported** — pi-ai's common stream options cannot guarantee stop-sequence behavior across providers, so the adapter rejects the field.
- **In-history `system` messages use pi-ai's common context conversion** — provider-specific placement follows pi-ai rather than a harness-owned wire override.
- **Provider HTTP status is unavailable** — pi-ai error events do not expose a stable HTTP status across providers; failures expose only stable harness error codes.
- **Retry policy is provider-owned, not an SDK retry** — each provider profile may configure nested `retryPolicy`, which `dsh-llm-retry` executes at the agent failed-step seam; pi-ai SDK retries stay disabled so durable agent steps and `llm/retry` events own every visible attempt, and direct `ctx.llm.stream()` calls remain single-attempt.
- **Retry policy is provider-owned, not an SDK retry** — each provider profile may configure nested `retryPolicy`, which `dsh-llm-retry` executes at the agent failed-step extension point; pi-ai SDK retries stay disabled so durable agent steps and `llm/retry` events own every visible attempt, and direct `ctx.llm.stream()` calls remain single-attempt.

View File

@@ -194,4 +194,4 @@ pi-ai 事件会变为 harness 推理、文本、工具调用、usage 与 finish
- **不支持 `GenerateOptions.stop`**pi-ai 的通用流选项无法保证所有提供方都支持 stop sequence因此适配器会拒绝该字段。
- **历史中的 `system` 消息使用 pi-ai 通用上下文转换**:提供方特定位置由 pi-ai 决定,而非由 harness 拥有的协议覆盖决定。
- **无法获取提供方 HTTP 状态**pi-ai 错误事件不会在所有提供方上公开稳定 HTTP 状态;失败只公开稳定 harness 错误 code。
- **重试策略由提供方持有,而不是 SDK 重试**:每个提供方 profile 都可以配置嵌套的 `retryPolicy`,由 `dsh-llm-retry` 在 agent 的失败步骤 seam 上执行pi-ai SDK 重试仍保持禁用,因此持久化的 agent 步骤与 `llm/retry` 事件记录每次可见尝试,直接 `ctx.llm.stream()` 调用仍只尝试一次。
- **重试策略由提供方持有,而不是 SDK 重试**:每个提供方 profile 都可以配置嵌套的 `retryPolicy`,由 `dsh-llm-retry` 在 agent 的失败步骤扩展点上执行pi-ai SDK 重试仍保持禁用,因此持久化的 agent 步骤与 `llm/retry` 事件记录每次可见尝试,直接 `ctx.llm.stream()` 调用仍只尝试一次。

View File

@@ -59,7 +59,7 @@ interface PiAiSnapshot {
models: Models
}
/** Constructor options for {@link PiAiAdapter}: the two resolution seams the plugin owns. */
/** Constructor options for {@link PiAiAdapter}: the two resolution hooks the plugin owns. */
export interface PiAiAdapterOptions {
/** Current validated profiles by provider route; called once per operation. */
profiles: () => ReadonlyMap<string, ResolvedPiAiProviderProfile>

View File

@@ -1,6 +1,6 @@
/**
* Provider-routed model-request retry policy on the agent loop's request
* recovery seam. Each scheduled retry is durable before its cancellable wait.
* recovery extension point. Each scheduled retry is durable before its cancellable wait.
*
* @module @deepseek-ai/dsh-llm-retry
*/
@@ -57,7 +57,7 @@ function validateConfig(config: Config): void {
throw new Error(`llm-retry: unknown key "${key}"`)
}
/** Non-serializable seams used to make timing policy deterministic in tests. */
/** Non-serializable hooks used to make timing policy deterministic in tests. */
export interface RetryInternals {
/** Random sample in the inclusive zero-to-one range used for jitter. */
random?: () => number
@@ -116,7 +116,7 @@ function cancellableDelay(delayMs: number, signal: AbortSignal): Promise<boolean
* Install provider-routed normal or unbounded request recovery.
* @param ctx - plugin context that owns the listener and active waits.
* @param config - empty executor config; provider registrations own policy.
* @param internals - non-serializable deterministic seams for tests.
* @param internals - non-serializable deterministic hooks for tests.
*/
export function apply(ctx: Context, config: Config = {}, internals: RetryInternals = {}): void {
validateConfig(config)

View File

@@ -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/llm/llm/README.md
README.md: a437a689e934701b925dbf5a39a912c3af7dd46b
README.zh.md: 7ed0c9c8a93e102b3d350be48be3a07e30011582
README.md: 0b463c73175e46d20e9c8f719b55b3fa4f56fde2
README.zh.md: cbabeb72216e9fc92b74d6c216d7f7b7154bc1a8

View File

@@ -71,7 +71,7 @@ Every adapter that puts a credential in an HTTP header judges it the same way be
- `LlmAdapter` — abstract base class for provider adapters. The only required method is `stream()`.
- `BlockAssembler` — incrementally assembles raw chunks into complete content blocks and can create an identified, frozen assistant message from them. The agent loop feeds it raw chunks (logging them for replay) while reading the assembled blocks for history.
- `HarnessError` — base class for the harness error taxonomy: a stable `code` string (distinct from the human `message`) plus `cause` chaining. Lives here, in the leaf package every other imports, so a single base is shared without a new dependency edge. Per-package errors (`LlmError`, `ToolArgsError`, `InvariantError`, …) extend it. `isHarnessError(value)` narrows at seams.
- `HarnessError` — base class for the harness error taxonomy: a stable `code` string (distinct from the human `message`) plus `cause` chaining. Lives here, in the leaf package every other imports, so a single base is shared without a new dependency edge. Per-package errors (`LlmError`, `ToolArgsError`, `InvariantError`, …) extend it. `isHarnessError(value)` narrows at process boundaries.
- `LlmError` — extends `HarnessError`; its stable `code` string (`NO_ADAPTER`, `DUPLICATE_ADAPTER`, and adapter codes like `AUTH`/`RATE_LIMIT`) matches its frozen serializable `failure.code`. The payload may also retain validated status, `Retry-After`, and branded provider request id facts; policy remains outside the error.
- `errorChain(value)` — renders a thrown value with its full `cause` chain and AggregateError members for diagnostic surfaces (UI notices, logger lines, durable `turn/end` messages), so transport wrappers like undici's `TypeError: fetch failed` surface the underlying `ECONNREFUSED`/DNS/TLS detail instead of masking it. Rendering only — route on `code`, never by parsing the result.
- `CONTEXT_WINDOW_EXCEEDED_CODE` — the provider-neutral code both DeepSeek adapters use when a request exceeds the model context window, regardless of thrown-HTTP versus in-band finish delivery. `isContextWindowExceededError(detail)` is their shared conservative classifier for OpenAI-compatible provider detail.
@@ -93,7 +93,7 @@ Pass-through; the registry preserves the assembled request prefix, while the sel
## Known Limitations and Deferred Work
- **No retry execution, caching, or rate limiting ships in this service** — provider registration stores retry policy, but `llm/stream` remains a single-attempt call-wrapper seam. The agent loop separately offers proven model-request failures to `agent/request-error`, whose default preserves the original failure; `@deepseek-ai/dsh-llm-retry` is the optional executor loaded by the shared example spine.
- **No retry execution, caching, or rate limiting ships in this service** — provider registration stores retry policy, but `llm/stream` remains a single-attempt call wrapper. The agent loop separately offers proven model-request failures to `agent/request-error`, whose default preserves the original failure; `@deepseek-ai/dsh-llm-retry` is the optional executor loaded by the shared example spine.
- **`GenerateOptions` sampling is `temperature`/`maxTokens`/`stop` only** — no `tool_choice`, `top_p`, or penalty fields; the vocabulary grows when a producer lands ([dropped inert knobs](../../../.agents/notes/archived/simplification/2026-07-04-drop-inert-request-knobs.md)).
- **Producer-gated variants stay out until produced** — `prefill`, per-tool `strict`, block `cache` hints, and the `agent` message-source variant were pruned as producerless ([Agent Note](../../../.agents/notes/archived/simplification/2026-07-04-prune-producerless-vocabulary-variants.md)).
- **`BlockAssembler` handles core block kinds only** — a plugin-added block type whose stream is never closed by `block-end` makes `blocks()` throw.

View File

@@ -71,7 +71,7 @@
- `LlmAdapter`:提供方适配器的抽象基类。唯一必需方法是 `stream()`
- `BlockAssembler`:将原始分片逐步组装为完整内容块,并能据此创建带标识且冻结的 assistant 消息。agent loop 向它提供原始分片(同时记录以供回放),并读取已组装块以构建历史。
- `HarnessError`harness 错误分类体系的基类,包含稳定 `code` 字符串(与面向人的 `message` 不同)加 `cause` 链接。它位于所有其他包都从中导入的叶子包中,因此可以共享单一基类,无需新的依赖边。各包的错误(`LlmError``ToolArgsError``InvariantError` 等)都继承自它。`isHarnessError(value)` seam 处收窄类型。
- `HarnessError`harness 错误分类体系的基类,包含稳定 `code` 字符串(与面向人的 `message` 不同)加 `cause` 链接。它位于所有其他包都从中导入的叶子包中,因此可以共享单一基类,无需新的依赖边。各包的错误(`LlmError``ToolArgsError``InvariantError` 等)都继承自它。`isHarnessError(value)`进程边界处收窄类型。
- `LlmError`:继承自 `HarnessError`;其稳定 `code` 字符串(`NO_ADAPTER``DUPLICATE_ADAPTER``AUTH``RATE_LIMIT` 等适配器 code与冻结可序列化 `failure.code` 匹配。Payload 还可以保留已验证状态、`Retry-After` 和品牌化提供方请求 id 事实;策略位于错误之外。
- `errorChain(value)`:渲染抛出值的完整 `cause` 链与 AggregateError 成员,供诊断表层使用,包括 UI 通知、logger 行和持久 `turn/end` 消息。因此 undici 的 `TypeError: fetch failed` 等传输包装层会显示底层 `ECONNREFUSED`DNSTLS 详细信息,而不是将其遮蔽。该函数只负责渲染:请按 `code` 路由,绝不解析结果。
- `CONTEXT_WINDOW_EXCEEDED_CODE`:当请求超过模型上下文窗口时,无论通过 HTTP 异常抛出还是带内 finish 交付,两个 DeepSeek 适配器都使用的提供方无关 code。`isContextWindowExceededError(detail)` 是它们针对 OpenAI 兼容提供方详细信息的共享保守分类器。
@@ -93,7 +93,7 @@
## 已知限制与暂缓事项
- **本服务不执行重试、缓存或速率限制**:提供方注册会存储重试策略,但 `llm/stream` 仍是单次尝试调用包装 seam。agent loop 会将已验证模型请求失败单独提供给 `agent/request-error`,其默认行为是保留原始失败;`@deepseek-ai/dsh-llm-retry` 是共享示例主干加载的可选执行器。
- **本服务不执行重试、缓存或速率限制**:提供方注册会存储重试策略,但 `llm/stream` 仍是单次尝试调用包装。agent loop 会将已验证模型请求失败单独提供给 `agent/request-error`,其默认行为是保留原始失败;`@deepseek-ai/dsh-llm-retry` 是共享示例主干加载的可选执行器。
- **`GenerateOptions` 采样只包含 `temperature``maxTokens``stop`**:没有 `tool_choice``top_p` 或 penalty 字段;有产生方落地时词汇才会增长(见 [已删除惰性旋钮](../../../.agents/notes/archived/simplification/2026-07-04-drop-inert-request-knobs.md))。
- **受产生方约束的变体在实际产生前不会加入**`prefill`、每工具 `strict`、块 `cache` 提示与 `agent` 消息源变体因没有产生方而被剪除(见 [Agent Note](../../../.agents/notes/archived/simplification/2026-07-04-prune-producerless-vocabulary-variants.md))。
- **`BlockAssembler` 只处理核心块类型**:如果插件添加块类型的流从未由 `block-end` 关闭,`blocks()` 会抛出异常。

View File

@@ -154,7 +154,7 @@ export function errorChain(value: unknown): string {
}
/**
* Narrow an arbitrary thrown value to a HarnessError (for `instanceof` at seams).
* Narrow an arbitrary thrown value to a HarnessError (for `instanceof` at runtime boundaries).
* @param value - the caught value (`unknown` in catch clauses).
* @returns true only for real instances; duck-typed or cross-realm errors do not narrow.
*/

View File

@@ -2,7 +2,7 @@
* Provider-owned request-retry policy configuration and resolution.
*
* Adapters expose one resolved policy per registered provider route; the
* optional dsh-llm-retry plugin executes it on the agent's failed-step seam.
* optional dsh-llm-retry plugin executes it on the agent's failed-step extension point.
*
* @module @deepseek-ai/dsh-llm/retry-policy
*/

View File

@@ -5,7 +5,7 @@ import type { AppIdentity } from '@deepseek-ai/dsh-llm'
const manifest = createRequire(import.meta.url)('../package.json') as { version: string }
/** A white-label identity exercising every override seam. */
/** A white-label identity exercising every override hook. */
const forkIdentity: AppIdentity = {
product: 'fork-agent',
version: '9.9.9',

View File

@@ -10,7 +10,7 @@ import { BlockAssembler, deepFreeze } from '@deepseek-ai/dsh-llm'
import type { Message, TokenUsage } from '@deepseek-ai/dsh-llm'
import type { EpochHeader, Session, SessionEvent } from '@deepseek-ai/dsh-session'
import { canonicalHeader, headerEquals, isSurfaceEvent } from '@deepseek-ai/dsh-session'
// Type-only: resolves the optional projection registry Context seam.
// Type-only: resolves the optional projection registry Context declaration.
import type {} from '@deepseek-ai/dsh-session-projection'
import type {
TokenMeasurement,