From 1ec77846bb7b1245f06867bd7d9ad7b4ea01f46d Mon Sep 17 00:00:00 2001 From: _Kerman Date: Fri, 16 Oct 2026 17:07:37 +0800 Subject: [PATCH] test(agent-loop): cover configured resume effort and missing route A config-driven resume applies an explicit configured effort, and an agent entry without a complete route keeps the recorded selection. --- .../tests/config-session-id.spec.ts | 29 ++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/packages/core/agent-loop/tests/config-session-id.spec.ts b/packages/core/agent-loop/tests/config-session-id.spec.ts index 525a80f15e..a15a19ec9b 100644 --- a/packages/core/agent-loop/tests/config-session-id.spec.ts +++ b/packages/core/agent-loop/tests/config-session-id.spec.ts @@ -1,4 +1,4 @@ -import { createUserMessage } from '@deepseek-ai/dsh-llm' +import { createUserMessage, ReasoningEffortId } from '@deepseek-ai/dsh-llm' import { afterEach, describe, expect, it, vi } from 'vitest' import { Context } from '@deepseek-ai/cordis' import { mkdtemp, rm } from 'node:fs/promises' @@ -487,6 +487,33 @@ describe('config-driven session id', () => { await ctx2.fiber.dispose() }) + it.each([ + { label: 'applies an explicit configured effort', route: { provider: 'mock', model: 'mock', reasoningEffort: ReasoningEffortId('low') }, expected: { provider: 'mock', model: 'mock', reasoningEffort: 'low' }, appended: 1 }, + { label: 'keeps the recorded choice without a configured route', route: {}, expected: { provider: 'mock', model: 'mock', reasoningEffort: 'high' }, appended: 0 }, + ])('config-driven resume $label', async ({ route, expected, appended }) => { + const root = await mkdtemp(join(tmpdir(), 'dsh-cfg-resume-route-')) + dirs.push(root) + const ctx1 = await makeCoreContext() + await ctx1.plugin(JsonlSessionPersistence, { root }) + await ctx1.plugin(AgentLoop, { agents: [] }) + ctx1.llm.registerAdapter(['mock'], new MockAdapter([textResponse('first')])) + const h1 = await ctx1.agents.create({ sessionId: SessionId('sticky-route'), agentOptions: { provider: 'mock', model: 'mock' } }) + h1.agent.followup(createUserMessage({ content: [{ type: 'text', text: 'remember me' }], source: { kind: 'user' } })) + await waitForIdle(ctx1, h1.agent) + ctx1.agentModel.select(h1.agent, { provider: 'mock', model: 'mock', reasoningEffort: ReasoningEffortId('high') }) + await h1.dispose() + await ctx1.fiber.dispose() + + const ctx2 = await makeCoreContext() + await ctx2.plugin(JsonlSessionPersistence, { root }) + await ctx2.plugin(AgentLoop, { agents: [{ id: SessionId('main'), ...route, resumeSessionId: SessionId('sticky-route') }] }) + await expect.poll(() => ctx2.agents.get(SessionId('sticky-route')), { timeout: 5_000 }).toBeDefined() + const resumed = ctx2.agents.get(SessionId('sticky-route'))! + expect(ctx2.agentModel.resolveForNextStep(resumed)).toEqual(expected) + expect(resumed.session.snapshotEvents().filter(event => event.type === 'model/selection')).toHaveLength(1 + appended) + await ctx2.fiber.dispose() + }) + it('config-driven resume of a missing session is contained: logs a warning, no agent, no crash', async () => { const root = await mkdtemp(join(tmpdir(), 'dsh-cfg-resume-miss-')) dirs.push(root)