feat(web): merge compact status and summary cards

This commit is contained in:
Yichen Jiang
2026-08-08 14:11:17 +08:00
parent cc407a2672
commit 1db327ea6c
47 changed files with 725 additions and 121 deletions

View File

@@ -2,7 +2,7 @@ import { describe, expect, it } from 'vitest'
import { Context } from 'cordis'
import Loader from '@cordisjs/plugin-loader'
import type { Agent } from '@deepseek-ai/dsh-agent'
import CommandService from '@deepseek-ai/dsh-commands'
import CommandService, { type CommandResult } from '@deepseek-ai/dsh-commands'
import {
CompactService,
ManualCompactionError,
@@ -15,9 +15,9 @@ import { Session, SessionId } from '@deepseek-ai/dsh-session'
import * as commandCompact from '@deepseek-ai/dsh-command-compact'
const RESULT: CompactionResult = {
startSeq: 10,
summarySeq: 11,
endSeq: 13,
startSeq: 1,
summarySeq: 2,
endSeq: 3,
summary: [{ type: 'text', text: 'summary' }],
shadowedRange: { start: 1, end: 7 },
shadowedSeqs: [1, 3, 7],
@@ -49,10 +49,24 @@ class StubCompactService extends CompactService {
this.calls.push({ agent, signal })
if (this.operation !== undefined) return this.operation()
return this.failure === undefined
? Promise.resolve(this.result)
? Promise.resolve(this.result === null ? null : this.appendResult(agent, this.result))
// oxlint-disable-next-line typescript/prefer-promise-reject-errors -- exercise arbitrary backend rejection values.
: Promise.reject(this.failure)
}
private appendResult(agent: ManualCompactAgentContext, result: CompactionResult): CompactionResult {
agent.session.append('compact/start', { turn: null })
agent.session.append('compact/summary', {
summary: result.summary,
shadowedRange: result.shadowedRange,
shadowedSeqs: result.shadowedSeqs,
shadowedTokenCount: result.shadowedTokenCount,
provider: 'command-test',
model: 'command-test',
})
agent.session.append('compact/end', { turn: null })
return result
}
}
interface Harness {
@@ -91,9 +105,11 @@ async function run(
function expectLastLifecycle(
test: Harness,
args: string,
outcome: { readonly kind: 'success' | 'error'; readonly text?: string },
outcome: CommandResult,
): string {
const lifecycle = test.agent.session.events.slice(-2)
const lifecycle = test.agent.session.events
.filter(event => event.type === 'command/run' || event.type === 'command/done')
.slice(-2)
const runEvent = lifecycle[0]
const doneEvent = lifecycle[1]
if (runEvent?.type !== 'command/run' || doneEvent?.type !== 'command/done') {
@@ -149,6 +165,7 @@ describe('/compact human command', () => {
expect(execution.result).toEqual({
kind: 'success',
text: 'Compacted 3 history items (~42 tokens).',
sourceEventSeq: RESULT.summarySeq,
})
expect(execution.commandId).toBe(expectLastLifecycle(test, '', execution.result))
expect(test.compact.calls).toEqual([{ agent: test.agent, signal: controller.signal }])