fix: address ds-review-bot v7 findings on the merged image-input head
- gate model selection on steering-placement image carriers from enqueue until their steering/message event publishes; release the gate when an admission ends idle without publication (both behaviorally asserted) - reject session.updateQueue edits carrying non-text blocks at the RPC boundary (queue edits cannot bypass image admission) - extend the durable-directory walk past a first-created DSH_HOME to the deepest pre-existing ancestor - strip Windows-style separators from attachment display names on POSIX - verify attachment reads with a header-only probe (digest already proves the bytes decoded fully at admission); document the read path - make SessionInputShell.addImages refusal observable and keep workspace transfers/composer intake from leaking refused drafts - own ONE recursive image walk (dsh-llm contentHasImage) across apiproxy, pi-ai, compact-basic, and the DeepSeek text-only assertion - drop the redundant canonical-base64 regex and the no-op role read - move AttachmentId/AttachmentError out of types.ts (brand.ts/error.ts); document why AttachmentError does not extend HarnessError - document the hard attachments inject in both consumer READMEs
This commit is contained in:
15
packages/attachment/attachment/src/brand.ts
Normal file
15
packages/attachment/attachment/src/brand.ts
Normal file
@@ -0,0 +1,15 @@
|
||||
/** Attachment identifier brand. @module @deepseek-ai/dsh-attachment/brand */
|
||||
|
||||
import type { Branded } from '@deepseek-ai/dsh-brand'
|
||||
|
||||
/** Opaque content-addressed identifier for one immutable attachment object. */
|
||||
export type AttachmentId = Branded<'AttachmentId'>
|
||||
|
||||
/**
|
||||
* Brand a validated storage identifier.
|
||||
* @param value - backend-produced opaque identifier.
|
||||
* @returns the branded identifier.
|
||||
*/
|
||||
export function AttachmentId(value: string): AttachmentId {
|
||||
return value as AttachmentId
|
||||
}
|
||||
26
packages/attachment/attachment/src/error.ts
Normal file
26
packages/attachment/attachment/src/error.ts
Normal file
@@ -0,0 +1,26 @@
|
||||
/** Attachment failure class. @module @deepseek-ai/dsh-attachment/error */
|
||||
|
||||
/**
|
||||
* Stable failures suitable for host RPC error mapping.
|
||||
*
|
||||
* Deliberately re-implements the `HarnessError` shape instead of extending it:
|
||||
* the base lives in `@deepseek-ai/dsh-llm`, which itself depends on this
|
||||
* package (`ImageBlock` references `ImageAttachmentRef`), so sharing the base
|
||||
* would create a dependency cycle. Consumers route on `code`, never on the
|
||||
* prototype chain, so the shapes stay interchangeable at the wire boundary.
|
||||
*/
|
||||
export class AttachmentError extends Error {
|
||||
/** Stable machine-routing failure code. */
|
||||
readonly code: string
|
||||
|
||||
/**
|
||||
* @param message - human-readable failure description without raw bytes or host paths.
|
||||
* @param code - stable machine-routing code.
|
||||
* @param options - optional chained cause.
|
||||
*/
|
||||
constructor(message: string, code: string, options?: ErrorOptions) {
|
||||
super(message, options)
|
||||
this.name = 'AttachmentError'
|
||||
this.code = code
|
||||
}
|
||||
}
|
||||
@@ -8,7 +8,8 @@ import type {
|
||||
StoredImageAttachment,
|
||||
} from './types.ts'
|
||||
|
||||
export { AttachmentError, AttachmentId } from './types.ts'
|
||||
export { AttachmentId } from './brand.ts'
|
||||
export { AttachmentError } from './error.ts'
|
||||
export type {
|
||||
AttachmentId as AttachmentIdType,
|
||||
ImageAttachmentLimits,
|
||||
|
||||
@@ -1,18 +1,8 @@
|
||||
/** Durable attachment vocabulary. @module @deepseek-ai/dsh-attachment/types */
|
||||
|
||||
import type { Branded } from '@deepseek-ai/dsh-brand'
|
||||
import type { AttachmentId } from './brand.ts'
|
||||
|
||||
/** Opaque content-addressed identifier for one immutable attachment object. */
|
||||
export type AttachmentId = Branded<'AttachmentId'>
|
||||
|
||||
/**
|
||||
* Brand a validated storage identifier.
|
||||
* @param value - backend-produced opaque identifier.
|
||||
* @returns the branded identifier.
|
||||
*/
|
||||
export function AttachmentId(value: string): AttachmentId {
|
||||
return value as AttachmentId
|
||||
}
|
||||
export type { AttachmentId } from './brand.ts'
|
||||
|
||||
/** Raster image formats accepted by the version-one attachment path. */
|
||||
export type ImageMediaType = 'image/png' | 'image/jpeg' | 'image/webp' | 'image/gif'
|
||||
@@ -56,20 +46,3 @@ export interface StoredImageAttachment {
|
||||
ref: ImageAttachmentRef
|
||||
data: Uint8Array
|
||||
}
|
||||
|
||||
/** Stable failures suitable for host RPC error mapping. */
|
||||
export class AttachmentError extends Error {
|
||||
/** Stable machine-routing failure code. */
|
||||
readonly code: string
|
||||
|
||||
/**
|
||||
* @param message - human-readable failure description without raw bytes or host paths.
|
||||
* @param code - stable machine-routing code.
|
||||
* @param options - optional chained cause.
|
||||
*/
|
||||
constructor(message: string, code: string, options?: ErrorOptions) {
|
||||
super(message, options)
|
||||
this.name = 'AttachmentError'
|
||||
this.code = code
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user