mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
Apply the accepted pre-release package, service, type, directory, and role renames as one repository-wide change.
133 lines
4.4 KiB
TypeScript
133 lines
4.4 KiB
TypeScript
/**
|
|
* The third-party memory examples stay config-only. This suite parses every
|
|
* checked-in overlay, verifies its package pin, transport, and secret handling, then replaces
|
|
* only the upstream endpoint with the package-owned keyless MCP fixture and
|
|
* proves the real Cordis Loader discovers a tool through the generic bridge.
|
|
*/
|
|
|
|
import { readFileSync } from 'node:fs'
|
|
import { resolve } from 'node:path'
|
|
import { afterEach, describe, expect, it } from 'vitest'
|
|
import type { Context } from '@deepseek-ai/cordis'
|
|
import type { PatchOptions } from '@deepseek-ai/cordis-plugin-include'
|
|
import { boot, loadOverlayPatches } from '@deepseek-ai/dsh-app-boot'
|
|
import SystemPrompt from '@deepseek-ai/dsh-system-prompt'
|
|
import ToolRuntime from '@deepseek-ai/dsh-tools'
|
|
import * as McpClient from '@deepseek-ai/dsh-mcp-client/src/index.ts'
|
|
|
|
interface ExampleContract {
|
|
file: string
|
|
id: string
|
|
serverName: string
|
|
transport: 'stdio' | 'streamable-http'
|
|
pin: string
|
|
}
|
|
|
|
interface InsertedRow {
|
|
id?: string
|
|
name?: string
|
|
config?: Record<string, unknown>
|
|
}
|
|
|
|
const root = resolve(import.meta.dirname, '../../..')
|
|
const exampleDir = resolve(root, 'examples/mcp-memory')
|
|
const baseConfig = resolve(import.meta.dirname, 'fixtures/memory-mcp-base.cordis.yml')
|
|
const fixtureServer = resolve(root, 'packages/mcp/mcp-client/tests/fixture-server.ts')
|
|
|
|
const examples: ExampleContract[] = [
|
|
{
|
|
file: 'memorix.cordis.yml',
|
|
id: 'memory-memorix',
|
|
serverName: 'memorix',
|
|
transport: 'stdio',
|
|
pin: '1.3.0',
|
|
},
|
|
{
|
|
file: 'mcp-reference-memory.cordis.yml',
|
|
id: 'memory-mcp-reference',
|
|
serverName: 'reference_memory',
|
|
transport: 'stdio',
|
|
pin: '2026.7.4',
|
|
},
|
|
{
|
|
file: 'engram.cordis.yml',
|
|
id: 'memory-engram',
|
|
serverName: 'engram',
|
|
transport: 'stdio',
|
|
pin: '1.20.0',
|
|
},
|
|
]
|
|
|
|
const liveContexts = new Set<Context>()
|
|
|
|
afterEach(async () => {
|
|
await Promise.all([...liveContexts].map(async ctx => ctx.fiber.dispose()))
|
|
liveContexts.clear()
|
|
})
|
|
|
|
function insertedRow(patches: PatchOptions[]): InsertedRow {
|
|
expect(patches).toHaveLength(1)
|
|
const insert = patches[0]?.insert
|
|
expect(insert).toHaveLength(1)
|
|
return insert?.[0] as InsertedRow
|
|
}
|
|
|
|
async function waitForTool(ctx: Context, name: string): Promise<void> {
|
|
const deadline = Date.now() + 10_000
|
|
while (!ctx.tools.schemas().some(schema => schema.name === name)) {
|
|
if (Date.now() >= deadline) throw new Error(`timed out waiting for ${name}`)
|
|
await new Promise(resolveWait => setTimeout(resolveWait, 25))
|
|
}
|
|
}
|
|
|
|
describe('third-party memory MCP example overlays', () => {
|
|
it.each(examples)('parses $file with the documented generic plugin fields', (contract) => {
|
|
const file = resolve(exampleDir, contract.file)
|
|
const source = readFileSync(file, 'utf8')
|
|
const row = insertedRow(loadOverlayPatches('memory-mcp-config-test', file))
|
|
|
|
expect(row.id).toBe(contract.id)
|
|
expect(row.name).toBe('@deepseek-ai/dsh-mcp-client')
|
|
expect(row.config?.serverName).toBe(contract.serverName)
|
|
expect(row.config?.transport).toBe(contract.transport)
|
|
expect(source.split('\n', 1)[0]).toContain(contract.pin)
|
|
expect(source).not.toMatch(/\bsk-[A-Za-z0-9_-]{8,}\b/)
|
|
expect(source).not.toContain('DEEPSEEK_API_KEY')
|
|
})
|
|
|
|
it.each(examples)('loads $file and discovers a keyless fixture tool', async (contract) => {
|
|
const patches = loadOverlayPatches(
|
|
'memory-mcp-config-test',
|
|
resolve(exampleDir, contract.file),
|
|
)
|
|
// The static config gate verifies the checked-in bare package specifier.
|
|
// The unit test maps it to the source module so a clean checkout needs no
|
|
// prebuilt `lib/` artifacts before proving the Loader/MCP behavior.
|
|
insertedRow(patches).name = 'cordis:memory-test-mcp-client'
|
|
const fixturePatch: PatchOptions = {
|
|
id: contract.id,
|
|
config: {
|
|
serverName: contract.serverName,
|
|
transport: 'stdio',
|
|
command: process.execPath,
|
|
args: [fixtureServer],
|
|
env: {},
|
|
cwd: root,
|
|
toolCallTimeoutMs: 5_000,
|
|
},
|
|
}
|
|
const ctx = await boot(
|
|
'memory-mcp-config-test',
|
|
baseConfig,
|
|
[...patches, fixturePatch],
|
|
(ctx) => {
|
|
liveContexts.add(ctx)
|
|
ctx.loader.builtins['memory-test-system-prompt'] = SystemPrompt
|
|
ctx.loader.builtins['memory-test-tools'] = ToolRuntime
|
|
ctx.loader.builtins['memory-test-mcp-client'] = McpClient
|
|
},
|
|
)
|
|
await waitForTool(ctx, `mcp__${contract.serverName}__greet`)
|
|
}, 15_000)
|
|
})
|