✨ feat(vscode): 问 AI 输入框能粘贴、拖进图片随问题发给 Claude Code,缩略图能点开看大图,图片存进 .spx/code-qa 跟着问答删
This commit is contained in:
1 parent
d9a5c3673e
commit
36d842e18e
28 files changed
+825
-121
No files matched your search
@@ -23,14 +23,14 @@ function run(...actions: QaAction[]): QaState {
|
||||
|
||||
describe('问 AI 的状态', () => {
|
||||
it('问一次:展开这块,当前这一轮多一条在答的;回答长了跟着变;答完记下存成的那条,历史里不再重复', () => {
|
||||
let state = run(qa([thread(IF, 'old')]), { type: 'ask', askId: 'a1', anchor: IF, question: '为什么?' })
|
||||
let state = run(qa([thread(IF, 'old')]), { type: 'ask', askId: 'a1', anchor: IF, question: '为什么?', images: [] })
|
||||
expect(state.open).toEqual([IF])
|
||||
expect(asksOf(state, IF)).toEqual([{ askId: 'a1', anchor: IF, question: '为什么?', text: '', status: 'running' }])
|
||||
expect(asksOf(state, IF)).toEqual([{ askId: 'a1', anchor: IF, question: '为什么?', images: [], text: '', status: 'running' }])
|
||||
state = qaReducer(state, { type: 'answer', askId: 'a1', text: '因为', activity: '读取 a.py' })
|
||||
expect(asksOf(state, IF)[0]).toMatchObject({ text: '因为', activity: '读取 a.py' })
|
||||
state = qaReducer(state, { type: 'answerEnd', end: { type: 'answerEnd', askId: 'a1', status: 'done', text: '因为要鉴权。', entryId: 'new' } })
|
||||
state = qaReducer(state, qa([thread(IF, 'old', 'new')]))
|
||||
expect(asksOf(state, IF)).toEqual([{ askId: 'a1', anchor: IF, question: '为什么?', text: '因为要鉴权。', status: 'done', entryId: 'new' }])
|
||||
expect(asksOf(state, IF)).toEqual([{ askId: 'a1', anchor: IF, question: '为什么?', images: [], text: '因为要鉴权。', status: 'done', entryId: 'new' }])
|
||||
expect(historyOf(state, IF).map(entry => entry.id)).toEqual(['old'])
|
||||
})
|
||||
|
||||
@@ -45,9 +45,9 @@ describe('问 AI 的状态', () => {
|
||||
it('收起就结束这一轮:答完的回到历史,还在答的留着;再展开', () => {
|
||||
let state = run(
|
||||
qa([thread(IF, 'e1')]),
|
||||
{ type: 'ask', askId: 'a1', anchor: IF, question: '1' },
|
||||
{ type: 'ask', askId: 'a1', anchor: IF, question: '1', images: [] },
|
||||
{ type: 'answerEnd', end: { type: 'answerEnd', askId: 'a1', status: 'done', entryId: 'e1' } },
|
||||
{ type: 'ask', askId: 'a2', anchor: IF, question: '2' },
|
||||
{ type: 'ask', askId: 'a2', anchor: IF, question: '2', images: [] },
|
||||
{ type: 'close', anchor: IF },
|
||||
)
|
||||
expect(state.open).toEqual([])
|
||||
@@ -67,12 +67,22 @@ describe('问 AI 的状态', () => {
|
||||
})
|
||||
|
||||
it('停止、失败照记;不认识的问题的消息不理', () => {
|
||||
let state = run(qa([]), { type: 'ask', askId: 'a1', anchor: IF, question: '1' }, { type: 'answer', askId: 'a1', text: '一半' })
|
||||
let state = run(qa([]), { type: 'ask', askId: 'a1', anchor: IF, question: '1', images: [] }, { type: 'answer', askId: 'a1', text: '一半' })
|
||||
state = qaReducer(state, { type: 'answerEnd', end: { type: 'answerEnd', askId: 'a1', status: 'stopped' } })
|
||||
expect(asksOf(state, IF)[0]).toMatchObject({ status: 'stopped', text: '一半' })
|
||||
expect(qaReducer(state, { type: 'answer', askId: 'a1', text: '晚到的' })).toEqual(state)
|
||||
expect(qaReducer(state, { type: 'answerEnd', end: { type: 'answerEnd', askId: 'nope', status: 'done' } })).toEqual(state)
|
||||
})
|
||||
|
||||
it('问题带的图片跟着这一问:答完、失败、停止都还在;页面重新加载后接上的没有', () => {
|
||||
const images = ['data:image/png;base64,AAA', 'data:image/jpeg;base64,BBB']
|
||||
let state = run(qa([]), { type: 'ask', askId: 'a1', anchor: IF, question: '看图', images })
|
||||
expect(asksOf(state, IF)[0].images).toEqual(images)
|
||||
for (const status of ['done', 'failed', 'stopped'] as const)
|
||||
expect(asksOf(qaReducer(state, { type: 'answerEnd', end: { type: 'answerEnd', askId: 'a1', status } }), IF)[0].images).toEqual(images)
|
||||
state = run(qa([], [{ askId: 'a2', anchor: IF, question: '1', text: '' }]))
|
||||
expect(asksOf(state, IF)[0].images).toBeUndefined()
|
||||
})
|
||||
})
|
||||
|
||||
describe('问的时间', () => {
|
||||
|
||||
Reference in new issue
Block a user