Add web multimodal image attachments

This commit is contained in:
Yichen Jiang
2026-07-23 15:20:47 +08:00
parent 3e3ea47296
commit cb4c11b869
116 changed files with 3177 additions and 151 deletions

View File

@@ -15,9 +15,9 @@ beforeEach(() => {
})
describe('createChatStore', () => {
it('init shape: empty selection/draft/view', () => {
it('init shape: empty selection/draft/images/view', () => {
const store = createChatStore().create()
expect(store.store.getSnapshot()).toEqual({ selection: null, draft: '', view: null })
expect(store.store.getSnapshot()).toEqual({ selection: null, draft: '', imageIds: [], view: null })
})
it('actions cover the declared write set', () => {
@@ -30,6 +30,11 @@ describe('createChatStore', () => {
store.actions.setDraft('hello')
expect(store.store.getSnapshot().draft).toBe('hello')
store.actions.addImages(['a', 'b'])
store.actions.removeImage('a')
expect(store.store.getSnapshot().imageIds).toEqual(['b'])
store.actions.pruneImages([])
expect(store.store.getSnapshot().imageIds).toEqual([])
store.actions.clearDraft()
expect(store.store.getSnapshot().draft).toBe('')
@@ -40,12 +45,15 @@ describe('createChatStore', () => {
it('restoreDraft only fills an empty draft (optimistic-send rollback contract)', () => {
const store = createChatStore().create()
// Rollback path: draft was cleared by send, nothing typed since.
store.actions.restoreDraft('failed text')
store.actions.restoreDraft('failed text', ['old-image'])
expect(store.store.getSnapshot().draft).toBe('failed text')
expect(store.store.getSnapshot().imageIds).toEqual(['old-image'])
// The user typed something new before the failure landed: keep theirs.
store.actions.setDraft('newer input')
store.actions.restoreDraft('stale text')
store.actions.addImages(['new-image'])
store.actions.restoreDraft('stale text', ['old-image'])
expect(store.store.getSnapshot().draft).toBe('newer input')
expect(store.store.getSnapshot().imageIds).toEqual(['old-image', 'new-image'])
})
it('persists per scope key and rehydrates a fresh instance', () => {