mirror of
https://github.com/deepseek-ai/deepseek-harness.git
synced 2026-10-26 16:55:08 +00:00
fix(cordis): clarify resolver limits and isolate composition tests
This commit is contained in:
1 parent
f0700602fa
commit
7052192d4c
4 files changed
+18
-16
No files matched your search
@@ -242,8 +242,11 @@ export default defineConfig({
|
||||
// through its own package.json exports from the importer's directory, and
|
||||
// CSS still rides Vite's pipeline because the client build preset emits it
|
||||
// beside the bundle. Plugin packages never enter this graph; they arrive as
|
||||
// runtime bundles through the client module system. The remaining alias
|
||||
// browserizes the vendored Cordis Loader's only Node import.
|
||||
// runtime bundles through the client module system. The node:module alias
|
||||
// supports Loader initialization; its filesystem resolver's other Node
|
||||
// imports must stay default imports for Vite's browser-external stubs.
|
||||
// Browser boot supplies loader.internal before importing plugin entries,
|
||||
// so the filesystem resolver is never invoked in the browser.
|
||||
alias: [
|
||||
{ find: /^node:module$/, replacement: src('./src/node-module-stub.ts') },
|
||||
],
|
||||
|
||||
@@ -4,7 +4,7 @@ import { mkdtemp, rm, writeFile } from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
import { join, resolve } from 'node:path'
|
||||
import { pathToFileURL } from 'node:url'
|
||||
import { afterEach, expect, it } from 'vitest'
|
||||
import { afterEach, expect, it, vi } from 'vitest'
|
||||
import { Context } from '@deepseek-ai/cordis'
|
||||
import Loader from '@deepseek-ai/cordis-plugin-loader'
|
||||
import Include from '@deepseek-ai/cordis-plugin-include'
|
||||
@@ -21,6 +21,9 @@ import ToolRuntime, { defineContentToolFixture } from '@deepseek-ai/dsh-tools'
|
||||
import * as ClaudeCodeMods from '../src/index.ts'
|
||||
import { MockAdapter, textResponse, toolCallResponse } from '../../../core/agent-loop/tests/mock-adapter.ts'
|
||||
|
||||
// Keep workspace imports in Vitest's source graph even when the config has a package scope.
|
||||
vi.mock('@deepseek-ai/cordis-plugin-loader/src/resolve.ts', () => ({ createResolve: () => undefined }))
|
||||
|
||||
const FIXTURES = resolve(import.meta.dirname, 'fixtures')
|
||||
|
||||
let ctx: Context | undefined
|
||||
@@ -35,6 +38,7 @@ afterEach(async () => {
|
||||
|
||||
it('loads from cordis.yml, counts the model\'s tool calls, and answers /tally through the composed command registry', async () => {
|
||||
root = await mkdtemp(join(tmpdir(), 'dsh-cc-mods-composition-'))
|
||||
await writeFile(join(root, 'package.json'), JSON.stringify({ type: 'module' }))
|
||||
const configPath = join(root, 'cordis.yml')
|
||||
const modules = new Map<string, unknown>([
|
||||
['@deepseek-ai/dsh-llm', LlmRuntime],
|
||||
@@ -62,8 +66,6 @@ it('loads from cordis.yml, counts the model\'s tool calls, and answers /tally th
|
||||
context.baseUrl = pathToFileURL(root).href + '/'
|
||||
await context.plugin(Loader)
|
||||
context.loader.builtins.include = Include
|
||||
// Without a Node internal loader the Loader imports bare names through this
|
||||
// test runner's module graph, which resolves workspace packages to `src`.
|
||||
context.loader.internal = undefined
|
||||
await context.loader.create({ name: 'cordis:include', config: { path: pathToFileURL(configPath).href } })
|
||||
await context.loader.await()
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/** Loader resolves configuration imports in their project when Node internals are unavailable. */
|
||||
import { Context } from '@deepseek-ai/cordis'
|
||||
import Loader, { ModuleLoader } from '@deepseek-ai/cordis-plugin-loader'
|
||||
import Loader from '@deepseek-ai/cordis-plugin-loader'
|
||||
import { existsSync } from 'node:fs'
|
||||
import * as fs from 'node:fs/promises'
|
||||
import { tmpdir } from 'node:os'
|
||||
@@ -101,13 +101,4 @@ describe('Loader project resolution', () => {
|
||||
const tree = await treeFor('https://example.com/cordis.yml')
|
||||
expect(await tree.import('node:path')).toMatchObject({ join })
|
||||
})
|
||||
|
||||
it('uses the running Node loader signature selected by its module-job API', () => {
|
||||
const loader = ModuleLoader.fromInternal()
|
||||
expect(loader).toBeDefined()
|
||||
const resolved = loader!.version === 'v2'
|
||||
? loader!.resolveSync(import.meta.url, { specifier: 'node:path', attributes: {} })
|
||||
: loader!.resolveSync('node:path', import.meta.url, {})
|
||||
expect(resolved.url).toBe('node:path')
|
||||
})
|
||||
})
|
||||
Vendored
+7
-1
@@ -50,7 +50,13 @@ For file-backed trees, use `@cordisjs/plugin-include`.
|
||||
|
||||
## Module resolution
|
||||
|
||||
Without Node module internals, Loader resolves bare specifiers, package imports and self-references in the nearest package scope containing the configuration file. It writes an ignored `.cordis/resolve.mjs` helper in that scope to preserve native ESM import conditions. Relative specifiers use the configuration URL directly. If no scope exists or helper creation fails, Loader uses its native import fallback; project-only dependencies can then remain unavailable. Node module internals are classified by their available APIs, including the v1 API used by Node 24.0–24.11.
|
||||
Without Node module internals, Loader resolves bare specifiers, package imports and self-references in the nearest package scope containing the configuration file. Relative specifiers use the configuration URL directly, and `cordis:` builtins bypass filesystem resolution. Other specifiers, including `node:` builtins and absolute URLs, initialize an ignored `.cordis/resolve.mjs` helper in that scope to preserve native ESM import conditions.
|
||||
|
||||
If no scope exists or writing the helper files fails, Loader uses its native import fallback. This fallback emits no diagnostic of its own; project-only dependencies can remain unavailable, and the resulting import error can name the Loader module rather than the configuration project. Failure to import a written helper propagates to the caller without this fallback.
|
||||
|
||||
Initialization results are cached for the lifetime of the resolver module, including failed writes and rejected helper imports. Fixing the filesystem does not retry initialization for an already cached scope. Concurrent initialization through filesystem aliases of the same package can contend for the temporary helper files and cause a write failure.
|
||||
|
||||
Node module internals are classified by their available APIs, including the v1 API used by Node 24.0–24.11.
|
||||
|
||||
## Volatile configuration
|
||||
|
||||
|
||||
Reference in new issue
Block a user