Files
deepseek-harness/packages/agent/tests/agent.spec.ts
T
Tianyi Cui d5a1d9bb75 Add abstract service interface packages
@deepseek-ai/dsh-llm: provider-neutral content-block vocabulary
(merge-extensible maps), raw StreamChunk protocol, ToolSchema,
abstract LlmAdapter, LlmService adapter registry, BlockAssembler.

@deepseek-ai/dsh-session: event-sourced Session (append-only log,
deriveMessages; context/steering render as tagged envelopes),
SessionStore, session/event + awaited session/flush durability seam.

@deepseek-ai/dsh-system-prompt: ordered sections + tool-schema
providers; assemble() through the system-prompt/assemble waterfall.
Tool schemas are part of the assembly by design.

@deepseek-ai/dsh-tools: tool registry feeding schemas into the
assembly; execute() through the tools/execute waterfall (the single
sandbox/permission/hook seam).

@deepseek-ai/dsh-agent: Agent interface (send/steer/inject/abort,
spawn/fork TODO seams), AgentRegistry, and the full agent/* event
taxonomy so plugins never depend on the concrete loop.
2026-06-11 10:54:06 +08:00

55 lines
1.7 KiB
TypeScript

import { describe, expect, it } from 'vitest'
import { Context } from 'cordis'
import { Session } from '@deepseek-ai/dsh-session'
import AgentRegistry, { Agent } from '@deepseek-ai/dsh-agent'
function stubAgent(id: string): Agent {
return {
id,
options: {},
session: new Session(`${id}-session`),
status: 'idle',
send() {},
steer() {},
inject() {},
abort() {},
}
}
describe('AgentRegistry', () => {
it('registers agents and emits created/disposed events', async () => {
const ctx = new Context()
await ctx.plugin(AgentRegistry)
const created: string[] = []
const disposed: string[] = []
ctx.on('agent/created', agent => void created.push(agent.id))
ctx.on('agent/disposed', agent => void disposed.push(agent.id))
const agent = stubAgent('a1')
const dispose = ctx.agents.register(agent)
expect(created).toEqual(['a1'])
expect(ctx.agents.get('a1')).toBe(agent)
expect(ctx.agents.list()).toEqual([agent])
dispose()
expect(disposed).toEqual(['a1'])
expect(ctx.agents.get('a1')).toBeUndefined()
})
it('rejects duplicate ids and unregisters on fiber dispose (HMR safety)', async () => {
const ctx = new Context()
await ctx.plugin(AgentRegistry)
ctx.agents.register(stubAgent('main'))
expect(() => ctx.agents.register(stubAgent('main'))).toThrow('already registered')
const fiber = await ctx.plugin(Object.assign((inner: Context) => {
inner.agents.register(stubAgent('scoped'))
}, { inject: ['agents'] }))
expect(ctx.agents.list().map(a => a.id)).toEqual(['main', 'scoped'])
await fiber.dispose()
expect(ctx.agents.list().map(a => a.id)).toEqual(['main'])
})
})