Files
deepseek-harness/docs/subsystems/attachment.zh.md
T

11 KiB

持久图片附件

English | 中文

附件 seam 将二进制图片的所有权与会话日志分离。生产方把经过校验的编码字节交给 ctx.attachments;只有对象完成持久化后,该服务才会发布不可变的内容寻址引用。会话事件和模型可见的 ImageBlock 包含该引用及其元数据,绝不包含浏览器对象 URL、宿主临时路径、提供方 URL 或 base64 数据。

未发送的浏览器草稿可以保留在内存中,原生客户端也可以将其暂存于操作系统临时存储。宿主接受用户消息后,会先把消息中的图片移到 <DSH_HOME>/attachments/v1 下,再追加用户事件。结构化模型图片输出遵循同样的先持久化、后追加事件规则。

来源:packages/attachment/attachment/src/types.ts

标识与经过校验的元数据

AttachmentId 是带类型标记的不透明字符串。本地后端目前生成 sha256:<digest>,但消费方既不能解析这种表示,也不能据此派生文件系统路径。

/** Raster image formats accepted by the version-one attachment path. */
type ImageMediaType = 'image/png' | 'image/jpeg' | 'image/webp' | 'image/gif'
/** Durable, serializable metadata for one immutable image object. */
interface ImageAttachmentRef {
  /** Opaque storage identifier; never a filesystem path or bearer URL. */
  attachmentId: AttachmentId
  /** Media type verified from the stored bytes. */
  mediaType: ImageMediaType
  /** Exact encoded byte length. */
  bytes: number
  /** Intrinsic encoded width in pixels. */
  width: number
  /** Intrinsic encoded height in pixels. */
  height: number
  /** Optional display name stripped of local path information. */
  name?: string
  /** Perceived source width before master-version downscaling; present only when it differs from {@link width}. */
  sourceWidth?: number
  /** Perceived source height before master-version downscaling; present only when it differs from {@link height}. */
  sourceHeight?: number
}
/** Deployment-resolved limits used by upload admission and request buffering. */
interface ImageAttachmentLimits {
  maxImageBytes: number
  maxImagesPerMessage: number
  maxMessageImageBytes: number
  maxImagePixels: number
  /** Maximum intrinsic width and maximum intrinsic height in pixels for one image. */
  maxImageDimension: number
  mediaTypes: readonly ImageMediaType[]
}

引用记录固有尺寸和编码长度,使客户端无需先解码即可排布历史记录;每次权威读取仍会根据对象重新校验摘要、媒体签名、尺寸和元数据。

提交与经校验读取的数据

/** Base64-encoded image upload accompanying one wire request. */
interface EncodedImageAttachment {
  /** Declared media type, verified against the decoded bytes during admission. */
  mediaType: ImageMediaType
  /** Canonical base64 encoding of the image bytes. */
  data: string
  /** Optional display name; it is never interpreted as a path. */
  name?: string
}
/** Request to validate and durably commit one image. */
interface SaveImageAttachment {
  data: Uint8Array
  /** Caller-declared media type, checked against fully decoded bytes. */
  mediaType: ImageMediaType
  /** Optional browser/provider display name; it is never interpreted as a path. */
  name?: string
}
/** Stored image bytes returned after reference and digest verification. */
interface StoredImageAttachment {
  ref: ImageAttachmentRef
  data: Uint8Array
}
/** Pixel rectangle in the oriented 2048px master-version coordinate system. */
interface MasterImageCrop {
  x: number
  y: number
  width: number
  height: number
}
/** Deterministic request-image policy selected by one exact model route. */
interface ImageRequestPolicy {
  /** Maximum width multiplied by height after aspect-preserving projection. */
  maxPixels: number
  /** Encoded-byte cap before base64 expansion or Files API upload. */
  maxBytes: number
  /** Optional master-coordinate crop applied before pixel-budget scaling. */
  crop?: MasterImageCrop
}
/** Crop coordinates measured by a model on the request preview it received. */
interface PreviewImageCrop {
  previewWidth: number
  previewHeight: number
  x: number
  y: number
  width: number
  height: number
}
/** Cached request version derived from one provider-independent master attachment. */
interface RequestImageAttachment {
  /** Cache and upload-index key over the master id, policy, crop, and fixed encoder parameters. */
  variantId: ImageVariantId
  /** Durable master reference from which this request version was derived. */
  master: ImageAttachmentRef
  /** Encoded request bytes. */
  data: Uint8Array
  mediaType: ImageMediaType
  bytes: number
  width: number
  height: number
  /** Provider-compatible sample depth proven after request encoding. */
  depth: 'uchar'
  /** Provider-compatible color space proven after request encoding. */
  space: 'srgb'
  /** Whether the encoded request version retains an alpha channel. */
  hasAlpha: boolean
  /** Applied master-coordinate crop, when present. */
  crop?: MasterImageCrop
}

