mirror of
https://github.com/deepseek-ai/deepseek-harness
synced 2026-08-15 21:04:50 +00:00
Machine-produced by `pnpm run rescope-vendor --apply` plus the regeneration it prints: `pnpm install` for the lockfile, `pnpm run gen-third-party-notices`, `verify-translation-pairing --write` for the touched bilingual pairs, `gen-doc-graphs`, and one typert snapshot whose ids embed character offsets. `pnpm run rescope-vendor --check` verifies the result. Renames nine vendored packages (cordis, cosmokit, schemastery and the six @cordisjs plugins) and every reference that resolves them: manifest names and dependency keys, module specifiers including declare-module merges, cordis.yml plugin names, tsconfig paths, every Markdown fence, and `docs/` prose. Directory names, upstream versions, and dependency ranges are unchanged, so vendor/README.md still reads as an upstream snapshot; its manifest table gains an upstream-name column so THIRD_PARTY_NOTICES keeps MIT attribution pointed at each fork's origin. The tutorial tier follows the rename end to end: its yaml fences named plugins the Loader can no longer resolve, its `ts ignore-check` fences disagreed with the compiled fences beside them, and its prose quoted both. The contracts that told readers to keep upstream names — the root convention and the vendoring cookbook's tree comment and manifest invariant — now say to rescope instead. Two rules read `@deepseek-ai/` as "another workspace plugin": the client bundle purity gate now names the vendored libraries a browser bundle inlines, and the files where a bare `cordis` is an agent-preset id keep that product data.
142 lines
5.2 KiB
TypeScript
142 lines
5.2 KiB
TypeScript
/** Covers fail-closed per-call classification and model-schema isolation. */
|
|
|
|
import { describe, expect, expectTypeOf, it } from 'vitest'
|
|
import { Context } from '@deepseek-ai/cordis'
|
|
import { CallId } from '@deepseek-ai/dsh-llm'
|
|
import SystemPrompt from '@deepseek-ai/dsh-system-prompt'
|
|
import ToolRegistry, {
|
|
defineContentToolFixture,
|
|
type ToolDefinition,
|
|
type ToolExecutionInput,
|
|
type ToolExecutionMode,
|
|
} from '@deepseek-ai/dsh-tools'
|
|
|
|
const testToolSignal = new AbortController().signal
|
|
|
|
async function setup() {
|
|
const ctx = new Context()
|
|
await ctx.plugin(SystemPrompt)
|
|
await ctx.plugin(ToolRegistry)
|
|
return ctx
|
|
}
|
|
|
|
function exec(name: string, args: unknown): ToolExecutionInput {
|
|
return { signal: testToolSignal, callId: CallId('c1'), name, arguments: args }
|
|
}
|
|
|
|
describe('ToolRegistry.executionMode', () => {
|
|
it('returns parallel only for an explicit true classifier', async () => {
|
|
const ctx = await setup()
|
|
ctx.tools.register(defineContentToolFixture({
|
|
name: 'safe',
|
|
description: 'parallel-safe',
|
|
parameters: {},
|
|
isConcurrencySafe: () => true,
|
|
async execute() { return [] },
|
|
}))
|
|
expect(ctx.tools.executionMode(exec('safe', {}))).toEqual({ kind: 'parallel' })
|
|
})
|
|
|
|
it('defaults to exclusive for a tool with no isConcurrencySafe declaration', async () => {
|
|
const ctx = await setup()
|
|
ctx.tools.register(defineContentToolFixture({
|
|
name: 'plain',
|
|
description: 'no declaration',
|
|
parameters: {},
|
|
async execute() { return [] },
|
|
}))
|
|
expect(ctx.tools.executionMode(exec('plain', {}))).toEqual({ kind: 'exclusive' })
|
|
})
|
|
|
|
it('returns exclusive for an unknown tool', async () => {
|
|
const ctx = await setup()
|
|
expect(ctx.tools.executionMode(exec('nonexistent', {}))).toEqual({ kind: 'exclusive' })
|
|
})
|
|
|
|
it('returns exclusive when the classifier returns false for these args', async () => {
|
|
const ctx = await setup()
|
|
ctx.tools.register(defineContentToolFixture({
|
|
name: 'rw',
|
|
description: 'read or write',
|
|
parameters: { mode: { type: 'string', required: true } },
|
|
isConcurrencySafe: args => args.mode === 'read',
|
|
async execute() { return [] },
|
|
}))
|
|
expect(ctx.tools.executionMode(exec('rw', { mode: 'read' }))).toEqual({ kind: 'parallel' })
|
|
expect(ctx.tools.executionMode(exec('rw', { mode: 'write' }))).toEqual({ kind: 'exclusive' })
|
|
})
|
|
|
|
it('classifies invalid defineContentToolFixture arguments as exclusive without throwing', async () => {
|
|
const ctx = await setup()
|
|
ctx.tools.register(defineContentToolFixture({
|
|
name: 'needs-mode',
|
|
description: 'requires mode',
|
|
parameters: { mode: { type: 'string', required: true } },
|
|
isConcurrencySafe: () => true,
|
|
async execute() { return [] },
|
|
}))
|
|
expect(ctx.tools.executionMode(exec('needs-mode', {}))).toEqual({ kind: 'exclusive' })
|
|
})
|
|
|
|
it('treats a throwing raw classifier as exclusive', async () => {
|
|
const ctx = await setup()
|
|
const raw: ToolDefinition = {
|
|
name: 'thrower',
|
|
description: 'classifier throws',
|
|
parameters: { type: 'object', properties: {} },
|
|
output: { schema: { type: 'null' }, render: () => [] },
|
|
isConcurrencySafe() { throw new Error('boom') },
|
|
async execute() { return null },
|
|
}
|
|
ctx.tools.register(raw)
|
|
expect(ctx.tools.executionMode(exec('thrower', {}))).toEqual({ kind: 'exclusive' })
|
|
})
|
|
|
|
it('treats a truthy non-boolean raw result as exclusive', async () => {
|
|
const ctx = await setup()
|
|
const raw = {
|
|
name: 'truthy',
|
|
description: 'classifier returns a truthy string',
|
|
parameters: { type: 'object', properties: {} },
|
|
output: { schema: { type: 'null' }, render: () => [] },
|
|
isConcurrencySafe() { return 'yes' },
|
|
async execute() { return null },
|
|
} as unknown as ToolDefinition
|
|
ctx.tools.register(raw)
|
|
expect(ctx.tools.executionMode(exec('truthy', {}))).toEqual({ kind: 'exclusive' })
|
|
})
|
|
|
|
it('passes parsed arguments directly to a raw definition', async () => {
|
|
const ctx = await setup()
|
|
let seen: unknown
|
|
ctx.tools.register({
|
|
name: 'raw-safe',
|
|
description: 'raw',
|
|
parameters: { type: 'object', properties: {} },
|
|
output: { schema: { type: 'null' }, render: () => [] },
|
|
isConcurrencySafe(args) { seen = args; return true },
|
|
async execute() { return null },
|
|
})
|
|
expect(ctx.tools.executionMode(exec('raw-safe', { anything: 1 }))).toEqual({ kind: 'parallel' })
|
|
expect(seen).toEqual({ anything: 1 })
|
|
})
|
|
|
|
it('isConcurrencySafe never reaches the model-facing schemas() projection', async () => {
|
|
const ctx = await setup()
|
|
ctx.tools.register(defineContentToolFixture({
|
|
name: 'safe',
|
|
description: 'parallel-safe',
|
|
parameters: { x: { type: 'string', required: true } },
|
|
isConcurrencySafe: () => true,
|
|
async execute() { return [] },
|
|
}))
|
|
const schema = ctx.tools.schemas()[0] as unknown as Record<string, unknown>
|
|
expect(Object.keys(schema).sort()).toEqual(['description', 'name', 'parameters'])
|
|
expect(schema.isConcurrencySafe).toBeUndefined()
|
|
})
|
|
|
|
it('ToolExecutionMode is the object-tagged union', () => {
|
|
expectTypeOf<ToolExecutionMode>().toEqualTypeOf<{ kind: 'parallel' } | { kind: 'exclusive' }>()
|
|
})
|
|
})
|