refactor(attachment): 求解器留在 llm-deepseek,存储层只接收目标尺寸
ImageRequestPolicy 改为 ImageRequestTarget,只含目标宽、高和字节目标;dsh-attachment 删除 token-grid 投影联合和 tokenGridProjection,只保留提供方无关的 requestImageDimensions 与 longEdgeDimensions。v41 求解器回到 llm-deepseek 的 image-tokens.ts,新增 deepSeekRequestImageDimensions,resolveRequestImageTarget 为每张图算出目标并加 4096 单边上限;pi-ai 路由按自身像素预算推导目标。 按 review 意见修正:v41 计价 Note 里已删除常量的过期句子就地改写;ProjectedDimensions 登记到 attachment 子系统页与 type-equiv 清单;Note 区分发送尺寸与提供方补齐后的网格;短边取整的措辞改为「按路由预测」。
This commit is contained in:
1 parent
e17a736cc3
commit
ba30b73f7b
52 files changed
+463
-552
No files matched your search
@@ -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: 259cbe8afe509cf448a54fa9fcddf297d4f2f588
|
||||
config-catalog.zh.md: 49e1064239f20fc6236c3dde6f2698791a9a1183
|
||||
config-catalog.md: de3b5c686121781860fae92a20f02e848508ee55
|
||||
config-catalog.zh.md: 9a2f1e86168ce5ebfe6a07ea258b4a94bba4c3fc
|
||||
@@ -1098,7 +1098,7 @@ export interface DeepSeekCatalogModel {
|
||||
|
||||
Depends on: [`ModelModality`](../packages/llm/llm/src/index.ts) · [`RetryPolicyConfig`](../packages/llm/llm/src/index.ts) · [`SystemPromptUpdate`](../packages/llm/llm/src/index.ts)
|
||||
|
||||
Source: [`packages/llm/llm-deepseek/src/index.ts:128`](../packages/llm/llm-deepseek/src/index.ts)
|
||||
Source: [`packages/llm/llm-deepseek/src/index.ts:129`](../packages/llm/llm-deepseek/src/index.ts)
|
||||
|
||||
<a id="deepseek-aidsh-llm-pi-ai"></a>
|
||||
|
||||
|
||||
@@ -1100,7 +1100,7 @@ export interface DeepSeekCatalogModel {
|
||||
|
||||
依赖:[`ModelModality`](../packages/llm/llm/src/index.ts) · [`RetryPolicyConfig`](../packages/llm/llm/src/index.ts) · [`SystemPromptUpdate`](../packages/llm/llm/src/index.ts)
|
||||
|
||||
来源:[`packages/llm/llm-deepseek/src/index.ts:128`](../packages/llm/llm-deepseek/src/index.ts)
|
||||
来源:[`packages/llm/llm-deepseek/src/index.ts:129`](../packages/llm/llm-deepseek/src/index.ts)
|
||||
|
||||
<a id="deepseek-aidsh-llm-pi-ai"></a>
|
||||
|
||||
|
||||
@@ -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/attachment.md
|
||||
attachment.md: bbcf438646eb4cae78ef5b86ccbf9e04b927fa55
|
||||
attachment.zh.md: 0e3c58fc59cb319bde681bdfa7124c852cb6da19
|
||||
attachment.md: db1c1cfa15f5d0815236f96b6472cbbd864decbd
|
||||
attachment.zh.md: 82379de5049012c0912734dc94257d6b8f354ad1
|
||||
@@ -126,52 +126,22 @@ interface StoredImageAttachment {
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Aspect-preserving downscale rule of one request image; small images are never enlarged. */
|
||||
type ImageRequestProjection =
|
||||
| {
|
||||
/** Hard cap on width multiplied by height. */
|
||||
kind: 'pixel-budget'
|
||||
/** Maximum width multiplied by height after projection. */
|
||||
maxPixels: number
|
||||
}
|
||||
| {
|
||||
/**
|
||||
* Largest aspect-preserving patch grid whose token count
|
||||
* `rows × (columns + 1) + 2` fits `maxTokens`; the DeepSeek published vision layout.
|
||||
*/
|
||||
kind: 'token-grid'
|
||||
/** Patch edge in pixels; a downscaled edge is a whole number of patches. */
|
||||
patchSize: number
|
||||
/** Patches per token cell along each axis. */
|
||||
downsampleRatio: number
|
||||
/** Token cap for one image. */
|
||||
maxTokens: number
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Dimensions a `token-grid` projection retains for one image and the tokens it charges. */
|
||||
interface TokenGridProjection {
|
||||
/** Retained width: the patch-padded source when it fits, otherwise the solved width. */
|
||||
/** Deterministic request-image target selected by one exact model route for one attachment. */
|
||||
interface ImageRequestTarget {
|
||||
/** Target width in pixels; a target above the source keeps the source width. */
|
||||
width: number
|
||||
/** Retained height: the patch-padded source when it fits, otherwise the solved height. */
|
||||
/** Target height in pixels; a target above the source keeps the source height. */
|
||||
height: number
|
||||
/** Tokens charged for the retained grid. */
|
||||
tokens: number
|
||||
/** Whether the patch-padded source already fits `maxTokens` without downscaling. */
|
||||
unscaled: boolean
|
||||
/** Encoded-byte target before base64 expansion or Files API upload; the smallest quality-ladder output is kept when no quality fits. */
|
||||
maxBytes: number
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Deterministic request-image policy selected by one exact model route. */
|
||||
interface ImageRequestPolicy {
|
||||
/** Downscale rule applied before the per-side cap. */
|
||||
projection: ImageRequestProjection
|
||||
/** Maximum width and maximum height after projection; omission bounds the long edge by the projection alone. */
|
||||
maxDimension?: number
|
||||
/** Encoded-byte target before base64 expansion or Files API upload; the smallest quality-ladder output is kept when no quality fits. */
|
||||
maxBytes: number
|
||||
/** Integer width and height of one projected image. */
|
||||
interface ProjectedDimensions {
|
||||
width: number
|
||||
height: number
|
||||
}
|
||||
```
|
||||
|
||||
@@ -197,7 +167,7 @@ interface RequestImageAttachment {
|
||||
}
|
||||
```
|
||||
|
||||
`saveImage()` prepares and atomically commits a provider-independent normalized attachment before returning its `ImageAttachmentRef`. `saveImages()` prepares every validated attachment once before publishing the batch, so validation rejection leaves no partial objects and publication does not repeat decoding or quality selection. `admitPromptContent()` accepts the complete ordered Host prompt after file receipt resolution, replaces base64 image uploads with durable references, and passes durable file references unchanged. `admitEncodedImages()` supports other wire entries and delegates count, aggregate-byte, and ordered batch admission to `saveImages()`. `admitEncodedFile()` gives encoded protocol adapters the same service-owned canonical-base64 admission, and `isAttachmentError()` lets those adapters recognize stable attachment failures without importing implementation helpers. `readImage()` verifies a normalized attachment from an authorized session path. `imageHostPath()` exposes only the provider-owned host object location; it does not decide whether the current tool execution world can read it. `readImageRequest()` derives and caches one deterministic request version under an exact route projection rule, optional per-side cap, and encoded-byte target. That version contains encoded bytes and metadata but no execution-world path. New entries are fully decoded before publication, while cache hits use a bounded metadata probe. Callers use `Promise.all` over the singular method when they need an ordered batch. The local implementation lazily encodes preferred candidates, singleflights equal request identities, lets each waiter cancel independently, stops shared work when no waiter remains, and bounds all transforms with its instance-level limiter, which defaults to two simultaneous transformations. The service is retention-neutral: resumed and forked sessions may share objects, so reference-aware garbage collection is deferred rather than tied to one session's deletion.
|
||||
`saveImage()` prepares and atomically commits a provider-independent normalized attachment before returning its `ImageAttachmentRef`. `saveImages()` prepares every validated attachment once before publishing the batch, so validation rejection leaves no partial objects and publication does not repeat decoding or quality selection. `admitPromptContent()` accepts the complete ordered Host prompt after file receipt resolution, replaces base64 image uploads with durable references, and passes durable file references unchanged. `admitEncodedImages()` supports other wire entries and delegates count, aggregate-byte, and ordered batch admission to `saveImages()`. `admitEncodedFile()` gives encoded protocol adapters the same service-owned canonical-base64 admission, and `isAttachmentError()` lets those adapters recognize stable attachment failures without importing implementation helpers. `readImage()` verifies a normalized attachment from an authorized session path. `imageHostPath()` exposes only the provider-owned host object location; it does not decide whether the current tool execution world can read it. `readImageRequest()` derives and caches one deterministic request version at an exact route-chosen target size and encoded-byte target. That version contains encoded bytes and metadata but no execution-world path. New entries are fully decoded before publication, while cache hits use a bounded metadata probe. Callers use `Promise.all` over the singular method when they need an ordered batch. The local implementation lazily encodes preferred candidates, singleflights equal request identities, lets each waiter cancel independently, stops shared work when no waiter remains, and bounds all transforms with its instance-level limiter, which defaults to two simultaneous transformations. The service is retention-neutral: resumed and forked sessions may share objects, so reference-aware garbage collection is deferred rather than tied to one session's deletion.
|
||||
|
||||
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
|
||||
|
||||
@@ -320,11 +290,11 @@ fileHostPath(ref: FileAttachmentRef): string | undefined
|
||||
/**
|
||||
* Generate or read one deterministic model-request version from the stored normalized image.
|
||||
* @param ref - durable provider-independent normalized attachment reference.
|
||||
* @param policy - route projection, optional per-side cap, and byte target; an unmet target yields the smallest ladder output.
|
||||
* @param target - route-chosen dimensions and byte target; an unmet byte target yields the smallest ladder output.
|
||||
* @param signal - optional cancellation.
|
||||
* @returns request bytes and the cache/upload identity covering every transform input.
|
||||
*/
|
||||
readImageRequest( ref: ImageAttachmentRef, policy: ImageRequestPolicy, signal?: AbortSignal, ): Promise<RequestImageAttachment>
|
||||
readImageRequest( ref: ImageAttachmentRef, target: ImageRequestTarget, signal?: AbortSignal, ): Promise<RequestImageAttachment>
|
||||
```
|
||||
|
||||
Source: [`packages/attachment/attachment/src/index.ts`](../../packages/attachment/attachment/src/index.ts)
|
||||
|
||||
@@ -126,52 +126,22 @@ interface StoredImageAttachment {
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Aspect-preserving downscale rule of one request image; small images are never enlarged. */
|
||||
type ImageRequestProjection =
|
||||
| {
|
||||
/** Hard cap on width multiplied by height. */
|
||||
kind: 'pixel-budget'
|
||||
/** Maximum width multiplied by height after projection. */
|
||||
maxPixels: number
|
||||
}
|
||||
| {
|
||||
/**
|
||||
* Largest aspect-preserving patch grid whose token count
|
||||
* `rows × (columns + 1) + 2` fits `maxTokens`; the DeepSeek published vision layout.
|
||||
*/
|
||||
kind: 'token-grid'
|
||||
/** Patch edge in pixels; a downscaled edge is a whole number of patches. */
|
||||
patchSize: number
|
||||
/** Patches per token cell along each axis. */
|
||||
downsampleRatio: number
|
||||
/** Token cap for one image. */
|
||||
maxTokens: number
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Dimensions a `token-grid` projection retains for one image and the tokens it charges. */
|
||||
interface TokenGridProjection {
|
||||
/** Retained width: the patch-padded source when it fits, otherwise the solved width. */
|
||||
/** Deterministic request-image target selected by one exact model route for one attachment. */
|
||||
interface ImageRequestTarget {
|
||||
/** Target width in pixels; a target above the source keeps the source width. */
|
||||
width: number
|
||||
/** Retained height: the patch-padded source when it fits, otherwise the solved height. */
|
||||
/** Target height in pixels; a target above the source keeps the source height. */
|
||||
height: number
|
||||
/** Tokens charged for the retained grid. */
|
||||
tokens: number
|
||||
/** Whether the patch-padded source already fits `maxTokens` without downscaling. */
|
||||
unscaled: boolean
|
||||
/** Encoded-byte target before base64 expansion or Files API upload; the smallest quality-ladder output is kept when no quality fits. */
|
||||
maxBytes: number
|
||||
}
|
||||
```
|
||||
|
||||
```ts type-equiv
|
||||
/** Deterministic request-image policy selected by one exact model route. */
|
||||
interface ImageRequestPolicy {
|
||||
/** Downscale rule applied before the per-side cap. */
|
||||
projection: ImageRequestProjection
|
||||
/** Maximum width and maximum height after projection; omission bounds the long edge by the projection alone. */
|
||||
maxDimension?: number
|
||||
/** Encoded-byte target before base64 expansion or Files API upload; the smallest quality-ladder output is kept when no quality fits. */
|
||||
maxBytes: number
|
||||
/** Integer width and height of one projected image. */
|
||||
interface ProjectedDimensions {
|
||||
width: number
|
||||
height: number
|
||||
}
|
||||
```
|
||||
|
||||
@@ -197,7 +167,7 @@ interface RequestImageAttachment {
|
||||
}
|
||||
```
|
||||
|
||||
`saveImage()` 准备并原子提交提供方无关的规范化附件,然后直接返回 `ImageAttachmentRef`。`saveImages()` 在发布批次前为每个成员各准备一次经过验证的附件,因此校验拒绝不会留下部分对象,发布也不会重复解码或选择质量。`admitPromptContent()` 在文件凭证解析后接收完整且有序的 Host prompt,把 base64 图片上传替换为持久引用,并让持久文件引用原样通过。`admitEncodedImages()` 支持其他 wire 入口,把张数、聚合字节和有序批量准入交给 `saveImages()`。`admitEncodedFile()` 让编码协议适配器使用服务拥有的规范 base64 准入,`isAttachmentError()` 让这些适配器无需导入实现辅助函数即可识别稳定的附件错误。`readImage()` 校验来自已授权会话路径的规范化附件。`imageHostPath()` 只公开提供方所持对象的宿主位置,不判断当前工具执行环境能否读取它。`readImageRequest()` 按确切路由的投影规则、可选单边上限和编码字节目标派生并缓存确定性请求版本。该版本包含编码字节和元数据,不包含执行环境路径。新条目在发布前完整解码,缓存命中只做有界元数据探测。调用方需要有序批次时,对单数方法使用 `Promise.all`。本地实现按需编码首选候选、合并相同请求身份的并发任务、允许每个等待方单独取消、没有等待方时停止共享任务,并通过实例级限流器限制全部变换,默认同时执行两项。该服务不规定保留策略:恢复和 fork 后的会话可能共享对象,因此基于引用的垃圾回收会延期实现,不与单个会话的删除绑定。
|
||||
`saveImage()` 准备并原子提交提供方无关的规范化附件,然后直接返回 `ImageAttachmentRef`。`saveImages()` 在发布批次前为每个成员各准备一次经过验证的附件,因此校验拒绝不会留下部分对象,发布也不会重复解码或选择质量。`admitPromptContent()` 在文件凭证解析后接收完整且有序的 Host prompt,把 base64 图片上传替换为持久引用,并让持久文件引用原样通过。`admitEncodedImages()` 支持其他 wire 入口,把张数、聚合字节和有序批量准入交给 `saveImages()`。`admitEncodedFile()` 让编码协议适配器使用服务拥有的规范 base64 准入,`isAttachmentError()` 让这些适配器无需导入实现辅助函数即可识别稳定的附件错误。`readImage()` 校验来自已授权会话路径的规范化附件。`imageHostPath()` 只公开提供方所持对象的宿主位置,不判断当前工具执行环境能否读取它。`readImageRequest()` 按确切的路由目标尺寸和编码字节目标派生并缓存确定性请求版本。该版本包含编码字节和元数据,不包含执行环境路径。新条目在发布前完整解码,缓存命中只做有界元数据探测。调用方需要有序批次时,对单数方法使用 `Promise.all`。本地实现按需编码首选候选、合并相同请求身份的并发任务、允许每个等待方单独取消、没有等待方时停止共享任务,并通过实例级限流器限制全部变换,默认同时执行两项。该服务不规定保留策略:恢复和 fork 后的会话可能共享对象,因此基于引用的垃圾回收会延期实现,不与单个会话的删除绑定。
|
||||
|
||||
<!-- BEGIN GENERATED cordis-surface (gen-cordis-catalog.ts) — do not edit between markers -->
|
||||
|
||||
@@ -320,11 +290,11 @@ fileHostPath(ref: FileAttachmentRef): string | undefined
|
||||
/**
|
||||
* Generate or read one deterministic model-request version from the stored normalized image.
|
||||
* @param ref - durable provider-independent normalized attachment reference.
|
||||
* @param policy - route projection, optional per-side cap, and byte target; an unmet target yields the smallest ladder output.
|
||||
* @param target - route-chosen dimensions and byte target; an unmet byte target yields the smallest ladder output.
|
||||
* @param signal - optional cancellation.
|
||||
* @returns request bytes and the cache/upload identity covering every transform input.
|
||||
*/
|
||||
readImageRequest( ref: ImageAttachmentRef, policy: ImageRequestPolicy, signal?: AbortSignal, ): Promise<RequestImageAttachment>
|
||||
readImageRequest( ref: ImageAttachmentRef, target: ImageRequestTarget, signal?: AbortSignal, ): Promise<RequestImageAttachment>
|
||||
```
|
||||
|
||||
Source: [`packages/attachment/attachment/src/index.ts`](../../packages/attachment/attachment/src/index.ts)
|
||||
|
||||
@@ -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/llm-streaming.md
|
||||
llm-streaming.md: b3d2468a41833139e3c9c9ded69cbb863e5fd8d3
|
||||
llm-streaming.zh.md: 2d849206746ee44736ff402a364f913301ed87a8
|
||||
llm-streaming.md: 28492b46435e3288609129b0dfc5cb40dd5f7296
|
||||
llm-streaming.zh.md: fe02e2ebe5b558162e849e26ff05b8d633c07ba0
|
||||
@@ -249,7 +249,7 @@ interface LlmFailure {
|
||||
|
||||
## Request-image pricing
|
||||
|
||||
An adapter whose provider charges visual tokens for request images declares per-route pricing by overriding `LlmAdapter.imageRequestPricing`, and `ctx.llm.imageRequestPricing(provider, model)` resolves it synchronously for consumers. The token meter resolves the routed model's pricing on every measurement so compaction pressure, retention, and range selection price image history as the routed request actually sends it; the DeepSeek adapter reproduces its own request projection (per-model projection and per-side cap, oldest-first offload) and prices retained images with the published vision accounting, while provider usage remains the authoritative anchor for completed requests.
|
||||
An adapter whose provider charges visual tokens for request images declares per-route pricing by overriding `LlmAdapter.imageRequestPricing`, and `ctx.llm.imageRequestPricing(provider, model)` resolves it synchronously for consumers. The token meter resolves the routed model's pricing on every measurement so compaction pressure, retention, and range selection price image history as the routed request actually sends it; the DeepSeek adapter reproduces its own request projection (per-model request target, oldest-first offload) and prices retained images with the published vision accounting, while provider usage remains the authoritative anchor for completed requests.
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
|
||||
@@ -251,7 +251,7 @@ interface LlmFailure {
|
||||
|
||||
## 请求图片定价
|
||||
|
||||
提供方对请求图片收取视觉 token 的适配器通过覆写 `LlmAdapter.imageRequestPricing` 声明按路由的定价,消费方经 `ctx.llm.imageRequestPricing(provider, model)` 同步解析。token 计量服务在每次计量时解析路由模型的定价,使 compaction 的压力、保留与选段都按路由请求实际发送的形式为图片历史计价;DeepSeek 适配器复现自身的请求投影(按模型的投影与单边上限、最旧优先 offload),并用官方公布的视觉计量为保留图片定价,已完成请求仍以 provider usage 为权威锚点。
|
||||
提供方对请求图片收取视觉 token 的适配器通过覆写 `LlmAdapter.imageRequestPricing` 声明按路由的定价,消费方经 `ctx.llm.imageRequestPricing(provider, model)` 同步解析。token 计量服务在每次计量时解析路由模型的定价,使 compaction 的压力、保留与选段都按路由请求实际发送的形式为图片历史计价;DeepSeek 适配器复现自身的请求投影(按模型的请求目标、最旧优先 offload),并用官方公布的视觉计量为保留图片定价,已完成请求仍以 provider usage 为权威锚点。
|
||||
|
||||
```ts type-equiv
|
||||
/**
|
||||
|
||||
Reference in new issue
Block a user