Add unit tests for skill capabilities, skill planner, and UV setup

- Implement tests for random ID generation, ensuring preference for crypto.randomUUID.
- Create tests for runtime context capabilities, validating the injection of enabled skill capabilities.
- Add tests for skill capability parsing, including classification and command example extraction.
- Introduce tests for the skill planner, verifying tool call planning based on user requests and attachment requirements.
- Establish tests for UV setup, ensuring proper handling of Python installation scenarios and environment checks.
This commit is contained in:
DEV_DSW
2026-04-24 17:02:59 +08:00
parent e11a2296cc
commit 4c61e93c3e
42 changed files with 12560 additions and 224 deletions

View File

@@ -1,4 +1,5 @@
import type { GatewayChatMessage } from '@electron/providers/BaseProvider';
import { getEnabledSkillCapabilities } from './skill-capability-registry';
const AGENT_RUNTIME_CONTEXT = [
'You are zn-ai, a desktop AI assistant running through a local OpenClaw-style gateway.',
@@ -6,13 +7,51 @@ const AGENT_RUNTIME_CONTEXT = [
'Do not promise that an action was performed unless the runtime actually executed a listed tool.',
].join(' ');
const TOOL_RUNTIME_CONTEXT = [
'Available host tools in this build:',
'- browser.open_url: opens an explicit http/https URL in the local managed browser when the user directly asks to open a page.',
'- skills.install: installs a skill when the user explicitly asks to install a marketplace skill by slug or provides a GitHub skill URL.',
'Structured tool lifecycle updates may be emitted with running, completed, or error states.',
'Only claim a skill was installed after the runtime reports the tool completed successfully.',
].join('\n');
function formatRuntimeCapabilityLine(skill: ReturnType<typeof getEnabledSkillCapabilities>[number]): string {
const details: string[] = [`category=${skill.category}`];
if (skill.operationHints.length > 0) {
details.push(`operations=${skill.operationHints.join(',')}`);
}
if (skill.inputExtensions.length > 0) {
details.push(`inputs=${skill.inputExtensions.join(',')}`);
}
if (skill.allowedTools.length > 0) {
details.push(`allowedTools=${skill.allowedTools.join(',')}`);
}
if (skill.requiredEnvVars.length > 0) {
details.push(`env=${skill.requiredEnvVars.join(',')}`);
}
if (skill.requiresAuth) {
details.push('auth=required');
}
details.push(`summary=${skill.plannerSummary}`);
return `- ${skill.slug}: ${details.join('; ')}`;
}
function buildToolRuntimeContext(): string {
const enabledSkillCapabilities = getEnabledSkillCapabilities();
const skillCapabilityLines = enabledSkillCapabilities.length > 0
? enabledSkillCapabilities.map((skill) => formatRuntimeCapabilityLine(skill))
: ['- none'];
return [
'Available host tools in this build:',
'- browser.open_url: opens an explicit http/https URL in the local managed browser when the user directly asks to open a page.',
'- skills.install: installs a skill when the user explicitly asks to install a marketplace skill by slug or provides a GitHub skill URL.',
'Enabled skill capabilities registered for routing/planning:',
...skillCapabilityLines,
'Treat registered skills as planning capabilities for the downstream planner/executor chain, not as a claim that execution already happened.',
'Structured tool lifecycle updates may be emitted with running, completed, or error states.',
'Only claim a tool or skill action completed after the runtime reports success.',
].join('\n');
}
export function buildRuntimeContextMessages(sessionKey: string): GatewayChatMessage[] {
return [
@@ -20,7 +59,7 @@ export function buildRuntimeContextMessages(sessionKey: string): GatewayChatMess
role: 'system',
content: [
AGENT_RUNTIME_CONTEXT,
TOOL_RUNTIME_CONTEXT,
buildToolRuntimeContext(),
`Current session key: ${sessionKey}`,
].join('\n\n'),
},