saveImage() 准备提供方无关的 2048px、4MiB 主版本,并在返回引用前以原子方式提交。saveImages() 在发布批次前为每个成员各准备一次经过验证的主版本,因此校验拒绝不会留下部分对象,发布也不会重复解码或选择质量。admitEncodedImages() 是面向 base64 上传的 wire 入口,把张数、聚合字节和有序批量准入交给 saveImages()。readImage() 校验来自已授权会话路径的主版本。readImageRequest() 按确切路由的像素和字节预算派生并缓存请求版本;readImageRequests() 允许实现按自身配置的有界变换并发处理有序批次。本地实现按需编码首选候选、合并相同请求身份的并发任务,默认同时执行两项变换。cropImage() 把模型预览坐标映射回主版本,并返回另一个持久附件。该服务不规定保留策略:恢复和 fork 后的会话可能共享对象,因此基于引用的垃圾回收会延期实现,不与单个会话的删除绑定。

Cordis API

Generated from source by scripts/gen-cordis-catalog.ts (verified fresh by pnpm run verify-cordis-catalog in doc-sync; regenerate with pnpm run gen-cordis-catalog) — the language sides differ only in locale-specific paired document paths. Signature blocks use a ts cordis-catalog fence and keep the original source JSDoc; dispatch modes are defined in the primer, and the framework-inherited ctx API lives in cordis-api/inherited.md.

ctx.attachments — AttachmentStore (abstract seam)

Immutable binary attachment service. Implementations validate bytes before publishing a reference.

/**
 * Validate one image without persisting it.
 * Batch callers validate every member before saving any member.
 * @param input - encoded bytes, declared media type, and optional display name.
 * @returns completion after the encoded raster has been fully decoded.
 */
abstract validateImage(input: SaveImageAttachment): Promise<void>

/**
 * Validate and durably commit one ordered image batch.
 * @param inputs - encoded images in owning-message order.
 * @returns durable master references in the same order after every member succeeds.
 */
async saveImages(inputs: readonly SaveImageAttachment[]): Promise<readonly ImageAttachmentRef[]>

/**
 * Validate and durably commit one image before its owning session event is appended.
 * Implementations may store a prepared master version of the submitted raster;
 * the returned reference always describes the stored bytes, while `source`
 * preserves the submitted raster's intrinsic facts for callers that report
 * or map coordinates against the original.
 * @param input - encoded bytes, declared media type, and optional display name.
 * @returns the durable content-addressed reference beside the submitted source facts.
 */
abstract saveImage(input: SaveImageAttachment): Promise<SavedImageAttachment>

/**
 * Read one image and verify that bytes still match the recorded reference.
 * @param ref - durable reference from the session log.
 * @param signal - optional cancellation for backend read and verification work.
 * @returns the verified bytes and master reference.
 * @throws the signal reason when aborted, or a storage error when verification fails.
 */
abstract readImage(ref: ImageAttachmentRef, signal?: AbortSignal): Promise<StoredImageAttachment>

/**
 * Generate or read one deterministic model-request version from the stored master image.
 * @param ref - durable provider-independent master reference.
 * @param policy - exact route pixel and encoded-byte budget.
 * @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>

/**
 * Generate or read an ordered batch of deterministic model-request versions.
 * Implementations may use their own bounded transform concurrency while preserving input order.
 * @param refs - durable provider-independent master references in request order.
 * @param policy - exact route pixel and encoded-byte budget shared by the batch.
 * @param signal - optional cancellation.
 * @returns request versions in the same order as `refs`.
 */
async readImageRequests( refs: readonly ImageAttachmentRef[], policy: ImageRequestPolicy, signal?: AbortSignal, ): Promise<readonly RequestImageAttachment[]>

/**
 * Crop the stored master by coordinates measured on a model request preview and persist the result.
 * @param ref - session-authorized master attachment.
 * @param crop - preview dimensions and preview-coordinate rectangle.
 * @param signal - optional cancellation.
 * @returns a new durable attachment reference suitable for a logged tool result.
 */
cropImage( ref: ImageAttachmentRef, crop: PreviewImageCrop, signal?: AbortSignal, ): Promise<SavedImageAttachment>

Source: packages/attachment/attachment/src/index.ts