feat: slot system + entries/priority/errorreport + typert generator

This commit is contained in:
imccyu
2026-08-12 21:59:23 +08:00
parent eec7f2ec74
commit 0367506471
28 changed files with 777 additions and 165 deletions

View File

@@ -5,9 +5,11 @@
import { describe, expect, it } from 'vitest'
import {
assertManifestComplete,
assertToolsHarvested,
collectToolCatalog,
render,
type ToolCatalog,
type ToolPackage,
} from '../../../../scripts/gen-tool-catalog.ts'
/** JSON Schema shape enough to reach the values AST extraction can't. */
@@ -23,7 +25,7 @@ describe('gen-tool-catalog collectToolCatalog', () => {
it('boots every shipped tool package and harvests its model-facing schemas', async () => {
const catalog = await collectToolCatalog()
const names = catalog.flatMap(entry => entry.schemas.map(s => s.name)).sort()
expect(names).toEqual(['ask_user_question', 'bash', 'bash', 'cordis_inspect', 'cordis_mount', 'cordis_unmount', 'create_goal', 'edit', 'exit_plan_mode', 'get_goal', 'glob', 'grep', 'interrupt_agent', 'job_kill', 'job_list', 'job_output', 'list_agents', 'lsp', 'pwsh', 'ralph', 'read', 'read_image', 'report', 'run_code', 'schedule_create', 'schedule_delete', 'schedule_list', 'send_message', 'session_event_read', 'session_event_search', 'session_event_trace', 'session_search', 'session_trace', 'skill', 'str_replace_editor', 'subagent', 'terminal_close', 'terminal_list', 'terminal_open', 'terminal_read', 'terminal_send', 'terminal_signal', 'todo_write', 'update_goal', 'web_fetch', 'web_search', 'workflow', 'write'])
expect(names).toEqual(['ask_user_question', 'bash', 'bash', 'cordis_define', 'cordis_package_inspect', 'cordis_run', 'cordis_runtime_inspect', 'cordis_stop', 'cordis_undefine', 'create_goal', 'edit', 'exit_plan_mode', 'get_goal', 'glob', 'grep', 'interrupt_agent', 'list_agents', 'lsp', 'pwsh', 'ralph', 'read', 'read_image', 'report', 'run_code', 'schedule_create', 'schedule_delete', 'schedule_list', 'send_message', 'session_event_read', 'session_event_search', 'session_event_trace', 'session_search', 'session_trace', 'skill', 'str_replace_editor', 'subagent', 'task_kill', 'task_list', 'task_output', 'terminal_close', 'terminal_list', 'terminal_open', 'terminal_read', 'terminal_send', 'terminal_signal', 'todo_write', 'update_goal', 'web_fetch', 'web_search', 'workflow', 'write'])
// Every tool carries a JSON-Schema `parameters` object (what the model sees).
for (const entry of catalog) {
for (const schema of entry.schemas) {
@@ -91,6 +93,29 @@ describe('gen-tool-catalog assertManifestComplete', () => {
})
})
describe('gen-tool-catalog assertToolsHarvested', () => {
const entry: ToolPackage = {
pkg: '@deepseek-ai/dsh-tool-demo',
dir: 'tool-demo',
source: 'packages/demo/tool-demo/src/index.ts',
requires: ['ctx.tools', 'ctx.somethingUnmounted'],
writes: ['tool/result'],
mount: () => Promise.resolve(),
}
it('accepts a boot that registered at least one tool', () => {
expect(() => { assertToolsHarvested(entry, 1) }).not.toThrow()
})
it('throws, naming the package and its requirements, when a boot registers nothing', () => {
// The failure this guards is silent by construction: the package is in the
// manifest, its plugin merely stays PENDING on an unmounted service, and the
// catalog would ship without its tools while every gate stays green.
expect(() => { assertToolsHarvested(entry, 0) }).toThrow(/@deepseek-ai\/dsh-tool-demo booted without registering a single tool/)
expect(() => { assertToolsHarvested(entry, 0) }).toThrow(/ctx.somethingUnmounted/)
})
})
describe('gen-tool-catalog render', () => {
it('emits a package heading, a tool heading, and a json schema fence', () => {
const catalog: ToolCatalog = [