test(subagent): align continuation fixtures with session API

This commit is contained in:
imccyu
2026-08-01 08:04:02 +08:00
committed by Tianyi Cui
parent f4a65a34e6
commit 9cd3c57b75
2 changed files with 11 additions and 9 deletions

View File

@@ -226,7 +226,7 @@ describe('dsh-subagent-fork', () => {
expect(fresh.seed).toBeUndefined() expect(fresh.seed).toBeUndefined()
// Complete one parent turn, then the prefix is captured once at creation. // Complete one parent turn, then the prefix is captured once at creation.
parent.followup({ content: [{ type: 'text', text: 'hello' }], source: { kind: 'user' } }) parent.followup(createUserMessage({ content: [{ type: 'text', text: 'hello' }], source: { kind: 'user' } }))
await parent.whenIdle() await parent.whenIdle()
const seeded = await provider.prepareContinuable!({ const seeded = await provider.prepareContinuable!({
sessionId: SessionId('continuable-seeded'), sessionId: SessionId('continuable-seeded'),

View File

@@ -12,7 +12,7 @@ import JsonlSessionPersistence from '@deepseek-ai/dsh-session-persistence-jsonl'
import * as SubagentSpawn from '@deepseek-ai/dsh-subagent-spawn' import * as SubagentSpawn from '@deepseek-ai/dsh-subagent-spawn'
import * as SubagentFork from '@deepseek-ai/dsh-subagent-fork' import * as SubagentFork from '@deepseek-ai/dsh-subagent-fork'
import type { GenerateOptions, MessageId, StreamChunk } from '@deepseek-ai/dsh-llm' import type { GenerateOptions, MessageId, StreamChunk } from '@deepseek-ai/dsh-llm'
import { LlmAdapter } from '@deepseek-ai/dsh-llm' import { createUserMessage, LlmAdapter } from '@deepseek-ai/dsh-llm'
import { defineTool } from '@deepseek-ai/dsh-tools' import { defineTool } from '@deepseek-ai/dsh-tools'
import InvariantService from '@deepseek-ai/dsh-invariants' import InvariantService from '@deepseek-ai/dsh-invariants'
import { MockAdapter, textResponse } from '../../../core/agent-loop/tests/mock-adapter.ts' import { MockAdapter, textResponse } from '../../../core/agent-loop/tests/mock-adapter.ts'
@@ -356,24 +356,26 @@ describe('SubagentService.startContinuable', () => {
await drainManager(fresh) await drainManager(fresh)
}) })
it('numbers the descriptor turn after an inherited fork prefix', async () => { it('continues turn numbering after an inherited fork prefix and pre-turn descriptor', async () => {
const { ctx, parent } = await setup([ const { ctx, parent } = await setup([
textResponse('parent turn'), textResponse('parent turn'),
textResponse('forked child'), textResponse('forked child'),
]) ])
// Complete one parent turn so fork has a prefix to contribute. // Complete one parent turn so fork has a prefix to contribute.
parent.followup({ content: message('parent work'), source: { kind: 'user' } }) parent.followup(createUserMessage({ content: message('parent work'), source: { kind: 'user' } }))
await parent.whenIdle() await parent.whenIdle()
const started = await ctx.subagents.startContinuable(startSpec(parent, 'fork')) const started = await ctx.subagents.startContinuable(startSpec(parent, 'fork'))
await waitNoActivation(ctx, started.childId) await waitNoActivation(ctx, started.childId)
const loaded = await ctx.sessionPersistence.load(started.childId) const loaded = await ctx.sessionPersistence.load(started.childId)
const descriptorTurn = loaded.events.find(event => event.type === 'turn/start' const descriptorIndex = loaded.events.findIndex(event => event.type === 'subagent/descriptor')
&& event.data.trigger.kind === 'subagent-descriptor') const childTurn = loaded.events.slice(descriptorIndex + 1)
// The seeded descriptor turn continues the inherited numbering rather than .find(event => event.type === 'turn/start')
// restarting at 1, so the replayed child log stays balanced. // The first child turn after the descriptor continues the inherited prefix
expect(descriptorTurn?.type === 'turn/start' && descriptorTurn.data.turn).toBe(2) // rather than restarting at 1, so the replayed child log stays balanced.
expect(descriptorIndex).toBeGreaterThanOrEqual(0)
expect(childTurn?.type === 'turn/start' && childTurn.data.turn).toBe(2)
expect(loaded.meta.seedLength).toBeGreaterThan(0) expect(loaded.meta.seedLength).toBeGreaterThan(0)
}) })