Merge branch 'master' of https://github.com/deepseek-harness/deepseek-harness into xtr/react-loop-simplification
# Conflicts: # .agents/notes/implemented/feature/2026-07-17-dedicated-full-screen-tui-front-door.i18n.yaml # docs/architecture.i18n.yaml # docs/cookbook/extension-cookbook.i18n.yaml # docs/cordis-catalog/events.md # docs/cordis-catalog/services.md # docs/core-data-structures/core.i18n.yaml # docs/core-data-structures/core.md # docs/core-data-structures/core.zh.md # docs/core-data-structures/llm-streaming.i18n.yaml # docs/core-data-structures/llm-streaming.md # docs/core-data-structures/llm-streaming.zh.md # docs/core-data-structures/session.i18n.yaml # docs/event-producer-consumer.md # docs/persistence-catalog.md # packages/cordis/tool-cordis/src/api-catalog.ts # packages/core/agent-loop/README.i18n.yaml # packages/core/agent-loop/src/agent.ts # packages/core/agent/README.i18n.yaml # packages/core/session/README.i18n.yaml # packages/core/session/src/types.ts # packages/llm/llm/README.i18n.yaml # packages/llm/llm/README.md # packages/llm/llm/README.zh.md # packages/llm/llm/src/index.ts # packages/llm/llm/tests/service.spec.ts # packages/sdk/sdk-client/README.i18n.yaml # packages/sdk/sdk-protocol/README.i18n.yaml # packages/sdk/sdk-protocol/README.md # packages/sdk/sdk-protocol/README.zh.md # packages/subagent/subagent-dsh-sdk/README.i18n.yaml # packages/ui/jsonrpc/README.i18n.yaml # packages/ui/jsonrpc/README.md # packages/ui/jsonrpc/README.zh.md # packages/ui/tui/src/index.ts # python/sdk/README.i18n.yaml # scripts/gen-cordis-catalog.ts
This commit is contained in:
@@ -155,7 +155,7 @@ describe('dsh-jsonrpc plugin apply', () => {
|
||||
vi.stubEnv('DEEPSEEK_API_KEY', 'test-key')
|
||||
const harness = await mountPlugin(storageDir)
|
||||
try {
|
||||
harness.send({ jsonrpc: '2.0', id: 'init-1', method: 'initialize', params: { cwd: storageDir, provider: 'deepseek', model: 'apply-model' } })
|
||||
harness.send({ jsonrpc: '2.0', id: 'init-1', method: 'initialize', params: { cwd: storageDir, provider: 'deepseek-official', model: 'apply-model' } })
|
||||
|
||||
const response = await harness.waitForFrame(frame => frame.id === 'init-1', 'initialize response')
|
||||
expect(response).toEqual({
|
||||
@@ -177,7 +177,7 @@ describe('dsh-jsonrpc plugin apply', () => {
|
||||
vi.stubEnv('DEEPSEEK_BASE_URL', llmServer.url)
|
||||
const harness = await mountPlugin(storageDir)
|
||||
try {
|
||||
harness.send({ jsonrpc: '2.0', id: 1, method: 'initialize', params: { cwd: storageDir, provider: 'deepseek', model: 'dsagent-model' } })
|
||||
harness.send({ jsonrpc: '2.0', id: 1, method: 'initialize', params: { cwd: storageDir, provider: 'deepseek-official', model: 'dsagent-model' } })
|
||||
await harness.waitForFrame(frame => frame.id === 1, 'initialize response')
|
||||
|
||||
harness.send({
|
||||
@@ -246,7 +246,7 @@ describe('dsh-jsonrpc plugin apply', () => {
|
||||
expect(harness.events.filter(event => event.kind === 'root-disposed')).toHaveLength(1)
|
||||
|
||||
const before = harness.frames().length
|
||||
harness.send({ jsonrpc: '2.0', id: 'after-exit', method: 'initialize', params: { cwd: storageDir, provider: 'deepseek', model: 'x' } })
|
||||
harness.send({ jsonrpc: '2.0', id: 'after-exit', method: 'initialize', params: { cwd: storageDir, provider: 'deepseek-official', model: 'x' } })
|
||||
await settle()
|
||||
expect(harness.frames().length).toBe(before)
|
||||
} finally {
|
||||
@@ -268,7 +268,7 @@ describe('dsh-jsonrpc plugin apply', () => {
|
||||
expect(harness.outputErrors.map(error => error.message)).toEqual(['flush callback failed'])
|
||||
|
||||
const before = harness.frames().length
|
||||
harness.send({ jsonrpc: '2.0', id: 'after-flush-failure', method: 'initialize', params: { cwd: storageDir, provider: 'deepseek', model: 'x' } })
|
||||
harness.send({ jsonrpc: '2.0', id: 'after-flush-failure', method: 'initialize', params: { cwd: storageDir, provider: 'deepseek-official', model: 'x' } })
|
||||
await settle()
|
||||
expect(harness.frames().length).toBe(before)
|
||||
} finally {
|
||||
@@ -293,7 +293,7 @@ describe('dsh-jsonrpc plugin apply', () => {
|
||||
expect(harness.events.some(event => event.kind === 'root-disposed')).toBe(false)
|
||||
|
||||
const before = harness.frames().length
|
||||
harness.send({ jsonrpc: '2.0', id: 'probe-2', method: 'initialize', params: { cwd: storageDir, provider: 'deepseek', model: 'x' } })
|
||||
harness.send({ jsonrpc: '2.0', id: 'probe-2', method: 'initialize', params: { cwd: storageDir, provider: 'deepseek-official', model: 'x' } })
|
||||
await settle()
|
||||
expect(harness.frames().length).toBe(before)
|
||||
expect(harness.exits()).toEqual([])
|
||||
|
||||
@@ -121,7 +121,7 @@ describe('HarnessSdkServer', () => {
|
||||
|
||||
const init = await server.handleRequest('initialize', {
|
||||
cwd: storageDir,
|
||||
provider: 'deepseek',
|
||||
provider: 'deepseek-official',
|
||||
model: 'dsagent-model',
|
||||
maxTokens: 321,
|
||||
}) as { serverInfo: { name: string } }
|
||||
@@ -157,7 +157,7 @@ describe('HarnessSdkServer', () => {
|
||||
const orphanHandle = await ctx.agents.create({
|
||||
sessionId: SessionId('orphan-session'),
|
||||
meta: { cwd: storageDir },
|
||||
agentOptions: { provider: 'deepseek', model: 'dsagent-model' },
|
||||
agentOptions: { provider: 'deepseek-official', model: 'dsagent-model' },
|
||||
})
|
||||
orphanHandle.agent.followup(createUserMessage({ content: [{ type: 'text', text: 'outside the sdk session map' }], source: { kind: 'user' } }))
|
||||
await orphanHandle.agent.whenIdle()
|
||||
@@ -304,7 +304,7 @@ describe('HarnessSdkServer', () => {
|
||||
try {
|
||||
const server = new HarnessSdkServer(ctx, new FakeTransport())
|
||||
|
||||
await server.initialize({ cwd: storageDir, provider: 'deepseek', model: 'plain-model' })
|
||||
await server.initialize({ cwd: storageDir, provider: 'deepseek-official', model: 'plain-model' })
|
||||
await server.prompt({
|
||||
sessionId: 'plain',
|
||||
contentBlocks: [{ type: 'text', text: 'hello' }],
|
||||
@@ -328,20 +328,20 @@ describe('HarnessSdkServer', () => {
|
||||
const parentHandle = await ctx.agents.create({
|
||||
sessionId: SessionId('main'),
|
||||
meta: { cwd: storageDir },
|
||||
agentOptions: { provider: 'deepseek', model: 'deepseek' },
|
||||
agentOptions: { provider: 'deepseek-official', model: 'deepseek-official' },
|
||||
})
|
||||
// A custom in-process provider may own its child at the provider/root
|
||||
// scope while preserving durable parent lineage.
|
||||
const handle = await ctx.agents.create({
|
||||
sessionId: SessionId('child-session'),
|
||||
meta: { cwd: storageDir, parentSession: SessionId('main') },
|
||||
agentOptions: { provider: 'deepseek', model: 'deepseek' },
|
||||
agentOptions: { provider: 'deepseek-official', model: 'deepseek-official' },
|
||||
})
|
||||
expect(ctx.agents.roots()).toContain(handle.agent)
|
||||
const parentlessHandle = await parentHandle.agent.ctx.agents.create({
|
||||
sessionId: SessionId('parentless-child-session'),
|
||||
meta: { cwd: storageDir },
|
||||
agentOptions: { model: 'deepseek' },
|
||||
agentOptions: { model: 'deepseek-official' },
|
||||
})
|
||||
await settleSubagent(ctx, parentHandle.agent, {
|
||||
provider: 'spawn',
|
||||
@@ -398,12 +398,12 @@ describe('HarnessSdkServer', () => {
|
||||
const parentHandle = await ctx.agents.create({
|
||||
sessionId: SessionId('collision-parent'),
|
||||
meta: { cwd: storageDir },
|
||||
agentOptions: { model: 'deepseek' },
|
||||
agentOptions: { model: 'deepseek-official' },
|
||||
})
|
||||
const collidingChild = await parentHandle.agent.ctx.agents.create({
|
||||
sessionId: SessionId('remote-run-id'),
|
||||
meta: { cwd: storageDir, parentSession: SessionId('collision-parent') },
|
||||
agentOptions: { model: 'deepseek' },
|
||||
agentOptions: { model: 'deepseek-official' },
|
||||
})
|
||||
|
||||
await settleSubagent(ctx, parentHandle.agent, {
|
||||
@@ -437,12 +437,12 @@ describe('HarnessSdkServer', () => {
|
||||
const parentHandle = await ctx.agents.create({
|
||||
sessionId: SessionId('continuation-parent'),
|
||||
meta: { cwd: storageDir },
|
||||
agentOptions: { model: 'deepseek' },
|
||||
agentOptions: { model: 'deepseek-official' },
|
||||
})
|
||||
const childHandle = await parentHandle.agent.ctx.agents.create({
|
||||
sessionId: SessionId('continuation-child'),
|
||||
meta: { cwd: storageDir, parentSession: SessionId('continuation-parent') },
|
||||
agentOptions: { model: 'deepseek' },
|
||||
agentOptions: { model: 'deepseek-official' },
|
||||
})
|
||||
|
||||
await settleSubagent(ctx, parentHandle.agent, {
|
||||
@@ -482,12 +482,12 @@ describe('HarnessSdkServer', () => {
|
||||
const oldParent = await ctx.agents.create({
|
||||
sessionId: SessionId('old-parent'),
|
||||
meta: { cwd: storageDir },
|
||||
agentOptions: { model: 'deepseek' },
|
||||
agentOptions: { model: 'deepseek-official' },
|
||||
})
|
||||
const oldChild = await oldParent.agent.ctx.agents.create({
|
||||
sessionId: SessionId('reused-child'),
|
||||
meta: { cwd: storageDir, parentSession: SessionId('old-parent') },
|
||||
agentOptions: { model: 'deepseek' },
|
||||
agentOptions: { model: 'deepseek-official' },
|
||||
})
|
||||
const first = Promise.withResolvers<SubagentResult>()
|
||||
const sameLifetime = Promise.withResolvers<SubagentResult>()
|
||||
@@ -523,12 +523,12 @@ describe('HarnessSdkServer', () => {
|
||||
const newParent = await ctx.agents.create({
|
||||
sessionId: SessionId('new-parent'),
|
||||
meta: { cwd: storageDir },
|
||||
agentOptions: { model: 'deepseek' },
|
||||
agentOptions: { model: 'deepseek-official' },
|
||||
})
|
||||
const newChild = await newParent.agent.ctx.agents.create({
|
||||
sessionId: SessionId('reused-child'),
|
||||
meta: { cwd: storageDir, parentSession: SessionId('new-parent') },
|
||||
agentOptions: { model: 'deepseek' },
|
||||
agentOptions: { model: 'deepseek-official' },
|
||||
})
|
||||
currentLocalAgent = newChild.agent
|
||||
const secondRun = await ctx.subagents.start('reused', {
|
||||
@@ -581,12 +581,12 @@ describe('HarnessSdkServer', () => {
|
||||
const parent = await ctx.agents.create({
|
||||
sessionId: SessionId('provider-reuse-parent'),
|
||||
meta: { cwd: storageDir },
|
||||
agentOptions: { model: 'deepseek' },
|
||||
agentOptions: { model: 'deepseek-official' },
|
||||
})
|
||||
const child = await parent.agent.ctx.agents.create({
|
||||
sessionId: SessionId('provider-reuse-child'),
|
||||
meta: { cwd: storageDir, parentSession: SessionId('provider-reuse-parent') },
|
||||
agentOptions: { model: 'deepseek' },
|
||||
agentOptions: { model: 'deepseek-official' },
|
||||
})
|
||||
const localResult = Promise.withResolvers<SubagentResult>()
|
||||
const remoteResult = Promise.withResolvers<SubagentResult>()
|
||||
@@ -674,18 +674,18 @@ describe('HarnessSdkServer', () => {
|
||||
parentHandle = await ctx.agents.create({
|
||||
sessionId: SessionId('fallback-parent'),
|
||||
meta: { cwd: storageDir },
|
||||
agentOptions: { provider: 'deepseek', model: 'deepseek' },
|
||||
agentOptions: { provider: 'deepseek-official', model: 'deepseek-official' },
|
||||
})
|
||||
handle = await parentHandle.agent.ctx.agents.create({
|
||||
sessionId: SessionId('fallback-child-session'),
|
||||
meta: { cwd: storageDir, parentSession: SessionId('fallback-parent') },
|
||||
agentOptions: { provider: 'deepseek', model: 'deepseek' },
|
||||
agentOptions: { provider: 'deepseek-official', model: 'deepseek-official' },
|
||||
})
|
||||
const fallbackChild = handle.agent
|
||||
failedHandle = await parentHandle.agent.ctx.agents.create({
|
||||
sessionId: SessionId('failed-child-session'),
|
||||
meta: { cwd: storageDir },
|
||||
agentOptions: { provider: 'deepseek', model: 'deepseek' },
|
||||
agentOptions: { provider: 'deepseek-official', model: 'deepseek-official' },
|
||||
})
|
||||
const missedStartResult = Promise.withResolvers<SubagentResult>()
|
||||
const disposeMissedStartProvider = ctx.subagents.registerProvider({
|
||||
@@ -783,11 +783,11 @@ describe('HarnessSdkServer', () => {
|
||||
const server = new HarnessSdkServer(ctx, new FakeTransport())
|
||||
const inspect = server as unknown as { hasAdapterFor(provider: string): boolean }
|
||||
|
||||
expect(inspect.hasAdapterFor('deepseek')).toBe(true)
|
||||
expect(inspect.hasAdapterFor('deepseek-official')).toBe(true)
|
||||
expect(inspect.hasAdapterFor('missing-provider')).toBe(false)
|
||||
await server.initialize({ cwd: storageDir, provider: 'deepseek', model: 'preinstalled-model' })
|
||||
await server.initialize({ cwd: storageDir, provider: 'deepseek-official', model: 'preinstalled-model' })
|
||||
|
||||
expect(ctx.get('llm')?.listProviders().filter(provider => provider.id === 'deepseek')).toEqual([{ id: 'deepseek', name: 'DeepSeek' }])
|
||||
expect(ctx.get('llm')?.listProviders().filter(provider => provider.id === 'deepseek-official')).toEqual([{ id: 'deepseek-official', name: 'DeepSeek' }])
|
||||
await server.shutdown()
|
||||
} finally {
|
||||
await ctx.fiber.dispose()
|
||||
@@ -806,7 +806,7 @@ describe('HarnessSdkServer', () => {
|
||||
await expect(server.initialize({ cwd: storageDir, provider: 'private', model: 'new-model' }))
|
||||
.rejects.toThrow('no adapter registered for provider "private"')
|
||||
|
||||
expect(ctx.get('llm')?.listProviders()).toEqual([{ id: 'deepseek', name: 'DeepSeek' }])
|
||||
expect(ctx.get('llm')?.listProviders()).toEqual([{ id: 'deepseek-official', name: 'DeepSeek' }])
|
||||
await server.shutdown()
|
||||
} finally {
|
||||
await ctx.fiber.dispose()
|
||||
@@ -823,7 +823,7 @@ describe('HarnessSdkServer', () => {
|
||||
const server = new HarnessSdkServer(ctx, new FakeTransport())
|
||||
await expect(server.initialize({
|
||||
cwd: storageDir,
|
||||
provider: 'deepseek',
|
||||
provider: 'deepseek-official',
|
||||
model: 'model',
|
||||
maxTokens,
|
||||
})).rejects.toThrow('initialize maxTokens must be a positive safe integer')
|
||||
|
||||
Reference in New Issue
Block a user