mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-08-29 04:26:38 +00:00
78 lines
3.0 KiB
TypeScript
78 lines
3.0 KiB
TypeScript
import { Context } from '@deepseek-ai/cordis'
|
|
import AgentRegistry from '@deepseek-ai/dsh-agent'
|
|
import type { Agent } from '@deepseek-ai/dsh-agent'
|
|
import { createUserMessage } from '@deepseek-ai/dsh-llm'
|
|
import SessionStore, { SessionId } from '@deepseek-ai/dsh-session'
|
|
import type { SessionEvent, SessionHeader } from '@deepseek-ai/dsh-session'
|
|
import { describe, expect, it, vi } from 'vitest'
|
|
import { createSessionTestController } from './test-remote.ts'
|
|
|
|
const defaults = {
|
|
defaultModelSelection: () => ({ provider: 'fixture', model: 'fixture-model' }),
|
|
cwd: '/tmp',
|
|
}
|
|
|
|
describe('SessionController facade', () => {
|
|
it('owns Host service methods and publishes Agent lifecycle projections', async () => {
|
|
const ctx = new Context()
|
|
await ctx.plugin(SessionStore)
|
|
await ctx.plugin(AgentRegistry)
|
|
const sessionId = SessionId('controller-session')
|
|
const header: SessionHeader = {
|
|
version: 0,
|
|
id: sessionId,
|
|
createdAt: 1,
|
|
cwd: '/workspace',
|
|
}
|
|
const events: SessionEvent[] = []
|
|
const inspect = vi.fn(() => Promise.resolve({ meta: header, events }))
|
|
ctx.provide('sessionPersistence', {
|
|
list: () => Promise.resolve([header]),
|
|
inspect,
|
|
} as never)
|
|
const controller = createSessionTestController(ctx, defaults)
|
|
const status = vi.fn()
|
|
const failure = vi.fn()
|
|
const activity = vi.fn()
|
|
ctx.on('api-session/status', status)
|
|
ctx.on('api-session/error', failure)
|
|
ctx.on('api-session/activity', activity)
|
|
|
|
await expect(controller.inspect(sessionId)).resolves.toEqual({ meta: header, events })
|
|
expect(inspect).toHaveBeenCalledOnce()
|
|
|
|
const session = ctx.sessions.create(sessionId, { meta: header })
|
|
const agent = {
|
|
id: sessionId,
|
|
session,
|
|
status: 'idle',
|
|
ctx,
|
|
} as Agent
|
|
ctx.agents.register(agent)
|
|
|
|
await expect(controller.resolveAgent(sessionId)).resolves.toEqual({ agent })
|
|
await expect(controller.inspect(sessionId)).resolves.toEqual({ meta: header, events })
|
|
expect(inspect).toHaveBeenCalledOnce()
|
|
ctx.emit('agent/status', { agent, status: 'running' })
|
|
ctx.emit('agent/error', { agent, turn: 1, step: 0, error: new Error('fixture failure') })
|
|
session.append('user/message', createUserMessage({
|
|
content: [{ type: 'text', text: 'hello' }],
|
|
source: { kind: 'user' },
|
|
}), { surfaceOp: 'append' })
|
|
expect(status).toHaveBeenCalledWith(sessionId, true)
|
|
expect(failure).toHaveBeenCalledWith(sessionId, expect.stringContaining('fixture failure'))
|
|
expect(activity).toHaveBeenCalledWith(sessionId, expect.any(Number))
|
|
|
|
const abort = new AbortController()
|
|
const iterator = controller.follow({
|
|
address: { kind: 'session', sessionId },
|
|
}, abort.signal)[Symbol.asyncIterator]()
|
|
await expect(iterator.next()).resolves.toMatchObject({
|
|
done: false,
|
|
value: { type: 'opened', cursor: 0 },
|
|
})
|
|
abort.abort()
|
|
await expect(iterator.next()).resolves.toEqual({ done: true, value: undefined })
|
|
})
|
|
})
|