refactor(llm): invalidate stale file mappings with the index generation type

This commit is contained in:
creatixchu committed 2026-09-25 16:31:25 +08:00
1 parent f9b8548dc3
commit 97d9115336
5 files changed
+11 -20

No files matched your search

+3 -12
View File
@@ -32,12 +32,6 @@ export interface DeepSeekFileReference {
uploaded: boolean
}
/** One request-image version with the exact remote id a model request rejected. */
export interface DeepSeekRejectedUpload {
version: RequestImageAttachment
fileId: DeepSeekFileId
}
interface FileStoreOptions {
index?: DeepSeekUploadIndex
now?: () => number
@@ -251,17 +245,14 @@ export class DeepSeekFileStore {
/**
* Invalidate exact local mappings in one index update after a model request rejects their remote ids.
* @param rejected - request-image versions with the exact file id the request used for each.
* @param generations - request-image variants with the exact file id the request used for each.
* @param connection - endpoint and API-key snapshot.
*/
async invalidate(
rejected: readonly DeepSeekRejectedUpload[],
generations: readonly Pick<DeepSeekUploadRecord, 'variantId' | 'fileId'>[],
connection: DeepSeekFileConnection,
): Promise<void> {
await this.index.remove(
fileScope(connection),
rejected.map(({ version, fileId }) => ({ variantId: version.variantId, fileId })),
)
await this.index.remove(fileScope(connection), generations)
}
/**
+1 -1
View File
@@ -28,7 +28,7 @@ export {
} from './request-pricing.ts'
export { deepSeekImageTokens, deepSeekRequestImageDimensions } from './image-tokens.ts'
export { DeepSeekFileStore, MAX_IMAGE_BYTES } from './file-store.ts'
export type { DeepSeekFileConnection, DeepSeekFilePolicy, DeepSeekFileReference, DeepSeekRejectedUpload } from './file-store.ts'
export type { DeepSeekFileConnection, DeepSeekFilePolicy, DeepSeekFileReference } from './file-store.ts'
export { DeepSeekFilesClient, MAX_FILE_EXPIRY_SECONDS, MAX_FILE_UPLOAD_BYTES, MAX_STORED_FILE_BYTES, MAX_STORED_FILE_COUNT, MIN_FILE_EXPIRY_SECONDS } from './files-api.ts'
export type { DeepSeekFileObject, DeepSeekFilePage } from './files-api.ts'
export { DeepSeekFileId } from './file-id.ts'
@@ -134,7 +134,10 @@ export class RequestFiles {
*/
async retry(detail: string): Promise<boolean> {
if (this.used.length === 0 || !providerRejectedFileId(detail)) return false
await this.files.invalidate(staleMappings(this.used, detail), this.connection)
await this.files.invalidate(
staleMappings(this.used, detail).map(file => ({ variantId: file.version.variantId, fileId: file.fileId })),
this.connection,
)
if (this.retried) return false
this.retried = true
return true
@@ -98,10 +98,10 @@ describe('DeepSeekFileStore', () => {
expect((await store.ensureUploaded(VERSION, { ...CONNECTION, baseURL: `${CONNECTION.baseURL}/v1/` }, POLICY)).record).toEqual(first.record)
const reopened = new DeepSeekFileStore({ index, fetch: remote.fetchImpl, now: () => now })
expect((await reopened.ensureUploaded(VERSION, CONNECTION, POLICY)).record).toEqual(first.record)
await reopened.invalidate([{ version: VERSION, fileId: other.record.fileId }], CONNECTION)
await reopened.invalidate([{ variantId: VERSION.variantId, fileId: other.record.fileId }], CONNECTION)
expect((await reopened.ensureUploaded(VERSION, CONNECTION, POLICY)).record).toEqual(first.record)
expect(remote.uploads()).toBe(2)
await reopened.invalidate([{ version: VERSION, fileId: first.record.fileId }], CONNECTION)
await reopened.invalidate([{ variantId: VERSION.variantId, fileId: first.record.fileId }], CONNECTION)
const replacement = await reopened.ensureUploaded(VERSION, CONNECTION, POLICY)
expect(replacement.record.fileId).not.toBe(first.record.fileId)
expect((await reopened.ensureUploaded(VERSION, alternate, POLICY)).record).toEqual(other.record)
@@ -73,10 +73,7 @@ describe('Messages Files requests', () => {
vi.stubGlobal('fetch', fetchImpl)
const h = harness()
await chunks(h.adapter.stream(request([ref, second])))
expect(h.invalidate).toHaveBeenCalledExactlyOnceWith(
[expect.objectContaining({ version: expect.objectContaining({ attachment: ref }), fileId: 'file-a' })],
expect.objectContaining({}),
)
expect(h.invalidate).toHaveBeenCalledExactlyOnceWith([{ variantId: version(ref).variantId, fileId: 'file-a' }], expect.objectContaining({}))
expect(fetchImpl).toHaveBeenCalledTimes(2)
expect(h.prepare).toHaveBeenCalledTimes(2)
expect(h.ensureUploaded).toHaveBeenCalledTimes(4)