fix: close Kimi runtime review gaps
This commit is contained in:
@@ -10,12 +10,17 @@
|
||||
const { test, describe, beforeEach, afterEach } = require('node:test');
|
||||
const assert = require('node:assert/strict');
|
||||
const fs = require('fs');
|
||||
const os = require('os');
|
||||
const path = require('path');
|
||||
const { spawnSync } = require('node:child_process');
|
||||
const { runGsdTools, createTempProject, cleanup } = require('./helpers.cjs');
|
||||
const { installerEnv } = require('./helpers/install-shared.cjs');
|
||||
|
||||
const AGENTS_DIR_NAME = 'agents';
|
||||
const MODEL_PROFILES = require('../gsd-core/bin/lib/model-profiles.cjs').MODEL_PROFILES;
|
||||
const EXPECTED_AGENTS = Object.keys(MODEL_PROFILES);
|
||||
const ROOT = path.join(__dirname, '..');
|
||||
const INSTALL_SCRIPT = path.join(ROOT, 'bin', 'install.js');
|
||||
|
||||
/**
|
||||
* Create a fake GSD install directory structure that mirrors what the installer
|
||||
@@ -276,6 +281,76 @@ describe('checkAgentsInstalled: Copilot .agent.md format (#1512)', () => {
|
||||
});
|
||||
});
|
||||
|
||||
// ─── Kimi agents/subagents detection (#743 review) ─────────────────────────
|
||||
|
||||
describe('checkAgentsInstalled: Kimi agents/subagents layout', () => {
|
||||
test('Kimi install is detected by init, validate agents, and health checks', () => {
|
||||
const tmpDir = createTempProject('gsd-kimi-agent-status-project-');
|
||||
const tmpConfig = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-kimi-agent-status-config-'));
|
||||
const tmpHome = fs.mkdtempSync(path.join(os.tmpdir(), 'gsd-kimi-agent-status-home-'));
|
||||
const env = installerEnv({
|
||||
HOME: tmpHome,
|
||||
USERPROFILE: tmpHome,
|
||||
KIMI_CONFIG_DIR: tmpConfig,
|
||||
});
|
||||
|
||||
try {
|
||||
const installResult = spawnSync(
|
||||
process.execPath,
|
||||
[INSTALL_SCRIPT, '--kimi', '--global', '--config-dir', tmpConfig, '--no-sdk'],
|
||||
{
|
||||
cwd: tmpDir,
|
||||
encoding: 'utf8',
|
||||
env,
|
||||
},
|
||||
);
|
||||
assert.strictEqual(
|
||||
installResult.status,
|
||||
0,
|
||||
`Kimi install failed\nstdout: ${installResult.stdout}\nstderr: ${installResult.stderr}`,
|
||||
);
|
||||
|
||||
fs.writeFileSync(
|
||||
path.join(tmpDir, '.planning', 'config.json'),
|
||||
JSON.stringify({ runtime: 'kimi', model_profile: 'balanced' }, null, 2),
|
||||
);
|
||||
|
||||
const initResult = runGsdTools('init new-workspace --raw', tmpDir, env);
|
||||
assert.ok(initResult.success, `init failed: ${initResult.error}`);
|
||||
const initOutput = JSON.parse(initResult.output);
|
||||
assert.strictEqual(initOutput.agent_runtime, 'kimi');
|
||||
assert.strictEqual(initOutput.agents_dir, path.join(tmpConfig, 'agents'));
|
||||
assert.strictEqual(initOutput.agents_installed, true);
|
||||
assert.deepStrictEqual(initOutput.missing_agents, []);
|
||||
|
||||
const validateResult = runGsdTools('validate agents --raw', tmpDir, {
|
||||
...env,
|
||||
GSD_RUNTIME: 'kimi',
|
||||
});
|
||||
assert.ok(validateResult.success, `validate agents failed: ${validateResult.error}`);
|
||||
const validateOutput = JSON.parse(validateResult.output);
|
||||
assert.strictEqual(validateOutput.agents_dir, path.join(tmpConfig, 'agents'));
|
||||
assert.strictEqual(validateOutput.agents_found, true);
|
||||
assert.deepStrictEqual(validateOutput.missing, []);
|
||||
|
||||
const healthResult = runGsdTools('validate health --raw', tmpDir, {
|
||||
...env,
|
||||
GSD_RUNTIME: 'kimi',
|
||||
});
|
||||
assert.ok(healthResult.success, `validate health failed: ${healthResult.error}`);
|
||||
const healthOutput = JSON.parse(healthResult.output);
|
||||
const agentWarnings = (healthOutput.warnings || []).filter(
|
||||
(warning) => warning.code === 'W010' || /GSD agents/i.test(warning.message || ''),
|
||||
);
|
||||
assert.deepStrictEqual(agentWarnings, []);
|
||||
} finally {
|
||||
cleanup(tmpDir);
|
||||
cleanup(tmpConfig);
|
||||
cleanup(tmpHome);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// ─── validate agents subcommand ─────────────────────────────────────────────
|
||||
|
||||
describe('validate agents subcommand (#1371)', () => {
|
||||
|
||||
@@ -334,7 +334,10 @@ describe('Kimi local install guard', () => {
|
||||
0,
|
||||
`second install failed\nstdout: ${second.stdout}\nstderr: ${second.stderr}`,
|
||||
);
|
||||
assert.match(`${second.stdout}\n${second.stderr}`, /locally modified GSD file/i);
|
||||
const secondOutput = `${second.stdout}\n${second.stderr}`;
|
||||
assert.match(secondOutput, /locally modified GSD file/i);
|
||||
assert.match(secondOutput, /\/skill:gsd-update --reapply/);
|
||||
assert.doesNotMatch(secondOutput, /Run\s+\/gsd-update --reapply/);
|
||||
|
||||
const skillBackup = path.join(tmpConfig, 'gsd-local-patches', 'skills', 'gsd-new-project', 'SKILL.md');
|
||||
const agentBackup = path.join(tmpConfig, 'gsd-local-patches', 'agents', 'subagents', 'gsd-executor.md');
|
||||
|
||||
@@ -9,6 +9,7 @@ const fs = require('node:fs');
|
||||
const path = require('node:path');
|
||||
|
||||
const { catalog, KNOWN_RUNTIMES } = require('../gsd-core/bin/lib/model-catalog.cjs');
|
||||
const { allRuntimes } = require('../bin/install.js');
|
||||
|
||||
const ROOT = path.join(__dirname, '..');
|
||||
const SETTINGS_ADVANCED = fs.readFileSync(path.join(ROOT, 'gsd-core', 'workflows', 'settings-advanced.md'), 'utf8');
|
||||
@@ -17,9 +18,14 @@ const CONFIG_DOC = fs.readFileSync(path.join(ROOT, 'docs', 'CONFIGURATION.md'),
|
||||
describe('model catalog runtime defaults parity (#3229)', () => {
|
||||
test('known runtimes include hermes and match catalog keys', () => {
|
||||
assert.ok(KNOWN_RUNTIMES.has('hermes'));
|
||||
assert.ok(KNOWN_RUNTIMES.has('kimi'));
|
||||
assert.deepStrictEqual([...KNOWN_RUNTIMES].sort(), Object.keys(catalog.runtimeTierDefaults).sort());
|
||||
});
|
||||
|
||||
test('installer-supported runtimes are all known to the model catalog', () => {
|
||||
assert.deepStrictEqual([...allRuntimes].sort(), [...KNOWN_RUNTIMES].sort());
|
||||
});
|
||||
|
||||
test('settings-advanced runtime defaults table matches catalog for concrete runtimes', () => {
|
||||
for (const [runtime, tiers] of Object.entries(catalog.runtimeTierDefaults)) {
|
||||
if (!tiers.opus) continue; // Group B runtimes intentionally have no built-ins
|
||||
|
||||
Reference in New Issue
Block a user