mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-07-21 22:27:13 +08:00
fix: skill list showing sub-skills inside collection
This commit is contained in:
@@ -53,6 +53,12 @@ class SkillLoader:
|
|||||||
"""
|
"""
|
||||||
Recursively load skills from a directory.
|
Recursively load skills from a directory.
|
||||||
|
|
||||||
|
If a subdirectory contains its own SKILL.md, it is treated as a
|
||||||
|
self-contained skill (or skill-collection) and its children are
|
||||||
|
NOT scanned further. This prevents sub-skills inside a collection
|
||||||
|
(e.g. style-collection/style-anjing) from being listed as
|
||||||
|
independent top-level skills.
|
||||||
|
|
||||||
:param dir_path: Directory to scan
|
:param dir_path: Directory to scan
|
||||||
:param source: Source identifier
|
:param source: Source identifier
|
||||||
:param include_root_files: Whether to include root-level .md files
|
:param include_root_files: Whether to include root-level .md files
|
||||||
@@ -67,37 +73,40 @@ class SkillLoader:
|
|||||||
diagnostics.append(f"Failed to list directory {dir_path}: {e}")
|
diagnostics.append(f"Failed to list directory {dir_path}: {e}")
|
||||||
return LoadSkillsResult(skills=skills, diagnostics=diagnostics)
|
return LoadSkillsResult(skills=skills, diagnostics=diagnostics)
|
||||||
|
|
||||||
|
# If this directory has its own SKILL.md, load it and stop recursing.
|
||||||
|
# The sub-directories are internal resources of this skill.
|
||||||
|
if not include_root_files and 'SKILL.md' in entries:
|
||||||
|
skill_md_path = os.path.join(dir_path, 'SKILL.md')
|
||||||
|
if os.path.isfile(skill_md_path):
|
||||||
|
skill_result = self._load_skill_from_file(skill_md_path, source)
|
||||||
|
if skill_result.skills:
|
||||||
|
skills.extend(skill_result.skills)
|
||||||
|
diagnostics.extend(skill_result.diagnostics)
|
||||||
|
return LoadSkillsResult(skills=skills, diagnostics=diagnostics)
|
||||||
|
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
# Skip hidden files and directories
|
|
||||||
if entry.startswith('.'):
|
if entry.startswith('.'):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Skip common non-skill directories
|
|
||||||
if entry in ('node_modules', '__pycache__', 'venv', '.git'):
|
if entry in ('node_modules', '__pycache__', 'venv', '.git'):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
full_path = os.path.join(dir_path, entry)
|
full_path = os.path.join(dir_path, entry)
|
||||||
|
|
||||||
# Handle directories
|
|
||||||
if os.path.isdir(full_path):
|
if os.path.isdir(full_path):
|
||||||
# Recursively scan subdirectories
|
|
||||||
sub_result = self._load_skills_recursive(full_path, source, include_root_files=False)
|
sub_result = self._load_skills_recursive(full_path, source, include_root_files=False)
|
||||||
skills.extend(sub_result.skills)
|
skills.extend(sub_result.skills)
|
||||||
diagnostics.extend(sub_result.diagnostics)
|
diagnostics.extend(sub_result.diagnostics)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Handle files
|
|
||||||
if not os.path.isfile(full_path):
|
if not os.path.isfile(full_path):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Check if this is a skill file
|
|
||||||
is_root_md = include_root_files and entry.endswith('.md') and entry.upper() != 'README.MD'
|
is_root_md = include_root_files and entry.endswith('.md') and entry.upper() != 'README.MD'
|
||||||
is_skill_md = not include_root_files and entry == 'SKILL.md'
|
|
||||||
|
|
||||||
if not (is_root_md or is_skill_md):
|
if not is_root_md:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
# Load the skill
|
|
||||||
skill_result = self._load_skill_from_file(full_path, source)
|
skill_result = self._load_skill_from_file(full_path, source)
|
||||||
if skill_result.skills:
|
if skill_result.skills:
|
||||||
skills.extend(skill_result.skills)
|
skills.extend(skill_result.skills)
|
||||||
|
|||||||
@@ -563,7 +563,7 @@ class ConfigHandler:
|
|||||||
_RECOMMENDED_MODELS = [
|
_RECOMMENDED_MODELS = [
|
||||||
const.MINIMAX_M2_7, const.MINIMAX_M2_5, const.MINIMAX_M2_1, const.MINIMAX_M2_1_LIGHTNING,
|
const.MINIMAX_M2_7, const.MINIMAX_M2_5, const.MINIMAX_M2_1, const.MINIMAX_M2_1_LIGHTNING,
|
||||||
const.GLM_5_TURBO, const.GLM_5, const.GLM_4_7,
|
const.GLM_5_TURBO, const.GLM_5, const.GLM_4_7,
|
||||||
const.QWEN3_MAX, const.QWEN35_PLUS,
|
const.QWEN35_PLUS, const.QWEN3_MAX,
|
||||||
const.KIMI_K2_5, const.KIMI_K2,
|
const.KIMI_K2_5, const.KIMI_K2,
|
||||||
const.DOUBAO_SEED_2_PRO, const.DOUBAO_SEED_2_CODE,
|
const.DOUBAO_SEED_2_PRO, const.DOUBAO_SEED_2_CODE,
|
||||||
const.CLAUDE_4_6_SONNET, const.CLAUDE_4_6_OPUS, const.CLAUDE_4_5_SONNET,
|
const.CLAUDE_4_6_SONNET, const.CLAUDE_4_6_OPUS, const.CLAUDE_4_5_SONNET,
|
||||||
@@ -592,7 +592,7 @@ class ConfigHandler:
|
|||||||
"api_key_field": "dashscope_api_key",
|
"api_key_field": "dashscope_api_key",
|
||||||
"api_base_key": None,
|
"api_base_key": None,
|
||||||
"api_base_default": None,
|
"api_base_default": None,
|
||||||
"models": [const.QWEN3_MAX, const.QWEN35_PLUS],
|
"models": [const.QWEN35_PLUS, const.QWEN3_MAX],
|
||||||
}),
|
}),
|
||||||
("moonshot", {
|
("moonshot", {
|
||||||
"label": "Kimi",
|
"label": "Kimi",
|
||||||
|
|||||||
@@ -172,7 +172,7 @@ MODEL_LIST = [
|
|||||||
DEEPSEEK_CHAT, DEEPSEEK_REASONER,
|
DEEPSEEK_CHAT, DEEPSEEK_REASONER,
|
||||||
|
|
||||||
# Qwen
|
# Qwen
|
||||||
QWEN, QWEN_TURBO, QWEN_PLUS, QWEN_MAX, QWEN_LONG, QWEN3_MAX, QWEN35_PLUS,
|
QWEN35_PLUS, QWEN3_MAX, QWEN_MAX, QWEN_PLUS, QWEN_TURBO, QWEN_LONG, QWEN,
|
||||||
|
|
||||||
# MiniMax
|
# MiniMax
|
||||||
MiniMax, MINIMAX_M2_7, MINIMAX_M2_5, MINIMAX_M2_1, MINIMAX_M2_1_LIGHTNING, MINIMAX_M2, MINIMAX_ABAB6_5,
|
MiniMax, MINIMAX_M2_7, MINIMAX_M2_5, MINIMAX_M2_1, MINIMAX_M2_1_LIGHTNING, MINIMAX_M2, MINIMAX_ABAB6_5,
|
||||||
|
|||||||
Reference in New Issue
Block a user