mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-11-09 20:07:43 +08:00
test(conversation): remove redundant retry test scaffolding
This commit is contained in:
@@ -26,9 +26,7 @@ import { createConversationStore } from '../src/client/stores.ts'
|
||||
import type { SessionInputShell } from '../src/client/input/facade.ts'
|
||||
import { RemoteError } from '@deepseek-ai/dsh-client-test-runtime'
|
||||
import { SessionSeq } from '@deepseek-ai/dsh-session/types'
|
||||
import { createUserMessage, LlmAttemptId } from '@deepseek-ai/dsh-llm'
|
||||
import { MutableSessionEventSource } from '@deepseek-ai/dsh-api-session-controller/client'
|
||||
import type { SessionEventWindow } from '@deepseek-ai/dsh-api-session-controller/client'
|
||||
import { createUserMessage } from '@deepseek-ai/dsh-llm'
|
||||
import type { InboxWireState } from '@deepseek-ai/dsh-agent/types'
|
||||
import { continuationTurn } from './continuation-fixture.ts'
|
||||
|
||||
@@ -231,54 +229,6 @@ describe('Conversation inject API', () => {
|
||||
expect(b.sessionFake.prompt.mock.calls[0]?.[0]).toEqual([])
|
||||
})
|
||||
|
||||
it('uses the Host projection on partial pages and does no history materialization for streaming chunks', async () => {
|
||||
const b = await bench()
|
||||
onTestFinished(() => b.runtime.dispose())
|
||||
await b.runtime.sessions.replaceEvents(ROOT, continuationTurn({ kind: 'error', error: { code: 'SERVER', message: 'busy' } }).slice(1), true)
|
||||
await b.runtime.sessions.setProjection(ROOT, 'conversationContinuation', SessionSeq(5))
|
||||
const source = b.runtime.sessions.binding(ROOT)!.session.projections.faceOf('conversationContinuation')
|
||||
expect(source.getSnapshot()).toBe(5)
|
||||
const history = Array.from({ length: 1666 }, (_, index) => continuationTurn({ kind: 'completed' }, index + 1)).flat()
|
||||
history.push(...continuationTurn({ kind: 'completed' }, 1667).slice(0, 4))
|
||||
await b.runtime.sessions.replaceEvents(ROOT, history)
|
||||
await b.runtime.sessions.setProjection(ROOT, 'conversationContinuation', null)
|
||||
const feed = b.runtime.sessions.binding(ROOT)!.eventSource
|
||||
if (!(feed instanceof MutableSessionEventSource)) throw new Error('expected mutable fixture feed')
|
||||
const rawSnapshot = feed.getSnapshot.bind(feed)
|
||||
const windows = new WeakMap<SessionEventWindow, SessionEventWindow>()
|
||||
let materializations = 0
|
||||
const read = vi.spyOn(feed, 'getSnapshot').mockImplementation(() => {
|
||||
const window = rawSnapshot()
|
||||
let observed = windows.get(window)
|
||||
if (observed === undefined) {
|
||||
observed = {
|
||||
get entries() { materializations++; return window.entries },
|
||||
hasMore: window.hasMore, revision: window.revision, change: window.change,
|
||||
}
|
||||
windows.set(window, observed)
|
||||
}
|
||||
return observed
|
||||
})
|
||||
onTestFinished(() => { read.mockRestore() })
|
||||
const notified = vi.fn()
|
||||
const unsubscribe = source.subscribe(notified)
|
||||
onTestFinished(unsubscribe)
|
||||
for (let index = 0; index < 2000; index++) {
|
||||
feed.append({ type: 'transient', event: { type: 'assistant/live-chunk', seq: 9999.5, time: index,
|
||||
data: { attemptId: LlmAttemptId('streaming'), turn: 1667, step: 1, chunk: { type: 'text-delta', index: 0, text: 'x' } },
|
||||
} })
|
||||
expect(source.getSnapshot()).toBeNull()
|
||||
}
|
||||
expect(materializations).toBe(0)
|
||||
expect(notified).not.toHaveBeenCalled()
|
||||
await b.runtime.sessions.setProjection(ROOT, 'conversationContinuation', SessionSeq(10001))
|
||||
expect(notified).toHaveBeenCalledOnce()
|
||||
expect(source.getSnapshot()).toBe(10001)
|
||||
unsubscribe()
|
||||
await b.runtime.sessions.setProjection(ROOT, 'conversationContinuation', null)
|
||||
expect(notified).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it.each(['next-turn', 'pending', 'block', 'attachment', 'subagent', 'removed', 'closed'] as const)(
|
||||
'rejects a stale continuation click after %s changes', async (condition) => {
|
||||
const b = await bench()
|
||||
|
||||
@@ -38,12 +38,6 @@ import { InputBar } from '../src/client/skeleton/InputBar.tsx'
|
||||
import type { InputBarProps } from '../src/client/skeleton/InputBar.tsx'
|
||||
import { en, zh } from '../src/client/locales.ts'
|
||||
|
||||
declare module '@deepseek-ai/dsh-llm' {
|
||||
interface MessageSourceMap {
|
||||
'input-bar-context-fixture': { kind: 'input-bar-context-fixture' }
|
||||
}
|
||||
}
|
||||
|
||||
// Every fixture carries the resource hook the resources plugin merges into GlobalStandardProps.
|
||||
const useResource = (() => ({ status: 'none' as const, value: undefined, failure: undefined })) as GlobalStandardProps['useResource']
|
||||
|
||||
@@ -145,15 +139,14 @@ function bench(over?: BenchOptions) {
|
||||
promptError: over?.promptError ?? null,
|
||||
}))
|
||||
type ShellDeps = ConstructorParameters<typeof SessionInputShell>[0]
|
||||
const inbox = createSnapshotStore<InboxState>({
|
||||
'next-turn': over?.queue ?? [],
|
||||
'next-step': over?.nextStep ?? [],
|
||||
})
|
||||
const shell = new SessionInputShell({
|
||||
actx: SCTX,
|
||||
defaultSink: sink,
|
||||
commandAttachments: { serialize: () => Promise.resolve([]), release: () => {}, unsupportedNotice: (token: string) => `${token.trim()} attachments-unsupported` },
|
||||
inbox,
|
||||
inbox: createSnapshotStore<InboxState>({
|
||||
'next-turn': over?.queue ?? [],
|
||||
'next-step': over?.nextStep ?? [],
|
||||
}),
|
||||
...(over?.steerQueue !== undefined ? { steerQueue: over.steerQueue } : {}),
|
||||
// Lexicon-only stub: adjudication untouched (undefined slash methods are
|
||||
// never reached — these benches drive plain-draft flows only).
|
||||
@@ -170,9 +163,6 @@ function bench(over?: BenchOptions) {
|
||||
if (over?.attachments !== undefined) shell.addAttachments(over.attachments.map(attachment => attachment.id))
|
||||
const stop = vi.fn()
|
||||
const retry = vi.fn()
|
||||
const continuation = createSnapshotStore<SessionSeq | null>(over?.retryableFailure ?? null)
|
||||
const useContinuation = bindSnapshotSelector(continuation)
|
||||
const useInbox = bindSnapshotSelector(inbox)
|
||||
const removeAttachment = vi.fn((id: DraftAttachmentId) => { shell.removeAttachment(id) })
|
||||
const menuLauncher = createSnapshotStore<string | null>(over?.commandMenuOpen === true ? 'command' : null)
|
||||
const busyEnter = createSnapshotStore<'queue' | 'steer'>(over?.busyEnter ?? 'queue')
|
||||
@@ -209,15 +199,14 @@ function bench(over?: BenchOptions) {
|
||||
...allowAllAccess,
|
||||
useContextMenu: contextMenuHook(),
|
||||
useAccess: endpoint => !(over?.deniedEndpoints ?? []).includes(endpoint),
|
||||
useProjection: ((key: string, selector: (v: unknown) => unknown = v => v) => {
|
||||
if (key === 'conversationContinuation') return useContinuation(selector)
|
||||
if (key === 'inbox') return useInbox(selector)
|
||||
return selector(key === 'plan'
|
||||
useProjection: ((key: string, selector: (v: unknown) => unknown = v => v) =>
|
||||
selector(key === 'plan'
|
||||
? over?.plan
|
||||
: key === 'goal' ? over?.goal
|
||||
: key === 'imageLimits' ? over?.imageLimits
|
||||
: key === 'contextPressure' ? over?.contextPressure : undefined)
|
||||
}),
|
||||
: key === 'conversationContinuation' ? over?.retryableFailure
|
||||
: key === 'inbox' ? { 'next-turn': over?.queue ?? [], 'next-step': over?.nextStep ?? [] }
|
||||
: key === 'imageLimits' ? over?.imageLimits
|
||||
: key === 'contextPressure' ? over?.contextPressure : undefined)),
|
||||
useInput: bindSnapshotSelector(shell.state),
|
||||
inputActions: shell.actions,
|
||||
keyboard: shell,
|
||||
@@ -278,7 +267,7 @@ function bench(over?: BenchOptions) {
|
||||
const interruptButton = view.container.querySelector<HTMLButtonElement>('button[aria-label="停止生成"]')
|
||||
return {
|
||||
view, textarea, button, interruptButton, props, sink, shell, wiring: shell, session, stop, removeAttachment, slotCalls,
|
||||
menuLauncher, busyEnter, stopShortcut, continuation, inbox, retry,
|
||||
menuLauncher, busyEnter, stopShortcut, retry,
|
||||
steerQueue: over?.steerQueue,
|
||||
get placeholder() { return placeholderOf(view.container) },
|
||||
get inputDisabled() { return textarea.getAttribute('aria-disabled') === 'true' },
|
||||
@@ -300,26 +289,10 @@ it('offers the play action only for an empty, idle composer with an eligible fai
|
||||
expect(b.retry).toHaveBeenCalledOnce()
|
||||
})
|
||||
|
||||
it('updates the continue action from failure and pending-input projections', async () => {
|
||||
const b = bench()
|
||||
expect(b.view.queryByRole('button', { name: '继续生成' })).toBeNull()
|
||||
await act(async () => { b.continuation.set(2 as SessionSeq) })
|
||||
expect(b.view.getByRole('button', { name: '继续生成' }).getAttribute('disabled')).toBeNull()
|
||||
const context = { ...row('context'), source: { kind: 'input-bar-context-fixture' as const } }
|
||||
await act(async () => { b.inbox.set({ 'next-turn': [], 'next-step': [context] }) })
|
||||
expect(b.view.getByRole('button', { name: '继续生成' })).not.toBeNull()
|
||||
await act(async () => { b.inbox.set({ 'next-turn': [], 'next-step': [context, row('new instruction')] }) })
|
||||
expect(b.view.queryByRole('button', { name: '继续生成' })).toBeNull()
|
||||
await act(async () => { b.inbox.set({ 'next-turn': [], 'next-step': [context] }) })
|
||||
fireEvent.click(b.view.getByRole('button', { name: '继续生成' }))
|
||||
expect(b.retry).toHaveBeenCalledExactlyOnceWith(2)
|
||||
await act(async () => { b.continuation.set(null) })
|
||||
expect(b.view.queryByRole('button', { name: '继续生成' })).toBeNull()
|
||||
})
|
||||
|
||||
it.each([
|
||||
{ running: true }, { attachments: [{ kind: 'image' as const, id: 'image' as DraftAttachmentId, file: new File([], 'x.png'), previewUrl: 'blob:test' }] },
|
||||
{ blocked: { reason: 'Select a model' } }, { subagent: CONTINUABLE_CHILD }, { deniedEndpoints: ['session/prompt'] },
|
||||
{ nextStep: [row('new instruction')] },
|
||||
])('keeps the continue action unavailable with %j', (options) => {
|
||||
const b = bench({ ...options, retryableFailure: 2 as SessionSeq })
|
||||
expect(b.view.queryByRole('button', { name: '继续生成' })).toBeNull()
|
||||
|
||||
Reference in New Issue
Block a user